Beispiel #1
0
    def processAlgorithm(self, feedback):
        layers = self.getParameterValue(self.INPUT_DATASOURCES)
        query = self.getParameterValue(self.INPUT_QUERY)
        uid_field = self.getParameterValue(self.INPUT_UID_FIELD)
        geometry_field = self.getParameterValue(self.INPUT_GEOMETRY_FIELD)
        geometry_type = self.getParameterValue(self.INPUT_GEOMETRY_TYPE)
        geometry_crs = self.getParameterValue(self.INPUT_GEOMETRY_CRS)

        df = QgsVirtualLayerDefinition()
        layerIdx = 1
        if layers:
            for layerSource in layers.split(';'):
                layer = dataobjects.getObjectFromUri(layerSource)
                if layer:
                    df.addSource('input{}'.format(layerIdx), layer.id())
                layerIdx += 1

        if query == '':
            raise GeoAlgorithmExecutionException(
                self.tr('Empty SQL. Please enter valid SQL expression and try again.'))
        else:
            df.setQuery(query)

        if uid_field:
            df.setUid(uid_field)

        if geometry_type == 1:  # no geometry
            df.setGeometryWkbType(QgsWkbTypes.NullGeometry)
        else:
            if geometry_field:
                df.setGeometryField(geometry_field)
            if geometry_type > 1:
                df.setGeometryWkbType(geometry_type - 1)
            if geometry_crs:
                crs = QgsCoordinateReferenceSystem(geometry_crs)
                if crs.isValid():
                    df.setGeometrySrid(crs.postgisSrid())

        vLayer = QgsVectorLayer(df.toString(), "temp_vlayer", "virtual")
        if not vLayer.isValid():
            raise GeoAlgorithmExecutionException(vLayer.dataProvider().error().message())

        writer = self.getOutputFromName(self.OUTPUT_LAYER).getVectorWriter(
            vLayer.fields().toList(),
            # Create a point layer (without any points) if 'no geometry' is chosen
            vLayer.wkbType() if geometry_type != 1 else 1,
            vLayer.crs())

        features = vector.features(vLayer)
        total = 100.0 / len(features)
        outFeat = QgsFeature()
        for current, inFeat in enumerate(features):
            outFeat.setAttributes(inFeat.attributes())
            if geometry_type != 1:
                outFeat.setGeometry(inFeat.geometry())
            writer.addFeature(outFeat)
            feedback.setProgress(int(current * total))
        del writer
Beispiel #2
0
 def setUpClass(cls):
     """Run before all tests"""
     # Create the layer for the common provider tests
     shp = os.path.join(TEST_DATA_DIR, 'provider/shapefile.shp')
     d = QgsVirtualLayerDefinition()
     d.addSource("vtab1", shp, "ogr")
     d.setUid("pk")
     cls.vl = QgsVectorLayer(d.toString(), u'test', u'virtual')
     assert (cls.vl.isValid())
     cls.provider = cls.vl.dataProvider()
Beispiel #3
0
 def toSqlLayer(self, sql, geomCol, uniqueCol, layerName="QueryLayer", layerType=None, avoidSelectById=False, _filter=""):
     df = QgsVirtualLayerDefinition()
     df.setQuery(sql)
     if uniqueCol is not None:
         uniqueCol = uniqueCol.strip('"').replace('""', '"')
         df.setUid(uniqueCol)
     if geomCol is not None:
         df.setGeometryField(geomCol)
     vl = QgsVectorLayer(df.toString(), layerName, "virtual")
     if _filter:
         vl.setSubsetString(_filter)
     return vl
Beispiel #4
0
    def processAlgorithm(self, parameters, context, feedback):
        layers = self.parameterAsLayerList(parameters, self.INPUT_DATASOURCES, context)
        query = self.parameterAsString(parameters, self.INPUT_QUERY, context)
        uid_field = self.parameterAsString(parameters, self.INPUT_UID_FIELD, context)
        geometry_field = self.parameterAsString(parameters, self.INPUT_GEOMETRY_FIELD, context)
        geometry_type = self.parameterAsEnum(parameters, self.INPUT_GEOMETRY_TYPE, context)
        geometry_crs = self.parameterAsCrs(parameters, self.INPUT_GEOMETRY_CRS, context)

        df = QgsVirtualLayerDefinition()
        for layerIdx, layer in enumerate(layers):
            df.addSource('input{}'.format(layerIdx + 1), layer.id())

        if query == '':
            raise QgsProcessingException(
                self.tr('Empty SQL. Please enter valid SQL expression and try again.'))
        else:
            localContext = self.createExpressionContext(parameters, context)
            expandedQuery = QgsExpression.replaceExpressionText(query, localContext)
            df.setQuery(expandedQuery)

        if uid_field:
            df.setUid(uid_field)

        if geometry_type == 1:  # no geometry
            df.setGeometryWkbType(QgsWkbTypes.NoGeometry)
        else:
            if geometry_field:
                df.setGeometryField(geometry_field)
            if geometry_type > 1:
                df.setGeometryWkbType(geometry_type - 1)
            if geometry_crs.isValid():
                df.setGeometrySrid(geometry_crs.postgisSrid())

        vLayer = QgsVectorLayer(df.toString(), "temp_vlayer", "virtual")
        if not vLayer.isValid():
            raise QgsProcessingException(vLayer.dataProvider().error().message())

        (sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context,
                                               vLayer.fields(), vLayer.wkbType() if geometry_type != 1 else 1, vLayer.crs())
        if sink is None:
            raise QgsProcessingException(self.invalidSinkError(parameters, self.OUTPUT))

        features = vLayer.getFeatures()
        total = 100.0 / vLayer.featureCount() if vLayer.featureCount() else 0
        for current, inFeat in enumerate(features):
            if feedback.isCanceled():
                break

            sink.addFeature(inFeat, QgsFeatureSink.FastInsert)
            feedback.setProgress(int(current * total))
        return {self.OUTPUT: dest_id}
Beispiel #5
0
    def setUpClass(cls):
        """Run before all tests"""
        # Create the layer for the common provider tests
        shp = os.path.join(TEST_DATA_DIR, "provider/shapefile.shp")
        d = QgsVirtualLayerDefinition()
        d.addSource("vtab1", shp, "ogr")
        d.setUid("pk")
        cls.vl = QgsVectorLayer(d.toString(), "test", "virtual")
        assert cls.vl.isValid()
        cls.provider = cls.vl.dataProvider()

        shp_poly = os.path.join(TEST_DATA_DIR, "provider/shapefile_poly.shp")
        d = QgsVirtualLayerDefinition()
        d.addSource("vtab2", shp_poly, "ogr")
        d.setUid("pk")
        cls.poly_vl = QgsVectorLayer(d.toString(), "test_poly", "virtual")
        assert cls.poly_vl.isValid()
        cls.poly_provider = cls.poly_vl.dataProvider()
Beispiel #6
0
    def setUpClass(cls):
        """Run before all tests"""
        # Create the layer for the common provider tests
        shp = os.path.join(TEST_DATA_DIR, 'provider/shapefile.shp')
        d = QgsVirtualLayerDefinition()
        d.addSource("vtab1", shp, "ogr")
        d.setUid("pk")
        cls.vl = QgsVectorLayer(d.toString(), 'test', 'virtual')
        assert (cls.vl.isValid())
        cls.provider = cls.vl.dataProvider()

        shp_poly = os.path.join(TEST_DATA_DIR, 'provider/shapefile_poly.shp')
        d = QgsVirtualLayerDefinition()
        d.addSource("vtab2", shp_poly, "ogr")
        d.setUid("pk")
        cls.poly_vl = QgsVectorLayer(d.toString(), 'test_poly', 'virtual')
        assert (cls.poly_vl.isValid())
        cls.poly_provider = cls.poly_vl.dataProvider()
Beispiel #7
0
 def toSqlLayer(self,
                sql,
                geomCol,
                uniqueCol,
                layerName="QueryLayer",
                layerType=None,
                avoidSelectById=False,
                _filter=""):
     df = QgsVirtualLayerDefinition()
     df.setQuery(sql)
     if uniqueCol is not None:
         uniqueCol = uniqueCol.strip('"').replace('""', '"')
         df.setUid(uniqueCol)
     if geomCol is not None:
         df.setGeometryField(geomCol)
     vl = QgsVectorLayer(df.toString(), layerName, "virtual")
     if _filter:
         vl.setSubsetString(_filter)
     return vl
Beispiel #8
0
    def processAlgorithm(self, feedback):
        layers = self.getParameterValue(self.INPUT_DATASOURCES)
        query = self.getParameterValue(self.INPUT_QUERY)
        uid_field = self.getParameterValue(self.INPUT_UID_FIELD)
        geometry_field = self.getParameterValue(self.INPUT_GEOMETRY_FIELD)
        geometry_type = self.getParameterValue(self.INPUT_GEOMETRY_TYPE)
        geometry_crs = self.getParameterValue(self.INPUT_GEOMETRY_CRS)

        df = QgsVirtualLayerDefinition()
        layerIdx = 1
        if layers:
            for layerSource in layers.split(';'):
                layer = dataobjects.getLayerFromString(layerSource)
                if layer:
                    df.addSource('input{}'.format(layerIdx), layer.id())
                layerIdx += 1

        if query == '':
            raise GeoAlgorithmExecutionException(
                self.
                tr('Empty SQL. Please enter valid SQL expression and try again.'
                   ))
        else:
            df.setQuery(query)

        if uid_field:
            df.setUid(uid_field)

        if geometry_type == 1:  # no geometry
            df.setGeometryWkbType(QgsWkbTypes.NullGeometry)
        else:
            if geometry_field:
                df.setGeometryField(geometry_field)
            if geometry_type > 1:
                df.setGeometryWkbType(geometry_type - 1)
            if geometry_crs:
                crs = QgsCoordinateReferenceSystem(geometry_crs)
                if crs.isValid():
                    df.setGeometrySrid(crs.postgisSrid())

        vLayer = QgsVectorLayer(df.toString(), "temp_vlayer", "virtual")
        if not vLayer.isValid():
            raise GeoAlgorithmExecutionException(
                vLayer.dataProvider().error().message())

        writer = self.getOutputFromName(self.OUTPUT_LAYER).getVectorWriter(
            vLayer.fields().toList(),
            # Create a point layer (without any points) if 'no geometry' is chosen
            vLayer.wkbType() if geometry_type != 1 else 1,
            vLayer.crs())

        features = vector.features(vLayer)
        total = 100.0 / len(features)
        outFeat = QgsFeature()
        for current, inFeat in enumerate(features):
            outFeat.setAttributes(inFeat.attributes())
            if geometry_type != 1:
                outFeat.setGeometry(inFeat.geometry())
            writer.addFeature(outFeat)
            feedback.setProgress(int(current * total))
        del writer
Beispiel #9
0
    def processAlgorithm(self, parameters, context, feedback):
        layers = self.parameterAsLayerList(parameters, self.INPUT_DATASOURCES,
                                           context)
        query = self.parameterAsString(parameters, self.INPUT_QUERY, context)
        uid_field = self.parameterAsString(parameters, self.INPUT_UID_FIELD,
                                           context)
        geometry_field = self.parameterAsString(parameters,
                                                self.INPUT_GEOMETRY_FIELD,
                                                context)
        geometry_type = self.parameterAsEnum(parameters,
                                             self.INPUT_GEOMETRY_TYPE, context)
        geometry_crs = self.parameterAsCrs(parameters, self.INPUT_GEOMETRY_CRS,
                                           context)

        df = QgsVirtualLayerDefinition()
        for layerIdx, layer in enumerate(layers):
            df.addSource('input{}'.format(layerIdx + 1), layer.id())

        if query == '':
            raise QgsProcessingException(
                self.
                tr('Empty SQL. Please enter valid SQL expression and try again.'
                   ))
        else:
            localContext = self.createExpressionContext(parameters, context)
            expandedQuery = QgsExpression.replaceExpressionText(
                query, localContext)
            df.setQuery(expandedQuery)

        if uid_field:
            df.setUid(uid_field)

        if geometry_type == 1:  # no geometry
            df.setGeometryWkbType(QgsWkbTypes.NoGeometry)
        else:
            if geometry_field:
                df.setGeometryField(geometry_field)
            if geometry_type > 1:
                df.setGeometryWkbType(geometry_type - 1)
            if geometry_crs.isValid():
                df.setGeometrySrid(geometry_crs.postgisSrid())

        vLayer = QgsVectorLayer(df.toString(), "temp_vlayer", "virtual")
        if not vLayer.isValid():
            raise QgsProcessingException(
                vLayer.dataProvider().error().message())

        (sink, dest_id) = self.parameterAsSink(
            parameters, self.OUTPUT, context, vLayer.fields(),
            vLayer.wkbType() if geometry_type != 1 else 1, vLayer.crs())
        if sink is None:
            raise QgsProcessingException(
                self.invalidSinkError(parameters, self.OUTPUT))

        features = vLayer.getFeatures()
        total = 100.0 / vLayer.featureCount() if vLayer.featureCount() else 0
        for current, inFeat in enumerate(features):
            if feedback.isCanceled():
                break

            sink.addFeature(inFeat, QgsFeatureSink.FastInsert)
            feedback.setProgress(int(current * total))
        return {self.OUTPUT: dest_id}
Beispiel #10
0
    def processAlgorithm(self, parameters, context, feedback):
        layers = self.parameterAsLayerList(parameters, self.INPUT_DATASOURCES,
                                           context)
        query = self.parameterAsString(parameters, self.INPUT_QUERY, context)
        uid_field = self.parameterAsString(parameters, self.INPUT_UID_FIELD,
                                           context)
        geometry_field = self.parameterAsString(parameters,
                                                self.INPUT_GEOMETRY_FIELD,
                                                context)
        geometry_type = self.parameterAsEnum(parameters,
                                             self.INPUT_GEOMETRY_TYPE, context)
        geometry_crs = self.parameterAsCrs(parameters, self.INPUT_GEOMETRY_CRS,
                                           context)

        df = QgsVirtualLayerDefinition()
        for layerIdx, layer in enumerate(layers):

            # Issue https://github.com/qgis/QGIS/issues/24041
            # When using this algorithm from the graphic modeler, it may try to
            # access (thanks the QgsVirtualLayerProvider) to memory layer that
            # belongs to temporary QgsMapLayerStore, not project.
            # So, we write them to disk is this is the case.
            if context.project() and not context.project().mapLayer(
                    layer.id()):
                basename = "memorylayer." + QgsVectorFileWriter.supportedFormatExtensions(
                )[0]
                tmp_path = QgsProcessingUtils.generateTempFilename(basename)
                QgsVectorFileWriter.writeAsVectorFormat(
                    layer, tmp_path,
                    layer.dataProvider().encoding())
                df.addSource('input{}'.format(layerIdx + 1), tmp_path, "ogr")
            else:
                df.addSource('input{}'.format(layerIdx + 1), layer.id())

        if query == '':
            raise QgsProcessingException(
                self.
                tr('Empty SQL. Please enter valid SQL expression and try again.'
                   ))
        localContext = self.createExpressionContext(parameters, context)
        expandedQuery = QgsExpression.replaceExpressionText(
            query, localContext)
        df.setQuery(expandedQuery)

        if uid_field:
            df.setUid(uid_field)

        if geometry_type == 1:  # no geometry
            df.setGeometryWkbType(QgsWkbTypes.NoGeometry)
        else:
            if geometry_field:
                df.setGeometryField(geometry_field)
            if geometry_type > 1:
                df.setGeometryWkbType(geometry_type - 1)
            if geometry_crs.isValid():
                df.setGeometrySrid(geometry_crs.postgisSrid())

        vLayer = QgsVectorLayer(df.toString(), "temp_vlayer", "virtual")
        if not vLayer.isValid():
            raise QgsProcessingException(
                vLayer.dataProvider().error().message())

        if vLayer.wkbType() == QgsWkbTypes.Unknown:
            raise QgsProcessingException(self.tr("Cannot find geometry field"))

        (sink, dest_id) = self.parameterAsSink(
            parameters, self.OUTPUT, context, vLayer.fields(),
            vLayer.wkbType() if geometry_type != 1 else 1, vLayer.crs())
        if sink is None:
            raise QgsProcessingException(
                self.invalidSinkError(parameters, self.OUTPUT))

        features = vLayer.getFeatures()
        total = 100.0 / vLayer.featureCount() if vLayer.featureCount() else 0
        for current, inFeat in enumerate(features):
            if feedback.isCanceled():
                break

            sink.addFeature(inFeat, QgsFeatureSink.FastInsert)
            feedback.setProgress(int(current * total))
        return {self.OUTPUT: dest_id}