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
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()
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
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}
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()
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()
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
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
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}
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}