def test_geometry_conversion(self): query = toPercent("select geomfromtext('multipoint((0 0),(1 1))') as geom") l = QgsVectorLayer("?query=%s&geometry=geom:multipoint:0" % query, "tt", "virtual", QgsVectorLayer.LayerOptions(False)) self.assertEqual(l.isValid(), True) for f in l.getFeatures(): self.assertEqual(f.geometry().asWkt().lower().startswith("multipoint"), True) self.assertEqual("),(" in f.geometry().asWkt(), True) # has two points query = toPercent("select geomfromtext('multipolygon(((0 0,1 0,1 1,0 1,0 0)),((0 1,1 1,1 2,0 2,0 1)))') as geom") l = QgsVectorLayer("?query=%s&geometry=geom:multipolygon:0" % query, "tt", "virtual", QgsVectorLayer.LayerOptions(False)) self.assertEqual(l.isValid(), True) for f in l.getFeatures(): self.assertEqual(f.geometry().asWkt().lower().startswith("multipolygon"), True) self.assertEqual(")),((" in f.geometry().asWkt(), True) # has two polygons query = toPercent("select geomfromtext('multilinestring((0 0,1 0,1 1,0 1,0 0),(0 1,1 1,1 2,0 2,0 1))') as geom") l = QgsVectorLayer("?query=%s&geometry=geom:multilinestring:0" % query, "tt", "virtual", QgsVectorLayer.LayerOptions(False)) self.assertEqual(l.isValid(), True) for f in l.getFeatures(): self.assertEqual(f.geometry().asWkt().lower().startswith("multilinestring"), True) self.assertEqual("),(" in f.geometry().asWkt(), True) # has two linestrings
def test_lazy(self): l1 = QgsVectorLayer(os.path.join(self.testDataDir, "france_parts.shp"), "françéà", "ogr", QgsVectorLayer.LayerOptions(False)) self.assertEqual(l1.isValid(), True) QgsProject.instance().addMapLayer(l1) df = QgsVirtualLayerDefinition() df.setQuery('select * from "françéà"') df.setLazy(True) vl = QgsVectorLayer(df.toString(), "testq", "virtual") self.assertEqual(vl.isValid(), True) ids = [f.id() for f in vl.getFeatures()] self.assertEqual(len(ids), 0) vl.reload() ids = [f.id() for f in vl.getFeatures()] self.assertEqual(len(ids), 4) QgsProject.instance().removeMapLayer(l1.id())
def test_sql(self): l1 = QgsVectorLayer(QUrl.fromLocalFile(os.path.join(self.testDataDir, "delimitedtext/test.csv")).toString() + "?type=csv&geomType=none&subsetIndex=no&watchFile=no", "test", "delimitedtext", QgsVectorLayer.LayerOptions(False)) self.assertEqual(l1.isValid(), True) QgsProject.instance().addMapLayer(l1) l3 = QgsVectorLayer("?query=SELECT * FROM test", "tt", "virtual") self.assertEqual(l3.isValid(), True) s = sum(f.id() for f in l3.getFeatures()) self.assertEqual(s, 15)
def test_rowid(self): source = toPercent(os.path.join(self.testDataDir, "france_parts.shp")) query = toPercent("select rowid as uid, * from vtab limit 1 offset 3") l = QgsVectorLayer("?layer=ogr:%s:vtab&query=%s" % (source, query), "vtab2", "virtual", QgsVectorLayer.LayerOptions(False)) # the last line must have a fixed rowid (not an autoincrement) for f in l.getFeatures(): lid = f.attributes()[0] self.assertEqual(lid, 3)
def standalone_table_to_QgsVectorLayer( layer: StandaloneTable, # pylint: disable=too-many-locals,too-many-branches input_file, context: Context): """ Converts a standalone table to a vector layer """ subset_string = '' if layer.definition_query: subset_string = ExpressionConverter.convert_esri_sql( layer.definition_query) base, _ = os.path.split(input_file) uri, wkb_type, provider, encoding, file_name = VectorLayerConverter.get_uri( source_layer=layer, obj=layer, base=base, crs=QgsCoordinateReferenceSystem(), subset=subset_string, context=context) if wkb_type is None: wkb_type = QgsWkbTypes.NoGeometry context.layer_type_hint = wkb_type if provider == 'ogr' and (not file_name or not os.path.exists(file_name) ) and context.invalid_layer_resolver: res = context.invalid_layer_resolver(layer.name, uri, wkb_type) uri = res.uri provider = res.providerKey if Qgis.QGIS_VERSION_INT >= 31000: opts = QgsVectorLayer.LayerOptions() if wkb_type is not None: opts.fallbackWkbType = wkb_type if provider == 'ogr' and subset_string: uri += '|subset={}'.format(subset_string) vl = QgsVectorLayer(uri, layer.name, provider, opts) else: vl = QgsMemoryProviderUtils.createMemoryLayer( layer.name, QgsFields(), wkb_type, QgsCoordinateReferenceSystem()) metadata = vl.metadata() metadata.setAbstract(layer.description) vl.setMetadata(metadata) # if Qgis.QGIS_VERSION_INT < 31000: vl.setDataSource(uri, layer.name, provider) if encoding: vl.dataProvider().setEncoding(encoding) if subset_string: vl.setSubsetString(subset_string) for e in layer.extensions: if e.__class__.__name__ == 'ServerLayerExtension': if 'CopyrightText' in e.properties.properties: layer_credits = e.properties.properties['CopyrightText'] metadata = vl.metadata() rights = metadata.rights() rights.append(layer_credits) metadata.setRights(rights) vl.setMetadata(metadata) # setup joins join_layer = VectorLayerConverter.add_joined_layer( source_layer=layer, input_file=input_file, base_layer=vl, context=context) context.dataset_name = '' vl.setLegend(QgsMapLayerLegend.defaultVectorLegend(vl)) res = [vl] if join_layer: res.append(join_layer) return res
def test_refLayers(self): l1 = QgsVectorLayer(QUrl.fromLocalFile(os.path.join(self.testDataDir, "delimitedtext/test.csv")).toString() + "?type=csv&geomType=none&subsetIndex=no&watchFile=no", "test", "delimitedtext", QgsVectorLayer.LayerOptions(False)) self.assertEqual(l1.isValid(), True) QgsProject.instance().addMapLayer(l1) # cf qgis bug #12266 for i in range(10): q = toPercent("select * from t" + str(i)) l2 = QgsVectorLayer("?layer_ref=%s:t%d&query=%s&uid=id" % (l1.id(), i, q), "vtab", "virtual", QgsVectorLayer.LayerOptions(False)) QgsProject.instance().addMapLayer(l2) self.assertEqual(l2.isValid(), True) s = sum([f.id() for f in l2.dataProvider().getFeatures()]) # NOQA self.assertEqual(sum([f.id() for f in l2.getFeatures()]), 21) QgsProject.instance().removeMapLayer(l2.id())
def test_QueryTableName(self): l1 = QgsVectorLayer(os.path.join(self.testDataDir, "france_parts.shp"), "france_parts", "ogr", QgsVectorLayer.LayerOptions(False)) self.assertEqual(l1.isValid(), True) QgsProject.instance().addMapLayer(l1) query = toPercent("SELECT * FROM vt") l2 = QgsVectorLayer("?layer_ref=%s:vt&query=%s&uid=ObJeCtId&nogeometry" % (l1.id(), query), "vtab", "virtual", QgsVectorLayer.LayerOptions(False)) self.assertEqual(l2.isValid(), True) self.assertEqual(l2.dataProvider().wkbType(), 100) # NoGeometry QgsProject.instance().removeMapLayer(l1.id())
def test_sql_field_types(self): query = toPercent( "SELECT 42 as t, 'ok'||'ok' as t2, GeomFromText('') as t3, 3.14*2 as t4" ) l4 = QgsVectorLayer("?query=%s" % query, "tt", "virtual", QgsVectorLayer.LayerOptions(False)) self.assertEqual(l4.isValid(), True) self.assertEqual(l4.dataProvider().fields().at(0).name(), "t") self.assertEqual(l4.dataProvider().fields().at(0).type(), QVariant.Int) self.assertEqual(l4.dataProvider().fields().at(1).name(), "t2") self.assertEqual(l4.dataProvider().fields().at(1).type(), QVariant.String) self.assertEqual(l4.dataProvider().fields().at(2).name(), "t3") self.assertEqual(l4.dataProvider().fields().at(2).type(), QVariant.String) self.assertEqual(l4.dataProvider().fields().at(3).name(), "t4") self.assertEqual(l4.dataProvider().fields().at(3).type(), QVariant.Double) # with type annotations query = toPercent( "SELECT '42.0' as t /*:real*/, 3 as t2/*:text */, GeomFromText('') as t3 /*:multiPoInT:4326 */, 3.14*2 as t4/*:int*/" ) l4 = QgsVectorLayer("?query=%s" % query, "tt", "virtual", QgsVectorLayer.LayerOptions(False)) self.assertEqual(l4.isValid(), True) self.assertEqual(l4.dataProvider().fields().at(0).name(), "t") self.assertEqual(l4.dataProvider().fields().at(0).type(), QVariant.Double) self.assertEqual(l4.dataProvider().fields().at(1).name(), "t2") self.assertEqual(l4.dataProvider().fields().at(1).type(), QVariant.String) self.assertEqual(l4.dataProvider().fields().at(2).name(), "t4") self.assertEqual(l4.dataProvider().fields().at(2).type(), QVariant.Int) self.assertEqual(l4.dataProvider().wkbType(), 4) # multipoint # test value types (!= from declared column types) for f in l4.getFeatures(): self.assertEqual(f.attributes()[0], "42.0") self.assertEqual(f.attributes()[1], 3) self.assertEqual(f.attributes()[2], 6.28) # with type annotations and url options query = toPercent( "SELECT 1 as id /*:int*/, geomfromtext('point(0 0)',4326) as geometry/*:point:4326*/" ) l4 = QgsVectorLayer("?query=%s&geometry=geometry" % query, "tt", "virtual", QgsVectorLayer.LayerOptions(False)) self.assertEqual(l4.isValid(), True) self.assertEqual(l4.dataProvider().wkbType(), 1) # point # with type annotations and url options (2) query = toPercent( "SELECT 1 as id /*:int*/, 3.14 as f, geomfromtext('point(0 0)',4326) as geometry/*:point:4326*/" ) l4 = QgsVectorLayer( "?query=%s&geometry=geometry&field=id:text" % query, "tt", "virtual", QgsVectorLayer.LayerOptions(False)) self.assertEqual(l4.isValid(), True) self.assertEqual(l4.dataProvider().fields().at(0).name(), "id") self.assertEqual(l4.dataProvider().fields().at(0).type(), QVariant.String) self.assertEqual(l4.dataProvider().fields().at(1).name(), "f") self.assertEqual(l4.dataProvider().fields().at(1).type(), QVariant.Double) self.assertEqual(l4.dataProvider().wkbType(), 1) # point
def test_DynamicGeometry(self): l1 = QgsVectorLayer(QUrl.fromLocalFile(os.path.join(self.testDataDir, "delimitedtext/testextpt.txt")).toString() + "?type=csv&delimiter=%7C&geomType=none&subsetIndex=no&watchFile=no", "test", "delimitedtext", QgsVectorLayer.LayerOptions(False)) self.assertEqual(l1.isValid(), True) QgsProject.instance().addMapLayer(l1) query = toPercent("select *,makepoint(x,y) as geom from vtab1") l2 = QgsVectorLayer("?layer_ref=%s&query=%s&geometry=geom:point:0&uid=id" % (l1.id(), query), "vtab", "virtual", QgsVectorLayer.LayerOptions(False)) self.assertEqual(l2.isValid(), True) QgsProject.instance().removeMapLayer(l1)
def test_QueryUrlEncoding(self): l1 = QgsVectorLayer(os.path.join(self.testDataDir, "france_parts.shp"), "france_parts", "ogr", QgsVectorLayer.LayerOptions(False)) self.assertEqual(l1.isValid(), True) QgsProject.instance().addMapLayer(l1) query = toPercent("SELECT * FROM vtab1") l2 = QgsVectorLayer("?layer_ref=%s&query=%s&uid=ObjectId&nogeometry" % (l1.id(), query), "vtab", "virtual", QgsVectorLayer.LayerOptions(False)) self.assertEqual(l2.isValid(), True) QgsProject.instance().removeMapLayer(l1.id())
def test(self): l1 = QgsVectorLayer(os.path.join(self.testDataDir, "france_parts.shp"), "françéà", "ogr", QgsVectorLayer.LayerOptions(False)) self.assertEqual(l1.isValid(), True) QgsProject.instance().addMapLayer(l1) df = QgsVirtualLayerDefinition() df.setQuery('select * from "françéà"') self.task = QgsVirtualLayerTask(df) ids = [f.id() for f in self.task.layer().getFeatures()] self.assertEqual(len(ids), 0) self.task.taskCompleted.connect(self.onSuccess) self.task.taskTerminated.connect(self.onFail) QgsApplication.taskManager().addTask(self.task) while not self._success and not self._fail: QCoreApplication.processEvents() self.assertTrue(self._success) self.assertFalse(self._fail) self.assertEqual(len(self.ids), 4) # Test exception self._success = False self._fail = False df.setQuery('select *') self.task = QgsVirtualLayerTask(df) self.task.taskCompleted.connect(self.onSuccess) self.task.taskTerminated.connect(self.onFail) QgsApplication.taskManager().addTask(self.task) while not self._success and not self._fail: QCoreApplication.processEvents() self.assertFalse(self._success) self.assertTrue(self._fail) self.assertEqual(self._exceptionText, 'Query preparation error on PRAGMA table_info(_tview): no tables specified', self._exceptionText)
def accept(self): """Do PetaBencana download and display it in QGIS. .. versionadded: 3.3 """ self.save_state() try: self.require_directory() except CanceledImportDialogError: return QgsApplication.instance().setOverrideCursor( QtGui.QCursor(QtCore.Qt.WaitCursor)) source = self.define_url() # save the file as json first name = 'jakarta_flood.json' output_directory = self.output_directory.text() output_prefix = self.filename_prefix.text() overwrite = self.overwrite_flag.isChecked() date_stamp_flag = self.include_date_flag.isChecked() output_base_file_path = self.get_output_base_path( output_directory, output_prefix, date_stamp_flag, name, overwrite) title = self.tr("Can't access API") try: self.download(source, output_base_file_path) # Open downloaded file as QgsMapLayer options = QgsVectorLayer.LayerOptions(False) layer = QgsVectorLayer(output_base_file_path, 'flood', 'ogr', options) except Exception as e: disable_busy_cursor() QMessageBox.critical(self, title, str(e)) return self.time_stamp = time.strftime('%d-%b-%Y %H:%M:%S') # Now save as shp name = 'jakarta_flood.shp' output_base_file_path = self.get_output_base_path( output_directory, output_prefix, date_stamp_flag, name, overwrite) QgsVectorFileWriter.writeAsVectorFormat(layer, output_base_file_path, 'CP1250', QgsCoordinateTransform(), 'ESRI Shapefile') # Get rid of the GeoJSON layer and rather use local shp del layer self.copy_style(output_base_file_path) self.copy_keywords(output_base_file_path) layer = self.add_flooded_field(output_base_file_path) # check if the layer has feature or not if layer.featureCount() <= 0: city = self.city_combo_box.currentText() message = self.tr('There are no floods data available on {city} ' 'at this time.').format(city=city) display_warning_message_box(self, self.tr('No data'), message) disable_busy_cursor() else: # add the layer to the map project = QgsProject.instance() project.addMapLayer(layer) disable_busy_cursor() self.done(QDialog.Accepted)
def add_joined_layer( source_layer: Union[FeatureLayer, StandaloneTable], # pylint: disable=too-many-branches input_file, base_layer: QgsVectorLayer, context: Context): """ Adds joined layers """ if not source_layer.join: return None if isinstance(source_layer.join, MemoryRelationshipClassName): if isinstance(source_layer.join.origin_name, RelQueryTableName): if context.unsupported_object_callback: context.unsupported_object_callback( '{}: Nested joins are not supported in QGIS'.format( context.layer_name), level=Context.CRITICAL) return None join_info = QgsVectorLayerJoinInfo() join_info.setJoinFieldName(source_layer.join.origin_primary_key) join_info.setTargetFieldName(source_layer.join.origin_foreign_key) base, _ = os.path.split(input_file) source_layer_props = DatasetNameConverter.convert( name=source_layer.join.destination_name, base=base, crs=QgsCoordinateReferenceSystem(), context=context) context.layer_type_hint = source_layer_props.wkb_type name = 'join' if hasattr(source_layer.join.destination_name, 'name'): name = source_layer.join.destination_name.name join_info.setPrefix(name + '.') if Qgis.QGIS_VERSION_INT >= 30800: opts = QgsVectorLayer.LayerOptions() if source_layer_props.wkb_type is not None: opts.fallbackWkbType = source_layer_props.wkb_type vl = QgsVectorLayer(source_layer_props.uri, name, source_layer_props.provider, opts) else: vl = QgsVectorLayer(source_layer_props.uri, name, source_layer_props.provider) if not vl.isValid() and Qgis.QGIS_VERSION_INT < 30600: if source_layer_props.provider == 'ogr' and not os.path.exists( source_layer_props.file_name ) and context.invalid_layer_resolver: res = context.invalid_layer_resolver( source_layer.join.name, source_layer_props.uri, source_layer_props.wkb_type) source_layer_props.uri = res.uri source_layer_props.provider = res.providerKey vl = QgsVectorLayer(source_layer_props.uri, 'join', source_layer_props.provider) # todo layer name vl.setRenderer(QgsNullSymbolRenderer()) try: vl.setFlags(vl.flags() | QgsMapLayer.Private) except AttributeError: pass join_info.setJoinLayer(vl) base_layer.addJoin(join_info) return vl else: if context.unsupported_object_callback: context.unsupported_object_callback( '{}: Join layers of type {} are not yet supported'.format( context.layer_name, source_layer.join.__class__.__name__), level=Context.CRITICAL) return None
def test_Query(self): l1 = QgsVectorLayer(os.path.join(self.testDataDir, "france_parts.shp"), "france_parts", "ogr", QgsVectorLayer.LayerOptions(False)) self.assertEqual(l1.isValid(), True) QgsProject.instance().addMapLayer(l1) ref_sum = sum(f.attributes()[0] for f in l1.getFeatures()) query = toPercent("SELECT * FROM vtab1") l2 = QgsVectorLayer( "?layer_ref=%s&geometry=geometry:3:4326&query=%s&uid=OBJECTID" % (l1.id(), query), "vtab", "virtual", QgsVectorLayer.LayerOptions(False)) self.assertEqual(l2.isValid(), True) self.assertEqual(l2.dataProvider().wkbType(), 3) ref_sum2 = sum(f.attributes()[0] for f in l2.getFeatures()) ref_sum3 = sum(f.id() for f in l2.getFeatures()) # check we have the same rows self.assertEqual(ref_sum, ref_sum2) # check the id is OK self.assertEqual(ref_sum, ref_sum3) # the same, without specifying the geometry column name l2 = QgsVectorLayer( "?layer_ref=%s&query=%s&uid=OBJECTID" % (l1.id(), query), "vtab", "virtual", QgsVectorLayer.LayerOptions(False)) self.assertEqual(l2.isValid(), True) self.assertEqual(l2.dataProvider().wkbType(), 6) ref_sum2 = sum(f.attributes()[0] for f in l2.getFeatures()) ref_sum3 = sum(f.id() for f in l2.getFeatures()) # check we have the same rows self.assertEqual(ref_sum, ref_sum2) # check the id is OK self.assertEqual(ref_sum, ref_sum3) # with two geometry columns query = toPercent("SELECT *,geometry as geom FROM vtab1") l2 = QgsVectorLayer( "?layer_ref=%s&query=%s&uid=OBJECTID&geometry=geom:3:4326" % (l1.id(), query), "vtab", "virtual", QgsVectorLayer.LayerOptions(False)) self.assertEqual(l2.isValid(), True) self.assertEqual(l2.dataProvider().wkbType(), 3) ref_sum2 = sum(f.attributes()[0] for f in l2.getFeatures()) ref_sum3 = sum(f.id() for f in l2.getFeatures()) # check we have the same rows self.assertEqual(ref_sum, ref_sum2) # check the id is OK self.assertEqual(ref_sum, ref_sum3) # with two geometry columns, but no geometry column specified (will take the first) l2 = QgsVectorLayer( "?layer_ref=%s&query=%s&uid=OBJECTID" % (l1.id(), query), "vtab", "virtual", QgsVectorLayer.LayerOptions(False)) self.assertEqual(l2.isValid(), True) self.assertEqual(l2.dataProvider().wkbType(), 6) ref_sum2 = sum(f.attributes()[0] for f in l2.getFeatures()) ref_sum3 = sum(f.id() for f in l2.getFeatures()) # check we have the same rows self.assertEqual(ref_sum, ref_sum2) # check the id is OK self.assertEqual(ref_sum, ref_sum3) # the same, without geometry query = toPercent("SELECT * FROM ww") l2 = QgsVectorLayer( "?layer_ref=%s:ww&query=%s&uid=ObJeCtId&nogeometry" % (l1.id(), query), "vtab", "virtual", QgsVectorLayer.LayerOptions(False)) self.assertEqual(l2.isValid(), True) self.assertEqual(l2.dataProvider().wkbType(), 100) # NoGeometry ref_sum2 = sum(f.attributes()[0] for f in l2.getFeatures()) ref_sum3 = sum(f.id() for f in l2.getFeatures()) self.assertEqual(ref_sum, ref_sum2) self.assertEqual(ref_sum, ref_sum3) # check that it fails when a query has a wrong geometry column l2 = QgsVectorLayer( "?layer_ref=%s&query=%s&geometry=geo" % (l1.id(), query), "vtab", "virtual", QgsVectorLayer.LayerOptions(False)) self.assertEqual(l2.isValid(), False) QgsProject.instance().removeMapLayer(l1.id())
def test_Join(self): l1 = QgsVectorLayer(os.path.join(self.testDataDir, "points.shp"), "points", "ogr", QgsVectorLayer.LayerOptions(False)) self.assertEqual(l1.isValid(), True) QgsProject.instance().addMapLayer(l1) l2 = QgsVectorLayer(os.path.join(self.testDataDir, "points_relations.shp"), "points_relations", "ogr", QgsVectorLayer.LayerOptions(False)) self.assertEqual(l2.isValid(), True) QgsProject.instance().addMapLayer(l2) ref_sum = sum(f.attributes()[1] for f in l2.getFeatures()) # use a temporary file query = toPercent("select id,Pilots,vtab1.geometry from vtab1,vtab2 where intersects(vtab1.geometry,vtab2.geometry)") l3 = QgsVectorLayer("?layer_ref=%s&layer_ref=%s&uid=id&query=%s&geometry=geometry:1:4326" % (l1.id(), l2.id(), query), "vtab", "virtual", QgsVectorLayer.LayerOptions(False)) self.assertEqual(l3.isValid(), True) self.assertEqual(l3.dataProvider().wkbType(), 1) self.assertEqual(l3.dataProvider().fields().count(), 2) ref_sum2 = sum(f.id() for f in l3.getFeatures()) self.assertEqual(ref_sum, ref_sum2) QgsProject.instance().removeMapLayer(l1) QgsProject.instance().removeMapLayer(l2)
def test_sql2(self): l2 = QgsVectorLayer(os.path.join(self.testDataDir, "france_parts.shp"), "france_parts", "ogr", QgsVectorLayer.LayerOptions(False)) self.assertEqual(l2.isValid(), True) QgsProject.instance().addMapLayer(l2) query = toPercent("SELECT * FROM france_parts") l4 = QgsVectorLayer("?query=%s&uid=ObjectId" % query, "tt", "virtual") self.assertEqual(l4.isValid(), True) self.assertEqual(l4.dataProvider().wkbType(), 6) self.assertEqual(l4.dataProvider().crs().postgisSrid(), 4326) n = 0 r = QgsFeatureRequest(QgsRectangle(-1.677, 49.624, -0.816, 49.086)) for f in l4.getFeatures(r): self.assertEqual(f.geometry() is not None, True) self.assertEqual(f.attributes()[0], 2661) n += 1 self.assertEqual(n, 1) # use uid query = toPercent("SELECT * FROM france_parts") l5 = QgsVectorLayer( "?query=%s&geometry=geometry:polygon:4326&uid=ObjectId" % query, "tt", "virtual") self.assertEqual(l5.isValid(), True) idSum = sum(f.id() for f in l5.getFeatures()) self.assertEqual(idSum, 10659) r = QgsFeatureRequest(2661) idSum2 = sum(f.id() for f in l5.getFeatures(r)) self.assertEqual(idSum2, 2661) r = QgsFeatureRequest() r.setFilterFids([2661, 2664]) self.assertEqual(sum(f.id() for f in l5.getFeatures(r)), 2661 + 2664) # test attribute subset r = QgsFeatureRequest() r.setFlags(QgsFeatureRequest.SubsetOfAttributes) r.setSubsetOfAttributes([1]) s = [(f.id(), f.attributes()[1]) for f in l5.getFeatures(r)] self.assertEqual(sum([x[0] for x in s]), 10659) self.assertEqual(sum([x[1] for x in s]), 3064.0) # test NoGeometry # by request flag r = QgsFeatureRequest() r.setFlags(QgsFeatureRequest.NoGeometry) self.assertEqual(all([not f.hasGeometry() for f in l5.getFeatures(r)]), True) # test subset self.assertEqual(l5.dataProvider().featureCount(), 4) l5.setSubsetString("ObjectId = 2661") idSum2 = sum(f.id() for f in l5.getFeatures(r)) self.assertEqual(idSum2, 2661) self.assertEqual(l5.dataProvider().featureCount(), 1)
def test_filter_rect(self): source = toPercent(os.path.join(self.testDataDir, "france_parts.shp")) query = toPercent("select * from vtab where _search_frame_=BuildMbr(-2.10,49.38,-1.3,49.99,4326)") l2 = QgsVectorLayer("?layer=ogr:%s:vtab&query=%s&uid=objectid" % (source, query), "vtab2", "virtual", QgsVectorLayer.LayerOptions(False)) self.assertEqual(l2.isValid(), True) self.assertEqual(l2.dataProvider().featureCount(), 1) a = [fit.attributes()[4] for fit in l2.getFeatures()] self.assertEqual(a, ["Basse-Normandie"])
def test(self): l1 = QgsVectorLayer(os.path.join(self.testDataDir, "france_parts.shp"), "françéà", "ogr", QgsVectorLayer.LayerOptions(False)) self.assertEqual(l1.isValid(), True) QgsProject.instance().addMapLayer(l1) df = QgsVirtualLayerDefinition() df.setQuery('select * from "françéà"') task = QgsVirtualLayerTask(df) ids = [f.id() for f in task.layer().getFeatures()] self.assertEqual(len(ids), 0) task.taskCompleted.connect(self.onSuccess) task.taskTerminated.connect(self.onFail) QgsApplication.taskManager().addTask(task) while not self.success and not self.fail: QCoreApplication.processEvents() self.assertTrue(self.success) self.assertFalse(self.fail) ids = [f.id() for f in task.layer().getFeatures()] self.assertEqual(len(ids), 4)
def layer_to_QgsVectorLayer( source_layer, # pylint: disable=too-many-locals,too-many-branches,too-many-statements input_file, context: Context, fallback_crs=QgsCoordinateReferenceSystem(), defer_layer_uri_set: bool = False): """ Converts a vector layer """ if source_layer.__class__.__name__ == 'CadFeatureLayer': layer = source_layer.layer else: layer = source_layer crs = CrsConverter.convert_crs( layer.layer_extent.crs, context) if layer.layer_extent else QgsCoordinateReferenceSystem() if not crs.isValid(): crs = fallback_crs subset_string = '' if layer.selection_set: subset_string = 'fid in ({})'.format(','.join( [str(s) for s in layer.selection_set])) elif layer.definition_query: subset_string = ExpressionConverter.convert_esri_sql( layer.definition_query) base, _ = os.path.split(input_file) uri, wkb_type, provider, encoding, file_name = VectorLayerConverter.get_uri( source_layer=source_layer, obj=layer, base=base, crs=crs, subset=subset_string, context=context) if wkb_type is None or wkb_type == QgsWkbTypes.Unknown: wkb_type = VectorLayerConverter.layer_to_wkb_type(layer) context.layer_type_hint = wkb_type if Qgis.QGIS_VERSION_INT >= 31600: # try to get the layer name so that we can remove it from field references. # e.g. if layer name is polys then qgis won't support to arcgis style "polys.field" format parts = QgsProviderRegistry.instance().decodeUri(provider, uri) context.main_layer_name = parts.get('layerName') if not context.main_layer_name and provider == 'ogr': context.main_layer_name = Path(parts['path']).stem if context.main_layer_name: subset_string = subset_string.replace( context.main_layer_name + '.', '') else: context.main_layer_name = None if provider == 'ogr' and (not file_name or not os.path.exists(file_name) ) and context.invalid_layer_resolver: res = context.invalid_layer_resolver(layer.name, uri, wkb_type) uri = res.uri provider = res.providerKey if Qgis.QGIS_VERSION_INT >= 31000: opts = QgsVectorLayer.LayerOptions() if wkb_type is not None: opts.fallbackWkbType = wkb_type if provider == 'ogr' and subset_string: uri += '|subset={}'.format(subset_string) original_uri = uri if defer_layer_uri_set: uri = 'xxxxxxxxx' + uri vl = QgsVectorLayer(uri, layer.name, provider, opts) if defer_layer_uri_set: vl.setCustomProperty('original_uri', original_uri) else: vl = QgsMemoryProviderUtils.createMemoryLayer( layer.name, QgsFields(), wkb_type, crs) # context.style_folder, _ = os.path.split(output_file) if layer.renderer: renderer = VectorRendererConverter.convert_renderer( layer.renderer, context) try: if not renderer.usingSymbolLevels(): renderer.setUsingSymbolLevels( layer.use_advanced_symbol_levels) except AttributeError: pass if layer.use_page_definition_query: filter_expression = '"{}" {} @atlas_pagename'.format( layer.page_name_field, layer.page_name_match_operator) root_rule = QgsRuleBasedRenderer.Rule(None) # special case -- convert a simple renderer if isinstance(renderer, QgsSingleSymbolRenderer): filter_rule = QgsRuleBasedRenderer.Rule( renderer.symbol().clone()) filter_rule.setFilterExpression(filter_expression) filter_rule.setLabel(layer.name) filter_rule.setDescription(layer.name) root_rule.appendChild(filter_rule) else: source_rule_renderer = QgsRuleBasedRenderer.convertFromRenderer( renderer) filter_rule = QgsRuleBasedRenderer.Rule(None) filter_rule.setFilterExpression(filter_expression) filter_rule.setLabel('Current Atlas Page') filter_rule.setDescription('Current Atlas Page') root_rule.appendChild(filter_rule) for child in source_rule_renderer.rootRule().children(): filter_rule.appendChild(child.clone()) renderer = QgsRuleBasedRenderer(root_rule) if renderer: vl.setRenderer(renderer) vl.triggerRepaint() else: vl.setRenderer(QgsNullSymbolRenderer()) vl.triggerRepaint() metadata = vl.metadata() metadata.setAbstract(layer.description) vl.setMetadata(metadata) # # layer.zoom_max = "don't show when zoomed out beyond" zoom_max = layer.zoom_max # layer.zoom_min = "don't show when zoomed in beyond" zoom_min = layer.zoom_min enabled_scale_range = bool(zoom_max or zoom_min) if zoom_max and zoom_min and zoom_min > zoom_max: # inconsistent scale range -- zoom_max should be bigger number than zoom_min zoom_min, zoom_max = zoom_max, zoom_min # qgis minimum scale = don't show when zoomed out beyond, i.e. ArcGIS zoom_max vl.setMinimumScale( zoom_max if enabled_scale_range else layer.stored_zoom_max) # qgis maximum scale = don't show when zoomed in beyond, i.e. ArcGIS zoom_min vl.setMaximumScale( zoom_min if enabled_scale_range else layer.stored_zoom_min) vl.setScaleBasedVisibility(enabled_scale_range) vl.setOpacity(1.0 - (layer.transparency or 0) / 100) if layer.display_expression_properties and layer.display_expression_properties.expression and layer.display_expression_properties.expression_parser is not None: vl.setDisplayExpression( ExpressionConverter.convert( layer.display_expression_properties.expression, layer.display_expression_properties.expression_parser, layer.display_expression_properties.advanced, context)) if Qgis.QGIS_VERSION_INT < 31000: vl.setDataSource(uri, layer.name, provider) if encoding: vl.dataProvider().setEncoding(encoding) if subset_string: vl.setSubsetString(subset_string) vl.setCrs(crs) for e in layer.extensions: if e.__class__.__name__ == 'ServerLayerExtension': if 'CopyrightText' in e.properties.properties: layer_credits = e.properties.properties['CopyrightText'] metadata = vl.metadata() rights = metadata.rights() rights.append(layer_credits) metadata.setRights(rights) vl.setMetadata(metadata) LabelConverter.convert_annotation_collection( layer.annotation_collection, dest_layer=vl, context=context) vl.setLabelsEnabled(layer.labels_enabled) DiagramConverter.convert_diagrams(layer.renderer, dest_layer=vl, context=context) # setup joins join_layer = VectorLayerConverter.add_joined_layer( source_layer=layer, input_file=input_file, base_layer=vl, context=context) context.dataset_name = '' vl.setLegend(QgsMapLayerLegend.defaultVectorLegend(vl)) if layer.hyperlinks: VectorLayerConverter.convert_hyperlinks(layer.hyperlinks, vl) vl.setDisplayExpression( QgsExpression.quotedColumnRef(layer.display_field)) res = [vl] if join_layer: res.append(join_layer) context.main_layer_name = None return res