def test_geometry_conversion(self): query = QUrl.toPercentEncoding("select geomfromtext('multipoint((0 0),(1 1))') as geom") l = QgsVectorLayer("?query=%s&geometry=geom:multipoint:0" % query, "tt", "virtual", False) self.assertEqual(l.isValid(), True) for f in l.getFeatures(): self.assertEqual(f.geometry().exportToWkt().lower().startswith("multipoint"), True) self.assertEqual("),(" in f.geometry().exportToWkt(), True) # has two points query = QUrl.toPercentEncoding( "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", False) self.assertEqual(l.isValid(), True) for f in l.getFeatures(): self.assertEqual(f.geometry().exportToWkt().lower().startswith("multipolygon"), True) self.assertEqual(")),((" in f.geometry().exportToWkt(), True) # has two polygons query = QUrl.toPercentEncoding( "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", False) self.assertEqual(l.isValid(), True) for f in l.getFeatures(): self.assertEqual(f.geometry().exportToWkt().lower().startswith("multilinestring"), True) self.assertEqual("),(" in f.geometry().exportToWkt(), True) # has two linestrings
def testReadExtentOnTable(self): # vector layer based on a standard table vl0 = QgsVectorLayer(self.dbconn + ' sslmode=disable key=\'pk\' srid=4326 type=POLYGON table="qgis_test"."some_poly_data" (geom) sql=', 'test', 'postgres') self.assertTrue(vl0.isValid()) self.assertTrue(vl0.dataProvider().hasMetadata()) # set a custom extent originalExtent = vl0.extent() customExtent = QgsRectangle(-80, 80, -70, 90) vl0.setExtent(customExtent) # write xml doc = QDomDocument("testdoc") elem = doc.createElement("maplayer") self.assertTrue(vl0.writeLayerXml(elem, doc, QgsReadWriteContext())) # read xml with the custom extent. It should not be used by default vl1 = QgsVectorLayer() vl1.readLayerXml(elem, QgsReadWriteContext()) self.assertTrue(vl1.isValid()) self.assertEqual(vl1.extent(), originalExtent) # read xml with custom extent with readExtent option. Extent read from # xml document should NOT be used because we don't have a view or a # materialized view vl2 = QgsVectorLayer() vl2.setReadExtentFromXml(True) vl2.readLayerXml(elem, QgsReadWriteContext()) self.assertTrue(vl2.isValid()) self.assertEqual(vl2.extent(), originalExtent)
def testGetFeaturesUniqueId(self): """ Test tables with inheritance for unique ids """ def test_unique(features, num_features): featureids = [] for f in features: self.assertFalse(f.id() in featureids) featureids.append(f.id()) self.assertEqual(len(features), num_features) vl = QgsVectorLayer('%s srid=4326 table="qgis_test".%s (geom) sql=' % (self.dbconn, 'someData'), "testgeom", "postgres") self.assertTrue(vl.isValid()) # Test someData test_unique([f for f in vl.getFeatures()], 5) # Test base_table_bad: layer is invalid vl = QgsVectorLayer('%s srid=4326 table="qgis_test".%s (geom) sql=' % (self.dbconn, 'base_table_bad'), "testgeom", "postgres") self.assertFalse(vl.isValid()) # Test base_table_bad with use estimated metadata: layer is valid because the unique test is skipped vl = QgsVectorLayer('%s srid=4326 estimatedmetadata="true" table="qgis_test".%s (geom) sql=' % (self.dbconn, 'base_table_bad'), "testgeom", "postgres") self.assertTrue(vl.isValid()) # Test base_table_good: layer is valid vl = QgsVectorLayer('%s srid=4326 table="qgis_test".%s (geom) sql=' % (self.dbconn, 'base_table_good'), "testgeom", "postgres") self.assertTrue(vl.isValid()) test_unique([f for f in vl.getFeatures()], 4) # Test base_table_good with use estimated metadata: layer is valid vl = QgsVectorLayer('%s srid=4326 estimatedmetadata="true" table="qgis_test".%s (geom) sql=' % (self.dbconn, 'base_table_good'), "testgeom", "postgres") self.assertTrue(vl.isValid()) test_unique([f for f in vl.getFeatures()], 4)
def test_Join(self): l1 = QgsVectorLayer(os.path.join(self.testDataDir, "points.shp"), "points", "ogr", False) self.assertEqual(l1.isValid(), True) QgsProject.instance().addMapLayer(l1) l2 = QgsVectorLayer(os.path.join(self.testDataDir, "points_relations.shp"), "points_relations", "ogr", 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", 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 testWriteWithBinaryField(self): """ Test writing with a binary field :return: """ basetestpath = tempfile.mkdtemp() tmpfile = os.path.join(basetestpath, 'binaryfield.sqlite') ds = ogr.GetDriverByName('SQLite').CreateDataSource(tmpfile) lyr = ds.CreateLayer('test', geom_type=ogr.wkbPoint, options=['FID=fid']) lyr.CreateField(ogr.FieldDefn('strfield', ogr.OFTString)) lyr.CreateField(ogr.FieldDefn('intfield', ogr.OFTInteger)) lyr.CreateField(ogr.FieldDefn('binfield', ogr.OFTBinary)) lyr.CreateField(ogr.FieldDefn('binfield2', ogr.OFTBinary)) f = None ds = None vl = QgsVectorLayer(tmpfile) self.assertTrue(vl.isValid()) # check that 1 of its fields is a bool fields = vl.fields() self.assertEqual(fields.at(fields.indexFromName('binfield')).type(), QVariant.ByteArray) dp = vl.dataProvider() f = QgsFeature(fields) bin_1 = b'xxx' bin_2 = b'yyy' bin_val1 = QByteArray(bin_1) bin_val2 = QByteArray(bin_2) f.setAttributes([1, 'str', 100, bin_val1, bin_val2]) self.assertTrue(dp.addFeature(f)) # write a gpkg package with a binary field filename = os.path.join(str(QDir.tempPath()), 'with_bin_field') rc, errmsg = QgsVectorFileWriter.writeAsVectorFormat(vl, filename, 'utf-8', vl.crs(), 'GPKG') self.assertEqual(rc, QgsVectorFileWriter.NoError) # open the resulting geopackage vl = QgsVectorLayer(filename + '.gpkg', '', 'ogr') self.assertTrue(vl.isValid()) fields = vl.fields() # test type of converted field idx = fields.indexFromName('binfield') self.assertEqual(fields.at(idx).type(), QVariant.ByteArray) idx2 = fields.indexFromName('binfield2') self.assertEqual(fields.at(idx2).type(), QVariant.ByteArray) # test values self.assertEqual(vl.getFeature(1).attributes()[idx], bin_val1) self.assertEqual(vl.getFeature(1).attributes()[idx2], bin_val2) del vl os.unlink(filename + '.gpkg')
def testAddZ(self): """Check adding z values to non z input.""" input = QgsVectorLayer( 'Point?crs=epsg:4326&field=name:string(20)', 'test', 'memory') self.assertTrue(input.isValid(), 'Provider not initialized') ft = QgsFeature() ft.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(10, 10))) myResult, myFeatures = input.dataProvider().addFeatures([ft]) self.assertTrue(myResult) self.assertTrue(myFeatures) dest_file_name = os.path.join(str(QDir.tempPath()), 'add_z.geojson') options = QgsVectorFileWriter.SaveVectorOptions() options.overrideGeometryType = QgsWkbTypes.PointZ options.driverName = 'GeoJSON' write_result, error_message = QgsVectorFileWriter.writeAsVectorFormat( input, dest_file_name, options) self.assertEqual(write_result, QgsVectorFileWriter.NoError, error_message) # Open result and check created_layer = QgsVectorLayer(dest_file_name, 'test', 'ogr') self.assertTrue(created_layer.isValid()) f = next(created_layer.getFeatures(QgsFeatureRequest())) self.assertEqual(f.geometry().asWkt(), 'PointZ (10 10 0)')
def testExportLayerToExistingDatabase(self): fields = QgsFields() fields.append(QgsField('f1', QVariant.Int)) tmpfile = os.path.join(self.basetestpath, 'testCreateNewGeopackage.gpkg') options = {} options['update'] = True options['driverName'] = 'GPKG' options['layerName'] = 'table1' exporter = QgsVectorLayerExporter(tmpfile, "ogr", fields, QgsWkbTypes.Polygon, QgsCoordinateReferenceSystem(3111), False, options) self.assertFalse(exporter.errorCode(), 'unexpected export error {}: {}'.format(exporter.errorCode(), exporter.errorMessage())) options['layerName'] = 'table2' exporter = QgsVectorLayerExporter(tmpfile, "ogr", fields, QgsWkbTypes.Point, QgsCoordinateReferenceSystem(3113), False, options) self.assertFalse(exporter.errorCode(), 'unexpected export error {} : {}'.format(exporter.errorCode(), exporter.errorMessage())) del exporter # make sure layers exist lyr = QgsVectorLayer('{}|layername=table1'.format(tmpfile), "lyr1", "ogr") self.assertTrue(lyr.isValid()) self.assertEqual(lyr.crs().authid(), 'EPSG:3111') self.assertEqual(lyr.wkbType(), QgsWkbTypes.Polygon) lyr2 = QgsVectorLayer('{}|layername=table2'.format(tmpfile), "lyr2", "ogr") self.assertTrue(lyr2.isValid()) self.assertEqual(lyr2.crs().authid(), 'EPSG:3113') self.assertEqual(lyr2.wkbType(), QgsWkbTypes.Point)
def testSetupProxy(self): """Test proxy setup""" settings = QgsSettings() settings.setValue("proxy/proxyEnabled", True) settings.setValue("proxy/proxyPort", '1234') settings.setValue("proxy/proxyHost", 'myproxyhostname.com') settings.setValue("proxy/proxyUser", 'username') settings.setValue("proxy/proxyPassword", 'password') settings.setValue("proxy/proxyExcludedUrls", "http://www.myhost.com|http://www.myotherhost.com") QgsNetworkAccessManager.instance().setupDefaultProxyAndCache() vl = QgsVectorLayer(TEST_DATA_DIR + '/' + 'lines.shp', 'proxy_test', 'ogr') self.assertTrue(vl.isValid()) self.assertEqual(gdal.GetConfigOption("GDAL_HTTP_PROXY"), "myproxyhostname.com:1234") self.assertEqual(gdal.GetConfigOption("GDAL_HTTP_PROXYUSERPWD"), "username:password") settings.setValue("proxy/proxyEnabled", True) settings.remove("proxy/proxyPort") settings.setValue("proxy/proxyHost", 'myproxyhostname.com') settings.setValue("proxy/proxyUser", 'username') settings.remove("proxy/proxyPassword") settings.setValue("proxy/proxyExcludedUrls", "http://www.myhost.com|http://www.myotherhost.com") QgsNetworkAccessManager.instance().setupDefaultProxyAndCache() vl = QgsVectorLayer(TEST_DATA_DIR + '/' + 'lines.shp', 'proxy_test', 'ogr') self.assertTrue(vl.isValid()) self.assertEqual(gdal.GetConfigOption("GDAL_HTTP_PROXY"), "myproxyhostname.com") self.assertEqual(gdal.GetConfigOption("GDAL_HTTP_PROXYUSERPWD"), "username")
def testStringListField(self): source = os.path.join(TEST_DATA_DIR, 'stringlist.gml') vl = QgsVectorLayer(source) self.assertTrue(vl.isValid()) fields = vl.fields() descriptive_group_field = fields[fields.lookupField('descriptiveGroup')] self.assertEqual(descriptive_group_field.type(), QVariant.List) self.assertEqual(descriptive_group_field.typeName(), 'StringList') self.assertEqual(descriptive_group_field.subType(), QVariant.String) feature = vl.getFeature(1000002717654) self.assertEqual(feature['descriptiveGroup'], ['Building']) self.assertEqual(feature['reasonForChange'], ['Reclassified', 'Attributes']) tmpfile = os.path.join(self.basetestpath, 'newstringlistfield.gml') ds = ogr.GetDriverByName('GML').CreateDataSource(tmpfile) lyr = ds.CreateLayer('test', geom_type=ogr.wkbPoint) lyr.CreateField(ogr.FieldDefn('strfield', ogr.OFTString)) lyr.CreateField(ogr.FieldDefn('intfield', ogr.OFTInteger)) lyr.CreateField(ogr.FieldDefn('strlistfield', ogr.OFTStringList)) ds = None vl = QgsVectorLayer(tmpfile) self.assertTrue(vl.isValid()) dp = vl.dataProvider() fields = dp.fields() list_field = fields[fields.lookupField('strlistfield')] self.assertEqual(list_field.type(), QVariant.List) self.assertEqual(list_field.typeName(), 'StringList') self.assertEqual(list_field.subType(), QVariant.String)
def test_queries(self): """Test loading of query-based layers""" # a query with a geometry, but no unique id # this allows to load a query without unique id # however, functions relying on such a unique id would fail l = QgsVectorLayer("dbname=%s table='(select * from test_q)' (geometry)" % self.dbname, "test_pg_query1", "spatialite") assert(l.isValid()) # the id() is not consistent sum_id1 = sum(f.id() for f in l.getFeatures()) # the attribute 'id' works sum_id2 = sum(f.attributes()[0] for f in l.getFeatures()) assert(sum_id1 == 0) assert(sum_id2 == 3) # and now with an id declared l = QgsVectorLayer("dbname=%s table='(select * from test_q)' (geometry) key='id'" % self.dbname, "test_pg_query1", "spatialite") assert(l.isValid()) sum_id1 = sum(f.id() for f in l.getFeatures()) sum_id2 = sum(f.attributes()[0] for f in l.getFeatures()) assert(sum_id1 == 3) assert(sum_id2 == 3) # a query, but no geometry l = QgsVectorLayer("dbname=%s table='(select id,name from test_q)' key='id'" % self.dbname, "test_pg_query1", "spatialite") assert(l.isValid()) sum_id1 = sum(f.id() for f in l.getFeatures()) sum_id2 = sum(f.attributes()[0] for f in l.getFeatures()) assert(sum_id1 == 3) assert(sum_id2 == 3)
def testSubSetStringEditable_bug17795_but_with_modified_behavior(self): """Test that a layer is editable after setting a subset""" tmpfile = os.path.join(self.basetestpath, 'testSubSetStringEditable_bug17795.gpkg') shutil.copy(TEST_DATA_DIR + '/' + 'provider/bug_17795.gpkg', tmpfile) isEditable = QgsVectorDataProvider.ChangeAttributeValues testPath = tmpfile + '|layername=bug_17795' vl = QgsVectorLayer(testPath, 'subset_test', 'ogr') self.assertTrue(vl.isValid()) self.assertTrue(vl.dataProvider().capabilities() & isEditable) vl = QgsVectorLayer(testPath, 'subset_test', 'ogr') vl.setSubsetString('') self.assertTrue(vl.isValid()) self.assertTrue(vl.dataProvider().capabilities() & isEditable) vl = QgsVectorLayer(testPath, 'subset_test', 'ogr') vl.setSubsetString('"category" = \'one\'') self.assertTrue(vl.isValid()) self.assertTrue(vl.dataProvider().capabilities() & isEditable) vl.setSubsetString('') self.assertTrue(vl.dataProvider().capabilities() & isEditable)
def testSubsetStringExtent_bug17863(self): """Check that the extent is correct when applied in the ctor and when modified after a subset string is set """ def _lessdigits(s): return re.sub(r'(\d+\.\d{3})\d+', r'\1', s) testPath = TEST_DATA_DIR + '/' + 'points.shp' subSetString = '"Class" = \'Biplane\'' subSet = '|layerid=0|subset=%s' % subSetString # unfiltered vl = QgsVectorLayer(testPath, 'test', 'ogr') self.assertTrue(vl.isValid()) unfiltered_extent = _lessdigits(vl.extent().toString()) del(vl) # filter after construction ... subSet_vl2 = QgsVectorLayer(testPath, 'test', 'ogr') self.assertEqual(_lessdigits(subSet_vl2.extent().toString()), unfiltered_extent) # ... apply filter now! subSet_vl2.setSubsetString(subSetString) self.assertEqual(subSet_vl2.subsetString(), subSetString) self.assertNotEqual(_lessdigits(subSet_vl2.extent().toString()), unfiltered_extent) filtered_extent = _lessdigits(subSet_vl2.extent().toString()) del(subSet_vl2) # filtered in constructor subSet_vl = QgsVectorLayer(testPath + subSet, 'subset_test', 'ogr') self.assertEqual(subSet_vl.subsetString(), subSetString) self.assertTrue(subSet_vl.isValid()) # This was failing in bug 17863 self.assertEqual(_lessdigits(subSet_vl.extent().toString()), filtered_extent) self.assertNotEqual(_lessdigits(subSet_vl.extent().toString()), unfiltered_extent)
def test_source_escaping2(self): def create_test_db(dbfile): if os.path.exists(dbfile): os.remove(dbfile) con = spatialite_connect(dbfile) cur = con.cursor() cur.execute("SELECT InitSpatialMetadata(1)") cur.execute("CREATE TABLE test (id INTEGER, name TEXT)") cur.execute("SELECT AddGeometryColumn('test', 'geometry', 4326, 'POINT', 'XY')") sql = "INSERT INTO test (id, name, geometry) " sql += "VALUES (1, 'toto',GeomFromText('POINT(0 0)',4326))" cur.execute(sql) con.close() # the source contains ',' and single quotes fn = os.path.join(tempfile.gettempdir(), "test,.db") create_test_db(fn) source = "dbname='%s' table=\"test\" (geometry) sql=" % fn d = QgsVirtualLayerDefinition() d.addSource("t", source, "spatialite") l = QgsVectorLayer(d.toString(), "vtab", "virtual", False) self.assertEqual(l.isValid(), True) # the source contains ':' and single quotes fn = os.path.join(tempfile.gettempdir(), "test:.db") create_test_db(fn) source = "dbname='%s' table=\"test\" (geometry) sql=" % fn d = QgsVirtualLayerDefinition() d.addSource("t", source, "spatialite") l = QgsVectorLayer(d.toString(), "vtab", "virtual", False) self.assertEqual(l.isValid(), True)
def testUpdatedFields(self): """Test when referenced layer update its fields https://issues.qgis.org/issues/20893 """ ml = QgsVectorLayer("Point?srid=EPSG:4326&field=a:int", "mem", "memory") self.assertEqual(ml.isValid(), True) QgsProject.instance().addMapLayer(ml) ml.startEditing() f1 = QgsFeature(ml.fields()) f1.setGeometry(QgsGeometry.fromWkt('POINT(2 3)')) ml.addFeatures([f1]) ml.commitChanges() vl = QgsVectorLayer("?query=select a, geometry from mem", "vl", "virtual") self.assertEqual(vl.isValid(), True) # add one more field ml.dataProvider().addAttributes([QgsField('newfield', QVariant.Int)]) ml.updateFields() self.assertEqual(ml.featureCount(), vl.featureCount()) self.assertEqual(vl.fields().count(), 1) geometry = next(vl.getFeatures()).geometry() self.assertTrue(geometry) point = geometry.asPoint() self.assertEqual(point.x(), 2) self.assertEqual(point.y(), 3) QgsProject.instance().removeMapLayer(ml)
def test_embeddedLayer(self): source = toPercent(os.path.join(self.testDataDir, "france_parts.shp")) l = QgsVectorLayer("?layer=ogr:%s" % source, "vtab", "virtual", False) self.assertEqual(l.isValid(), True) l = QgsVectorLayer("?layer=ogr:%s:nn" % source, "vtab", "virtual", False) self.assertEqual(l.isValid(), True)
def test_geometryTypes(self): geo = [(1, "POINT", "(0 0)"), (2, "LINESTRING", "(0 0,1 0)"), (3, "POLYGON", "((0 0,1 0,1 1,0 0))"), (4, "MULTIPOINT", "((1 1))"), (5, "MULTILINESTRING", "((0 0,1 0),(0 1,1 1))"), (6, "MULTIPOLYGON", "(((0 0,1 0,1 1,0 0)),((2 2,3 0,3 3,2 2)))")] for wkb_type, wkt_type, wkt in geo: l = QgsVectorLayer("%s?crs=epsg:4326" % wkt_type, "m1", "memory", False) self.assertEqual(l.isValid(), True) QgsProject.instance().addMapLayer(l) f1 = QgsFeature(1) g = QgsGeometry.fromWkt(wkt_type + wkt) self.assertEqual(g is None, False) f1.setGeometry(g) l.dataProvider().addFeatures([f1]) l2 = QgsVectorLayer("?layer_ref=%s" % l.id(), "vtab", "virtual", False) self.assertEqual(l2.isValid(), True) self.assertEqual(l2.dataProvider().featureCount(), 1) self.assertEqual(l2.dataProvider().wkbType(), wkb_type) QgsProject.instance().removeMapLayer(l.id())
def _loadLogLayer(self, sourceLayer, layerPath, layerName): layer = None layerId = '' layerList = QgsMapLayerRegistry.instance().mapLayersByName(layerName) if (len(layerList) > 0): layer = layerList[0] self._iface.legendInterface().moveLayer(layer, self._bufferGroupIndex) else: fullLayerPath = self.projectPath + '/' + layerPath if (layerName and layerPath and sourceLayer and sourceLayer.isValid()): if not QFile.exists(fullLayerPath): # If the layer doesn't exist, clone from the source layer layer = layers.cloneAsShapefile(sourceLayer, fullLayerPath, layerName) if layer and layer.isValid(): layer.dataProvider().addAttributes([QgsField('timestamp', QVariant.String, '', 10, 0, 'timestamp')]) layer.dataProvider().addAttributes([QgsField('event', QVariant.String, '', 6, 0, 'event')]) else: # If the layer does exist, then load it and copy the style layer = QgsVectorLayer(fullLayerPath, layerName, 'ogr') if layer and layer.isValid(): layers.loadStyle(layer, fromLayer=sourceLayer) if layer and layer.isValid(): layerId = layer.id() layer.setFeatureFormSuppress(QgsVectorLayer.SuppressOn) self._iface.legendInterface().setLayerExpanded(layer, False) else: layer = None return layer, layerId
def test_queries(self): """Test loading of query-based layers""" # a query with a geometry, but no unique id # the id will be autoincremented l = QgsVectorLayer("dbname=%s table='(select * from test_q)' (geometry)" % self.dbname, "test_pg_query1", "spatialite") self.assertTrue(l.isValid()) # the id() is autoincremented sum_id1 = sum(f.id() for f in l.getFeatures()) # the attribute 'id' works sum_id2 = sum(f.attributes()[0] for f in l.getFeatures()) self.assertEqual(sum_id1, 32) # 11 + 21 self.assertEqual(sum_id2, 32) # 11 + 21 # and now with an id declared l = QgsVectorLayer("dbname=%s table='(select * from test_q)' (geometry) key='id'" % self.dbname, "test_pg_query1", "spatialite") self.assertTrue(l.isValid()) sum_id1 = sum(f.id() for f in l.getFeatures()) sum_id2 = sum(f.attributes()[0] for f in l.getFeatures()) self.assertEqual(sum_id1, 32) self.assertEqual(sum_id2, 32) # a query, but no geometry l = QgsVectorLayer("dbname=%s table='(select id,name from test_q)' key='id'" % self.dbname, "test_pg_query1", "spatialite") self.assertTrue(l.isValid()) sum_id1 = sum(f.id() for f in l.getFeatures()) sum_id2 = sum(f.attributes()[0] for f in l.getFeatures()) self.assertEqual(sum_id1, 32) self.assertEqual(sum_id2, 32)
def test_embeddedLayer( self ): source = QUrl.toPercentEncoding(os.path.join(self.testDataDir_, "france_parts.shp")) l = QgsVectorLayer("?layer=ogr:%s" % source, "vtab", "virtual", False) self.assertEqual(l.isValid(), True) l = QgsVectorLayer("?layer=ogr:%s:nn" % source, "vtab", "virtual", False) self.assertEqual(l.isValid(), True) print sum([f.id() for f in l.getFeatures()])
def testFeatureSourceInput(self): # create a memory layer and add to project and context layer = QgsVectorLayer("Point?crs=epsg:3857&field=fldtxt:string&field=fldint:integer", "testmem", "memory") self.assertTrue(layer.isValid()) pr = layer.dataProvider() f = QgsFeature() f.setAttributes(["test", 123]) f.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(100, 200))) f2 = QgsFeature() f2.setAttributes(["test2", 457]) f2.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(110, 200))) self.assertTrue(pr.addFeatures([f, f2])) self.assertEqual(layer.featureCount(), 2) # select first feature layer.selectByIds([next(layer.getFeatures()).id()]) self.assertEqual(len(layer.selectedFeatureIds()), 1) QgsProject.instance().addMapLayer(layer) context = QgsProcessingContext() context.setProject(QgsProject.instance()) alg = QgsApplication.processingRegistry().createAlgorithmById('grass7:v.buffer') self.assertIsNotNone(alg) temp_file = os.path.join(self.temp_dir, 'grass_output_sel.shp') parameters = {'input': QgsProcessingFeatureSourceDefinition('testmem', True), 'cats': '', 'where': '', 'type': [0, 1, 4], 'distance': 1, 'minordistance': None, 'angle': 0, 'column': None, 'scale': 1, 'tolerance': 0.01, '-s': False, '-c': False, '-t': False, 'output': temp_file, 'GRASS_REGION_PARAMETER': None, 'GRASS_SNAP_TOLERANCE_PARAMETER': -1, 'GRASS_MIN_AREA_PARAMETER': 0.0001, 'GRASS_OUTPUT_TYPE_PARAMETER': 0, 'GRASS_VECTOR_DSCO': '', 'GRASS_VECTOR_LCO': ''} feedback = QgsProcessingFeedback() results, ok = alg.run(parameters, context, feedback) self.assertTrue(ok) self.assertTrue(os.path.exists(temp_file)) # make sure that layer has correct features res = QgsVectorLayer(temp_file, 'res') self.assertTrue(res.isValid()) self.assertEqual(res.featureCount(), 1) QgsProject.instance().removeMapLayer(layer)
def testPkLessQuery(self): """Test if features in queries with/without pk can be retrieved by id""" # create test db dbname = os.path.join(tempfile.gettempdir(), "test_pkless.sqlite") if os.path.exists(dbname): os.remove(dbname) con = spatialite_connect(dbname, isolation_level=None) cur = con.cursor() cur.execute("BEGIN") sql = "SELECT InitSpatialMetadata()" cur.execute(sql) # simple table with primary key sql = "CREATE TABLE test_pk (id INTEGER NOT NULL PRIMARY KEY, name TEXT NOT NULL)" cur.execute(sql) sql = "SELECT AddGeometryColumn('test_pk', 'geometry', 4326, 'POINT', 'XY')" cur.execute(sql) for i in range(11, 21): sql = "INSERT INTO test_pk (id, name, geometry) " sql += "VALUES ({id}, 'name {id}', GeomFromText('POINT({id} {id})', 4326))".format(id=i) cur.execute(sql) # simple table without primary key sql = "CREATE TABLE test_no_pk (name TEXT NOT NULL)" cur.execute(sql) sql = "SELECT AddGeometryColumn('test_no_pk', 'geometry', 4326, 'POINT', 'XY')" cur.execute(sql) for i in range(11, 21): sql = "INSERT INTO test_no_pk (name, geometry) " sql += "VALUES ('name {id}', GeomFromText('POINT({id} {id})', 4326))".format(id=i) cur.execute(sql) cur.execute("COMMIT") con.close() def _check_features(vl, offset): self.assertEqual(vl.featureCount(), 10) i = 11 for f in vl.getFeatures(): self.assertTrue(f.isValid()) self.assertTrue(vl.getFeature(i - offset).isValid()) self.assertEqual(vl.getFeature(i - offset)['name'], 'name {id}'.format(id=i)) self.assertEqual(f.id(), i - offset) self.assertEqual(f['name'], 'name {id}'.format(id=i)) self.assertEqual(f.geometry().asWkt(), 'Point ({id} {id})'.format(id=i)) i += 1 vl_pk = QgsVectorLayer('dbname=\'%s\' table="(select * from test_pk)" (geometry) sql=' % dbname, 'pk', 'spatialite') self.assertTrue(vl_pk.isValid()) _check_features(vl_pk, 0) vl_no_pk = QgsVectorLayer('dbname=\'%s\' table="(select * from test_no_pk)" (geometry) sql=' % dbname, 'pk', 'spatialite') self.assertTrue(vl_no_pk.isValid()) _check_features(vl_no_pk, 10)
def testVectorLayerInput(self): alg = QgsApplication.processingRegistry().createAlgorithmById('grass7:v.buffer') self.assertIsNotNone(alg) self.assertFalse(alg.commands) def get_command(alg): command = alg.commands[-1] command = re.sub(r'output=".*?"', 'output="###"', command) command = command.replace(testDataPath, 'testdata') return command # GML source source = os.path.join(testDataPath, 'points.gml') vl = QgsVectorLayer(source) self.assertTrue(vl.isValid()) alg.loadVectorLayer('test_layer', vl, external=False) self.assertEqual(get_command(alg), 'v.in.ogr min_area=None snap=None input="testdata/points.gml" output="###" --overwrite -o') # try with external -- not support for GML, so should fall back to v.in.ogr alg.loadVectorLayer('test_layer', vl, external=True) self.assertEqual(get_command(alg), 'v.in.ogr min_area=None snap=None input="testdata/points.gml" output="###" --overwrite -o') # SHP source source = os.path.join(testDataPath, 'lines_z.shp') vl = QgsVectorLayer(source) self.assertTrue(vl.isValid()) alg.loadVectorLayer('test_layer', vl, external=False) self.assertEqual(get_command(alg), 'v.in.ogr min_area=None snap=None input="testdata/lines_z.shp" output="###" --overwrite -o') # try with external -- should work for shapefile alg.loadVectorLayer('test_layer', vl, external=True) self.assertEqual(get_command(alg), 'v.external input="testdata/lines_z.shp" output="###" --overwrite -o') # GPKG source source = os.path.join(testDataPath, 'custom/pol.gpkg') vl = QgsVectorLayer(source + '|layername=pol2') self.assertTrue(vl.isValid()) alg.loadVectorLayer('test_layer', vl, external=False) self.assertEqual(get_command(alg), 'v.in.ogr min_area=None snap=None input="testdata/custom/pol.gpkg" layer="pol2" output="###" --overwrite -o') # try with external -- should work for Geopackage (although grass itself tends to crash here!) alg.loadVectorLayer('test_layer', vl, external=True) self.assertEqual(get_command(alg), 'v.external input="testdata/custom/pol.gpkg" layer="pol2" output="###" --overwrite -o') # different layer source = os.path.join(testDataPath, 'custom/pol.gpkg') vl = QgsVectorLayer(source + '|layername=pol3') self.assertTrue(vl.isValid()) alg.loadVectorLayer('test_layer', vl, external=False) self.assertEqual(get_command(alg), 'v.in.ogr min_area=None snap=None input="testdata/custom/pol.gpkg" layer="pol3" output="###" --overwrite -o') alg.loadVectorLayer('test_layer', vl, external=True) self.assertEqual(get_command(alg), 'v.external input="testdata/custom/pol.gpkg" layer="pol3" output="###" --overwrite -o') # GPKG no layer: you get what you get and you don't get upset source = os.path.join(testDataPath, 'custom/pol.gpkg') vl = QgsVectorLayer(source) self.assertTrue(vl.isValid()) alg.loadVectorLayer('test_layer', vl, external=False) self.assertEqual(get_command(alg), 'v.in.ogr min_area=None snap=None input="testdata/custom/pol.gpkg" output="###" --overwrite -o') alg.loadVectorLayer('test_layer', vl, external=True) self.assertEqual(get_command(alg), 'v.external input="testdata/custom/pol.gpkg" output="###" --overwrite -o')
def test_CsvNoGeometry(self): l1 = QgsVectorLayer(QUrl.fromLocalFile(os.path.join(self.testDataDir, "delimitedtext/test.csv")).toString() + "?type=csv&geomType=none&subsetIndex=no&watchFile=no", "test", "delimitedtext", False) self.assertEqual(l1.isValid(), True) QgsProject.instance().addMapLayer(l1) l2 = QgsVectorLayer("?layer_ref=" + l1.id(), "vtab", "virtual", False) self.assertEqual(l2.isValid(), True) QgsProject.instance().removeMapLayer(l1.id())
def test_sql2(self): l2 = QgsVectorLayer(os.path.join(self.testDataDir, "france_parts.shp"), "france_parts", "ogr", 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(), 3) 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 testHasMetadata(self): # views don't have metadata vl = QgsVectorLayer('{} table="qgis_test"."{}" key="pk" sql='.format(self.dbconn, 'bikes_view'), "bikes_view", "postgres") self.assertTrue(vl.isValid()) self.assertFalse(vl.dataProvider().hasMetadata()) # ordinary tables have metadata vl = QgsVectorLayer('%s table="qgis_test"."someData" sql=' % (self.dbconn), "someData", "postgres") self.assertTrue(vl.isValid()) self.assertTrue(vl.dataProvider().hasMetadata())
def test_recursiveLayer(self): source = toPercent(os.path.join(self.testDataDir, "france_parts.shp")) l = QgsVectorLayer("?layer=ogr:%s" % source, "vtab", "virtual", False) self.assertEqual(l.isValid(), True) QgsProject.instance().addMapLayer(l) l2 = QgsVectorLayer("?layer_ref=" + l.id(), "vtab2", "virtual", False) self.assertEqual(l2.isValid(), True) QgsProject.instance().removeMapLayer(l.id())
def test_refLayers2(self): l1 = QgsVectorLayer(QUrl.fromLocalFile(os.path.join(self.testDataDir, "delimitedtext/test.csv")).toString() + "?type=csv&geomType=none&subsetIndex=no&watchFile=no", "test", "delimitedtext", False) self.assertEqual(l1.isValid(), True) QgsProject.instance().addMapLayer(l1) # referenced layers cannot be stored ! tmp = QUrl.fromLocalFile(os.path.join(tempfile.gettempdir(), "t.sqlite")).toString() l2 = QgsVectorLayer("%s?layer_ref=%s" % (tmp, l1.id()), "tt", "virtual", False) self.assertEqual(l2.isValid(), False) self.assertEqual("Cannot store referenced layers" in l2.dataProvider().error().message(), True)
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", 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_sql4(self): l2 = QgsVectorLayer(os.path.join(self.testDataDir, "france_parts.shp"), "france_parts", "ogr", False) self.assertEqual(l2.isValid(), True) QgsProject.instance().addMapLayer(l2) query = toPercent("SELECT OBJECTId from france_parts") l4 = QgsVectorLayer("?query=%s" % query, "tt", "virtual", False) self.assertEqual(l4.isValid(), True) s = sum(f.attributes()[0] for f in l4.getFeatures()) self.assertEqual(s, 10659)
def test_reopen2(self): source = toPercent(os.path.join(self.testDataDir, "france_parts.shp")) tmp = QUrl.fromLocalFile(os.path.join(tempfile.gettempdir(), "t.sqlite")).toString() l = QgsVectorLayer("%s?layer=ogr:%s:vtab&nogeometry" % (tmp, source), "vtab2", "virtual", False) self.assertEqual(l.isValid(), True) l2 = QgsVectorLayer(tmp, "tt", "virtual", False) self.assertEqual(l2.isValid(), True) self.assertEqual(l2.dataProvider().wkbType(), 100) self.assertEqual(l2.dataProvider().featureCount(), 4)
class TestQgsMapLayerAction(unittest.TestCase): def __init__(self, methodName): """Run once on class initialization.""" unittest.TestCase.__init__(self, methodName) self.vector_layer = QgsVectorLayer("Point?field=fldtxt:string&field=fldint:integer&field=flddate:datetime", "test_layer", "memory") assert self.vector_layer.isValid() self.vector_layer2 = QgsVectorLayer("Point?field=fldtxt:string&field=fldint:integer&field=flddate:datetime", "test_layer", "memory") assert self.vector_layer2.isValid() raster_path = os.path.join(unitTestDataPath(), 'landsat.tif') self.raster_layer = QgsRasterLayer(raster_path, 'raster') assert self.raster_layer.isValid() def testCanRunUsingLayer(self): """ Test that actions correctly indicate when they can run for a layer """ action_all_layers = QgsMapLayerAction('action1', None) self.assertTrue(action_all_layers.canRunUsingLayer(None)) self.assertTrue(action_all_layers.canRunUsingLayer(self.vector_layer)) self.assertTrue(action_all_layers.canRunUsingLayer(self.raster_layer)) action_vector_layers_only = QgsMapLayerAction('action2', None, QgsMapLayer.VectorLayer) self.assertFalse(action_vector_layers_only.canRunUsingLayer(None)) self.assertTrue(action_vector_layers_only.canRunUsingLayer(self.vector_layer)) self.assertFalse(action_vector_layers_only.canRunUsingLayer(self.raster_layer)) action_raster_layers_only = QgsMapLayerAction('action3', None, QgsMapLayer.RasterLayer) self.assertFalse(action_raster_layers_only.canRunUsingLayer(None)) self.assertFalse(action_raster_layers_only.canRunUsingLayer(self.vector_layer)) self.assertTrue(action_raster_layers_only.canRunUsingLayer(self.raster_layer)) action_specific_layer_only = QgsMapLayerAction('action4', None, self.vector_layer) self.assertFalse(action_specific_layer_only.canRunUsingLayer(None)) self.assertTrue(action_specific_layer_only.canRunUsingLayer(self.vector_layer)) self.assertFalse(action_specific_layer_only.canRunUsingLayer(self.vector_layer2)) self.assertFalse(action_specific_layer_only.canRunUsingLayer(self.raster_layer)) action_specific_raster_layer_only = QgsMapLayerAction('action4', None, self.raster_layer) self.assertFalse(action_specific_raster_layer_only.canRunUsingLayer(None)) self.assertFalse(action_specific_raster_layer_only.canRunUsingLayer(self.vector_layer)) self.assertFalse(action_specific_raster_layer_only.canRunUsingLayer(self.vector_layer2)) self.assertTrue(action_specific_raster_layer_only.canRunUsingLayer(self.raster_layer)) action_editable_layer_only = QgsMapLayerAction('action1', None, flags=QgsMapLayerAction.EnabledOnlyWhenEditable) self.assertFalse(action_editable_layer_only.canRunUsingLayer(None)) self.assertFalse(action_editable_layer_only.canRunUsingLayer(self.vector_layer)) self.assertFalse(action_editable_layer_only.canRunUsingLayer(self.vector_layer2)) self.assertFalse(action_editable_layer_only.canRunUsingLayer(self.raster_layer)) self.vector_layer.startEditing() self.assertFalse(action_editable_layer_only.canRunUsingLayer(None)) self.assertTrue(action_editable_layer_only.canRunUsingLayer(self.vector_layer)) self.assertFalse(action_editable_layer_only.canRunUsingLayer(self.vector_layer2)) self.assertFalse(action_editable_layer_only.canRunUsingLayer(self.raster_layer)) self.vector_layer.commitChanges() self.assertFalse(action_editable_layer_only.canRunUsingLayer(None)) self.assertFalse(action_editable_layer_only.canRunUsingLayer(self.vector_layer)) self.assertFalse(action_editable_layer_only.canRunUsingLayer(self.vector_layer2)) self.assertFalse(action_editable_layer_only.canRunUsingLayer(self.raster_layer))
def test_joined_layers_conversion(self): v1 = QgsVectorLayer("Point?field=id:integer&field=b_id:integer&field=c_id:integer&field=name:string", "A", "memory") self.assertEqual(v1.isValid(), True) v2 = QgsVectorLayer("Point?field=id:integer&field=bname:string&field=bfield:integer", "B", "memory") self.assertEqual(v2.isValid(), True) v3 = QgsVectorLayer("Point?field=id:integer&field=cname:string", "C", "memory") self.assertEqual(v3.isValid(), True) tl1 = QgsVectorLayer("NoGeometry?field=id:integer&field=e_id:integer&field=0name:string", "D", "memory") self.assertEqual(tl1.isValid(), True) tl2 = QgsVectorLayer("NoGeometry?field=id:integer&field=ena me:string", "E", "memory") self.assertEqual(tl2.isValid(), True) QgsProject.instance().addMapLayers([v1, v2, v3, tl1, tl2]) joinInfo = QgsVectorLayerJoinInfo() joinInfo.setTargetFieldName("b_id") joinInfo.setJoinLayer(v2) joinInfo.setJoinFieldName("id") #joinInfo.setPrefix("B_") v1.addJoin(joinInfo) self.assertEqual(len(v1.fields()), 6) df = QgsVirtualLayerDefinitionUtils.fromJoinedLayer(v1) self.assertEqual(df.query(), 'SELECT t.geometry, t.rowid AS uid, t."id", t."b_id", t."c_id", t."name", j1."bname" AS "B_bname", j1."bfield" AS "B_bfield" FROM "{}" AS t LEFT JOIN "{}" AS j1 ON t."b_id"=j1."id"'.format(v1.id(), v2.id())) # with a field subset v1.removeJoin(v2.id()) joinInfo.setJoinFieldNamesSubset(["bname"]) v1.addJoin(joinInfo) self.assertEqual(len(v1.fields()), 5) df = QgsVirtualLayerDefinitionUtils.fromJoinedLayer(v1) self.assertEqual(df.query(), 'SELECT t.geometry, t.rowid AS uid, t."id", t."b_id", t."c_id", t."name", j1."bname" AS "B_bname" FROM "{}" AS t LEFT JOIN "{}" AS j1 ON t."b_id"=j1."id"'.format(v1.id(), v2.id())) joinInfo.setJoinFieldNamesSubset(None) # add a table prefix to the join v1.removeJoin(v2.id()) joinInfo.setPrefix("BB_") v1.addJoin(joinInfo) self.assertEqual(len(v1.fields()), 6) df = QgsVirtualLayerDefinitionUtils.fromJoinedLayer(v1) self.assertEqual(df.query(), 'SELECT t.geometry, t.rowid AS uid, t."id", t."b_id", t."c_id", t."name", j1."bname" AS "BB_bname", j1."bfield" AS "BB_bfield" FROM "{}" AS t LEFT JOIN "{}" AS j1 ON t."b_id"=j1."id"'.format(v1.id(), v2.id())) joinInfo.setPrefix("") v1.removeJoin(v2.id()) v1.addJoin(joinInfo) # add another join joinInfo2 = QgsVectorLayerJoinInfo() joinInfo2.setTargetFieldName("c_id") joinInfo2.setJoinLayer(v3) joinInfo2.setJoinFieldName("id") v1.addJoin(joinInfo2) self.assertEqual(len(v1.fields()), 7) df = QgsVirtualLayerDefinitionUtils.fromJoinedLayer(v1) self.assertEqual(df.query(), ('SELECT t.geometry, t.rowid AS uid, t."id", t."b_id", t."c_id", t."name", j1."bname" AS "B_bname", j1."bfield" AS "B_bfield", j2."cname" AS "C_cname" FROM "{}" AS t ' + 'LEFT JOIN "{}" AS j1 ON t."b_id"=j1."id" ' + 'LEFT JOIN "{}" AS j2 ON t."c_id"=j2."id"').format(v1.id(), v2.id(), v3.id())) # test NoGeometry joined layers with field names starting with a digit or containing white spaces joinInfo3 = QgsVectorLayerJoinInfo() joinInfo3.setTargetFieldName("e_id") joinInfo3.setJoinLayer(tl2) joinInfo3.setJoinFieldName("id") tl1.addJoin(joinInfo3) self.assertEqual(len(tl1.fields()), 4) df = QgsVirtualLayerDefinitionUtils.fromJoinedLayer(tl1) self.assertEqual(df.query(), 'SELECT t.rowid AS uid, t."id", t."e_id", t."0name", j1."ena me" AS "E_ena me" FROM "{}" AS t LEFT JOIN "{}" AS j1 ON t."e_id"=j1."id"'.format(tl1.id(), tl2.id())) QgsProject.instance().removeMapLayers([v1.id(), v2.id(), v3.id(), tl1.id(), tl2.id()])
def testMinMaxCache(self): """ Test that min/max cache is appropriately cleared :return: """ vl = QgsVectorLayer( 'Point?crs=epsg:4326&field=f1:integer&field=f2:integer', 'test', 'memory') self.assertTrue(vl.isValid()) f1 = QgsFeature() f1.setAttributes([5, -200]) f2 = QgsFeature() f2.setAttributes([3, 300]) f3 = QgsFeature() f3.setAttributes([1, 100]) f4 = QgsFeature() f4.setAttributes([2, 200]) f5 = QgsFeature() f5.setAttributes([4, 400]) res, [f1, f2, f3, f4, f5] = vl.dataProvider().addFeatures([f1, f2, f3, f4, f5]) self.assertTrue(res) self.assertEqual(vl.dataProvider().minimumValue(0), 1) self.assertEqual(vl.dataProvider().minimumValue(1), -200) self.assertEqual(vl.dataProvider().maximumValue(0), 5) self.assertEqual(vl.dataProvider().maximumValue(1), 400) # add feature f6 = QgsFeature() f6.setAttributes([15, 1400]) res, [f6] = vl.dataProvider().addFeatures([f6]) self.assertTrue(res) self.assertEqual(vl.dataProvider().minimumValue(0), 1) self.assertEqual(vl.dataProvider().minimumValue(1), -200) self.assertEqual(vl.dataProvider().maximumValue(0), 15) self.assertEqual(vl.dataProvider().maximumValue(1), 1400) f7 = QgsFeature() f7.setAttributes([-1, -1400]) res, [f7] = vl.dataProvider().addFeatures([f7]) self.assertTrue(res) self.assertEqual(vl.dataProvider().minimumValue(0), -1) self.assertEqual(vl.dataProvider().minimumValue(1), -1400) self.assertEqual(vl.dataProvider().maximumValue(0), 15) self.assertEqual(vl.dataProvider().maximumValue(1), 1400) # change attribute values self.assertTrue(vl.dataProvider().changeAttributeValues({f6.id(): {0: 3, 1: 150}, f7.id(): {0: 4, 1: -100}})) self.assertEqual(vl.dataProvider().minimumValue(0), 1) self.assertEqual(vl.dataProvider().minimumValue(1), -200) self.assertEqual(vl.dataProvider().maximumValue(0), 5) self.assertEqual(vl.dataProvider().maximumValue(1), 400) # delete features self.assertTrue(vl.dataProvider().deleteFeatures([f4.id(), f1.id()])) self.assertEqual(vl.dataProvider().minimumValue(0), 1) self.assertEqual(vl.dataProvider().minimumValue(1), -100) self.assertEqual(vl.dataProvider().maximumValue(0), 4) self.assertEqual(vl.dataProvider().maximumValue(1), 400) # delete attributes self.assertTrue(vl.dataProvider().deleteAttributes([0])) self.assertEqual(vl.dataProvider().minimumValue(0), -100) self.assertEqual(vl.dataProvider().maximumValue(0), 400)
def test_exceptions(self): ml = QgsVectorLayer( "Point?crs=epsg:4236&field=id:integer&field=value:double", "test_data", "memory") assert ml.isValid() fields = ml.fields() # check no error fields.remove(1) # check exceptions raised with self.assertRaises(KeyError): fields.remove(-1) with self.assertRaises(KeyError): fields.remove(111) fields = ml.fields() # check no error self.assertEqual("value", fields[1].name()) self.assertEqual("value", fields[-1].name()) # check exceptions raised with self.assertRaises(IndexError): fields[111] # check no error fields.at(1) # check exceptions raised with self.assertRaises(KeyError): fields.at(-1) with self.assertRaises(KeyError): fields.at(111) # check no error fields.field(1) # check exceptions raised with self.assertRaises(KeyError): fields.field(-1) with self.assertRaises(KeyError): fields.field(111) # check no error fields.field('value') # check exceptions raised with self.assertRaises(KeyError): fields.field('bad') # check no error fields.fieldOrigin(1) # check exceptions raised with self.assertRaises(KeyError): fields.fieldOrigin(-1) with self.assertRaises(KeyError): fields.fieldOrigin(111) # check no error fields.fieldOriginIndex(1) # check exceptions raised with self.assertRaises(KeyError): fields.fieldOriginIndex(-1) with self.assertRaises(KeyError): fields.fieldOriginIndex(111) # check no error fields.iconForField(1) # check exceptions raised with self.assertRaises(KeyError): fields.iconForField(-1) with self.assertRaises(KeyError): fields.iconForField(111)
def testIteration(self): p = QgsProject() vectorFileInfo = QFileInfo(unitTestDataPath() + "/france_parts.shp") vector_layer = QgsVectorLayer(vectorFileInfo.filePath(), vectorFileInfo.completeBaseName(), "ogr") self.assertTrue(vector_layer.isValid()) p.addMapLayer(vector_layer) l = QgsPrintLayout(p) atlas = l.atlas() atlas.setEnabled(True) atlas.setCoverageLayer(vector_layer) atlas_feature_changed_spy = QSignalSpy(atlas.featureChanged) context_changed_spy = QSignalSpy(l.reportContext().changed) self.assertTrue(atlas.beginRender()) self.assertTrue(atlas.first()) self.assertEqual(len(atlas_feature_changed_spy), 1) self.assertEqual(len(context_changed_spy), 1) self.assertEqual(atlas.currentFeatureNumber(), 0) self.assertEqual(l.reportContext().feature()[4], 'Basse-Normandie') self.assertEqual(l.reportContext().layer(), vector_layer) f1 = l.reportContext().feature() self.assertTrue(atlas.next()) self.assertEqual(len(atlas_feature_changed_spy), 2) self.assertEqual(len(context_changed_spy), 2) self.assertEqual(atlas.currentFeatureNumber(), 1) self.assertEqual(l.reportContext().feature()[4], 'Bretagne') f2 = l.reportContext().feature() self.assertTrue(atlas.next()) self.assertEqual(len(atlas_feature_changed_spy), 3) self.assertEqual(len(context_changed_spy), 3) self.assertEqual(atlas.currentFeatureNumber(), 2) self.assertEqual(l.reportContext().feature()[4], 'Pays de la Loire') f3 = l.reportContext().feature() self.assertTrue(atlas.next()) self.assertEqual(len(atlas_feature_changed_spy), 4) self.assertEqual(len(context_changed_spy), 4) self.assertEqual(atlas.currentFeatureNumber(), 3) self.assertEqual(l.reportContext().feature()[4], 'Centre') f4 = l.reportContext().feature() self.assertFalse(atlas.next()) self.assertTrue(atlas.seekTo(2)) self.assertEqual(len(atlas_feature_changed_spy), 5) self.assertEqual(len(context_changed_spy), 5) self.assertEqual(atlas.currentFeatureNumber(), 2) self.assertEqual(l.reportContext().feature()[4], 'Pays de la Loire') self.assertTrue(atlas.last()) self.assertEqual(len(atlas_feature_changed_spy), 6) self.assertEqual(len(context_changed_spy), 6) self.assertEqual(atlas.currentFeatureNumber(), 3) self.assertEqual(l.reportContext().feature()[4], 'Centre') self.assertTrue(atlas.previous()) self.assertEqual(len(atlas_feature_changed_spy), 7) self.assertEqual(len(context_changed_spy), 7) self.assertEqual(atlas.currentFeatureNumber(), 2) self.assertEqual(l.reportContext().feature()[4], 'Pays de la Loire') self.assertTrue(atlas.previous()) self.assertTrue(atlas.previous()) self.assertEqual(len(atlas_feature_changed_spy), 9) self.assertFalse(atlas.previous()) self.assertEqual(len(atlas_feature_changed_spy), 9) self.assertTrue(atlas.endRender()) self.assertEqual(len(atlas_feature_changed_spy), 10) self.assertTrue(atlas.seekTo(f1)) self.assertEqual(l.reportContext().feature()[4], 'Basse-Normandie') self.assertTrue(atlas.seekTo(f4)) self.assertEqual(l.reportContext().feature()[4], 'Centre') self.assertTrue(atlas.seekTo(f3)) self.assertEqual(l.reportContext().feature()[4], 'Pays de la Loire') self.assertTrue(atlas.seekTo(f2)) self.assertEqual(l.reportContext().feature()[4], 'Bretagne') self.assertFalse(atlas.seekTo(QgsFeature(5)))
def testWriteShapefileWithAttributeSubsets(self): """Tests writing subsets of attributes to files.""" ml = QgsVectorLayer(( 'Point?crs=epsg:4326&field=id:int&field=field1:int&field=field2:int&field=field3:int' ), 'test', 'memory') self.assertIsNotNone(ml, 'Provider not initialized') self.assertTrue(ml.isValid(), 'Source layer not valid') provider = ml.dataProvider() self.assertIsNotNone(provider) ft = QgsFeature() ft.setGeometry(QgsGeometry.fromWkt('Point (1 2)')) ft.setAttributes([1, 11, 12, 13]) res, features = provider.addFeatures([ft]) self.assertTrue(res) self.assertTrue(features) # first write out with all attributes dest_file_name = os.path.join(str(QDir.tempPath()), 'all_attributes.shp') crs = QgsCoordinateReferenceSystem() crs.createFromId(4326, QgsCoordinateReferenceSystem.EpsgCrsId) write_result, error_message = QgsVectorFileWriter.writeAsVectorFormat( ml, dest_file_name, 'utf-8', crs, 'ESRI Shapefile', attributes=[]) self.assertEqual(write_result, QgsVectorFileWriter.NoError, error_message) # Open result and check created_layer = QgsVectorLayer('{}|layerid=0'.format(dest_file_name), 'test', 'ogr') self.assertEqual(created_layer.fields().count(), 4) f = next(created_layer.getFeatures(QgsFeatureRequest())) self.assertEqual(f['id'], 1) self.assertEqual(f['field1'], 11) self.assertEqual(f['field2'], 12) self.assertEqual(f['field3'], 13) # now test writing out only a subset of attributes dest_file_name = os.path.join(str(QDir.tempPath()), 'subset_attributes.shp') write_result, error_message = QgsVectorFileWriter.writeAsVectorFormat( ml, dest_file_name, 'utf-8', crs, 'ESRI Shapefile', attributes=[1, 3]) self.assertEqual(write_result, QgsVectorFileWriter.NoError, error_message) # Open result and check created_layer = QgsVectorLayer('{}|layerid=0'.format(dest_file_name), 'test', 'ogr') self.assertEqual(created_layer.fields().count(), 2) f = next(created_layer.getFeatures(QgsFeatureRequest())) self.assertEqual(f['field1'], 11) self.assertEqual(f['field3'], 13) # finally test writing no attributes dest_file_name = os.path.join(str(QDir.tempPath()), 'no_attributes.shp') write_result, error_message = QgsVectorFileWriter.writeAsVectorFormat( ml, dest_file_name, 'utf-8', crs, 'ESRI Shapefile', skipAttributeCreation=True) self.assertEqual(write_result, QgsVectorFileWriter.NoError, error_message) # Open result and check created_layer = QgsVectorLayer('{}|layerid=0'.format(dest_file_name), 'test', 'ogr') # expect only a default 'FID' field for shapefiles self.assertEqual(created_layer.fields().count(), 1) self.assertEqual(created_layer.fields()[0].name(), 'FID') # in this case we also check that the geometry exists, to make sure feature has been correctly written # even without attributes f = next(created_layer.getFeatures(QgsFeatureRequest())) g = f.geometry() wkt = g.asWkt() expWkt = 'Point (1 2)' self.assertTrue( compareWkt(expWkt, wkt), "geometry not saved correctly when saving without attributes : mismatch Expected:\n%s\nGot:\n%s\n" % (expWkt, wkt)) self.assertEqual(f['FID'], 0)
def create_file(self): layer = QgsVectorLayer(PROFILE_LINES_PATH, "profiles", "ogr") assert layer.isValid() return PreCourlisFileLine(layer)
def testCtors(self): testVectors = ["Point", "LineString", "Polygon", "MultiPoint", "MultiLineString", "MultiPolygon", "None"] for v in testVectors: layer = QgsVectorLayer(v, "test", "memory") assert layer.isValid(), "Failed to create valid %s memory layer" % (v)
def test_project_roundtrip(self): """Tests that a project with bad layers can be saved and restored""" p = QgsProject.instance() temp_dir = QTemporaryDir() for ext in ('shp', 'dbf', 'shx', 'prj'): copyfile(os.path.join(TEST_DATA_DIR, 'lines.%s' % ext), os.path.join(temp_dir.path(), 'lines.%s' % ext)) copyfile( os.path.join(TEST_DATA_DIR, 'raster', 'band1_byte_ct_epsg4326.tif'), os.path.join(temp_dir.path(), 'band1_byte_ct_epsg4326.tif')) copyfile( os.path.join(TEST_DATA_DIR, 'raster', 'band1_byte_ct_epsg4326.tif'), os.path.join(temp_dir.path(), 'band1_byte_ct_epsg4326_copy.tif')) l = QgsVectorLayer(os.path.join(temp_dir.path(), 'lines.shp'), 'lines', 'ogr') self.assertTrue(l.isValid()) rl = QgsRasterLayer( os.path.join(temp_dir.path(), 'band1_byte_ct_epsg4326.tif'), 'raster', 'gdal') self.assertTrue(rl.isValid()) rl_copy = QgsRasterLayer( os.path.join(temp_dir.path(), 'band1_byte_ct_epsg4326_copy.tif'), 'raster_copy', 'gdal') self.assertTrue(rl_copy.isValid()) self.assertTrue(p.addMapLayers([l, rl, rl_copy])) # Save project project_path = os.path.join(temp_dir.path(), 'project.qgs') self.assertTrue(p.write(project_path)) # Re-load the project, checking for the XML properties p.removeAllMapLayers() self.assertTrue(p.read(project_path)) vector = list(p.mapLayersByName('lines'))[0] raster = list(p.mapLayersByName('raster'))[0] raster_copy = list(p.mapLayersByName('raster_copy'))[0] self.assertTrue(vector.originalXmlProperties() != '') self.assertTrue(raster.originalXmlProperties() != '') self.assertTrue(raster_copy.originalXmlProperties() != '') # Test setter raster.setOriginalXmlProperties('pippo') self.assertEqual(raster.originalXmlProperties(), 'pippo') # Now create and invalid project: bad_project_path = os.path.join(temp_dir.path(), 'project_bad.qgs') with open(project_path, 'r') as infile: with open(bad_project_path, 'w+') as outfile: outfile.write(infile.read().replace( './lines.shp', './lines-BAD_SOURCE.shp').replace( 'band1_byte_ct_epsg4326_copy.tif', 'band1_byte_ct_epsg4326_copy-BAD_SOURCE.tif')) # Load the bad project p.removeAllMapLayers() self.assertTrue(p.read(bad_project_path)) # Check layer is invalid vector = list(p.mapLayersByName('lines'))[0] raster = list(p.mapLayersByName('raster'))[0] raster_copy = list(p.mapLayersByName('raster_copy'))[0] self.assertIsNotNone(vector.dataProvider()) self.assertIsNotNone(raster.dataProvider()) self.assertIsNotNone(raster_copy.dataProvider()) self.assertFalse(vector.isValid()) self.assertFalse(raster_copy.isValid()) # Try a getFeatures self.assertEqual([f for f in vector.getFeatures()], []) self.assertTrue(raster.isValid()) self.assertEqual(vector.providerType(), 'ogr') # Save the project bad_project_path2 = os.path.join(temp_dir.path(), 'project_bad2.qgs') p.write(bad_project_path2) # Re-save the project, with fixed paths good_project_path = os.path.join(temp_dir.path(), 'project_good.qgs') with open(bad_project_path2, 'r') as infile: with open(good_project_path, 'w+') as outfile: outfile.write(infile.read().replace( './lines-BAD_SOURCE.shp', './lines.shp').replace( 'band1_byte_ct_epsg4326_copy-BAD_SOURCE.tif', 'band1_byte_ct_epsg4326_copy.tif')) # Load the good project p.removeAllMapLayers() self.assertTrue(p.read(good_project_path)) # Check layer is valid vector = list(p.mapLayersByName('lines'))[0] raster = list(p.mapLayersByName('raster'))[0] raster_copy = list(p.mapLayersByName('raster_copy'))[0] self.assertTrue(vector.isValid()) self.assertTrue(raster.isValid()) self.assertTrue(raster_copy.isValid())
def testWriteShapefileWithZ(self): """Check writing geometries with Z dimension to an ESRI shapefile.""" # start by saving a memory layer and forcing z ml = QgsVectorLayer( ('Point?crs=epsg:4326&field=id:int'), 'test', 'memory') self.assertIsNotNone(ml, 'Provider not initialized') self.assertTrue(ml.isValid(), 'Source layer not valid') provider = ml.dataProvider() self.assertIsNotNone(provider) ft = QgsFeature() ft.setGeometry(QgsGeometry.fromWkt('PointZ (1 2 3)')) ft.setAttributes([1]) res, features = provider.addFeatures([ft]) self.assertTrue(res) self.assertTrue(features) # check with both a standard PointZ and 25d style Point25D type for t in [QgsWkbTypes.PointZ, QgsWkbTypes.Point25D]: dest_file_name = os.path.join(str(QDir.tempPath()), 'point_{}.shp'.format(QgsWkbTypes.displayString(t))) crs = QgsCoordinateReferenceSystem() crs.createFromId(4326, QgsCoordinateReferenceSystem.EpsgCrsId) write_result, error_message = QgsVectorFileWriter.writeAsVectorFormat( ml, dest_file_name, 'utf-8', crs, 'ESRI Shapefile', overrideGeometryType=t) self.assertEqual(write_result, QgsVectorFileWriter.NoError, error_message) # Open result and check created_layer = QgsVectorLayer('{}|layerid=0'.format(dest_file_name), 'test', 'ogr') f = next(created_layer.getFeatures(QgsFeatureRequest())) g = f.geometry() wkt = g.asWkt() expWkt = 'PointZ (1 2 3)' self.assertTrue(compareWkt(expWkt, wkt), "saving geometry with Z failed: mismatch Expected:\n%s\nGot:\n%s\n" % (expWkt, wkt)) # also try saving out the shapefile version again, as an extra test # this tests that saving a layer with z WITHOUT explicitly telling the writer to keep z values, # will stay retain the z values dest_file_name = os.path.join(str(QDir.tempPath()), 'point_{}_copy.shp'.format(QgsWkbTypes.displayString(t))) crs = QgsCoordinateReferenceSystem() crs.createFromId(4326, QgsCoordinateReferenceSystem.EpsgCrsId) write_result, error_message = QgsVectorFileWriter.writeAsVectorFormat( created_layer, dest_file_name, 'utf-8', crs, 'ESRI Shapefile') self.assertEqual(write_result, QgsVectorFileWriter.NoError, error_message) # Open result and check created_layer_from_shp = QgsVectorLayer('{}|layerid=0'.format(dest_file_name), 'test', 'ogr') f = next(created_layer_from_shp.getFeatures(QgsFeatureRequest())) g = f.geometry() wkt = g.asWkt() self.assertTrue(compareWkt(expWkt, wkt), "saving geometry with Z failed: mismatch Expected:\n%s\nGot:\n%s\n" % (expWkt, wkt))
def create_layer(): layer = QgsVectorLayer("Point?field=fldtxt:string&field=fldint:integer", "addfeat", "memory") assert layer.isValid() return layer
def testProjectStorage(self): # New project without fileName p0 = QgsProject() self.assertTrue(p0.auxiliaryStorage().isValid()) # Create new layers with key otherwise auxiliary layers are not # automacially created when added in project vl0 = createLayer() vl0Shp = writeShape(vl0, 'vl0.shp') vl1 = createLayer() vl1Shp = writeShape(vl1, 'vl1.shp') vl0 = QgsVectorLayer(vl0Shp, 'points', 'ogr') self.assertTrue(vl0.isValid()) vl1 = QgsVectorLayer(vl1Shp, 'points', 'ogr') self.assertTrue(vl1.isValid()) # Add layers to project and check underlying auxiliary layers p0.addMapLayers([vl0, vl1]) self.assertTrue(vl0.loadAuxiliaryLayer(p0.auxiliaryStorage(), 'pk')) self.assertTrue( vl1.loadAuxiliaryLayer(p0.auxiliaryStorage(), 'num_char')) al0 = vl0.auxiliaryLayer() al1 = vl1.auxiliaryLayer() self.assertEqual(al0.joinInfo().targetFieldName(), 'pk') self.assertEqual(al1.joinInfo().targetFieldName(), 'num_char') # Add a field in auxiliary layers pdef0 = QgsPropertyDefinition('propname', QgsPropertyDefinition.DataTypeNumeric, '', '', 'ut') self.assertTrue(al0.addAuxiliaryField(pdef0)) pdef1 = QgsPropertyDefinition('propname1', QgsPropertyDefinition.DataTypeString, '', '', 'ut') self.assertTrue(al1.addAuxiliaryField(pdef1)) # Check auxiliary fields names af0Name = QgsAuxiliaryLayer.nameFromProperty(pdef0, False) self.assertEqual(af0Name, 'ut_propname') af1Name = QgsAuxiliaryLayer.nameFromProperty(pdef1, False) self.assertEqual(af1Name, 'ut_propname1') # Set value for auxiliary fields req = QgsFeatureRequest().setFilterExpression("name = 'Honey'") f = QgsFeature() vl0.getFeatures(req).nextFeature(f) self.assertTrue(f.isValid()) af0Name = QgsAuxiliaryLayer.nameFromProperty(pdef0, True) index0 = vl0.fields().indexOf(af0Name) vl0.changeAttributeValue(f.id(), index0, 333) req = QgsFeatureRequest().setFilterExpression("name = 'Apple'") f = QgsFeature() vl1.getFeatures(req).nextFeature(f) self.assertTrue(f.isValid()) af1Name = QgsAuxiliaryLayer.nameFromProperty(pdef1, True) index1 = vl1.fields().indexOf(af1Name) vl1.changeAttributeValue(f.id(), index0, 'myvalue') req = QgsFeatureRequest().setFilterExpression("name = 'Orange'") f = QgsFeature() vl1.getFeatures(req).nextFeature(f) self.assertTrue(f.isValid()) vl1.changeAttributeValue(f.id(), index0, 'myvalue1') # Save the project in a zip file f = tmpPath() + '.qgz' p0.write(f) # Open the zip file with embedded auxiliary storage p1 = QgsProject() p1.read(f) # Check that auxiliary fields are well loaded in layers self.assertEqual(len(p1.mapLayers().values()), 2) for vl in p1.mapLayers().values(): al = vl.auxiliaryLayer() self.assertEqual(len(al.auxiliaryFields()), 1) af = al.auxiliaryFields()[0] afPropDef = QgsAuxiliaryLayer.propertyDefinitionFromField(af) self.assertEqual(afPropDef.origin(), 'ut') if vl.auxiliaryLayer().joinInfo().targetFieldName() == 'pk': self.assertEqual(afPropDef.name(), 'propname') self.assertEqual(al.featureCount(), 1) req = QgsFeatureRequest().setFilterExpression("name = 'Honey'") f = QgsFeature() vl.getFeatures(req).nextFeature(f) self.assertTrue(f.isValid()) self.assertEqual(f.attributes()[index0], 333.0) else: # num_char self.assertEqual(al.featureCount(), 2) self.assertEqual(afPropDef.name(), 'propname1') req = QgsFeatureRequest().setFilterExpression("name = 'Apple'") f = QgsFeature() vl.getFeatures(req).nextFeature(f) self.assertTrue(f.isValid()) self.assertEqual(f.attributes()[index1], 'myvalue') req = QgsFeatureRequest().setFilterExpression( "name = 'Orange'") f = QgsFeature() vl.getFeatures(req).nextFeature(f) self.assertTrue(f.isValid()) self.assertEqual(f.attributes()[index1], 'myvalue1')
def testInvalidGeometries(self): """ Test what happens when SQL Server is a POS and throws an exception on encountering an invalid geometry """ vl = QgsVectorLayer( '%s srid=4167 type=POLYGON table="qgis_test"."invalid_polys" (ogr_geometry) sql=' % (self.dbconn), "testinvalid", "mssql") self.assertTrue(vl.isValid()) self.assertEqual( vl.dataProvider().extent().toString(1), QgsRectangle(173.953, -41.513, 173.967, -41.502).toString(1)) #burn through features - don't want SQL server to trip up on the invalid ones count = 0 for f in vl.dataProvider().getFeatures(): count += 1 self.assertEqual(count, 39) count = 0 for f in vl.dataProvider().getFeatures( QgsFeatureRequest(QgsRectangle(173, -42, 174, -41))): count += 1 # two invalid geometry features self.assertEqual(count, 37) # sorry... you get NO chance to see these features exist and repair them... because SQL server. Use PostGIS instead and live a happier life! # with estimated metadata vl = QgsVectorLayer( '%s srid=4167 type=POLYGON estimatedmetadata=true table="qgis_test"."invalid_polys" (ogr_geometry) sql=' % (self.dbconn), "testinvalid", "mssql") self.assertTrue(vl.isValid()) self.assertEqual( vl.dataProvider().extent().toString(1), QgsRectangle(173.954, -41.513, 173.967, -41.502).toString(1)) # Now, play on the edge! Let's disable invalid geometry handling and watch things crash and burn vl = QgsVectorLayer( '%s srid=4167 type=POLYGON table="qgis_test"."invalid_polys" (ogr_geometry) disableInvalidGeometryHandling="1" sql=' % (self.dbconn), "testinvalid", "mssql") self.assertTrue(vl.isValid()) self.assertEqual(vl.dataProvider().extent().toString(1), 'Empty') # HAHA - you asked for it #burn through features - don't expect anything wrong here yet count = 0 for f in vl.dataProvider().getFeatures(): count += 1 self.assertEqual(count, 39) count = 0 for f in vl.dataProvider().getFeatures( QgsFeatureRequest(QgsRectangle(173, -42, 174, -41))): count += 1 # now you only get 1 feature *sad trumpet* self.assertEqual(count, 1) count = 0 # same, with estimated metadata vl = QgsVectorLayer( '%s srid=4167 type=POLYGON estimatedmetadata=true table="qgis_test"."invalid_polys" (ogr_geometry) disableInvalidGeometryHandling="1" sql=' % (self.dbconn), "testinvalid", "mssql") self.assertTrue(vl.isValid()) self.assertEqual(vl.dataProvider().extent().toString(1), 'Empty')
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
class TestQgsLayoutMap(unittest.TestCase, LayoutItemTestCase): @classmethod def setUpClass(cls): cls.item_class = QgsLayoutItemMap def setUp(self): self.report = "<h1>Python QgsLayoutItemMap Tests</h1>\n" def tearDown(self): report_file_path = "%s/qgistest.html" % QDir.tempPath() with open(report_file_path, 'a') as report_file: report_file.write(self.report) def __init__(self, methodName): """Run once on class initialization.""" unittest.TestCase.__init__(self, methodName) myPath = os.path.join(TEST_DATA_DIR, 'rgb256x256.png') rasterFileInfo = QFileInfo(myPath) self.raster_layer = QgsRasterLayer(rasterFileInfo.filePath(), rasterFileInfo.completeBaseName()) rasterRenderer = QgsMultiBandColorRenderer( self.raster_layer.dataProvider(), 1, 2, 3) self.raster_layer.setRenderer(rasterRenderer) myPath = os.path.join(TEST_DATA_DIR, 'points.shp') vector_file_info = QFileInfo(myPath) self.vector_layer = QgsVectorLayer(vector_file_info.filePath(), vector_file_info.completeBaseName(), 'ogr') assert self.vector_layer.isValid() QgsProject.instance().addMapLayers([self.raster_layer, self.vector_layer]) # create layout with layout map self.layout = QgsLayout(QgsProject.instance()) self.layout.initializeDefaults() self.map = QgsLayoutItemMap(self.layout) self.map.attemptSetSceneRect(QRectF(20, 20, 200, 100)) self.map.setFrameEnabled(True) self.map.setLayers([self.raster_layer]) self.layout.addLayoutItem(self.map) def testOverviewMap(self): overviewMap = QgsLayoutItemMap(self.layout) overviewMap.attemptSetSceneRect(QRectF(20, 130, 70, 70)) overviewMap.setFrameEnabled(True) overviewMap.setLayers([self.raster_layer]) self.layout.addLayoutItem(overviewMap) # zoom in myRectangle = QgsRectangle(96, -152, 160, -120) self.map.setExtent(myRectangle) myRectangle2 = QgsRectangle(0, -256, 256, 0) overviewMap.setExtent(myRectangle2) overviewMap.overview().setLinkedMap(self.map) checker = QgsLayoutChecker('composermap_overview', self.layout) checker.setColorTolerance(6) checker.setControlPathPrefix("composer_mapoverview") myTestResult, myMessage = checker.testLayout() self.report += checker.report() self.layout.removeLayoutItem(overviewMap) self.assertTrue(myTestResult, myMessage) def testOverviewMapBlend(self): overviewMap = QgsLayoutItemMap(self.layout) overviewMap.attemptSetSceneRect(QRectF(20, 130, 70, 70)) overviewMap.setFrameEnabled(True) overviewMap.setLayers([self.raster_layer]) self.layout.addLayoutItem(overviewMap) # zoom in myRectangle = QgsRectangle(96, -152, 160, -120) self.map.setExtent(myRectangle) myRectangle2 = QgsRectangle(0, -256, 256, 0) overviewMap.setExtent(myRectangle2) overviewMap.overview().setLinkedMap(self.map) overviewMap.overview().setBlendMode(QPainter.CompositionMode_Multiply) checker = QgsLayoutChecker('composermap_overview_blending', self.layout) checker.setControlPathPrefix("composer_mapoverview") myTestResult, myMessage = checker.testLayout() self.report += checker.report() self.layout.removeLayoutItem(overviewMap) self.assertTrue(myTestResult, myMessage) def testOverviewMapInvert(self): overviewMap = QgsLayoutItemMap(self.layout) overviewMap.attemptSetSceneRect(QRectF(20, 130, 70, 70)) overviewMap.setFrameEnabled(True) overviewMap.setLayers([self.raster_layer]) self.layout.addLayoutItem(overviewMap) # zoom in myRectangle = QgsRectangle(96, -152, 160, -120) self.map.setExtent(myRectangle) myRectangle2 = QgsRectangle(0, -256, 256, 0) overviewMap.setExtent(myRectangle2) overviewMap.overview().setLinkedMap(self.map) overviewMap.overview().setInverted(True) checker = QgsLayoutChecker('composermap_overview_invert', self.layout) checker.setControlPathPrefix("composer_mapoverview") myTestResult, myMessage = checker.testLayout() self.report += checker.report() self.layout.removeLayoutItem(overviewMap) self.assertTrue(myTestResult, myMessage) def testOverviewMapCenter(self): overviewMap = QgsLayoutItemMap(self.layout) overviewMap.attemptSetSceneRect(QRectF(20, 130, 70, 70)) overviewMap.setFrameEnabled(True) overviewMap.setLayers([self.raster_layer]) self.layout.addLayoutItem(overviewMap) # zoom in myRectangle = QgsRectangle(192, -288, 320, -224) self.map.setExtent(myRectangle) myRectangle2 = QgsRectangle(0, -256, 256, 0) overviewMap.setExtent(myRectangle2) overviewMap.overview().setLinkedMap(self.map) overviewMap.overview().setInverted(False) overviewMap.overview().setCentered(True) checker = QgsLayoutChecker('composermap_overview_center', self.layout) checker.setControlPathPrefix("composer_mapoverview") myTestResult, myMessage = checker.testLayout() self.report += checker.report() self.layout.removeLayoutItem(overviewMap) self.assertTrue(myTestResult, myMessage) def testAsMapLayer(self): l = QgsLayout(QgsProject.instance()) l.initializeDefaults() map = QgsLayoutItemMap(l) map.attemptSetSceneRect(QRectF(20, 20, 200, 100)) l.addLayoutItem(map) overviewMap = QgsLayoutItemMap(l) overviewMap.attemptSetSceneRect(QRectF(20, 130, 70, 70)) l.addLayoutItem(overviewMap) # zoom in myRectangle = QgsRectangle(96, -152, 160, -120) map.setExtent(myRectangle) myRectangle2 = QgsRectangle(0, -256, 256, 0) overviewMap.setExtent(myRectangle2) overviewMap.overview().setLinkedMap(map) layer = overviewMap.overview().asMapLayer() self.assertIsNotNone(layer) self.assertTrue(layer.isValid()) self.assertEqual([f.geometry().asWkt() for f in layer.getFeatures()], ['Polygon ((96 -120, 160 -120, 160 -152, 96 -152, 96 -120))']) # check that layer has correct renderer fill_symbol = QgsFillSymbol.createSimple({'color': '#00ff00', 'outline_color': '#ff0000', 'outline_width': '10'}) overviewMap.overview().setFrameSymbol(fill_symbol) layer = overviewMap.overview().asMapLayer() self.assertIsInstance(layer.renderer(), QgsSingleSymbolRenderer) self.assertEqual(layer.renderer().symbol().symbolLayer(0).properties()['color'], '0,255,0,255') self.assertEqual(layer.renderer().symbol().symbolLayer(0).properties()['outline_color'], '255,0,0,255') # test layer blend mode self.assertEqual(layer.blendMode(), QPainter.CompositionMode_SourceOver) overviewMap.overview().setBlendMode(QPainter.CompositionMode_Clear) layer = overviewMap.overview().asMapLayer() self.assertEqual(layer.blendMode(), QPainter.CompositionMode_Clear) # should have no effect overviewMap.setMapRotation(45) layer = overviewMap.overview().asMapLayer() self.assertEqual([f.geometry().asWkt() for f in layer.getFeatures()], ['Polygon ((96 -120, 160 -120, 160 -152, 96 -152, 96 -120))']) map.setMapRotation(15) layer = overviewMap.overview().asMapLayer() self.assertEqual([f.geometry().asWkt(0) for f in layer.getFeatures()], ['Polygon ((93 -129, 155 -112, 163 -143, 101 -160, 93 -129))']) # with reprojection map.setCrs(QgsCoordinateReferenceSystem('EPSG:3875')) layer = overviewMap.overview().asMapLayer() self.assertEqual([f.geometry().asWkt(0) for f in layer.getFeatures()], ['Polygon ((93 -129, 96 -128, 99 -127, 102 -126, 105 -126, 108 -125, 111 -124, 114 -123, 116 -123, 119 -122, 122 -121, 125 -120, 128 -119, 131 -119, 134 -118, 137 -117, 140 -116, 143 -115, 146 -115, 149 -114, 152 -113, 155 -112, 155 -114, 156 -115, 156 -117, 156 -118, 157 -120, 157 -121, 158 -123, 158 -124, 158 -126, 159 -127, 159 -128, 160 -130, 160 -131, 160 -133, 161 -134, 161 -136, 161 -137, 162 -139, 162 -140, 163 -142, 163 -143, 160 -144, 157 -145, 154 -146, 151 -146, 148 -147, 145 -148, 142 -149, 140 -149, 137 -150, 134 -151, 131 -152, 128 -153, 125 -153, 122 -154, 119 -155, 116 -156, 113 -157, 110 -157, 107 -158, 104 -159, 101 -160, 101 -158, 100 -157, 100 -155, 100 -154, 99 -152, 99 -151, 98 -149, 98 -148, 98 -146, 97 -145, 97 -144, 96 -142, 96 -141, 96 -139, 95 -138, 95 -136, 95 -135, 94 -133, 94 -132, 93 -130, 93 -129))']) map.setCrs(overviewMap.crs()) # with invert overviewMap.overview().setInverted(True) layer = overviewMap.overview().asMapLayer() self.assertEqual([f.geometry().asWkt(0) for f in layer.getFeatures()], ['Polygon ((-53 -128, 128 53, 309 -128, 128 -309, -53 -128),(93 -129, 101 -160, 163 -143, 155 -112, 93 -129))']) def test_StackingPosition(self): l = QgsLayout(QgsProject.instance()) l.initializeDefaults() overviewMap = QgsLayoutItemMap(l) overviewMap.attemptSetSceneRect(QRectF(20, 130, 70, 70)) l.addLayoutItem(overviewMap) overviewMap.overview().setStackingPosition(QgsLayoutItemMapItem.StackBelowMap) self.assertEqual(overviewMap.overview().stackingPosition(), QgsLayoutItemMapItem.StackBelowMap) overviewMap.overview().setStackingPosition(QgsLayoutItemMapItem.StackBelowMapLayer) self.assertEqual(overviewMap.overview().stackingPosition(), QgsLayoutItemMapItem.StackBelowMapLayer) overviewMap.overview().setStackingLayer(self.raster_layer) self.assertEqual(overviewMap.overview().stackingLayer(), self.raster_layer) overviewMap.overview().setStackingLayer(self.vector_layer) self.assertEqual(overviewMap.overview().stackingLayer(), self.vector_layer) overviewMap.overview().setStackingLayer(None) self.assertIsNone(overviewMap.overview().stackingLayer()) def test_ModifyMapLayerList(self): l = QgsLayout(QgsProject.instance()) l.initializeDefaults() overviewMap = QgsLayoutItemMap(l) overviewMap.attemptSetSceneRect(QRectF(20, 130, 70, 70)) l.addLayoutItem(overviewMap) map = QgsLayoutItemMap(l) map.attemptSetSceneRect(QRectF(20, 20, 200, 100)) l.addLayoutItem(map) self.assertFalse(overviewMap.overviews().modifyMapLayerList([])) self.assertEqual(overviewMap.overviews().modifyMapLayerList([self.raster_layer, self.vector_layer]), [self.raster_layer, self.vector_layer]) overviewMap.overview().setLinkedMap(map) overviewMap.overview().setStackingPosition(QgsLayoutItemMapItem.StackBelowMap) self.assertEqual(overviewMap.overviews().modifyMapLayerList([self.raster_layer, self.vector_layer]), [self.raster_layer, self.vector_layer, overviewMap.overview().asMapLayer()]) overviewMap.overview().setStackingPosition(QgsLayoutItemMapItem.StackBelowMapLayer) self.assertEqual(overviewMap.overviews().modifyMapLayerList([self.raster_layer, self.vector_layer]), [self.raster_layer, self.vector_layer]) overviewMap.overview().setStackingLayer(self.raster_layer) self.assertEqual(overviewMap.overviews().modifyMapLayerList([self.raster_layer, self.vector_layer]), [self.raster_layer, overviewMap.overview().asMapLayer(), self.vector_layer]) overviewMap.overview().setStackingLayer(self.vector_layer) self.assertEqual(overviewMap.overviews().modifyMapLayerList([self.raster_layer, self.vector_layer]), [self.raster_layer, self.vector_layer, overviewMap.overview().asMapLayer()]) overviewMap.overview().setStackingPosition(QgsLayoutItemMapItem.StackAboveMapLayer) overviewMap.overview().setStackingLayer(None) self.assertEqual(overviewMap.overviews().modifyMapLayerList([self.raster_layer, self.vector_layer]), [self.raster_layer, self.vector_layer]) overviewMap.overview().setStackingLayer(self.raster_layer) self.assertEqual(overviewMap.overviews().modifyMapLayerList([self.raster_layer, self.vector_layer]), [overviewMap.overview().asMapLayer(), self.raster_layer, self.vector_layer]) overviewMap.overview().setStackingLayer(self.vector_layer) self.assertEqual(overviewMap.overviews().modifyMapLayerList([self.raster_layer, self.vector_layer]), [self.raster_layer, overviewMap.overview().asMapLayer(), self.vector_layer]) overviewMap.overview().setStackingPosition(QgsLayoutItemMapItem.StackBelowMapLabels) self.assertEqual(overviewMap.overviews().modifyMapLayerList([self.raster_layer, self.vector_layer]), [overviewMap.overview().asMapLayer(), self.raster_layer, self.vector_layer]) overviewMap.overview().setStackingPosition(QgsLayoutItemMapItem.StackAboveMapLabels) self.assertEqual(overviewMap.overviews().modifyMapLayerList([self.raster_layer, self.vector_layer]), [self.raster_layer, self.vector_layer]) # two overviews overviewMap.overview().setStackingPosition(QgsLayoutItemMapItem.StackBelowMap) overviewMap.overviews().addOverview(QgsLayoutItemMapOverview('x', overviewMap)) overviewMap.overviews().overview(1).setLinkedMap(map) overviewMap.overviews().overview(1).setStackingPosition(QgsLayoutItemMapItem.StackBelowMapLabels) self.assertEqual(overviewMap.overviews().modifyMapLayerList([self.raster_layer, self.vector_layer]), [overviewMap.overviews().overview(1).asMapLayer(), self.raster_layer, self.vector_layer, overviewMap.overview().asMapLayer()]) def testOverviewStacking(self): l = QgsLayout(QgsProject.instance()) l.initializeDefaults() map = QgsLayoutItemMap(l) map.attemptSetSceneRect(QRectF(20, 20, 200, 100)) map.setFrameEnabled(True) map.setLayers([self.raster_layer]) l.addLayoutItem(map) overviewMap = QgsLayoutItemMap(l) overviewMap.attemptSetSceneRect(QRectF(20, 130, 70, 70)) l.addLayoutItem(overviewMap) overviewMap.setFrameEnabled(True) overviewMap.setLayers([self.raster_layer]) # zoom in myRectangle = QgsRectangle(96, -152, 160, -120) map.setExtent(myRectangle) myRectangle2 = QgsRectangle(-20, -276, 276, 20) overviewMap.setExtent(myRectangle2) overviewMap.overview().setLinkedMap(map) overviewMap.overview().setInverted(True) overviewMap.overview().setStackingPosition(QgsLayoutItemMapItem.StackBelowMapLayer) overviewMap.overview().setStackingLayer(self.raster_layer) checker = QgsLayoutChecker('composermap_overview_belowmap', l) checker.setColorTolerance(6) checker.setControlPathPrefix("composer_mapoverview") myTestResult, myMessage = checker.testLayout() self.report += checker.report() self.assertTrue(myTestResult, myMessage) overviewMap.overview().setStackingPosition(QgsLayoutItemMapItem.StackAboveMapLayer) overviewMap.overview().setStackingLayer(self.raster_layer) checker = QgsLayoutChecker('composermap_overview_abovemap', l) checker.setColorTolerance(6) checker.setControlPathPrefix("composer_mapoverview") myTestResult, myMessage = checker.testLayout() self.report += checker.report() self.assertTrue(myTestResult, myMessage)
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)
class TestQgsComposerMap(unittest.TestCase): def __init__(self, methodName): """Run once on class initialization.""" unittest.TestCase.__init__(self, methodName) myPath = os.path.join(TEST_DATA_DIR, 'rgb256x256.png') rasterFileInfo = QFileInfo(myPath) self.raster_layer = QgsRasterLayer(rasterFileInfo.filePath(), rasterFileInfo.completeBaseName()) rasterRenderer = QgsMultiBandColorRenderer( self.raster_layer.dataProvider(), 1, 2, 3) self.raster_layer.setRenderer(rasterRenderer) myPath = os.path.join(TEST_DATA_DIR, 'points.shp') vector_file_info = QFileInfo(myPath) self.vector_layer = QgsVectorLayer(vector_file_info.filePath(), vector_file_info.completeBaseName(), 'ogr') assert self.vector_layer.isValid() # pipe = mRasterLayer.pipe() # assert pipe.set(rasterRenderer), 'Cannot set pipe renderer' QgsProject.instance().addMapLayers( [self.raster_layer, self.vector_layer]) # create composition with composer map self.mComposition = QgsComposition(QgsProject.instance()) self.mComposition.setPaperSize(297, 210) self.mComposerMap = QgsComposerMap(self.mComposition, 20, 20, 200, 100) self.mComposerMap.setFrameEnabled(True) self.mComposerMap.setLayers([self.raster_layer]) self.mComposition.addComposerMap(self.mComposerMap) def testOverviewMap(self): overviewMap = QgsComposerMap(self.mComposition, 20, 130, 70, 70) overviewMap.setFrameEnabled(True) overviewMap.setLayers([self.raster_layer]) self.mComposition.addComposerMap(overviewMap) # zoom in myRectangle = QgsRectangle(96, -152, 160, -120) self.mComposerMap.setNewExtent(myRectangle) myRectangle2 = QgsRectangle(0, -256, 256, 0) overviewMap.setNewExtent(myRectangle2) overviewMap.overview().setFrameMap(self.mComposerMap.id()) checker = QgsCompositionChecker('composermap_overview', self.mComposition) checker.setControlPathPrefix("composer_mapoverview") myTestResult, myMessage = checker.testComposition() self.mComposition.removeComposerItem(overviewMap) assert myTestResult, myMessage def testOverviewMapBlend(self): overviewMap = QgsComposerMap(self.mComposition, 20, 130, 70, 70) overviewMap.setFrameEnabled(True) overviewMap.setLayers([self.raster_layer]) self.mComposition.addComposerMap(overviewMap) # zoom in myRectangle = QgsRectangle(96, -152, 160, -120) self.mComposerMap.setNewExtent(myRectangle) myRectangle2 = QgsRectangle(0, -256, 256, 0) overviewMap.setNewExtent(myRectangle2) overviewMap.overview().setFrameMap(self.mComposerMap.id()) overviewMap.overview().setBlendMode(QPainter.CompositionMode_Multiply) checker = QgsCompositionChecker('composermap_overview_blending', self.mComposition) checker.setControlPathPrefix("composer_mapoverview") myTestResult, myMessage = checker.testComposition() self.mComposition.removeComposerItem(overviewMap) assert myTestResult, myMessage def testOverviewMapInvert(self): overviewMap = QgsComposerMap(self.mComposition, 20, 130, 70, 70) overviewMap.setFrameEnabled(True) overviewMap.setLayers([self.raster_layer]) self.mComposition.addComposerMap(overviewMap) # zoom in myRectangle = QgsRectangle(96, -152, 160, -120) self.mComposerMap.setNewExtent(myRectangle) myRectangle2 = QgsRectangle(0, -256, 256, 0) overviewMap.setNewExtent(myRectangle2) overviewMap.overview().setFrameMap(self.mComposerMap.id()) overviewMap.overview().setInverted(True) checker = QgsCompositionChecker('composermap_overview_invert', self.mComposition) checker.setControlPathPrefix("composer_mapoverview") myTestResult, myMessage = checker.testComposition() self.mComposition.removeComposerItem(overviewMap) assert myTestResult, myMessage def testOverviewMapCenter(self): overviewMap = QgsComposerMap(self.mComposition, 20, 130, 70, 70) overviewMap.setFrameEnabled(True) overviewMap.setLayers([self.raster_layer]) self.mComposition.addComposerMap(overviewMap) # zoom in myRectangle = QgsRectangle(192, -288, 320, -224) self.mComposerMap.setNewExtent(myRectangle) myRectangle2 = QgsRectangle(0, -256, 256, 0) overviewMap.setNewExtent(myRectangle2) overviewMap.overview().setFrameMap(self.mComposerMap.id()) overviewMap.overview().setInverted(False) overviewMap.overview().setCentered(True) checker = QgsCompositionChecker('composermap_overview_center', self.mComposition) checker.setControlPathPrefix("composer_mapoverview") myTestResult, myMessage = checker.testComposition() self.mComposition.removeComposerItem(overviewMap) assert myTestResult, myMessage def testMapCrs(self): # create composition with composer map map_settings = QgsMapSettings() map_settings.setLayers([self.vector_layer]) composition = QgsComposition(QgsProject.instance()) composition.setPaperSize(297, 210) # check that new maps inherit project CRS QgsProject.instance().setCrs(QgsCoordinateReferenceSystem('EPSG:4326')) map = QgsComposerMap(composition, 20, 20, 200, 100) map.setFrameEnabled(True) rectangle = QgsRectangle(-13838977, 2369660, -8672298, 6250909) map.setNewExtent(rectangle) map.setLayers([self.vector_layer]) composition.addComposerMap(map) self.assertEqual(map.crs().authid(), 'EPSG:4326') self.assertFalse(map.presetCrs().isValid()) # overwrite CRS map.setCrs(QgsCoordinateReferenceSystem('EPSG:3857')) self.assertEqual(map.crs().authid(), 'EPSG:3857') self.assertEqual(map.presetCrs().authid(), 'EPSG:3857') checker = QgsCompositionChecker('composermap_crs3857', composition) checker.setControlPathPrefix("composer_map") result, message = checker.testComposition() self.assertTrue(result, message) # overwrite CRS map.setCrs(QgsCoordinateReferenceSystem('EPSG:4326')) self.assertEqual(map.presetCrs().authid(), 'EPSG:4326') self.assertEqual(map.crs().authid(), 'EPSG:4326') rectangle = QgsRectangle(-124, 17, -78, 52) map.zoomToExtent(rectangle) checker = QgsCompositionChecker('composermap_crs4326', composition) checker.setControlPathPrefix("composer_map") result, message = checker.testComposition() self.assertTrue(result, message) # change back to project CRS map.setCrs(QgsCoordinateReferenceSystem()) self.assertEqual(map.crs().authid(), 'EPSG:4326') self.assertFalse(map.presetCrs().isValid()) def testuniqueId(self): doc = QDomDocument() documentElement = doc.createElement('ComposerItemClipboard') self.mComposition.writeXml(documentElement, doc) self.mComposition.addItemsFromXml(documentElement, doc) # test if both composer maps have different ids newMap = QgsComposerMap(self.mComposition, 0, 0, 10, 10) mapList = self.mComposition.composerMapItems() for mapIt in mapList: if mapIt != self.mComposerMap: newMap = mapIt break oldId = self.mComposerMap.id() newId = newMap.id() self.mComposition.removeComposerItem(newMap) myMessage = 'old: %s new: %s' % (oldId, newId) assert oldId != newId, myMessage def testWorldFileGeneration(self): myRectangle = QgsRectangle(781662.375, 3339523.125, 793062.375, 3345223.125) self.mComposerMap.setNewExtent(myRectangle) self.mComposerMap.setMapRotation(30.0) self.mComposition.setGenerateWorldFile(True) self.mComposition.setReferenceMap(self.mComposerMap) p = self.mComposition.computeWorldFileParameters() pexpected = (4.180480199790922, 2.4133064516129026, 779443.7612381146, 2.4136013686911886, -4.179969388427311, 3342408.5663611) ptolerance = (0.001, 0.001, 1, 0.001, 0.001, 1e+03) for i in range(0, 6): assert abs(p[i] - pexpected[i]) < ptolerance[i]
def testFieldsWithSpecialCharacters(self): ml = QgsVectorLayer("Point?srid=EPSG:4326&field=123:int", "mem_with_nontext_fieldnames", "memory") self.assertEqual(ml.isValid(), True) QgsProject.instance().addMapLayer(ml) ml.startEditing() self.assertTrue(ml.addAttribute(QgsField('abc:123', QVariant.String))) self.assertTrue(ml.addAttribute(QgsField( 'map', QVariant.String))) # matches QGIS expression function name f1 = QgsFeature(ml.fields()) f1.setGeometry(QgsGeometry.fromWkt('POINT(0 0)')) f1.setAttributes([1, 'a', 'b']) f2 = QgsFeature(ml.fields()) f2.setGeometry(QgsGeometry.fromWkt('POINT(1 1)')) f2.setAttributes([2, 'c', 'd']) ml.addFeatures([f1, f2]) ml.commitChanges() vl = QgsVectorLayer("?query=select * from mem_with_nontext_fieldnames", "vl", "virtual") self.assertEqual(vl.isValid(), True) self.assertEqual(vl.fields().at(0).name(), '123') self.assertEqual(vl.fields().at(1).name(), 'abc:123') self.assertEqual(vl.featureCount(), 2) features = [ f for f in vl.getFeatures(QgsFeatureRequest().setFilterExpression( '"abc:123"=\'c\'')) ] self.assertEqual(len(features), 1) self.assertEqual(features[0].attributes(), [2, 'c', 'd']) features = [ f for f in vl.getFeatures(QgsFeatureRequest().setFilterExpression( '"map"=\'b\'')) ] self.assertEqual(len(features), 1) self.assertEqual(features[0].attributes(), [1, 'a', 'b']) vl2 = QgsVectorLayer( "?query=select * from mem_with_nontext_fieldnames where \"abc:123\"='c'", "vl", "virtual") self.assertEqual(vl2.isValid(), True) self.assertEqual(vl2.fields().at(0).name(), '123') self.assertEqual(vl2.fields().at(1).name(), 'abc:123') self.assertEqual(vl2.featureCount(), 1) features = [f for f in vl2.getFeatures()] self.assertEqual(len(features), 1) self.assertEqual(features[0].attributes(), [2, 'c', 'd']) vl3 = QgsVectorLayer( "?query=select * from mem_with_nontext_fieldnames where \"map\"='b'", "vl", "virtual") self.assertEqual(vl3.isValid(), True) self.assertEqual(vl3.fields().at(0).name(), '123') self.assertEqual(vl3.fields().at(1).name(), 'abc:123') self.assertEqual(vl3.featureCount(), 1) features = [f for f in vl3.getFeatures()] self.assertEqual(len(features), 1) self.assertEqual(features[0].attributes(), [1, 'a', 'b']) QgsProject.instance().removeMapLayer(ml)
def testDateTimeWriteShapefile(self): """Check writing date and time fields to an ESRI shapefile.""" ml = QgsVectorLayer( ('Point?crs=epsg:4326&field=id:int&' 'field=date_f:date&field=time_f:time&field=dt_f:datetime'), 'test', 'memory') self.assertTrue(ml.isValid()) provider = ml.dataProvider() self.assertIsNotNone(provider) ft = QgsFeature() ft.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(10, 10))) ft.setAttributes([ 1, QDate(2014, 3, 5), QTime(13, 45, 22), QDateTime(QDate(2014, 3, 5), QTime(13, 45, 22)) ]) res, features = provider.addFeatures([ft]) self.assertTrue(res) self.assertTrue(features) dest_file_name = os.path.join(str(QDir.tempPath()), 'datetime.shp') crs = QgsCoordinateReferenceSystem() crs.createFromId(4326, QgsCoordinateReferenceSystem.EpsgCrsId) write_result, error_message = QgsVectorFileWriter.writeAsVectorFormat( ml, dest_file_name, 'utf-8', crs, 'ESRI Shapefile') self.assertEqual(write_result, QgsVectorFileWriter.NoError, error_message) # Open result and check created_layer = QgsVectorLayer('{}|layerid=0'.format(dest_file_name), 'test', 'ogr') fields = created_layer.dataProvider().fields() self.assertEqual( fields.at(fields.indexFromName('date_f')).type(), QVariant.Date) # shapefiles do not support time types, result should be string self.assertEqual( fields.at(fields.indexFromName('time_f')).type(), QVariant.String) # shapefiles do not support datetime types, result should be string self.assertEqual( fields.at(fields.indexFromName('dt_f')).type(), QVariant.String) f = next(created_layer.getFeatures(QgsFeatureRequest())) date_idx = created_layer.fields().lookupField('date_f') self.assertIsInstance(f.attributes()[date_idx], QDate) self.assertEqual(f.attributes()[date_idx], QDate(2014, 3, 5)) time_idx = created_layer.fields().lookupField('time_f') # shapefiles do not support time types self.assertIsInstance(f.attributes()[time_idx], str) self.assertEqual(f.attributes()[time_idx], '13:45:22') # shapefiles do not support datetime types datetime_idx = created_layer.fields().lookupField('dt_f') self.assertIsInstance(f.attributes()[datetime_idx], str) self.assertEqual( f.attributes()[datetime_idx], QDateTime(QDate(2014, 3, 5), QTime(13, 45, 22)).toString("yyyy/MM/dd hh:mm:ss.zzz"))
def test_joined_layers_conversion(self): v1 = QgsVectorLayer( "Point?field=id:integer&field=b_id:integer&field=c_id:integer&field=name:string", "A", "memory") self.assertEqual(v1.isValid(), True) v2 = QgsVectorLayer( "Point?field=id:integer&field=bname:string&field=bfield:integer", "B", "memory") self.assertEqual(v2.isValid(), True) v3 = QgsVectorLayer("Point?field=id:integer&field=cname:string", "C", "memory") self.assertEqual(v3.isValid(), True) QgsProject.instance().addMapLayers([v1, v2, v3]) joinInfo = QgsVectorLayerJoinInfo() joinInfo.setTargetFieldName("b_id") joinInfo.setJoinLayer(v2) joinInfo.setJoinFieldName("id") #joinInfo.setPrefix("B_") v1.addJoin(joinInfo) self.assertEqual(len(v1.fields()), 6) df = QgsVirtualLayerDefinitionUtils.fromJoinedLayer(v1) self.assertEqual( df.query(), 'SELECT t.rowid AS uid, t.id, t.b_id, t.c_id, t.name, j1.bname AS B_bname, j1.bfield AS B_bfield FROM {} AS t LEFT JOIN {} AS j1 ON t."b_id"=j1."id"' .format(v1.id(), v2.id())) # with a field subset v1.removeJoin(v2.id()) joinInfo.setJoinFieldNamesSubset(["bname"]) v1.addJoin(joinInfo) self.assertEqual(len(v1.fields()), 5) df = QgsVirtualLayerDefinitionUtils.fromJoinedLayer(v1) self.assertEqual( df.query(), 'SELECT t.rowid AS uid, t.id, t.b_id, t.c_id, t.name, j1.bname AS B_bname FROM {} AS t LEFT JOIN {} AS j1 ON t."b_id"=j1."id"' .format(v1.id(), v2.id())) joinInfo.setJoinFieldNamesSubset(None) # add a table prefix to the join v1.removeJoin(v2.id()) joinInfo.setPrefix("BB_") v1.addJoin(joinInfo) self.assertEqual(len(v1.fields()), 6) df = QgsVirtualLayerDefinitionUtils.fromJoinedLayer(v1) self.assertEqual( df.query(), 'SELECT t.rowid AS uid, t.id, t.b_id, t.c_id, t.name, j1.bname AS BB_bname, j1.bfield AS BB_bfield FROM {} AS t LEFT JOIN {} AS j1 ON t."b_id"=j1."id"' .format(v1.id(), v2.id())) joinInfo.setPrefix("") v1.removeJoin(v2.id()) v1.addJoin(joinInfo) # add another join joinInfo2 = QgsVectorLayerJoinInfo() joinInfo2.setTargetFieldName("c_id") joinInfo2.setJoinLayer(v3) joinInfo2.setJoinFieldName("id") v1.addJoin(joinInfo2) self.assertEqual(len(v1.fields()), 7) df = QgsVirtualLayerDefinitionUtils.fromJoinedLayer(v1) self.assertEqual(df.query(), ( 'SELECT t.rowid AS uid, t.id, t.b_id, t.c_id, t.name, j1.bname AS B_bname, j1.bfield AS B_bfield, j2.cname AS C_cname FROM {} AS t ' + 'LEFT JOIN {} AS j1 ON t."b_id"=j1."id" ' + 'LEFT JOIN {} AS j2 ON t."c_id"=j2."id"').format( v1.id(), v2.id(), v3.id())) QgsProject.instance().removeMapLayers([v1.id(), v2.id(), v3.id()])
def testSurfaces(self): vl = QgsVectorLayer( '%s table="QGIS"."POLY_DATA" (GEOM) srid=4326 type=POLYGON sql=' % (self.dbconn), "testpoly", "oracle") self.assertTrue(vl.isValid()) features = {f['pk']: f for f in vl.getFeatures()} self.assertTrue( compareWkt(features[1].geometry().asWkt(), 'Polygon ((1 2, 11 2, 11 22, 1 22, 1 2))', 0.00001), features[1].geometry().asWkt()) self.assertTrue( compareWkt(features[2].geometry().asWkt(), 'PolygonZ ((1 2 3, 11 2 13, 11 22 15, 1 22 7, 1 2 3))', 0.00001), features[2].geometry().asWkt()) self.assertTrue( compareWkt( features[3].geometry().asWkt(), 'Polygon ((1 2, 11 2, 11 22, 1 22, 1 2),(5 6, 8 9, 8 6, 5 6),(3 4, 5 6, 3 6, 3 4))', 0.00001), features[3].geometry().asWkt()) self.assertTrue( compareWkt( features[4].geometry().asWkt(), 'PolygonZ ((1 2 3, 11 2 13, 11 22 15, 1 22 7, 1 2 3),(5 6 1, 8 9 -1, 8 6 2, 5 6 1))', 0.00001), features[4].geometry().asWkt()) self.assertTrue( compareWkt(features[5].geometry().asWkt(), 'Polygon ((1 2, 11 2, 11 22, 1 22, 1 2))', 0.00001), features[5].geometry().asWkt()) self.assertTrue( compareWkt( features[6].geometry().asWkt(), 'CurvePolygon (CircularString (6.76923076923076916 22.82875364393326834, 17.98259979777942519 11.61538461538461497, 6.76923076923076916 0.40201558683595984, -4.44413825931788598 11.61538461538461497, 6.76923076923076916 22.82875364393326834))', 0.00001), features[6].geometry().asWkt()) self.assertTrue( compareWkt( features[7].geometry().asWkt(), 'MultiPolygon (((1 2, 11 2, 11 22, 1 22, 1 2)),((1 2, 11 2, 11 22, 1 22, 1 2),(5 6, 8 9, 8 6, 5 6),(3 4, 5 6, 3 6, 3 4)))', 0.00001), features[7].geometry().asWkt()) self.assertTrue( compareWkt( features[8].geometry().asWkt(), 'MultiPolygonZ (((1 2 3, 11 2 13, 11 22 15, 1 22 7, 1 2 3)),((1 2 3, 11 2 13, 11 22 15, 1 22 7, 1 2 3),(5 6 1, 8 9 -1, 8 6 2, 5 6 1)))', 0.00001), features[8].geometry().asWkt()) self.assertTrue( compareWkt( features[9].geometry().asWkt(), 'CurvePolygon (CircularString (1 3, 3 5, 4 7, 7 3, 1 3))', 0.00001), features[9].geometry().asWkt()) self.assertTrue( compareWkt( features[10].geometry().asWkt(), 'CurvePolygon (CircularString (1 3, 3 5, 4 7, 7 3, 1 3),CircularString (3.1 3.3, 3.3 3.5, 3.4 3.7, 3.7 3.3, 3.1 3.3))', 0.00001), features[10].geometry().asWkt()) self.assertTrue( compareWkt( features[11].geometry().asWkt(), 'CurvePolygon(CompoundCurve ((-1 -5, 1 2),CircularString (1 2, 5 4, 7 2.20, 10 0.1, 13 4),(13 4, 17 -6),CircularString (17 -6, 5 -7, -1 -5)))', 0.00001), features[11].geometry().asWkt()) self.assertTrue( compareWkt( features[12].geometry().asWkt(), 'MultiSurface (CurvePolygon (CircularString (1 3, 3 5, 4 7, 7 3, 1 3)),CurvePolygon (CircularString (11 3, 13 5, 14 7, 17 3, 11 3)))', 0.00001), features[12].geometry().asWkt())
def test_read_write_project(self): """ Test saving/restoring dialog state in project """ # print('read write project test') p = QgsProject.instance() dialog = DataPlotlyPanelWidget(None, override_iface=IFACE) dialog.set_plot_type('violin') # first, disable saving to project dialog.read_from_project = False dialog.save_to_project = False path = os.path.join(tempfile.gettempdir(), 'test_dataplotly_project.qgs') layer_path = os.path.join( os.path.dirname(__file__), 'test_layer.geojson') # create QgsVectorLayer from path and test validity vl = QgsVectorLayer(layer_path, 'test_layer', 'ogr') self.assertTrue(vl.isValid()) # print(dialog.layer_combo.currentLayer()) self.assertTrue(p.write(path)) res = PlotSettings() # def read(doc): # self.assertTrue(res.read_from_project(doc)) # self.assertEqual(res.plot_type, 'violin') # self.read_triggered = True p.clear() for _ in range(100): QCoreApplication.processEvents() self.assertTrue(p.read(path)) self.assertEqual(res.plot_type, 'scatter') # TODO - enable when dialog can restore properties and avoid this fragile test # # enable saving to project # dialog.save_to_project = True # dialog.read_from_project = True # self.assertTrue(p.write(path)) # for _ in range(100): # QCoreApplication.processEvents() # p.clear() # p.readProject.connect(read) # self.assertTrue(p.read(path)) # for _ in range(100): # QCoreApplication.processEvents() # self.assertTrue(self.read_triggered) # todo - test that dialog can restore properties, but requires the missing set_settings method dialog.x_combo.setExpression('"Ca"') dialog.layer_combo.setLayer(vl) dialog.x_combo.currentText() self.assertTrue(dialog.x_combo.expression(), '"Ca"')
def testDuplicateFeature(self): """ test duplicating a feature """ project = QgsProject().instance() # LAYERS # - add first layer (parent) layer1 = QgsVectorLayer("Point?field=fldtxt:string&field=pkid:integer", "parentlayer", "memory") # > check first layer (parent) self.assertTrue(layer1.isValid()) # - set the value for the copy layer1.setDefaultValueDefinition(1, QgsDefaultValue("rand(1000,2000)")) # > check first layer (parent) self.assertTrue(layer1.isValid()) # - add second layer (child) layer2 = QgsVectorLayer( "Point?field=fldtxt:string&field=id:integer&field=foreign_key:integer", "childlayer", "memory") # > check second layer (child) self.assertTrue(layer2.isValid()) # - add layers project.addMapLayers([layer1, layer2]) # FEATURES # - add 2 features on layer1 (parent) l1f1orig = QgsFeature() l1f1orig.setFields(layer1.fields()) l1f1orig.setAttributes(["F_l1f1", 100]) l1f2orig = QgsFeature() l1f2orig.setFields(layer1.fields()) l1f2orig.setAttributes(["F_l1f2", 101]) # > check by adding features self.assertTrue(layer1.dataProvider().addFeatures([l1f1orig, l1f2orig])) # add 4 features on layer2 (child) l2f1orig = QgsFeature() l2f1orig.setFields(layer2.fields()) l2f1orig.setAttributes(["F_l2f1", 201, 100]) l2f2orig = QgsFeature() l2f2orig.setFields(layer2.fields()) l2f2orig.setAttributes(["F_l2f2", 202, 100]) l2f3orig = QgsFeature() l2f3orig.setFields(layer2.fields()) l2f3orig.setAttributes(["F_l2f3", 203, 100]) l2f4orig = QgsFeature() l2f4orig.setFields(layer2.fields()) l2f4orig.setAttributes(["F_l2f4", 204, 101]) # > check by adding features self.assertTrue(layer2.dataProvider().addFeatures( [l2f1orig, l2f2orig, l2f3orig, l2f4orig])) # RELATION # - create the relationmanager relMgr = project.relationManager() # - create the relation rel = QgsRelation() rel.setId('rel1') rel.setName('childrel') rel.setReferencingLayer(layer2.id()) rel.setReferencedLayer(layer1.id()) rel.addFieldPair('foreign_key', 'pkid') rel.setStrength(QgsRelation.Composition) # > check relation self.assertTrue(rel.isValid()) # - add relation relMgr.addRelation(rel) # > check if referencedLayer is layer1 self.assertEqual(rel.referencedLayer(), layer1) # > check if referencingLayer is layer2 self.assertEqual(rel.referencingLayer(), layer2) # > check if the layers are correct in relation when loading from relationManager relations = project.relationManager().relations() relation = relations[list(relations.keys())[0]] # > check if referencedLayer is layer1 self.assertEqual(relation.referencedLayer(), layer1) # > check if referencingLayer is layer2 self.assertEqual(relation.referencingLayer(), layer2) # > check the relatedfeatures ''' # testoutput 1 print( "\nAll Features and relations") featit=layer1.getFeatures() f=QgsFeature() while featit.nextFeature(f): print( f.attributes()) childFeature = QgsFeature() relfeatit=rel.getRelatedFeatures(f) while relfeatit.nextFeature(childFeature): print( childFeature.attributes() ) print( "\n--------------------------") print( "\nFeatures on layer1") for f in layer1.getFeatures(): print( f.attributes() ) print( "\nFeatures on layer2") for f in layer2.getFeatures(): print( f.attributes() ) ''' # DUPLICATION # - duplicate feature l1f1orig with children layer1.startEditing() results = QgsVectorLayerUtils.duplicateFeature(layer1, l1f1orig, project, 0) # > check if name is name of duplicated (pk is different) result_feature = results[0] self.assertEqual(result_feature.attribute('fldtxt'), l1f1orig.attribute('fldtxt')) # > check duplicated child layer result_layer = results[1].layers()[0] self.assertEqual(result_layer, layer2) # > check duplicated child features self.assertTrue(results[1].duplicatedFeatures(result_layer)) ''' # testoutput 2 print( "\nFeatures on layer1 (after duplication)") for f in layer1.getFeatures(): print( f.attributes() ) print( "\nFeatures on layer2 (after duplication)") for f in layer2.getFeatures(): print( f.attributes() ) print( "\nAll Features and relations") featit=layer1.getFeatures() f=QgsFeature() while featit.nextFeature(f): print( f.attributes()) childFeature = QgsFeature() relfeatit=rel.getRelatedFeatures(f) while relfeatit.nextFeature(childFeature): print( childFeature.attributes() ) ''' # > compare text of parent feature self.assertEqual(result_feature.attribute('fldtxt'), l1f1orig.attribute('fldtxt')) # - create copyValueList childFeature = QgsFeature() relfeatit = rel.getRelatedFeatures(result_feature) copyValueList = [] while relfeatit.nextFeature(childFeature): copyValueList.append(childFeature.attribute('fldtxt')) # - create origValueList childFeature = QgsFeature() relfeatit = rel.getRelatedFeatures(l1f1orig) origValueList = [] while relfeatit.nextFeature(childFeature): origValueList.append(childFeature.attribute('fldtxt')) # - check if the ids are still the same self.assertEqual(copyValueList, origValueList)
def testRelativePaths(self): """ Test whether paths to layer sources are stored as relative to the project path """ tmpDir = QTemporaryDir() tmpFile = "{}/project.qgs".format(tmpDir.path()) copyfile(os.path.join(TEST_DATA_DIR, "points.shp"), os.path.join(tmpDir.path(), "points.shp")) copyfile(os.path.join(TEST_DATA_DIR, "points.dbf"), os.path.join(tmpDir.path(), "points.dbf")) copyfile(os.path.join(TEST_DATA_DIR, "points.shx"), os.path.join(tmpDir.path(), "points.shx")) copyfile(os.path.join(TEST_DATA_DIR, "lines.shp"), os.path.join(tmpDir.path(), "lines.shp")) copyfile(os.path.join(TEST_DATA_DIR, "lines.dbf"), os.path.join(tmpDir.path(), "lines.dbf")) copyfile(os.path.join(TEST_DATA_DIR, "lines.shx"), os.path.join(tmpDir.path(), "lines.shx")) copyfile(os.path.join(TEST_DATA_DIR, "landsat_4326.tif"), os.path.join(tmpDir.path(), "landsat_4326.tif")) project = QgsProject() l0 = QgsVectorLayer(os.path.join(tmpDir.path(), "points.shp"), "points", "ogr") l1 = QgsVectorLayer(os.path.join(tmpDir.path(), "lines.shp"), "lines", "ogr") l2 = QgsRasterLayer(os.path.join(tmpDir.path(), "landsat_4326.tif"), "landsat", "gdal") self.assertTrue(l0.isValid()) self.assertTrue(l1.isValid()) self.assertTrue(l2.isValid()) self.assertTrue(project.addMapLayers([l0, l1, l2])) self.assertTrue(project.write(tmpFile)) del project with open(tmpFile, 'r') as f: content = ''.join(f.readlines()) self.assertTrue('source="./lines.shp"' in content) self.assertTrue('source="./points.shp"' in content) self.assertTrue('source="./landsat_4326.tif"' in content) # Re-read the project and store absolute project = QgsProject() self.assertTrue(project.read(tmpFile)) store = project.layerStore() self.assertEquals(set([l.name() for l in store.mapLayers().values()]), set(['lines', 'landsat', 'points'])) project.writeEntryBool('Paths', '/Absolute', True) tmpFile2 = "{}/project2.qgs".format(tmpDir.path()) self.assertTrue(project.write(tmpFile2)) with open(tmpFile2, 'r') as f: content = ''.join(f.readlines()) self.assertTrue( 'source="{}/lines.shp"'.format(tmpDir.path()) in content) self.assertTrue( 'source="{}/points.shp"'.format(tmpDir.path()) in content) self.assertTrue('source="{}/landsat_4326.tif"'.format( tmpDir.path()) in content) del project
def testPkLessQuery(self): """Test if features in queries with/without pk can be retrieved by id""" # create test db dbname = os.path.join(tempfile.gettempdir(), "test_pkless.sqlite") if os.path.exists(dbname): os.remove(dbname) con = spatialite_connect(dbname, isolation_level=None) cur = con.cursor() cur.execute("BEGIN") sql = "SELECT InitSpatialMetadata()" cur.execute(sql) # simple table with primary key sql = "CREATE TABLE \"test pk\" (id INTEGER NOT NULL PRIMARY KEY, name TEXT NOT NULL)" cur.execute(sql) sql = "SELECT AddGeometryColumn('test pk', 'geometry', 4326, 'POINT', 'XY')" cur.execute(sql) for i in range(11, 21): sql = "INSERT INTO \"test pk\" (id, name, geometry) " sql += "VALUES ({id}, 'name {id}', GeomFromText('POINT({id} {id})', 4326))".format(id=i) cur.execute(sql) def _make_table(table_name): # simple table without primary key sql = "CREATE TABLE \"%s\" (name TEXT NOT NULL)" % table_name cur.execute(sql) sql = "SELECT AddGeometryColumn('%s', 'geom', 4326, 'POINT', 'XY')" % table_name cur.execute(sql) for i in range(11, 21): sql = "INSERT INTO \"%s\" (name, geom) " % table_name sql += "VALUES ('name {id}', GeomFromText('POINT({id} {id})', 4326))".format(id=i) cur.execute(sql) _make_table("somedata") _make_table("some data") sql = "CREATE VIEW \"some view\" AS SELECT * FROM \"somedata\"" cur.execute(sql) cur.execute("COMMIT") con.close() def _check_features(vl, offset): self.assertEqual(vl.featureCount(), 10) i = 11 for f in vl.getFeatures(): self.assertTrue(f.isValid()) self.assertTrue(vl.getFeature(i - offset).isValid()) self.assertEqual(vl.getFeature(i - offset)['name'], 'name {id}'.format(id=i)) self.assertEqual(f.id(), i - offset) self.assertEqual(f['name'], 'name {id}'.format(id=i)) self.assertEqual(f.geometry().asWkt(), 'Point ({id} {id})'.format(id=i)) i += 1 vl_pk = QgsVectorLayer('dbname=\'%s\' table="(select * from \\"test pk\\")" (geometry) sql=' % dbname, 'pk', 'spatialite') self.assertTrue(vl_pk.isValid()) _check_features(vl_pk, 0) vl_no_pk = QgsVectorLayer('dbname=\'%s\' table="(select * from somedata)" (geom) sql=' % dbname, 'pk', 'spatialite') self.assertTrue(vl_no_pk.isValid()) _check_features(vl_no_pk, 10) vl_no_pk = QgsVectorLayer('dbname=\'%s\' table="(select * from \\"some data\\")" (geom) sql=' % dbname, 'pk', 'spatialite') self.assertTrue(vl_no_pk.isValid()) _check_features(vl_no_pk, 10) # Test regression when sending queries with aliased tables from DB manager self._aliased_sql_helper(dbname)
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())
class TestQgsLayoutMap(unittest.TestCase, LayoutItemTestCase): @classmethod def setUpClass(cls): cls.item_class = QgsLayoutItemMap def setUp(self): self.report = "<h1>Python QgsLayoutItemMap Tests</h1>\n" def tearDown(self): report_file_path = "%s/qgistest.html" % QDir.tempPath() with open(report_file_path, 'a') as report_file: report_file.write(self.report) def __init__(self, methodName): """Run once on class initialization.""" unittest.TestCase.__init__(self, methodName) myPath = os.path.join(TEST_DATA_DIR, 'rgb256x256.png') rasterFileInfo = QFileInfo(myPath) self.raster_layer = QgsRasterLayer(rasterFileInfo.filePath(), rasterFileInfo.completeBaseName()) rasterRenderer = QgsMultiBandColorRenderer( self.raster_layer.dataProvider(), 1, 2, 3) self.raster_layer.setRenderer(rasterRenderer) myPath = os.path.join(TEST_DATA_DIR, 'points.shp') vector_file_info = QFileInfo(myPath) self.vector_layer = QgsVectorLayer(vector_file_info.filePath(), vector_file_info.completeBaseName(), 'ogr') assert self.vector_layer.isValid() # pipe = mRasterLayer.pipe() # assert pipe.set(rasterRenderer), 'Cannot set pipe renderer' QgsProject.instance().addMapLayers( [self.raster_layer, self.vector_layer]) # create layout with layout map self.layout = QgsLayout(QgsProject.instance()) self.layout.initializeDefaults() self.map = QgsLayoutItemMap(self.layout) self.map.attemptSetSceneRect(QRectF(20, 20, 200, 100)) self.map.setFrameEnabled(True) self.map.setLayers([self.raster_layer]) self.layout.addLayoutItem(self.map) def testOverviewMap(self): overviewMap = QgsLayoutItemMap(self.layout) overviewMap.attemptSetSceneRect(QRectF(20, 130, 70, 70)) overviewMap.setFrameEnabled(True) overviewMap.setLayers([self.raster_layer]) self.layout.addLayoutItem(overviewMap) # zoom in myRectangle = QgsRectangle(96, -152, 160, -120) self.map.setExtent(myRectangle) myRectangle2 = QgsRectangle(0, -256, 256, 0) overviewMap.setExtent(myRectangle2) overviewMap.overview().setLinkedMap(self.map) checker = QgsLayoutChecker('composermap_overview', self.layout) checker.setColorTolerance(6) checker.setControlPathPrefix("composer_mapoverview") myTestResult, myMessage = checker.testLayout() self.report += checker.report() self.layout.removeLayoutItem(overviewMap) assert myTestResult, myMessage def testOverviewMapBlend(self): overviewMap = QgsLayoutItemMap(self.layout) overviewMap.attemptSetSceneRect(QRectF(20, 130, 70, 70)) overviewMap.setFrameEnabled(True) overviewMap.setLayers([self.raster_layer]) self.layout.addLayoutItem(overviewMap) # zoom in myRectangle = QgsRectangle(96, -152, 160, -120) self.map.setExtent(myRectangle) myRectangle2 = QgsRectangle(0, -256, 256, 0) overviewMap.setExtent(myRectangle2) overviewMap.overview().setLinkedMap(self.map) overviewMap.overview().setBlendMode(QPainter.CompositionMode_Multiply) checker = QgsLayoutChecker('composermap_overview_blending', self.layout) checker.setControlPathPrefix("composer_mapoverview") myTestResult, myMessage = checker.testLayout() self.report += checker.report() self.layout.removeLayoutItem(overviewMap) assert myTestResult, myMessage def testOverviewMapInvert(self): overviewMap = QgsLayoutItemMap(self.layout) overviewMap.attemptSetSceneRect(QRectF(20, 130, 70, 70)) overviewMap.setFrameEnabled(True) overviewMap.setLayers([self.raster_layer]) self.layout.addLayoutItem(overviewMap) # zoom in myRectangle = QgsRectangle(96, -152, 160, -120) self.map.setExtent(myRectangle) myRectangle2 = QgsRectangle(0, -256, 256, 0) overviewMap.setExtent(myRectangle2) overviewMap.overview().setLinkedMap(self.map) overviewMap.overview().setInverted(True) checker = QgsLayoutChecker('composermap_overview_invert', self.layout) checker.setControlPathPrefix("composer_mapoverview") myTestResult, myMessage = checker.testLayout() self.report += checker.report() self.layout.removeLayoutItem(overviewMap) assert myTestResult, myMessage def testOverviewMapCenter(self): overviewMap = QgsLayoutItemMap(self.layout) overviewMap.attemptSetSceneRect(QRectF(20, 130, 70, 70)) overviewMap.setFrameEnabled(True) overviewMap.setLayers([self.raster_layer]) self.layout.addLayoutItem(overviewMap) # zoom in myRectangle = QgsRectangle(192, -288, 320, -224) self.map.setExtent(myRectangle) myRectangle2 = QgsRectangle(0, -256, 256, 0) overviewMap.setExtent(myRectangle2) overviewMap.overview().setLinkedMap(self.map) overviewMap.overview().setInverted(False) overviewMap.overview().setCentered(True) checker = QgsLayoutChecker('composermap_overview_center', self.layout) checker.setControlPathPrefix("composer_mapoverview") myTestResult, myMessage = checker.testLayout() self.report += checker.report() self.layout.removeLayoutItem(overviewMap) assert myTestResult, myMessage def testMapCrs(self): # create layout with layout map map_settings = QgsMapSettings() map_settings.setLayers([self.vector_layer]) layout = QgsLayout(QgsProject.instance()) layout.initializeDefaults() # check that new maps inherit project CRS QgsProject.instance().setCrs(QgsCoordinateReferenceSystem('EPSG:4326')) map = QgsLayoutItemMap(layout) map.attemptSetSceneRect(QRectF(20, 20, 200, 100)) map.setFrameEnabled(True) rectangle = QgsRectangle(-13838977, 2369660, -8672298, 6250909) map.setExtent(rectangle) map.setLayers([self.vector_layer]) layout.addLayoutItem(map) self.assertEqual(map.crs().authid(), 'EPSG:4326') self.assertFalse(map.presetCrs().isValid()) # overwrite CRS map.setCrs(QgsCoordinateReferenceSystem('EPSG:3857')) self.assertEqual(map.crs().authid(), 'EPSG:3857') self.assertEqual(map.presetCrs().authid(), 'EPSG:3857') checker = QgsLayoutChecker('composermap_crs3857', layout) checker.setControlPathPrefix("composer_map") result, message = checker.testLayout() self.report += checker.report() self.assertTrue(result, message) # overwrite CRS map.setCrs(QgsCoordinateReferenceSystem('EPSG:4326')) self.assertEqual(map.presetCrs().authid(), 'EPSG:4326') self.assertEqual(map.crs().authid(), 'EPSG:4326') rectangle = QgsRectangle(-124, 17, -78, 52) map.zoomToExtent(rectangle) checker = QgsLayoutChecker('composermap_crs4326', layout) checker.setControlPathPrefix("composer_map") result, message = checker.testLayout() self.report += checker.report() self.assertTrue(result, message) # change back to project CRS map.setCrs(QgsCoordinateReferenceSystem()) self.assertEqual(map.crs().authid(), 'EPSG:4326') self.assertFalse(map.presetCrs().isValid()) def testContainsAdvancedEffects(self): map_settings = QgsMapSettings() map_settings.setLayers([self.vector_layer]) layout = QgsLayout(QgsProject.instance()) map = QgsLayoutItemMap(layout) self.assertFalse(map.containsAdvancedEffects()) self.vector_layer.setBlendMode(QPainter.CompositionMode_Darken) result = map.containsAdvancedEffects() self.vector_layer.setBlendMode(QPainter.CompositionMode_SourceOver) self.assertTrue(result) def testRasterization(self): map_settings = QgsMapSettings() map_settings.setLayers([self.vector_layer]) layout = QgsLayout(QgsProject.instance()) map = QgsLayoutItemMap(layout) self.assertFalse(map.requiresRasterization()) self.vector_layer.setBlendMode(QPainter.CompositionMode_Darken) self.assertFalse(map.requiresRasterization()) self.assertTrue(map.containsAdvancedEffects()) map.setBackgroundEnabled(False) self.assertTrue(map.requiresRasterization()) map.setBackgroundEnabled(True) map.setBackgroundColor(QColor(1, 1, 1, 1)) self.assertTrue(map.requiresRasterization()) self.vector_layer.setBlendMode(QPainter.CompositionMode_SourceOver)
def testStyle(self): # First test with invalid URI vl = QgsVectorLayer('/idont/exist.gpkg', 'test', 'ogr') self.assertFalse( vl.dataProvider().isSaveAndLoadStyleToDatabaseSupported()) related_count, idlist, namelist, desclist, errmsg = vl.listStylesInDatabase( ) self.assertEqual(related_count, -1) self.assertEqual(idlist, []) self.assertEqual(namelist, []) self.assertEqual(desclist, []) self.assertNotEqual(errmsg, "") qml, errmsg = vl.getStyleFromDatabase("1") self.assertEqual(qml, "") self.assertNotEqual(errmsg, "") qml, success = vl.loadNamedStyle('/idont/exist.gpkg') self.assertFalse(success) errorMsg = vl.saveStyleToDatabase("name", "description", False, "") self.assertNotEqual(errorMsg, "") # Now with valid URI tmpfile = os.path.join(self.basetestpath, 'testStyle.gpkg') ds = ogr.GetDriverByName('GPKG').CreateDataSource(tmpfile) lyr = ds.CreateLayer('test', geom_type=ogr.wkbMultiPolygon) lyr.CreateField(ogr.FieldDefn('foo', ogr.OFTString)) f = ogr.Feature(lyr.GetLayerDefn()) f['foo'] = 'bar' lyr.CreateFeature(f) f = None lyr = ds.CreateLayer('test2', geom_type=ogr.wkbMultiPolygon) lyr.CreateField(ogr.FieldDefn('foo', ogr.OFTString)) f = ogr.Feature(lyr.GetLayerDefn()) f['foo'] = 'bar' lyr.CreateFeature(f) f = None ds = None vl = QgsVectorLayer('{}|layername=test'.format(tmpfile), 'test', 'ogr') self.assertTrue(vl.isValid()) vl2 = QgsVectorLayer('{}|layername=test2'.format(tmpfile), 'test2', 'ogr') self.assertTrue(vl2.isValid()) self.assertTrue( vl.dataProvider().isSaveAndLoadStyleToDatabaseSupported()) related_count, idlist, namelist, desclist, errmsg = vl.listStylesInDatabase( ) self.assertEqual(related_count, 0) self.assertEqual(idlist, []) self.assertEqual(namelist, []) self.assertEqual(desclist, []) self.assertNotEqual(errmsg, "") qml, errmsg = vl.getStyleFromDatabase("not_existing") self.assertEqual(qml, "") self.assertNotEqual(errmsg, "") qml, success = vl.loadNamedStyle('{}|layerid=0'.format(tmpfile)) self.assertFalse(success) errorMsg = vl.saveStyleToDatabase("name", "description", False, "") self.assertEqual(errorMsg, "") qml, errmsg = vl.getStyleFromDatabase("not_existing") self.assertEqual(qml, "") self.assertNotEqual(errmsg, "") related_count, idlist, namelist, desclist, errmsg = vl.listStylesInDatabase( ) self.assertEqual(related_count, 1) self.assertEqual(errmsg, "") self.assertEqual(idlist, ['1']) self.assertEqual(namelist, ['name']) self.assertEqual(desclist, ['description']) qml, errmsg = vl.getStyleFromDatabase("100") self.assertEqual(qml, "") self.assertNotEqual(errmsg, "") qml, errmsg = vl.getStyleFromDatabase("1") self.assertTrue(qml.startswith('<!DOCTYPE qgis'), qml) self.assertEqual(errmsg, "") # Try overwrite it but simulate answer no settings = QgsSettings() settings.setValue("/qgis/overwriteStyle", False) errorMsg = vl.saveStyleToDatabase("name", "description_bis", False, "") self.assertNotEqual(errorMsg, "") related_count, idlist, namelist, desclist, errmsg = vl.listStylesInDatabase( ) self.assertEqual(related_count, 1) self.assertEqual(errmsg, "") self.assertEqual(idlist, ['1']) self.assertEqual(namelist, ['name']) self.assertEqual(desclist, ['description']) # Try overwrite it and simulate answer yes settings = QgsSettings() settings.setValue("/qgis/overwriteStyle", True) errorMsg = vl.saveStyleToDatabase("name", "description_bis", False, "") self.assertEqual(errorMsg, "") related_count, idlist, namelist, desclist, errmsg = vl.listStylesInDatabase( ) self.assertEqual(related_count, 1) self.assertEqual(errmsg, "") self.assertEqual(idlist, ['1']) self.assertEqual(namelist, ['name']) self.assertEqual(desclist, ['description_bis']) errorMsg = vl2.saveStyleToDatabase("name_test2", "description_test2", True, "") self.assertEqual(errorMsg, "") errorMsg = vl.saveStyleToDatabase("name2", "description2", True, "") self.assertEqual(errorMsg, "") errorMsg = vl.saveStyleToDatabase("name3", "description3", True, "") self.assertEqual(errorMsg, "") related_count, idlist, namelist, desclist, errmsg = vl.listStylesInDatabase( ) self.assertEqual(related_count, 3) self.assertEqual(errmsg, "") self.assertEqual(idlist, ['1', '3', '4', '2']) self.assertEqual(namelist, ['name', 'name2', 'name3', 'name_test2']) self.assertEqual( desclist, ['description_bis', 'description2', 'description3', 'name_test2']) # Check that layers_style table is not list in subLayers() vl = QgsVectorLayer(tmpfile, 'test', 'ogr') sublayers = vl.dataProvider().subLayers() self.assertEqual(len(sublayers), 2, sublayers)
def testRequestRepaintMultiple(self): """ test requesting repaint with multiple dependent layers """ layer1 = QgsVectorLayer("Point?field=fldtxt:string", "layer1", "memory") layer2 = QgsVectorLayer("Point?field=fldtxt:string", "layer2", "memory") QgsProject.instance().addMapLayers([layer1, layer2]) self.assertTrue(layer1.isValid()) self.assertTrue(layer2.isValid()) # add image to cache - no dependent layers cache = QgsMapRendererCache() im1 = QImage(200, 200, QImage.Format_RGB32) cache.setCacheImage('nolayer', im1) self.assertFalse(cache.cacheImage('nolayer').isNull()) self.assertTrue(cache.hasCacheImage('nolayer')) # trigger repaint on layer layer1.triggerRepaint() layer1.triggerRepaint( ) # do this a couple of times - we don't want errors due to multiple disconnects, etc layer2.triggerRepaint() layer2.triggerRepaint() # cache image should still exist - it's not dependent on layers self.assertFalse(cache.cacheImage('nolayer').isNull()) self.assertTrue(cache.hasCacheImage('nolayer')) # image depends on 1 layer im_l1 = QImage(200, 200, QImage.Format_RGB32) cache.setCacheImage('im1', im_l1, [layer1]) # image depends on 2 layers im_l1_l2 = QImage(200, 200, QImage.Format_RGB32) cache.setCacheImage('im1_im2', im_l1_l2, [layer1, layer2]) # image depends on 2nd layer alone im_l2 = QImage(200, 200, QImage.Format_RGB32) cache.setCacheImage('im2', im_l2, [layer2]) self.assertFalse(cache.cacheImage('im1').isNull()) self.assertTrue(cache.hasCacheImage('im1')) self.assertFalse(cache.cacheImage('im1_im2').isNull()) self.assertTrue(cache.hasCacheImage('im1_im2')) self.assertFalse(cache.cacheImage('im2').isNull()) self.assertTrue(cache.hasCacheImage('im2')) # trigger repaint layer 1 (check twice - don't want disconnect errors) for i in range(2): layer1.triggerRepaint() # should be cleared self.assertTrue(cache.cacheImage('im1').isNull()) self.assertFalse(cache.hasCacheImage('im1')) self.assertTrue(cache.cacheImage('im1_im2').isNull()) self.assertFalse(cache.hasCacheImage('im1_im2')) # should be retained self.assertTrue(cache.hasCacheImage('im2')) self.assertFalse(cache.cacheImage('im2').isNull()) self.assertEqual(cache.cacheImage('im2'), im_l2) self.assertTrue(cache.hasCacheImage('nolayer')) self.assertFalse(cache.cacheImage('nolayer').isNull()) self.assertEqual(cache.cacheImage('nolayer'), im1) # trigger repaint layer 2 for i in range(2): layer2.triggerRepaint() # should be cleared self.assertFalse(cache.hasCacheImage('im1')) self.assertTrue(cache.cacheImage('im1').isNull()) self.assertFalse(cache.hasCacheImage('im1_im2')) self.assertTrue(cache.cacheImage('im1_im2').isNull()) self.assertFalse(cache.hasCacheImage('im2')) self.assertTrue(cache.cacheImage('im2').isNull()) # should be retained self.assertTrue(cache.hasCacheImage('nolayer')) self.assertFalse(cache.cacheImage('nolayer').isNull()) self.assertEqual(cache.cacheImage('nolayer'), im1)
def test_valid_import_geom_2d_to_db_gpkg(self): print( '\nINFO: Validating ETL-Model from [ Point, PointZ, PointM, PointZM ] to Point geometries...' ) # Layer in LADM for test test_layer = self.qgis_utils.get_layer(self.db_connection, BOUNDARY_POINT_TABLE, load=True) # Point To Point print("Validating Point to Point") uri = self.gpkg_path + '|layername={layername}'.format( layername='points') point_layer = QgsVectorLayer(uri, 'points', 'ogr') print("Is Valid layer :", point_layer.isValid()) run_etl_model(point_layer, out_layer=test_layer) test_layer.startEditing() print("Info: Validating geometry Point...") self.assertEqual(QgsWkbTypes.PointGeometry, test_layer.type()) self.assertEqual(QgsWkbTypes.Point, point_layer.wkbType()) self.assertEqual(QgsWkbTypes.Point, test_layer.wkbType()) self.assertEqual(test_layer.featureCount(), 51) clean_table('test_ladm_col', BOUNDARY_POINT_TABLE) test_layer.dataProvider().truncate() # PointZ To Point print("Validating PointZ to Point") uri = self.gpkg_path + '|layername={layername}'.format( layername='points_Z') point_layer = QgsVectorLayer(uri, 'points_Z', 'ogr') print("Is Valid layer :", point_layer.isValid()) self.assertIn(point_layer.wkbType(), [QgsWkbTypes.PointZ, QgsWkbTypes.Point25D]) output = run_etl_model(point_layer, out_layer=test_layer) print("Info: Validating geometry PointZ...", test_layer.wkbType()) self.assertEqual(QgsWkbTypes.PointGeometry, test_layer.type()) self.assertEqual(QgsWkbTypes.Point, test_layer.wkbType()) self.assertEqual(test_layer.featureCount(), 51) clean_table('test_ladm_col', BOUNDARY_POINT_TABLE) test_layer.dataProvider().truncate() # PointM To Point print("Validating PointM To Point") uri = self.gpkg_path + '|layername={layername}'.format( layername='points_M') point_layer = QgsVectorLayer(uri, 'points', 'ogr') print("Is Valid layer :", point_layer.isValid()) run_etl_model(point_layer, out_layer=test_layer) print("Info: Validating geometry PointZ...", test_layer.wkbType()) self.assertEqual(QgsWkbTypes.PointGeometry, test_layer.type()) self.assertEqual(QgsWkbTypes.PointM, point_layer.wkbType()) self.assertEqual(QgsWkbTypes.Point, test_layer.wkbType()) self.assertEqual(test_layer.featureCount(), 51) clean_table('test_ladm_col', BOUNDARY_POINT_TABLE) test_layer.dataProvider().truncate() # PointZM To Point print("Validating PointZM To Point") uri = self.gpkg_path + '|layername={layername}'.format( layername='points_ZM') point_layer = QgsVectorLayer(uri, 'points', 'ogr') print("Is Valid layer :", point_layer.isValid()) run_etl_model(point_layer, out_layer=test_layer) print("Info: Validating geometry PointZ...", test_layer.wkbType()) self.assertEqual(QgsWkbTypes.PointGeometry, test_layer.type()) self.assertEqual(QgsWkbTypes.PointZM, point_layer.wkbType()) self.assertEqual(QgsWkbTypes.Point, test_layer.wkbType()) self.assertEqual(test_layer.featureCount(), 51) clean_table('test_ladm_col', BOUNDARY_POINT_TABLE) test_layer.dataProvider().truncate()