def test_zip_unzip(self): tmpDir = QTemporaryDir() tmpFile = "{}/project.qgz".format(tmpDir.path()) project = QgsProject() l0 = QgsVectorLayer(os.path.join(TEST_DATA_DIR, "points.shp"), "points", "ogr") l1 = QgsVectorLayer(os.path.join(TEST_DATA_DIR, "lines.shp"), "lines", "ogr") project.addMapLayers([l0, l1]) self.assertTrue(project.write(tmpFile)) project2 = QgsProject() self.assertFalse(project2.isZipped()) self.assertTrue(project2.fileName() == "") self.assertTrue(project2.read(tmpFile)) self.assertTrue(project2.isZipped()) self.assertTrue(project2.fileName() == tmpFile) layers = project2.mapLayers() self.assertEqual(len(layers.keys()), 2) self.assertTrue(layers[l0.id()].isValid(), True) self.assertTrue(layers[l1.id()].isValid(), True) project2.clear() self.assertFalse(project2.isZipped())
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 checkRepaintNonLabeledLayerDoesNotInvalidateLabelCache(self, job_type): layer = QgsVectorLayer("Point?field=fldtxt:string", "layer1", "memory") settings = QgsMapSettings() settings.setExtent(QgsRectangle(5, 25, 25, 45)) settings.setOutputSize(QSize(600, 400)) settings.setLayers([layer]) # with cache - first run should populate cache cache = QgsMapRendererCache() job = job_type(settings) job.setCache(cache) job.start() job.waitForFinished() self.assertFalse(job.usedCachedLabels()) self.assertTrue(cache.hasCacheImage('_labels_')) self.assertTrue(cache.hasCacheImage(layer.id())) self.assertEqual(cache.dependentLayers('_labels_'), []) # trigger repaint on layer - should not invalidate label cache because layer is not labeled layer.triggerRepaint() self.assertTrue(cache.hasCacheImage('_labels_')) self.assertFalse(cache.hasCacheImage(layer.id())) self.assertTrue(job.takeLabelingResults()) # second job should still use label cache job = job_type(settings) job.setCache(cache) job.start() job.waitForFinished() self.assertTrue(job.usedCachedLabels()) self.assertTrue(cache.hasCacheImage('_labels_')) self.assertTrue(job.takeLabelingResults())
def applySymbology(self): self.getConnection() vlayer = qgis.utils.iface.mapCanvas().currentLayer() if vlayer == None: return fields = vlayer.dataProvider().fields() classField = None for f in fields: if f.name() == "classtype": classField = 'classtype' elif f.name() == "result": classField = 'result' print classField class_loaded = False for layer in QgsMapLayerRegistry.instance().mapLayers().values(): if layer.name() == "class": vlayerClass = layer class_loaded = True if not class_loaded: uriSubClass = QgsDataSourceURI() uriSubClass.setConnection(self.serverName, "5432", self.database, self.usr , self.pw) uriSubClass.setDataSource("classification", "class", None, "", "id") vlayerClass = QgsVectorLayer(uriSubClass.uri(), "class", "postgres") QgsMapLayerRegistry.instance().addMapLayer(vlayerClass) for field in fields: index = vlayer.fieldNameIndex(field.name()) if field.name() == classField: vlayer.editFormConfig().setWidgetType(index, 'ValueRelation') vlayer.editFormConfig().setWidgetConfig(index, {'Layer': vlayerClass.id(), 'Key': 'id', 'Value': 'classname'}) useJoin = True if useJoin: joinObject = QgsVectorJoinInfo() joinObject.joinLayerId = vlayerClass.id() joinObject.joinFieldName = 'id' joinObject.targetFieldName = classField joinObject.memoryCache = True vlayer.addJoin(joinObject) self.join.append(joinObject) categories = [] iter = vlayerClass.getFeatures() for feature in iter: classname = feature['classname'] color = QColor(feature['red'], feature['green'], feature['blue']) sym = QgsSymbolV2.defaultSymbol(vlayer.geometryType()) sym.setColor(QColor(color)) category = QgsRendererCategoryV2(classname, sym, classname) categories.append(category) field = "class_classname" renderer = QgsCategorizedSymbolRendererV2(field, categories) vlayer.setRendererV2(renderer) qgis.utils.iface.messageBar().pushMessage("Information", "Editor widget set", level = qgis.gui.QgsMessageBar.INFO, duration = 5) qgis.utils.iface.setActiveLayer(vlayer)
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 preview(request, layer_slug): """Home page for layers. :param request: The web request. :param layer_slug: The layer """ layer = get_object_or_404(Layer, slug=layer_slug) layer_path = os.path.join( settings.MEDIA_ROOT, 'layers', layer.slug, 'raw') map_layer = QgsVectorLayer(layer_path, layer.name, 'ogr') QgsMapLayerRegistry.instance().addMapLayer(map_layer) layer_uri = tempfile.NamedTemporaryFile( suffix='.png', prefix='inasafe-web-', dir='/tmp/').name # create image image = QImage(QSize(100, 100), QImage.Format_ARGB32_Premultiplied) # set image's background color color = QColor(255, 255, 255) image.fill(color.rgb()) # create painter p = QPainter() p.begin(image) p.setRenderHint(QPainter.Antialiasing) renderer = QgsMapRenderer() # set layer set layers = [map_layer.id()] # add ID of every layer renderer.setLayerSet(layers) # set extent rect = QgsRectangle(renderer.fullExtent()) rect.scale(1.1) renderer.setExtent(rect) # set output size renderer.setOutputSize(image.size(), image.logicalDpiX()) # do the rendering renderer.render(p) p.end() # clean up registry_list = qgis_layers() QgsMapLayerRegistry.instance().removeMapLayer(map_layer.id()) print registry_list # save image image.save(layer_uri, 'png') with open(layer_uri, 'rb') as f: response = HttpResponse(f.read(), content_type='png') os.remove(layer_uri) return response
def legend_test(self): self.mAtlasMap.setAtlasDriven(True) self.mAtlasMap.setAtlasScalingMode(QgsComposerMap.Auto) self.mAtlasMap.setAtlasMargin(0.10) # add a point layer ptLayer = QgsVectorLayer("Point?crs=epsg:4326&field=attr:int(1)&field=label:string(20)", "points", "memory") pr = ptLayer.dataProvider() f1 = QgsFeature(1) f1.initAttributes(2) f1.setAttribute(0, 1) f1.setAttribute(1, "Test label 1") f1.setGeometry(QgsGeometry.fromPoint(QgsPoint(-0.638, 48.954))) f2 = QgsFeature(2) f2.initAttributes(2) f2.setAttribute(0, 2) f2.setAttribute(1, "Test label 2") f2.setGeometry(QgsGeometry.fromPoint(QgsPoint(-1.682, 48.550))) pr.addFeatures([f1, f2]) # categorized symbology r = QgsCategorizedSymbolRendererV2("attr", [QgsRendererCategoryV2(1, QgsMarkerSymbolV2.createSimple({"color": "255,0,0"}), "red"), QgsRendererCategoryV2(2, QgsMarkerSymbolV2.createSimple({"color": "0,0,255"}), "blue")]) ptLayer.setRendererV2(r) QgsMapLayerRegistry.instance().addMapLayer(ptLayer) # add the point layer to the map settings layers = self.mapSettings.layers() layers = [ptLayer.id()] + layers self.mapSettings.setLayers(layers) # add a legend legend = QgsComposerLegend(self.mComposition) legend.moveBy(200, 100) # sets the legend filter parameter legend.setComposerMap(self.mAtlasMap) legend.setLegendFilterOutAtlas(True) self.mComposition.addComposerLegend(legend) self.mAtlas.beginRender() self.mAtlas.prepareForFeature(0) self.mLabel1.adjustSizeToText() checker = QgsCompositionChecker('atlas_legend', self.mComposition) myTestResult, myMessage = checker.testComposition() assert myTestResult self.mAtlas.endRender() # restore state self.mapSettings.setLayers([layers[1]]) self.mComposition.removeComposerItem(legend) QgsMapLayerRegistry.instance().removeMapLayer(ptLayer.id())
class TestQgsArrowSymbolLayer(unittest.TestCase): def setUp(self): self.iface = get_iface() lines_shp = os.path.join(TEST_DATA_DIR, 'lines.shp') self.lines_layer = QgsVectorLayer(lines_shp, 'Lines', 'ogr') QgsMapLayerRegistry.instance().addMapLayer(self.lines_layer) # Create style sym2 = QgsLineSymbolV2.createSimple({'color': '#fdbf6f'}) self.lines_layer.setRendererV2(QgsSingleSymbolRendererV2(sym2)) self.mapsettings = self.iface.mapCanvas().mapSettings() self.mapsettings.setOutputSize(QSize(400, 400)) self.mapsettings.setOutputDpi(96) self.mapsettings.setExtent(QgsRectangle(-113, 28, -91, 40)) self.mapsettings.setBackgroundColor(QColor("white")) def tearDown(self): QgsMapLayerRegistry.instance().removeAllMapLayers() def test_1(self): sym = self.lines_layer.rendererV2().symbol() sym_layer = QgsArrowSymbolLayer.create({'head_size': '6.5'}) dd = QgsDataDefined("(@geometry_point_num % 4) * 2") sym_layer.setDataDefinedProperty("arrow_width", dd) dd2 = QgsDataDefined("(@geometry_point_num % 4) * 2") sym_layer.setDataDefinedProperty("head_size", dd2) fill_sym = QgsFillSymbolV2.createSimple({'color': '#8bcfff', 'outline_color': '#000000', 'outline_style': 'solid', 'outline_width': '1'}) sym_layer.setSubSymbol(fill_sym) sym.changeSymbolLayer(0, sym_layer) rendered_layers = [self.lines_layer.id()] self.mapsettings.setLayers(rendered_layers) renderchecker = QgsMultiRenderChecker() renderchecker.setMapSettings(self.mapsettings) renderchecker.setControlName('expected_arrowsymbollayer_1') self.assertTrue(renderchecker.runTest('arrowsymbollayer_1')) def test_2(self): sym = self.lines_layer.rendererV2().symbol() # double headed sym_layer = QgsArrowSymbolLayer.create({'arrow_width': '5', 'head_size': '6.5', 'head_type': '2'}) fill_sym = QgsFillSymbolV2.createSimple({'color': '#8bcfff', 'outline_color': '#000000', 'outline_style': 'solid', 'outline_width': '1'}) sym_layer.setSubSymbol(fill_sym) sym.changeSymbolLayer(0, sym_layer) rendered_layers = [self.lines_layer.id()] self.mapsettings.setLayers(rendered_layers) renderchecker = QgsMultiRenderChecker() renderchecker.setMapSettings(self.mapsettings) renderchecker.setControlName('expected_arrowsymbollayer_2') self.assertTrue(renderchecker.runTest('arrowsymbollayer_2'))
def test_QueryUrlEncoding(self): l1 = QgsVectorLayer(os.path.join(self.testDataDir, "france_parts.shp"), "france_parts", "ogr", False) self.assertEqual(l1.isValid(), True) QgsProject.instance().addMapLayer(l1) query = toPercent("SELECT * FROM vtab1") l2 = QgsVectorLayer("?layer_ref=%s&query=%s&uid=ObjectId&nogeometry" % (l1.id(), query), "vtab", "virtual", False) self.assertEqual(l2.isValid(), True) QgsProject.instance().removeMapLayer(l1.id())
def test_CsvNoGeometry(self): l1 = QgsVectorLayer( os.path.join(self.testDataDir_, "test.csv") + "?type=csv&geomType=none&subsetIndex=no&watchFile=no", "test", "delimitedtext", False) self.assertEqual( l1.isValid(), True ) QgsMapLayerRegistry.instance().addMapLayer(l1) l2 = QgsVectorLayer( "?layer_ref=" + l1.id(), "vtab", "virtual", False ) self.assertEqual(l2.isValid(), True) print sum([f.id() for f in l2.getFeatures()]) QgsMapLayerRegistry.instance().removeMapLayer(l1.id())
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_QueryTableName(self): l1 = QgsVectorLayer(os.path.join(self.testDataDir, "france_parts.shp"), "france_parts", "ogr", False) self.assertEqual(l1.isValid(), True) QgsProject.instance().addMapLayer(l1) query = toPercent("SELECT * FROM vt") l2 = QgsVectorLayer("?layer_ref=%s:vt&query=%s&uid=ObJeCtId&nogeometry" % (l1.id(), query), "vtab", "virtual", False) self.assertEqual(l2.isValid(), True) self.assertEqual(l2.dataProvider().wkbType(), 100) # NoGeometry QgsProject.instance().removeMapLayer(l1.id())
def test_QueryUrlEncoding( self ): l1 = QgsVectorLayer( os.path.join(self.testDataDir_, "france_parts.shp"), "france_parts", "ogr", False ) self.assertEqual( l1.isValid(), True ) QgsMapLayerRegistry.instance().addMapLayer(l1) query = str(QUrl.toPercentEncoding("SELECT * FROM vtab1")) l2 = QgsVectorLayer("?layer_ref=%s&query=%s&uid=ObjectId&nogeometry" % (l1.id(), query), "vtab", "virtual", False) self.assertEqual( l2.isValid(), True ) print sum([f.id() for f in l2.getFeatures()]) QgsMapLayerRegistry.instance().removeMapLayer(l1.id())
def test_DynamicGeometry(self): l1 = QgsVectorLayer( os.path.join(self.testDataDir_, "testextpt.txt") + "?type=csv&delimiter=%7C&geomType=none&subsetIndex=no&watchFile=no", "test", "delimitedtext", False) self.assertEqual( l1.isValid(), True ) QgsMapLayerRegistry.instance().addMapLayer(l1) query = QUrl.toPercentEncoding("select *,makepoint(x,y) as geom from vtab1") l2 = QgsVectorLayer( "?layer_ref=%s&query=%s&geometry=geom&uid=id" % (l1.id(),query), "vtab", "virtual", False ) self.assertEqual( l2.isValid(), True ) print sum([f.id() for f in l2.getFeatures()]) QgsMapLayerRegistry.instance().removeMapLayer(l1.id())
def test_recursiveLayer( 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) QgsMapLayerRegistry.instance().addMapLayer(l) l2 = QgsVectorLayer("?layer_ref=" + l.id(), "vtab2", "virtual", False) self.assertEqual( l2.isValid(), True ) print sum([f.id() for f in l2.getFeatures()]) QgsMapLayerRegistry.instance().removeMapLayer(l.id())
def test_refLayer(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) # now delete the layer QgsProject.instance().removeMapLayer(l1.id()) # check that it does not crash print((sum([f.id() for f in l2.getFeatures()])))
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) QgsMapLayerRegistry.instance().addMapLayers([v1, v2, v3]) joinInfo = QgsVectorJoinInfo() joinInfo.targetFieldName = "b_id" joinInfo.joinLayerId = v2.id() joinInfo.joinFieldName = "id" #joinInfo.prefix = "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.prefix = "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.prefix = "" v1.removeJoin(v2.id()) v1.addJoin(joinInfo) # add another join joinInfo2 = QgsVectorJoinInfo() joinInfo2.targetFieldName = "c_id" joinInfo2.joinLayerId = v3.id() joinInfo2.joinFieldName = "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())) QgsMapLayerRegistry.instance().removeMapLayers([v1, v2, v3])
def test_ShapefileWithGeometry(self): l1 = QgsVectorLayer(os.path.join(self.testDataDir, "france_parts.shp"), "france_parts", "ogr", False) self.assertEqual(l1.isValid(), True) QgsProject.instance().addMapLayer(l1) # use a temporary file l2 = QgsVectorLayer("?layer_ref=" + l1.id(), "vtab", "virtual", False) self.assertEqual(l2.isValid(), True) l2 = QgsVectorLayer("?layer_ref=%s:nn" % l1.id(), "vtab", "virtual", False) self.assertEqual(l2.isValid(), True) QgsProject.instance().removeMapLayer(l1.id())
def test_refLayers(self): l1 = QgsVectorLayer(QUrl.fromLocalFile(os.path.join(self.testDataDir, "delimitedtext/test.csv")).toString() + "?type=csv&geomType=none&subsetIndex=no&watchFile=no", "test", "delimitedtext", False) self.assertEqual(l1.isValid(), True) QgsProject.instance().addMapLayer(l1) # cf qgis bug #12266 for i in range(10): q = toPercent("select * from t" + str(i)) l2 = QgsVectorLayer("?layer_ref=%s:t%d&query=%s&uid=id" % (l1.id(), i, q), "vtab", "virtual", False) QgsProject.instance().addMapLayer(l2) self.assertEqual(l2.isValid(), True) s = sum([f.id() for f in l2.dataProvider().getFeatures()]) # NOQA self.assertEqual(sum([f.id() for f in l2.getFeatures()]), 21) QgsProject.instance().removeMapLayer(l2.id())
def testFilterByLayer(self): """ test filtering by layer""" QgsProject.instance().clear() m = QgsMapLayerProxyModel() l1 = QgsVectorLayer("Point?crs=EPSG:3111&field=fldtxt:string&field=fldint:integer", 'layer 1', "memory") QgsProject.instance().addMapLayer(l1) l2 = QgsVectorLayer("Polygon?crs=EPSG:3111&field=fldtxt:string&field=fldint:integer", 'lAyEr 2', "memory") QgsProject.instance().addMapLayer(l2) l3 = QgsVectorLayer("None?field=fldtxt:string&field=fldint:integer", 'another', "memory") QgsProject.instance().addMapLayer(l3) l4 = QgsVectorLayer("LineString?crs=EPSG:3111&field=fldtxt:string&field=fldint:integer", 'final layer', "memory") QgsProject.instance().addMapLayer(l4) self.assertEqual(m.rowCount(), 4) self.assertEqual(m.data(m.index(0, 0)), 'another') self.assertEqual(m.data(m.index(1, 0)), 'final layer') self.assertEqual(m.data(m.index(2, 0)), 'layer 1') self.assertEqual(m.data(m.index(3, 0)), 'lAyEr 2') m.setExceptedLayerList([l1, l3]) self.assertEqual(m.rowCount(), 2) self.assertEqual(m.data(m.index(0, 0)), 'final layer') self.assertEqual(m.data(m.index(1, 0)), 'lAyEr 2') m.setExceptedLayerIds([l2.id(), l4.id()]) self.assertEqual(m.rowCount(), 2) self.assertEqual(m.data(m.index(0, 0)), 'another') self.assertEqual(m.data(m.index(1, 0)), 'layer 1') m.setLayerWhitelist([l1]) self.assertEqual(m.rowCount(), 1) self.assertEqual(m.data(m.index(0, 0)), 'layer 1') m.setExceptedLayerIds([]) self.assertEqual(m.rowCount(), 1) self.assertEqual(m.data(m.index(0, 0)), 'layer 1') m.setLayerWhitelist([l2, l3]) self.assertEqual(m.rowCount(), 2) self.assertEqual(m.data(m.index(0, 0)), 'another') self.assertEqual(m.data(m.index(1, 0)), 'lAyEr 2') m.setLayerWhitelist([]) self.assertEqual(m.rowCount(), 4)
def test_expressionRequiresFormScope(self): res = list(QgsValueRelationFieldFormatter.expressionFormAttributes("current_value('ONE') AND current_value('TWO')")) res = sorted(res) self.assertEqual(res, ['ONE', 'TWO']) res = list(QgsValueRelationFieldFormatter.expressionFormVariables("@current_geometry")) self.assertEqual(res, ['current_geometry']) self.assertFalse(QgsValueRelationFieldFormatter.expressionRequiresFormScope("")) self.assertTrue(QgsValueRelationFieldFormatter.expressionRequiresFormScope("current_value('TWO')")) self.assertTrue(QgsValueRelationFieldFormatter.expressionRequiresFormScope("current_value ( 'TWO' )")) self.assertTrue(QgsValueRelationFieldFormatter.expressionRequiresFormScope("@current_geometry")) self.assertTrue(QgsValueRelationFieldFormatter.expressionIsUsable("", QgsFeature())) self.assertFalse(QgsValueRelationFieldFormatter.expressionIsUsable("@current_geometry", QgsFeature())) self.assertFalse(QgsValueRelationFieldFormatter.expressionIsUsable("current_value ( 'TWO' )", QgsFeature())) layer = QgsVectorLayer("none?field=pkid:integer&field=decoded:string", "layer", "memory") self.assertTrue(layer.isValid()) QgsProject.instance().addMapLayer(layer) f = QgsFeature(layer.fields()) f.setAttributes([1, 'value']) point = QgsGeometry.fromPointXY(QgsPointXY(123, 456)) f.setGeometry(point) self.assertTrue(QgsValueRelationFieldFormatter.expressionIsUsable("current_geometry", f)) self.assertFalse(QgsValueRelationFieldFormatter.expressionIsUsable("current_value ( 'TWO' )", f)) self.assertTrue(QgsValueRelationFieldFormatter.expressionIsUsable("current_value ( 'pkid' )", f)) self.assertTrue(QgsValueRelationFieldFormatter.expressionIsUsable("@current_geometry current_value ( 'pkid' )", f)) QgsProject.instance().removeMapLayer(layer.id())
def setUp(self): self.iface = get_iface() myShpFile = os.path.join(TEST_DATA_DIR, 'rectangles.shp') layer = QgsVectorLayer(myShpFile, 'Points', 'ogr') QgsMapLayerRegistry.instance().addMapLayer(layer) # Create rulebased style sym1 = QgsFillSymbolV2.createSimple({'color': '#fdbf6f'}) sym2 = QgsFillSymbolV2.createSimple({'color': '#71bd6c'}) sym3 = QgsFillSymbolV2.createSimple({'color': '#1f78b4'}) self.r1 = QgsRuleBasedRendererV2.Rule(sym1, 0, 0, '"id" = 1') self.r2 = QgsRuleBasedRendererV2.Rule(sym2, 0, 0, '"id" = 2') self.r3 = QgsRuleBasedRendererV2.Rule(sym3, 0, 0, 'ELSE') self.rootrule = QgsRuleBasedRendererV2.Rule(None) self.rootrule.appendChild(self.r1) self.rootrule.appendChild(self.r2) self.rootrule.appendChild(self.r3) self.renderer = QgsRuleBasedRendererV2(self.rootrule) layer.setRendererV2(self.renderer) self.mapsettings = self.iface.mapCanvas().mapSettings() self.mapsettings.setOutputSize(QSize(400, 400)) self.mapsettings.setOutputDpi(96) self.mapsettings.setExtent(QgsRectangle(-163, 22, -70, 52)) rendered_layers = [layer.id()] self.mapsettings.setLayers(rendered_layers)
def testRenderMarkerLayerDataDefined(self): """ test that rendering a marker symbol with data defined enabled layer works""" points_shp = os.path.join(TEST_DATA_DIR, 'points.shp') points_layer = QgsVectorLayer(points_shp, 'Points', 'ogr') QgsMapLayerRegistry.instance().addMapLayer(points_layer) layer = QgsSimpleMarkerSymbolLayer() layer.setDataDefinedProperty("enabled", QgsDataDefined("Class='Biplane'")) layer.setColor(QColor(100, 150, 150)) layer.setSize(5) layer.setOutlineStyle(Qt.NoPen) symbol = QgsMarkerSymbol() symbol.changeSymbolLayer(0, layer) points_layer.setRenderer(QgsSingleSymbolRenderer(symbol)) ms = QgsMapSettings() ms.setOutputSize(QSize(400, 400)) ms.setOutputDpi(96) ms.setExtent(QgsRectangle(-133, 22, -70, 52)) ms.setLayers([points_layer.id()]) renderchecker = QgsMultiRenderChecker() renderchecker.setMapSettings(ms) renderchecker.setControlPathPrefix('symbol_layer') renderchecker.setControlName('expected_markerlayer_ddenabled') self.assertTrue(renderchecker.runTest('markerlayer_ddenabled')) QgsMapLayerRegistry.instance().removeMapLayer(points_layer)
def return_batch_route(self, features): """Save and/or display the routes retrieved""" osrm_batch_route_layer = QgsVectorLayer( "Linestring?crs=epsg:4326&field=id:integer" "&field=total_time:integer(20)&field=distance:integer(20)", "routes_osrm{}".format(self.nb_done), "memory") provider = osrm_batch_route_layer.dataProvider() provider.addFeatures(features) QgsMapLayerRegistry.instance().addMapLayer(osrm_batch_route_layer) if self.filename: error = QgsVectorFileWriter.writeAsVectorFormat( osrm_batch_route_layer, self.filename, self.encoding, None, "ESRI Shapefile") if error != QgsVectorFileWriter.NoError: self.iface.messageBar().pushMessage( "Error", "Can't save the result into {} - Output have been " "added to the canvas (see QGis log for error trace" "back)".format(self.filename), duration=10) QgsMessageLog.logMessage( 'OSRM-plugin error report :\n {}'.format(error), level=QgsMessageLog.WARNING) self.iface.setActiveLayer(osrm_batch_route_layer) return -1 else: QtGui.QMessageBox.information( self.iface.mainWindow(), 'Info', "Result saved in {}".format(self.filename)) if self.check_add_layer.isChecked(): self.iface.setActiveLayer(osrm_batch_route_layer) else: QgsMapLayerRegistry.instance().removeMapLayer( osrm_batch_route_layer.id()) self.iface.messageBar().clearWidgets()
def testRequestRepaintSimple(self): """ test requesting repaint with a single dependent layer """ layer = QgsVectorLayer("Point?field=fldtxt:string", "layer", "memory") QgsProject.instance().addMapLayers([layer]) self.assertTrue(layer.isValid()) # add image to cache cache = QgsMapRendererCache() im = QImage(200, 200, QImage.Format_RGB32) cache.setCacheImage('xxx', im, [layer]) self.assertFalse(cache.cacheImage('xxx').isNull()) self.assertTrue(cache.hasCacheImage('xxx')) # trigger repaint on layer layer.triggerRepaint() # cache image should be cleared self.assertTrue(cache.cacheImage('xxx').isNull()) self.assertFalse(cache.hasCacheImage('xxx')) QgsProject.instance().removeMapLayer(layer.id()) # test that cache is also cleared on deferred update layer = QgsVectorLayer("Point?field=fldtxt:string", "layer", "memory") cache.setCacheImage('xxx', im, [layer]) layer.triggerRepaint(True) self.assertFalse(cache.hasCacheImage('xxx'))
def testRenderLineLayerDataDefined(self): """ test that rendering a line symbol with data defined enabled layer works""" lines_shp = os.path.join(TEST_DATA_DIR, 'lines.shp') lines_layer = QgsVectorLayer(lines_shp, 'Lines', 'ogr') QgsMapLayerRegistry.instance().addMapLayer(lines_layer) layer = QgsSimpleLineSymbolLayer() layer.setDataDefinedProperty("enabled", QgsDataDefined("Name='Highway'")) layer.setColor(QColor(100, 150, 150)) layer.setWidth(5) symbol = QgsLineSymbol() symbol.changeSymbolLayer(0, layer) lines_layer.setRenderer(QgsSingleSymbolRenderer(symbol)) ms = QgsMapSettings() ms.setOutputSize(QSize(400, 400)) ms.setOutputDpi(96) ms.setExtent(QgsRectangle(-133, 22, -70, 52)) ms.setLayers([lines_layer.id()]) renderchecker = QgsMultiRenderChecker() renderchecker.setMapSettings(ms) renderchecker.setControlPathPrefix('symbol_layer') renderchecker.setControlName('expected_linelayer_ddenabled') self.assertTrue(renderchecker.runTest('linelayer_ddenabled')) QgsMapLayerRegistry.instance().removeMapLayer(lines_layer)
def _loadBufferLayer(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) else: # If the layer does exist, then load it and copy the style layer = QgsVectorLayer(fullLayerPath, layerName, 'ogr') layer = layers.addLayerToLegend(self._iface, layer, self._bufferGroupIndex) if layer and layer.isValid(): layerId = layer.id() layers.loadStyle(layer, fromLayer=sourceLayer) self._setDefaultSnapping(layer) layer.startEditing() layer.setFeatureFormSuppress(QgsVectorLayer.SuppressOn) self._iface.legendInterface().setLayerExpanded(layer, False) else: layer = None return layer, layerId
def testNoSliverPolygons(self): # create a layer with some polygons that will be used as a source for "avoid intersections" l = QgsVectorLayer('MultiPolygon', 'test_layer', 'memory') assert l.isValid() QgsProject.instance().addMapLayer(l) QgsProject.instance().writeEntry("Digitizing", "/AvoidIntersectionsList", [l.id()]) features = [] for i, wkt in enumerate(feat_wkt): f = QgsFeature(i + 1) f.setGeometry(QgsGeometry.fromWkt(wkt)) features.append(f) l.dataProvider().addFeatures(features) assert l.pendingFeatureCount() == 7 # create a geometry and remove its intersections with other geometries g = QgsGeometry.fromWkt(newg_wkt) assert g.avoidIntersections() == 0 # the resulting multi-polygon must have exactly three parts # (in QGIS 2.0 it has one more tiny part that appears at the border between two of the original polygons) mpg = g.asMultiPolygon() assert len(mpg) == 3
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 testLayerDataSourceReset(self): """When adding a layer with the same id to the store make sure the data source is also updated in case the layer validity has changed from False to True""" p = QgsProject() store = p.layerStore() vl1 = createLayer('valid') vl2 = QgsVectorLayer('/not_a_valid_path.shp', 'invalid', 'ogr') self.assertTrue(vl1.isValid()) self.assertFalse(vl2.isValid()) store.addMapLayers([vl1, vl2]) self.assertEqual(store.validCount(), 1) self.assertEqual(len(store.mapLayers()), 2) # Re-add the bad layer store.addMapLayers([vl2]) self.assertEqual(store.validCount(), 1) self.assertEqual(len(store.mapLayers()), 2) doc = QDomDocument() doc.setContent('<maplayer><provider encoding="UTF-8">ogr</provider><layername>fixed</layername><id>%s</id></maplayer>' % vl2.id()) layer_node = QDomNode(doc.firstChild()) self.assertTrue(vl2.writeXml(layer_node, doc, QgsReadWriteContext())) datasource_node = doc.createElement("datasource") datasource_node.appendChild(doc.createTextNode(os.path.join(TEST_DATA_DIR, 'points.shp'))) layer_node.appendChild(datasource_node) p.readLayer(layer_node) self.assertEqual(store.validCount(), 2) self.assertEqual(len(store.mapLayers()), 2) self.assertEqual(store.mapLayers()[vl2.id()].name(), 'fixed')
def test_Query(self): l1 = QgsVectorLayer(os.path.join(self.testDataDir, "france_parts.shp"), "france_parts", "ogr", 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", 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", 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 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", 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", 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 geometry query = toPercent("SELECT * FROM ww") l2 = QgsVectorLayer( "?layer_ref=%s:ww&query=%s&uid=ObJeCtId&nogeometry" % (l1.id(), query), "vtab", "virtual", 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", False) self.assertEqual(l2.isValid(), False) QgsProject.instance().removeMapLayer(l1.id())
class AddField: def __init__(self, parent_widget): """This class handle the creation of Fields. This class is also imported in the MeanAnalyse class. Parameters ---------- parent_widget: GeoDataFarm """ self.iface = parent_widget.iface self.tsk_mngr = parent_widget.tsk_mngr self.db = parent_widget.db translate = TR('AddField') self.tr = translate.tr self.dock_widget = parent_widget.dock_widget self.parent = parent_widget self.AFD = AddFieldFileDialog() self.field = None self.defined_field = '' def run(self): """Presents the sub widget AddField and connects the different buttons to their function""" self.AFD.show() self.AFD.PBSelectExtent.clicked.connect(self.clicked_define_field) self.AFD.PBSave.clicked.connect(self.save) self.AFD.PBHelp.clicked.connect(self.help) self.AFD.PBQuit.clicked.connect(self.quit) self.AFD.exec() self.parent.populate.reload_fields() def set_widget_connections(self): """Function that sets the main widget connections.""" self.parent.dock_widget.PBAddField.clicked.connect(self.run) self.parent.dock_widget.PBRemoveField.clicked.connect( self.remove_field) self.parent.dock_widget.PBViewFields.clicked.connect(self.view_fields) def clicked_define_field(self, ignore_name=True): """Creates an empty polygon that's define a field""" if ignore_name: self.field = QgsVectorLayer("Polygon?crs=epsg:4326", 'Search area', "memory") else: name = self.AFD.LEFieldName.text() if len(name) == 0: QMessageBox.information( None, self.tr('Error:'), self.tr('Field name must be filled in.')) return self.field = QgsVectorLayer("Polygon?crs=epsg:4326", name, "memory") add_background() set_zoom(self.parent.iface, 2) self.field.startEditing() self.iface.actionAddFeature().trigger() QgsProject.instance().addMapLayer(self.field) def remove_field(self): """Removes a field that the user wants, a check that there are no data that is depended on is made.""" j = -1 for i in range(self.parent.dock_widget.LWFields.count()): j += 1 item = self.parent.dock_widget.LWFields.item(j) if item.checkState() == 2: field_name = item.text() qm = QMessageBox() res = qm.question( None, self.tr('Question'), self.tr("Do you want to delete ") + str(field_name), qm.Yes, qm.No) if res == qm.No: continue field_names = [] for tble_type in [ 'plant', 'ferti', 'spray', 'harvest', 'soil' ]: field_names.extend( self.db.execute_and_return( "select field from {type}.manual".format( type=tble_type))) sql = """SELECT table_name FROM information_schema.tables WHERE table_schema = 'other'""" for tble_type in self.db.execute_and_return(sql): tbl = tble_type[0] field_names.extend( self.db.execute_and_return( "select field from other.{tbl}".format(tbl=tbl))) stop_removing = False for row in field_names: if row[0] == field_name: QMessageBox.information( None, self.tr('Error'), self. tr('There are data sets that are dependent on this field, ' 'it cant be removed.')) stop_removing = True if stop_removing: continue sql = "delete from fields where field_name='{f}'".format( f=field_name) self.db.execute_sql(sql) self.parent.dock_widget.LWFields.takeItem(j) j -= 1 def view_fields(self): """Add all fields that aren't displayed on the canvas, if no background map is loaded Google maps are loaded.""" defined_field = self.defined_field if defined_field == '': add_background() sources = [ layer.name().split('_')[0] for layer in QgsProject.instance().mapLayers().values() ] fields_db = self.db.execute_and_return("select field_name from fields") task = QgsTask.fromFunction('Adding fields to the canvas', add_fields_2_canvas, self.db, fields_db, defined_field, sources, on_finished=self.finish) self.tsk_mngr.addTask(task) def finish(self, result, values): """Produces either an error message telling what went wrong or adds the fields to canvas and zoom to the layers. Parameters ---------- result: object values: list If all went ok: [True, list of layers] Else: [False, exception, traceback] """ if values[0] is False: QMessageBox.information( None, self.tr('Error'), self.tr( 'Following error occurred: {m}\n\n Traceback: {t}'.format( m=values[1], t=values[2]))) return for layer in values[-1]: QgsProject.instance().addMapLayer(layer) if self.defined_field == '': set_zoom(self.parent.iface, 1.1) self.defined_field = '' def quit(self): """Closes the widget.""" self.AFD.PBSelectExtent.clicked.disconnect() self.AFD.PBSave.clicked.disconnect() self.AFD.PBHelp.clicked.disconnect() self.AFD.PBQuit.clicked.disconnect() self.AFD.done(0) def save(self): """Saves the field in the database""" try: self.iface.actionSaveActiveLayerEdits().trigger() self.iface.actionToggleEditing().trigger() feature = self.field.getFeature(1) QgsProject.instance().removeMapLayers([self.field.id()]) except: QMessageBox.information( None, self.tr("Error:"), self. tr('No coordinates were found, did you mark the field on the canvas?' )) return polygon = feature.geometry().asWkt() name = self.AFD.LEFieldName.text() if len(name) == 0: QMessageBox.information(None, self.tr('Error:'), self.tr('Field name must be filled in.')) return sql = """Insert into fields (field_name, polygon) VALUES ('{name}', st_geomfromtext('{poly}', 4326))""".format( name=name, poly=polygon) try: self.db.execute_sql(sql) except IntegrityError: QMessageBox.information( None, self.tr('Error:'), self.tr('Field name already exist, please select a new name')) return except InternalError as e: QMessageBox.information(None, self.tr('Error:'), str(e)) return _name = QApplication.translate("qadashboard", name, None) item = QListWidgetItem(_name, self.dock_widget.LWFields) item.setFlags(item.flags() | QtCore.Qt.ItemIsUserCheckable) item.setCheckState(QtCore.Qt.Unchecked) self.defined_field = name self.view_fields() def help(self): """A function that gives some advice on how the function works for the user. """ QMessageBox.information( None, self.tr("Help:"), self. tr('Here is where you add a field.\n' '1. Start with giving the field a name.\n' '2. Press "select extent" and switch to the QGIS window and zoom to your field.\n' '3. To mark your field, left click with the mouse in one corner of the field.\n' 'then left click in all corners of the field then right click anywhere on the map.\n' '(There might be some errors while clicking the corners if the lines are crossing each other but in the end this does not matter if they does not do it in the end)\n' '4. Press "Save field" to store the field.\n' '5. When all fields are added press "Finished"')) return
def testCreateExpression(self): """ Test creating an expression using the widget""" layer = QgsVectorLayer( "Point?field=fldtxt:string&field=fldint:integer", "test", "memory") # setup value relation parent_layer = QgsVectorLayer( "Point?field=stringkey:string&field=intkey:integer&field=display:string", "parent", "memory") f1 = QgsFeature(parent_layer.fields(), 1) f1.setAttributes(['a', 1, 'value a']) f2 = QgsFeature(parent_layer.fields(), 2) f2.setAttributes(['b', 2, 'value b']) f3 = QgsFeature(parent_layer.fields(), 3) f3.setAttributes(['c', 3, 'value c']) parent_layer.dataProvider().addFeatures([f1, f2, f3]) QgsProject.instance().addMapLayers([layer, parent_layer]) relationManager = QgsProject.instance().relationManager() relation = QgsRelation() relation.setId('relation') relation.setReferencingLayer(layer.id()) relation.setReferencedLayer(parent_layer.id()) relation.addFieldPair('fldtxt', 'stringkey') self.assertTrue(relation.isValid()) relationManager.addRelation(relation) # Everything valid config = {'Relation': relation.id(), 'AllowNULL': True} w = QgsRelationReferenceSearchWidgetWrapper(layer, 0, None) w.setConfig(config) w.widget().setForeignKey('a') self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.IsNull), '"fldtxt" IS NULL') self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.IsNotNull), '"fldtxt" IS NOT NULL') self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.EqualTo), '"fldtxt"=\'a\'') self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.NotEqualTo), '"fldtxt"<>\'a\'') w.widget().setForeignKey('b') self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.IsNull), '"fldtxt" IS NULL') self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.IsNotNull), '"fldtxt" IS NOT NULL') self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.EqualTo), '"fldtxt"=\'b\'') self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.NotEqualTo), '"fldtxt"<>\'b\'') w.widget().setForeignKey('c') self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.IsNull), '"fldtxt" IS NULL') self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.IsNotNull), '"fldtxt" IS NOT NULL') self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.EqualTo), '"fldtxt"=\'c\'') self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.NotEqualTo), '"fldtxt"<>\'c\'') w.widget().setForeignKey(None) self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.IsNull), '"fldtxt" IS NULL') self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.IsNotNull), '"fldtxt" IS NOT NULL') self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.EqualTo), '"fldtxt" IS NULL') self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.NotEqualTo), '"fldtxt" IS NOT NULL')
class oivImportFileWidget(QDockWidget, FORM_CLASS): """the actions class for the import""" parentWidget = None canvas = None selectTool = None importLayer = None layerImportType = None mappingDict = {} layerTypes = ['Point', 'LineString', 'Polygon'] def __init__(self, parent=None): """Constructor.""" super(oivImportFileWidget, self).__init__(parent) self.iface = iface self.setupUi(self) self.select_file.clicked.connect(self.selectfile) self.terug.clicked.connect(self.close_import) self.mapping.clicked.connect(self.run_mapping) self.import_file.clicked.connect(self.inlezen) self.hide_all() def selectfile(self): """select the import shape or dxf file""" dxfInfo = None importFile = QFileDialog.getOpenFileName( None, "Selecteer bestand:", None, "AutoCad (*.dxf);;Shape (*.shp);;GeoPackage (*.gpkg)")[0] self.bestandsnaam.setText(importFile) if importFile: if importFile.endswith('.dxf'): self.layerImportType, ok = DxfDialogObject.getGeometryType() dxfInfo = "|layername=entities|geometrytype=" + self.layerImportType importFileFeat = importFile + dxfInfo if not self.layerImportType or not ok: return self.importLayer = QgsVectorLayer(importFileFeat, "import", "ogr") elif importFile.endswith('.gpkg'): layerNames = [l.GetName() for l in ogr.Open(importFile)] GpkgDialog.layerNames = layerNames layerName, dummy = GpkgDialog.getLayerName() gpkgInfo = "|layername={}".format(layerName) importFileFeat = importFile + gpkgInfo self.importLayer = QgsVectorLayer(importFileFeat, "import", "ogr") else: importFileFeat = importFile self.importLayer = QgsVectorLayer(importFileFeat, "import", "ogr") if self.importLayer.geometryType() < 3: self.layerImportType = self.layerTypes[ self.importLayer.geometryType()] else: return else: return crs = self.importLayer.crs() crs.createFromId(28992) self.importLayer.setCrs(crs) QgsProject.instance().addMapLayer(self.importLayer, True) fields = self.importLayer.fields() for field in fields: self.type.addItem(field.name()) self.label3.setVisible(True) self.type.setVisible(True) self.label6.setVisible(True) self.mapping.setVisible(True) def read_types(self): types = {} actionList, dummy, dummy = get_actions('config_object') for lst in actionList: tempList = [] for action in lst: layerName = action[0] layer = getlayer_byname(layerName) layerType = check_layer_type(layer) tempList.append(action[1]) tempList.append("niet importeren") if layerType in types: types[layerType].update({layerName: tempList}) else: types.update({layerType: {layerName: tempList}}) return types def inlezen(self): """import the file after all settings wehere made""" importAttr = self.type.currentText() invalidCount = 0 for importType in self.mappingDict: if self.mappingDict[importType]["targetType"] != 'niet importeren': checkConv = False expr = QgsExpression('"{}"= \'{}\''.format( importAttr, importType)) featureIt = self.importLayer.getFeatures( QgsFeatureRequest(expr)) targetFeature = QgsFeature() targetLayerName = self.mappingDict[importType]["layerName"] if 'Labels' in targetLayerName: LabelDialog.attributes = [ self.type.itemText(i) for i in range(self.type.count()) ] LabelDialog.importType = importType labelField, dummy = LabelDialog.getLabelAtrribute() targetLayer = getlayer_byname(targetLayerName) targetFields = targetLayer.fields() targetFeature.initAttributes(targetFields.count()) targetFeature.setFields(targetFields) if self.mappingDict[importType][ "convType"] != self.layerImportType: checkConv = True query = "SELECT foreign_key, identifier, input_label FROM config_object WHERE child_layer = '{}'".format( targetLayerName) attrs = read_settings(query, False)[0] targetFeature[ attrs[1]] = self.mappingDict[importType]["targetType"] targetFeature[attrs[0]] = self.object_id.text() targetLayer.startEditing() for feat in featureIt: geom = None if not checkConv: geom = getfeature_geometry(feat.geometry(), self.layerImportType) if 'Labels' in targetLayerName: if feat[labelField]: targetFeature[attrs[2]] = feat[labelField] else: targetFeature[attrs[2]] = 'geen label' if geom: targetFeature.setGeometry(geom) invalidCheck = write_layer(targetLayer, targetFeature, True) if invalidCheck == 'invalid': invalidCount += 1 targetLayer.commitChanges() if invalidCount > 0: message = ( 'Features zijn geimporteerd.\n' '{} features zijn niet geimporteerd vanwege ongeldige geometrie!' .format(invalidCount)) else: message = 'Alle feature zijn succesvol geimporteerd!' QMessageBox.information(None, "INFO:", message) QgsProject.instance().removeMapLayers([self.importLayer.id()]) def run_mapping(self): """get attribute mapping from the user""" targetTypes = self.read_types() importTypes = [] importAttribute = self.type.currentText() for feat in self.importLayer.getFeatures(): if feat[importAttribute] not in importTypes: importTypes.append(feat[importAttribute]) if self.layerImportType == 'Point': MappingDialog.layerType = ['Point'] else: MappingDialog.layerType = ['LineString', 'Polygon'] MappingDialog.targetTypes = targetTypes MappingDialog.importTypes = importTypes self.mappingDict, ok = MappingDialog.getMapping() if ok: self.label7.setVisible(True) self.import_file.setVisible(True) def hide_all(self): """when the import start hide all on the UI""" self.bouwlaag_id.setVisible(False) self.label1.setVisible(True) self.label3.setVisible(False) self.label6.setVisible(False) self.label7.setVisible(False) self.mapping.setVisible(False) self.type.setVisible(False) self.select_file.setVisible(True) self.bestandsnaam.setVisible(True) self.import_file.setVisible(False) def close_import(self): """close feature form and save changes""" try: QgsProject.instance().removeMapLayers([self.importLayer.id()]) except: # pylint: disable=bare-except pass self.hide_all() self.close() try: self.parentWidget.show() del self.parentWidget except: # pylint: disable=bare-except pass del self
def legend_test(self): self.atlas_map.setAtlasDriven(True) self.atlas_map.setAtlasScalingMode(QgsLayoutItemMap.Auto) self.atlas_map.setAtlasMargin(0.10) # add a point layer ptLayer = QgsVectorLayer( "Point?crs=epsg:4326&field=attr:int(1)&field=label:string(20)", "points", "memory") pr = ptLayer.dataProvider() f1 = QgsFeature(1) f1.initAttributes(2) f1.setAttribute(0, 1) f1.setAttribute(1, "Test label 1") f1.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(-0.638, 48.954))) f2 = QgsFeature(2) f2.initAttributes(2) f2.setAttribute(0, 2) f2.setAttribute(1, "Test label 2") f2.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(-1.682, 48.550))) pr.addFeatures([f1, f2]) # categorized symbology r = QgsCategorizedSymbolRenderer("attr", [ QgsRendererCategory( 1, QgsMarkerSymbol.createSimple({ "color": "255,0,0", 'outline_color': 'black' }), "red"), QgsRendererCategory( 2, QgsMarkerSymbol.createSimple({ "color": "0,0,255", 'outline_color': 'black' }), "blue") ]) ptLayer.setRenderer(r) QgsProject.instance().addMapLayer(ptLayer) # add the point layer to the map settings layers = self.layers layers = [ptLayer] + layers self.atlas_map.setLayers(layers) self.overview.setLayers(layers) # add a legend legend = QgsLayoutItemLegend(self.layout) legend.attemptMove(QgsLayoutPoint(200, 100)) # sets the legend filter parameter legend.setLinkedMap(self.atlas_map) legend.setLegendFilterOutAtlas(True) self.layout.addLayoutItem(legend) self.atlas.beginRender() self.atlas.seekTo(0) self.mLabel1.adjustSizeToText() checker = QgsLayoutChecker('atlas_legend', self.layout) myTestResult, myMessage = checker.testLayout() self.report += checker.report() self.assertTrue(myTestResult, myMessage) self.atlas.endRender() # restore state self.atlas_map.setLayers([layers[1]]) self.layout.removeLayoutItem(legend) QgsProject.instance().removeMapLayer(ptLayer.id())
class TestQgsBlendModes(unittest.TestCase): def __init__(self, methodName): """Run once on class initialization.""" unittest.TestCase.__init__(self, methodName) self.iface = get_iface() # initialize class MapRegistry, Canvas, MapRenderer, Map and PAL self.mMapRegistry = QgsMapLayerRegistry.instance() # create point layer myShpFile = os.path.join(TEST_DATA_DIR, 'points.shp') self.mPointLayer = QgsVectorLayer(myShpFile, 'Points', 'ogr') self.mMapRegistry.addMapLayer(self.mPointLayer) self.mSimplifyMethod = QgsVectorSimplifyMethod() self.mSimplifyMethod.setSimplifyHints( QgsVectorSimplifyMethod.NoSimplification) # create polygon layer myShpFile = os.path.join(TEST_DATA_DIR, 'polys.shp') self.mPolygonLayer = QgsVectorLayer(myShpFile, 'Polygons', 'ogr') self.mPolygonLayer.setSimplifyMethod(self.mSimplifyMethod) self.mMapRegistry.addMapLayer(self.mPolygonLayer) # create line layer myShpFile = os.path.join(TEST_DATA_DIR, 'lines.shp') self.mLineLayer = QgsVectorLayer(myShpFile, 'Lines', 'ogr') self.mLineLayer.setSimplifyMethod(self.mSimplifyMethod) self.mMapRegistry.addMapLayer(self.mLineLayer) # create two raster layers myRasterFile = os.path.join(TEST_DATA_DIR, 'rgb256x256.png') self.mRasterLayer1 = QgsRasterLayer(myRasterFile, "raster1") self.mRasterLayer2 = QgsRasterLayer(myRasterFile, "raster2") myMultiBandRenderer1 = QgsMultiBandColorRenderer( self.mRasterLayer1.dataProvider(), 1, 2, 3) self.mRasterLayer1.setRenderer(myMultiBandRenderer1) self.mMapRegistry.addMapLayer(self.mRasterLayer1) myMultiBandRenderer2 = QgsMultiBandColorRenderer( self.mRasterLayer2.dataProvider(), 1, 2, 3) self.mRasterLayer2.setRenderer(myMultiBandRenderer2) self.mMapRegistry.addMapLayer(self.mRasterLayer2) # to match blend modes test comparisons background self.mapSettings = QgsMapSettings() self.mapSettings.setLayers( [self.mRasterLayer1.id(), self.mRasterLayer2.id()]) self.mapSettings.setBackgroundColor(QColor(152, 219, 249)) self.mapSettings.setOutputSize(QSize(400, 400)) self.mapSettings.setOutputDpi(96) self.extent = QgsRectangle(-118.8888888888887720, 22.8002070393376783, -83.3333333333331581, 46.8719806763287536) def testVectorBlending(self): """Test that blend modes work for vector layers.""" # Add vector layers to map myLayers = [] myLayers.append(self.mLineLayer.id()) myLayers.append(self.mPolygonLayer.id()) self.mapSettings.setLayers(myLayers) self.mapSettings.setExtent(self.extent) # Set blending modes for both layers self.mLineLayer.setBlendMode(QPainter.CompositionMode_Difference) self.mPolygonLayer.setBlendMode(QPainter.CompositionMode_Difference) checker = QgsMultiRenderChecker() checker.setControlName("expected_vector_blendmodes") checker.setMapSettings(self.mapSettings) checker.setColorTolerance(1) myResult = checker.runTest("vector_blendmodes", 20) myMessage = ('vector blending failed') assert myResult, myMessage # Reset layers self.mLineLayer.setBlendMode(QPainter.CompositionMode_SourceOver) self.mPolygonLayer.setBlendMode(QPainter.CompositionMode_SourceOver) def testVectorFeatureBlending(self): """Test that feature blend modes work for vector layers.""" # Add vector layers to map myLayers = [] myLayers.append(self.mLineLayer.id()) myLayers.append(self.mPolygonLayer.id()) self.mapSettings.setLayers(myLayers) self.mapSettings.setExtent(self.extent) # Set feature blending for line layer self.mLineLayer.setFeatureBlendMode(QPainter.CompositionMode_Plus) checker = QgsMultiRenderChecker() checker.setControlName("expected_vector_featureblendmodes") checker.setMapSettings(self.mapSettings) checker.setColorTolerance(1) myResult = checker.runTest("vector_featureblendmodes", 20) myMessage = ('vector feature blending failed') assert myResult, myMessage # Reset layers self.mLineLayer.setFeatureBlendMode( QPainter.CompositionMode_SourceOver) def testVectorLayerTransparency(self): """Test that layer transparency works for vector layers.""" # Add vector layers to map myLayers = [] myLayers.append(self.mLineLayer.id()) myLayers.append(self.mPolygonLayer.id()) self.mapSettings.setLayers(myLayers) self.mapSettings.setExtent(self.extent) # Set feature blending for line layer self.mLineLayer.setLayerTransparency(50) checker = QgsMultiRenderChecker() checker.setControlName("expected_vector_layertransparency") checker.setMapSettings(self.mapSettings) checker.setColorTolerance(1) myResult = checker.runTest("vector_layertransparency", 20) myMessage = ('vector layer transparency failed') assert myResult, myMessage def testRasterBlending(self): """Test that blend modes work for raster layers.""" # Add raster layers to map myLayers = [] myLayers.append(self.mRasterLayer1.id()) myLayers.append(self.mRasterLayer2.id()) self.mapSettings.setLayers(myLayers) self.mapSettings.setExtent(self.mRasterLayer1.extent()) # Set blending mode for top layer self.mRasterLayer1.setBlendMode(QPainter.CompositionMode_Difference) checker = QgsMultiRenderChecker() checker.setControlName("expected_raster_blendmodes") checker.setMapSettings(self.mapSettings) checker.setColorTolerance(1) checker.setColorTolerance(1) myResult = checker.runTest("raster_blendmodes", 20) myMessage = ('raster blending failed') assert myResult, myMessage
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 testExportFeatureRelations(self): """ Test exporting a feature with relations """ #parent layer parent = QgsVectorLayer( "Point?field=fldtxt:string&field=fldint:integer&field=foreignkey:integer", "parent", "memory") pr = parent.dataProvider() pf1 = QgsFeature() pf1.setFields(parent.fields()) pf1.setAttributes(["test1", 67, 123]) pf2 = QgsFeature() pf2.setFields(parent.fields()) pf2.setAttributes(["test2", 68, 124]) assert pr.addFeatures([pf1, pf2]) #child layer child = QgsVectorLayer( "Point?field=x:string&field=y:integer&field=z:integer", "referencedlayer", "memory") pr = child.dataProvider() f1 = QgsFeature() f1.setFields(child.fields()) f1.setAttributes(["foo", 123, 321]) f2 = QgsFeature() f2.setFields(child.fields()) f2.setAttributes(["bar", 123, 654]) f3 = QgsFeature() f3.setFields(child.fields()) f3.setAttributes(["foobar", 124, 554]) assert pr.addFeatures([f1, f2, f3]) QgsProject.instance().addMapLayers([child, parent]) rel = QgsRelation() rel.setId('rel1') rel.setName('relation one') rel.setReferencingLayer(child.id()) rel.setReferencedLayer(parent.id()) rel.addFieldPair('y', 'foreignkey') QgsProject.instance().relationManager().addRelation(rel) exporter = QgsJsonExporter() exporter.setVectorLayer(parent) self.assertEqual(exporter.vectorLayer(), parent) exporter.setIncludeRelated(True) self.assertEqual(exporter.includeRelated(), True) expected = """{ "type":"Feature", "id":0, "geometry":null, "properties":{ "fldtxt":"test1", "fldint":67, "foreignkey":123, "relation one":[{"x":"foo", "y":123, "z":321}, {"x":"bar", "y":123, "z":654}] } }""" self.assertEqual(exporter.exportFeature(pf1), expected) expected = """{ "type":"Feature", "id":0, "geometry":null, "properties":{ "fldtxt":"test2", "fldint":68, "foreignkey":124, "relation one":[{"x":"foobar", "y":124, "z":554}] } }""" self.assertEqual(exporter.exportFeature(pf2), expected) # with field formatter setup = QgsEditorWidgetSetup('ValueMap', {"map": { "apples": 123, "bananas": 124 }}) child.setEditorWidgetSetup(1, setup) expected = """{ "type":"Feature", "id":0, "geometry":null, "properties":{ "fldtxt":"test1", "fldint":67, "foreignkey":123, "relation one":[{"x":"foo", "y":"apples", "z":321}, {"x":"bar", "y":"apples", "z":654}] } }""" self.assertEqual(exporter.exportFeature(pf1), expected) # test excluding related attributes exporter.setIncludeRelated(False) self.assertEqual(exporter.includeRelated(), False) expected = """{ "type":"Feature", "id":0, "geometry":null, "properties":{ "fldtxt":"test2", "fldint":68, "foreignkey":124 } }""" self.assertEqual(exporter.exportFeature(pf2), expected) # test without vector layer set exporter.setIncludeRelated(True) exporter.setVectorLayer(None) expected = """{ "type":"Feature", "id":0, "geometry":null, "properties":{ "fldtxt":"test2", "fldint":68, "foreignkey":124 } }""" self.assertEqual(exporter.exportFeature(pf2), expected)
class Print_utility(QObject): progressBarUpdated = pyqtSignal(int, int) HOME = os.environ['PYARCHINIT_HOME'] FILEPATH = os.path.dirname(__file__) LAYER_STYLE_PATH = '{}{}{}{}'.format(FILEPATH, os.sep, 'styles', os.sep) LAYER_STYLE_PATH_SPATIALITE = '{}{}{}{}'.format(FILEPATH, os.sep, 'styles_spatialite', os.sep) SRS = 3004 layerUS = "" layerQuote = "" ## layerCL = "" ## layerGriglia = "" #sperimentale da riattivare USLayerId = "" CLayerId = "" QuoteLayerId = "" GrigliaLayerId = "" mapHeight = "" mapWidth = "" tav_num = "" us = "" uri = "" def __init__(self, iface, data): super().__init__() self.iface = iface self.data = data # self.area = area # self.us = us self.canvas = self.iface.mapCanvas() # set host name, port, database name, username and password """ def on_pushButton_runTest_pressed(self): self.first_batch_try() """ def first_batch_try(self, server): if server == 'postgres': for i in range(len(self.data)): test = self.charge_layer_postgis(self.data[i].sito, self.data[i].area, self.data[i].us) self.us = self.data[i].us if test != 0: if self.layerUS.featureCount() > 0: self.test_bbox() tav_num = i self.print_map(tav_num) self.progressBarUpdated.emit(i, len(self.data) - 1) QApplication.processEvents() else: self.remove_layer() if test == 0: Report_path = '{}{}{}'.format( self.HOME, os.sep, "pyarchinit_Report_folder/report_errori.txt") f = open(Report_path, "w") f.write(str("Presenza di errori nel layer")) f.close() elif server == 'sqlite': for i in range(len(self.data)): test = self.charge_layer_sqlite(self.data[i].sito, self.data[i].area, self.data[i].us) self.us = self.data[i].us if test != 0: if self.layerUS.featureCount() > 0: self.test_bbox() tav_num = i self.print_map(tav_num) self.progressBarUpdated.emit(i, len(self.data) - 1) QApplication.processEvents() else: self.remove_layer() else: pass def converter_1_20(self, n): n *= 100 res = n / 20 return res def test_bbox(self): # f = open("/test_type.txt", "w") # ff.write(str(type(self.layerUS))) # ff.close() self.layerUS.select([]) # recuperi tutte le geometrie senza attributi # featPoly = QgsFeature() # crei una feature vuota per il poligono dizionario_id_contains = {} lista_quote = [] it = self.layerUS.getFeatures() featPoly = next( it ) # cicli sulle feature recuperate, featPoly conterra la feature poligonale attuale bbox = featPoly.geometry().boundingBox( ) # recupera i punti nel bbox del poligono self.height = self.converter_1_20(float( bbox.height())) * 10 # la misura da cm e' portata in mm self.width = self.converter_1_20(float( bbox.width())) * 10 # la misura da cm e' portata in mm # f = open("/test_paper_size_5.txt", "w") # f.write(str(self.width)) # f.close() def getMapExtentFromMapCanvas(self, mapWidth, mapHeight, scale): # code from easyPrint plugin # print "in methode: " + str(scale) xmin = self.canvas.extent().xMinimum() xmax = self.canvas.extent().xMaximum() ymin = self.canvas.extent().yMinimum() ymax = self.canvas.extent().yMaximum() xcenter = xmin + (xmax - xmin) / 2 ycenter = ymin + (ymax - ymin) / 2 mapWidth = mapWidth * scale / 1000 # misura in punti mapHeight = mapHeight * scale / 1000 # misura in punti # f = open("/test_paper_size_3.txt", "w") # f.write(str(mapWidth)) # f.close() minx = xcenter - mapWidth / 2 miny = ycenter - mapHeight / 2 maxx = xcenter + mapWidth / 2 maxy = ycenter + mapHeight / 2 return QgsRectangle(minx, miny, maxx, maxy) def print_map(self, tav_num): self.tav_num = tav_num p = QgsProject.instance() crs = QgsCoordinateReferenceSystem() crs.createFromSrid(self.SRS) p.setCrs(crs) l = QgsLayout(p) l.initializeDefaults() page = l.pageCollection().page(0) # map - this item tells the libraries where to put the map itself. Here we create a map and stretch it over the whole paper size: x, y = 0, 0 # angolo 0, o in alto a sx if (0 <= self.width <= 297) and (0 <= self.height <= 210): width, height = 297, 210 # Formato A4 Landscape elif (0 <= self.height <= 297) and (0 <= self.width <= 210): width, height = 210, 297 # Formato A4 elif (0 <= self.width <= 420) and (0 <= self.height <= 297): width, height = 297, 420 # Formato A3 Landscape elif (0 <= self.height <= 420) and (0 <= self.width <= 297): width, height = 240, 297 # Formato A4 elif (0 <= self.width <= 1189) and (0 <= self.height <= 841): width, height = 1189, 841 # Formato A0 Landscape elif (0 <= self.height <= 1189) and (0 <= self.width <= 841): width, height = 841, 1189 # Formato A0 else: width, height = self.width * 1.2, self.height * 1.2 # self.width*10, self.height*10 da un valore alla larghezza e altezza del foglio aumentato di 5 per dare un margine size = QgsLayoutSize(width, height) page.setPageSize(size) map = QgsLayoutItemMap(l) rect = self.getMapExtentFromMapCanvas(page.pageSize().width(), page.pageSize().height(), 20.0) map.attemptSetSceneRect( QRectF(0, 0, page.pageSize().width(), page.pageSize().height())) map.setExtent(rect) map.setLayers([self.layerUS]) l.setReferenceMap(map) l.addLayoutItem(map) intestazioneLabel = QgsLayoutItemLabel(l) txt = "Tavola %s - US:%d" % (self.tav_num + 1, self.us) intestazioneLabel.setText(txt) intestazioneLabel.adjustSizeToText() intestazioneLabel.attemptMove(QgsLayoutPoint(1, 0), page=0) intestazioneLabel.setFrameEnabled(False) l.addLayoutItem(intestazioneLabel) scaleLabel = QgsLayoutItemLabel(l) txt = "Scala: " scaleLabel.setText(txt) scaleLabel.adjustSizeToText() scaleLabel.attemptMove(QgsLayoutPoint(1, 5), page=0) scaleLabel.setFrameEnabled(False) l.addLayoutItem(scaleLabel) # aggiunge la scale bar scaleBarItem = QgsLayoutItemScaleBar(l) scaleBarItem.setStyle('Numeric') # optionally modify the style scaleBarItem.setLinkedMap(map) scaleBarItem.applyDefaultSize() scaleBarItem.attemptMove(QgsLayoutPoint(10, 5), page=0) scaleBarItem.setFrameEnabled(False) l.addLayoutItem(scaleBarItem) le = QgsLayoutExporter(l) settings = QgsLayoutExporter.ImageExportSettings() settings.dpi = 100 MAPS_path = '{}{}{}'.format(self.HOME, os.sep, "pyarchinit_MAPS_folder") tav_name = "Tavola_{}_us_{}.png".format(self.tav_num + 1, self.us) filename_png = '{}{}{}'.format(MAPS_path, os.sep, tav_name) le.exportToImage(filename_png, settings) self.remove_layer() def open_connection_postgis(self): cfg_rel_path = os.path.join(os.sep, 'pyarchinit_DB_folder', 'config.cfg') file_path = '{}{}'.format(self.HOME, cfg_rel_path) conf = open(file_path, "r") con_sett = conf.read() conf.close() settings = Settings(con_sett) settings.set_configuration() self.uri = QgsDataSourceUri() self.uri.setConnection(settings.HOST, settings.PORT, settings.DATABASE, settings.USER, settings.PASSWORD) def remove_layer(self): if self.USLayerId != "": QgsProject.instance().removeMapLayer(self.USLayerId) self.USLayerId = "" if self.QuoteLayerId != "": QgsProject.instance().removeMapLayer(self.QuoteLayerId) self.QuoteLayerId = "" def charge_layer_sqlite(self, sito, area, us): sqliteDB_path = os.path.join(os.sep, 'pyarchinit_DB_folder', 'pyarchinit_db.sqlite') db_file_path = '{}{}'.format(self.HOME, sqliteDB_path) srs = QgsCoordinateReferenceSystem( 3004, QgsCoordinateReferenceSystem.PostgisCrsId) gidstr = "scavo_s = '%s' and area_s = '%s' and us_s = '%d'" % ( sito, area, us) uri = QgsDataSourceUri() uri.setDatabase(db_file_path) uri.setDataSource('', 'pyarchinit_us_view', 'the_geom', gidstr, "ROWID") self.layerUS = QgsVectorLayer(uri.uri(), 'pyarchinit_us_view', 'spatialite') if self.layerUS.isValid(): self.layerUS.setCrs(srs) self.USLayerId = self.layerUS.id() # self.mapLayerRegistry.append(USLayerId) style_path = '{}{}'.format(self.LAYER_STYLE_PATH_SPATIALITE, 'us_view.qml') self.layerUS.loadNamedStyle(style_path) self.iface.mapCanvas().setExtent(self.layerUS.extent()) QgsProject.instance().addMapLayer(self.layerUS, True) else: QMessageBox.warning(None, "Errore", "Non Valido", QMessageBox.Ok) return 0 # QMessageBox.warning(self, "Messaggio", "Geometria inesistente", QMessageBox.Ok) gidstr = "sito_q = '%s' and area_q = '%s' and us_q = '%d'" % (sito, area, us) uri.setDataSource('', 'pyarchinit_quote_view', 'the_geom', gidstr, "ROWID") self.layerQuote = QgsVectorLayer(uri.uri(), 'pyarchinit_quote_view', 'spatialite') if self.layerQuote.isValid(): self.layerQuote.setCrs(srs) self.QuoteLayerId = self.layerQuote.id() # self.mapLayerRegistry.append(QuoteLayerId) style_path = '{}{}'.format(self.LAYER_STYLE_PATH_SPATIALITE, 'stile_quote.qml') self.layerQuote.loadNamedStyle(style_path) QgsProject.instance().addMapLayer(self.layerQuote, True) def charge_layer_postgis(self, sito, area, us): self.open_connection_postgis() srs = QgsCoordinateReferenceSystem( 3004, QgsCoordinateReferenceSystem.PostgisCrsId) gidstr = "scavo_s = '%s' and area_s = '%s' and us_s = '%d'" % ( sito, area, us) self.uri.setDataSource("public", "pyarchinit_us_view", "the_geom", gidstr, 'gid') self.layerUS = QgsVectorLayer(self.uri.uri(), "US", "postgres") if self.layerUS.isValid(): self.layerUS.setCrs(srs) self.USLayerId = self.layerUS.id() # self.mapLayerRegistry.append(USLayerId) style_path = '{}{}'.format(self.LAYER_STYLE_PATH, 'us_caratterizzazioni.qml') self.layerUS.loadNamedStyle(style_path) self.iface.mapCanvas().setExtent(self.layerUS.extent()) QgsProject.instance().addMapLayer(self.layerUS, True) else: return 0 gidstr = "sito_q = '%s' and area_q = '%s' and us_q = '%d'" % (sito, area, us) self.uri.setDataSource("public", "pyarchinit_quote", "the_geom", gidstr, 'gid') self.layerQuote = QgsVectorLayer(self.uri.uri(), "Quote", "postgres") if self.layerQuote.isValid(): self.layerQuote.setCrs(srs) self.QuoteLayerId = self.layerQuote.id() # self.mapLayerRegistry.append(QuoteLayerId) style_path = '{}{}'.format(self.LAYER_STYLE_PATH, 'stile_quote.qml') self.layerQuote.loadNamedStyle(style_path) QgsProject.instance().addMapLayer(self.layerQuote, True)
class TestQgsEditFormConfig(unittest.TestCase): @classmethod def setUpClass(cls): QgsGui.editorWidgetRegistry().initEditors() # Bring up a simple HTTP server os.chdir(unitTestDataPath() + '') handler = http.server.SimpleHTTPRequestHandler cls.httpd = socketserver.TCPServer(('localhost', 0), handler) cls.port = cls.httpd.server_address[1] cls.httpd_thread = threading.Thread(target=cls.httpd.serve_forever) cls.httpd_thread.setDaemon(True) cls.httpd_thread.start() def createLayer(self): self.layer = QgsVectorLayer("Point?field=fldtxt:string&field=fldint:integer", "addfeat", "memory") return self.layer def testReadWriteXml(self): layer = self.createLayer() config = layer.editFormConfig() config.setReadOnly(0, True) config.setReadOnly(1, False) config.setLabelOnTop(0, False) config.setLabelOnTop(1, True) doc = QDomDocument("testdoc") elem = doc.createElement('edit') config.writeXml(elem, QgsReadWriteContext()) layer2 = self.createLayer() config2 = layer2.editFormConfig() config2.readXml(elem, QgsReadWriteContext()) self.assertTrue(config2.readOnly(0)) self.assertFalse(config2.readOnly(1)) self.assertFalse(config2.labelOnTop(0)) self.assertTrue(config2.labelOnTop(1)) def testFormUi(self): layer = self.createLayer() config = layer.editFormConfig() config.setLayout(QgsEditFormConfig.GeneratedLayout) self.assertEqual(config.layout(), QgsEditFormConfig.GeneratedLayout) uiLocal = os.path.join( unitTestDataPath(), '/qgis_local_server/layer_attribute_form.ui') config.setUiForm(uiLocal) self.assertEqual(config.layout(), QgsEditFormConfig.UiFileLayout) config.setLayout(QgsEditFormConfig.GeneratedLayout) self.assertEqual(config.layout(), QgsEditFormConfig.GeneratedLayout) uiUrl = 'http://localhost:' + \ str(self.port) + '/qgis_local_server/layer_attribute_form.ui' config.setUiForm(uiUrl) self.assertEqual(config.layout(), QgsEditFormConfig.UiFileLayout) content = QgsApplication.networkContentFetcherRegistry().fetch(uiUrl) self.assertTrue(content is not None) while True: if content.status() in (QgsFetchedContent.Finished, QgsFetchedContent.Failed): break app.processEvents() self.assertEqual(content.status(), QgsFetchedContent.Finished) def testReadOnly(self): layer = self.createLayer() config = layer.editFormConfig() # safety checks config.setReadOnly(-1, True) config.setReadOnly(100, True) # real checks config.setReadOnly(0, True) config.setReadOnly(1, True) self.assertTrue(config.readOnly(0)) self.assertTrue(config.readOnly(1)) config.setReadOnly(0, False) config.setReadOnly(1, False) self.assertFalse(config.readOnly(0)) self.assertFalse(config.readOnly(1)) def testLabelOnTop(self): layer = self.createLayer() config = layer.editFormConfig() # safety checks config.setLabelOnTop(-1, True) config.setLabelOnTop(100, True) # real checks config.setLabelOnTop(0, True) config.setLabelOnTop(1, True) self.assertTrue(config.labelOnTop(0)) self.assertTrue(config.labelOnTop(1)) config.setLabelOnTop(0, False) config.setLabelOnTop(1, False) self.assertFalse(config.labelOnTop(0)) self.assertFalse(config.labelOnTop(1)) def test_backgroundColorSerialize(self): """Test backgroundColor serialization""" layer = self.createLayer() config = layer.editFormConfig() color_name = '#ff00ff' container = QgsAttributeEditorContainer('container name', None, QColor('#ff00ff')) doc = QDomDocument() element = container.toDomElement(doc) config = QgsEditFormConfig() container2 = config.attributeEditorElementFromDomElement(element, None, self.layer.id()) self.assertEqual(container2.backgroundColor().name(), color_name)
def test_representValue(self): first_layer = QgsVectorLayer("none?field=foreign_key:integer", "first_layer", "memory") self.assertTrue(first_layer.isValid()) second_layer = QgsVectorLayer( "none?field=pkid:integer&field=decoded:string", "second_layer", "memory") self.assertTrue(second_layer.isValid()) QgsProject.instance().addMapLayers([first_layer, second_layer]) f = QgsFeature() f.setAttributes([123]) first_layer.dataProvider().addFeatures([f]) f = QgsFeature() f.setAttributes([123, 'decoded_val']) second_layer.dataProvider().addFeatures([f]) relMgr = QgsProject.instance().relationManager() fieldFormatter = QgsRelationReferenceFieldFormatter() rel = QgsRelation() rel.setId('rel1') rel.setName('Relation Number One') rel.setReferencingLayer(first_layer.id()) rel.setReferencedLayer(second_layer.id()) rel.addFieldPair('foreign_key', 'pkid') self.assertTrue(rel.isValid()) relMgr.addRelation(rel) # Everything valid config = {'Relation': rel.id()} second_layer.setDisplayExpression('decoded') self.assertEqual( fieldFormatter.representValue(first_layer, 0, config, None, '123'), 'decoded_val') # Code not find match in foreign layer config = {'Relation': rel.id()} second_layer.setDisplayExpression('decoded') self.assertEqual( fieldFormatter.representValue(first_layer, 0, config, None, '456'), '456') # Invalid relation id config = {'Relation': 'invalid'} second_layer.setDisplayExpression('decoded') self.assertEqual( fieldFormatter.representValue(first_layer, 0, config, None, '123'), '123') # No display expression config = {'Relation': rel.id()} second_layer.setDisplayExpression(None) self.assertEqual( fieldFormatter.representValue(first_layer, 0, config, None, '123'), '123') # Invalid display expression config = {'Relation': rel.id()} second_layer.setDisplayExpression('invalid +') self.assertEqual( fieldFormatter.representValue(first_layer, 0, config, None, '123'), '123') # Missing relation config = {} second_layer.setDisplayExpression('decoded') self.assertEqual( fieldFormatter.representValue(first_layer, 0, config, None, '123'), '123') # Inconsistent layer provided to representValue() config = {'Relation': rel.id()} second_layer.setDisplayExpression('decoded') self.assertEqual( fieldFormatter.representValue(second_layer, 0, config, None, '123'), '123') # Inconsistent idx provided to representValue() config = {'Relation': rel.id()} second_layer.setDisplayExpression('decoded') self.assertEqual( fieldFormatter.representValue(first_layer, 1, config, None, '123'), '123') # Invalid relation rel = QgsRelation() rel.setId('rel2') rel.setName('Relation Number Two') rel.setReferencingLayer(first_layer.id()) rel.addFieldPair('foreign_key', 'pkid') self.assertFalse(rel.isValid()) relMgr.addRelation(rel) config = {'Relation': rel.id()} second_layer.setDisplayExpression('decoded') self.assertEqual( fieldFormatter.representValue(first_layer, 0, config, None, '123'), '123') QgsProject.instance().removeAllMapLayers()
def test_representValue(self): first_layer = QgsVectorLayer("none?field=foreign_key:integer", "first_layer", "memory") self.assertTrue(first_layer.isValid()) second_layer = QgsVectorLayer( "none?field=pkid:integer&field=decoded:string", "second_layer", "memory") self.assertTrue(second_layer.isValid()) QgsProject.instance().addMapLayer(second_layer) f = QgsFeature() f.setAttributes([123]) first_layer.dataProvider().addFeatures([f]) f = QgsFeature() f.setAttributes([123, 'decoded_val']) second_layer.dataProvider().addFeatures([f]) fieldFormatter = QgsValueRelationFieldFormatter() # Everything valid config = { 'Layer': second_layer.id(), 'Key': 'pkid', 'Value': 'decoded' } self.assertEqual( fieldFormatter.representValue(first_layer, 0, config, None, '123'), 'decoded_val') # Code not find match in foreign layer config = { 'Layer': second_layer.id(), 'Key': 'pkid', 'Value': 'decoded' } self.assertEqual( fieldFormatter.representValue(first_layer, 0, config, None, '456'), '(456)') # Missing Layer config = {'Key': 'pkid', 'Value': 'decoded'} self.assertEqual( fieldFormatter.representValue(first_layer, 0, config, None, '456'), '(456)') # Invalid Layer config = {'Layer': 'invalid', 'Key': 'pkid', 'Value': 'decoded'} self.assertEqual( fieldFormatter.representValue(first_layer, 0, config, None, '456'), '(456)') # Invalid Key config = { 'Layer': second_layer.id(), 'Key': 'invalid', 'Value': 'decoded' } self.assertEqual( fieldFormatter.representValue(first_layer, 0, config, None, '456'), '(456)') # Invalid Value config = { 'Layer': second_layer.id(), 'Key': 'pkid', 'Value': 'invalid' } self.assertEqual( fieldFormatter.representValue(first_layer, 0, config, None, '456'), '(456)') QgsProject.instance().removeMapLayer(second_layer.id())
def testMasterLayerOrder(self): """ test master layer order""" prj = QgsProject.instance() prj.clear() layer = QgsVectorLayer("Point?field=fldtxt:string", "layer1", "memory") layer2 = QgsVectorLayer("Point?field=fldtxt:string", "layer2", "memory") layer3 = QgsVectorLayer("Point?field=fldtxt:string", "layer3", "memory") prj.addMapLayers([layer, layer2, layer3]) prj.layerTreeRoot().setHasCustomLayerOrder(True) prj.layerTreeRoot().setCustomLayerOrder([layer2, layer]) self.assertEqual(prj.mapThemeCollection().masterLayerOrder(), [layer2, layer]) prj.layerTreeRoot().setCustomLayerOrder([layer, layer2, layer3]) # make some themes... theme1 = QgsMapThemeCollection.MapThemeRecord() theme1.setLayerRecords([QgsMapThemeCollection.MapThemeLayerRecord(layer3), QgsMapThemeCollection.MapThemeLayerRecord(layer)]) theme2 = QgsMapThemeCollection.MapThemeRecord() theme2.setLayerRecords([QgsMapThemeCollection.MapThemeLayerRecord(layer3), QgsMapThemeCollection.MapThemeLayerRecord(layer2), QgsMapThemeCollection.MapThemeLayerRecord(layer)]) theme3 = QgsMapThemeCollection.MapThemeRecord() theme3.setLayerRecords([QgsMapThemeCollection.MapThemeLayerRecord(layer2), QgsMapThemeCollection.MapThemeLayerRecord(layer)]) prj.mapThemeCollection().insert('theme1', theme1) prj.mapThemeCollection().insert('theme2', theme2) prj.mapThemeCollection().insert('theme3', theme3) #order of layers in theme should respect master order self.assertEqual(prj.mapThemeCollection().mapThemeVisibleLayers('theme1'), [layer, layer3]) self.assertEqual(prj.mapThemeCollection().mapThemeVisibleLayers('theme2'), [layer, layer2, layer3]) self.assertEqual(prj.mapThemeCollection().mapThemeVisibleLayers('theme3'), [layer, layer2]) # also check ids! self.assertEqual(prj.mapThemeCollection().mapThemeVisibleLayerIds('theme1'), [layer.id(), layer3.id()]) self.assertEqual(prj.mapThemeCollection().mapThemeVisibleLayerIds('theme2'), [layer.id(), layer2.id(), layer3.id()]) self.assertEqual(prj.mapThemeCollection().mapThemeVisibleLayerIds('theme3'), [layer.id(), layer2.id()]) # reset master order prj.layerTreeRoot().setCustomLayerOrder([layer2, layer3, layer]) self.assertEqual(prj.mapThemeCollection().mapThemeVisibleLayers('theme1'), [layer3, layer]) self.assertEqual(prj.mapThemeCollection().mapThemeVisibleLayers('theme2'), [layer2, layer3, layer]) self.assertEqual(prj.mapThemeCollection().mapThemeVisibleLayers('theme3'), [layer2, layer]) self.assertEqual(prj.mapThemeCollection().mapThemeVisibleLayerIds('theme1'), [layer3.id(), layer.id()]) self.assertEqual(prj.mapThemeCollection().mapThemeVisibleLayerIds('theme2'), [layer2.id(), layer3.id(), layer.id()]) self.assertEqual(prj.mapThemeCollection().mapThemeVisibleLayerIds('theme3'), [layer2.id(), layer.id()]) # check that layers include those hidden in the layer tree canvas = QgsMapCanvas() bridge = QgsLayerTreeMapCanvasBridge(prj.layerTreeRoot(), canvas) root = prj.layerTreeRoot() layer_node = root.findLayer(layer2.id()) layer_node.setItemVisibilityChecked(False) app.processEvents() prj.layerTreeRoot().setHasCustomLayerOrder(False) self.assertEqual(prj.mapThemeCollection().masterLayerOrder(), [layer, layer2, layer3]) self.assertEqual(prj.mapThemeCollection().mapThemeVisibleLayers('theme1'), [layer, layer3]) self.assertEqual(prj.mapThemeCollection().mapThemeVisibleLayers('theme2'), [layer, layer2, layer3]) self.assertEqual(prj.mapThemeCollection().mapThemeVisibleLayers('theme3'), [layer, layer2]) self.assertEqual(prj.mapThemeCollection().mapThemeVisibleLayerIds('theme1'), [layer.id(), layer3.id()]) self.assertEqual(prj.mapThemeCollection().mapThemeVisibleLayerIds('theme2'), [layer.id(), layer2.id(), layer3.id()]) self.assertEqual(prj.mapThemeCollection().mapThemeVisibleLayerIds('theme3'), [layer.id(), layer2.id()])
class TestQgsEditFormConfig(unittest.TestCase): @classmethod def setUpClass(cls): QgsGui.editorWidgetRegistry().initEditors() QgsSettings().clear() # Bring up a simple HTTP server os.chdir(unitTestDataPath() + '') handler = http.server.SimpleHTTPRequestHandler cls.httpd = socketserver.TCPServer(('localhost', 0), handler) cls.port = cls.httpd.server_address[1] cls.httpd_thread = threading.Thread(target=cls.httpd.serve_forever) cls.httpd_thread.setDaemon(True) cls.httpd_thread.start() def createLayer(self): self.layer = QgsVectorLayer( "Point?field=fldtxt:string&field=fldint:integer", "addfeat", "memory") f = QgsFeature() pr = self.layer.dataProvider() assert pr.addFeatures([f]) return self.layer def testReadWriteXml(self): layer = self.createLayer() config = layer.editFormConfig() config.setReadOnly(0, True) config.setReadOnly(1, False) config.setLabelOnTop(0, False) config.setLabelOnTop(1, True) doc = QDomDocument("testdoc") elem = doc.createElement('edit') config.writeXml(elem, QgsReadWriteContext()) layer2 = self.createLayer() config2 = layer2.editFormConfig() config2.readXml(elem, QgsReadWriteContext()) self.assertTrue(config2.readOnly(0)) self.assertFalse(config2.readOnly(1)) self.assertFalse(config2.labelOnTop(0)) self.assertTrue(config2.labelOnTop(1)) def testFormUi(self): layer = self.createLayer() config = layer.editFormConfig() config.setLayout(QgsEditFormConfig.GeneratedLayout) self.assertEqual(config.layout(), QgsEditFormConfig.GeneratedLayout) uiLocal = os.path.join(unitTestDataPath(), '/qgis_local_server/layer_attribute_form.ui') config.setUiForm(uiLocal) self.assertEqual(config.layout(), QgsEditFormConfig.UiFileLayout) config.setLayout(QgsEditFormConfig.GeneratedLayout) self.assertEqual(config.layout(), QgsEditFormConfig.GeneratedLayout) uiUrl = 'http://localhost:' + \ str(self.port) + '/qgis_local_server/layer_attribute_form.ui' config.setUiForm(uiUrl) self.assertEqual(config.layout(), QgsEditFormConfig.UiFileLayout) content = QgsApplication.networkContentFetcherRegistry().fetch( uiUrl, QgsNetworkContentFetcherRegistry.DownloadImmediately) self.assertTrue(content is not None) while True: if content.status() in (QgsFetchedContent.Finished, QgsFetchedContent.Failed): break app.processEvents() self.assertEqual(content.status(), QgsFetchedContent.Finished) # Failing on Travis, seg fault in event loop, no idea why """ @unittest.expectedFailure def testFormPy(self): layer = self.createLayer() config = layer.editFormConfig() config.setInitCodeSource(QgsEditFormConfig.CodeSourceFile) uiLocal = os.path.join( unitTestDataPath(), 'qgis_local_server/layer_attribute_form.ui') config.setUiForm(uiLocal) pyUrl = 'http://localhost:' + \ str(self.port) + '/qgis_local_server/layer_attribute_form.py' QgsSettings().setEnumValue('qgis/enableMacros', Qgis.Always) config.setInitFilePath(pyUrl) config.setInitFunction('formOpen') content = QgsApplication.networkContentFetcherRegistry().fetch(pyUrl, QgsNetworkContentFetcherRegistry.DownloadImmediately) self.assertTrue(content is not None) while True: if content.status() in (QgsFetchedContent.Finished, QgsFetchedContent.Failed): break app.processEvents() self.assertEqual(content.status(), QgsFetchedContent.Finished) layer.setEditFormConfig(config) form = QgsAttributeForm(layer, next(layer.getFeatures())) label = form.findChild(QLabel, 'label') self.assertIsNotNone(label) self.assertEqual(label.text(), 'Flying Monkey') """ def testReadOnly(self): layer = self.createLayer() config = layer.editFormConfig() # safety checks config.setReadOnly(-1, True) config.setReadOnly(100, True) # real checks config.setReadOnly(0, True) config.setReadOnly(1, True) self.assertTrue(config.readOnly(0)) self.assertTrue(config.readOnly(1)) config.setReadOnly(0, False) config.setReadOnly(1, False) self.assertFalse(config.readOnly(0)) self.assertFalse(config.readOnly(1)) def testLabelOnTop(self): layer = self.createLayer() config = layer.editFormConfig() # safety checks config.setLabelOnTop(-1, True) config.setLabelOnTop(100, True) # real checks config.setLabelOnTop(0, True) config.setLabelOnTop(1, True) self.assertTrue(config.labelOnTop(0)) self.assertTrue(config.labelOnTop(1)) config.setLabelOnTop(0, False) config.setLabelOnTop(1, False) self.assertFalse(config.labelOnTop(0)) self.assertFalse(config.labelOnTop(1)) def test_backgroundColorSerialize(self): """Test backgroundColor serialization""" layer = self.createLayer() config = layer.editFormConfig() color_name = '#ff00ff' container = QgsAttributeEditorContainer('container name', None, QColor('#ff00ff')) doc = QDomDocument() element = container.toDomElement(doc) config = QgsEditFormConfig() container2 = config.attributeEditorElementFromDomElement( element, None, self.layer.id()) self.assertEqual(container2.backgroundColor().name(), color_name)
def test_Join(self): l1 = QgsVectorLayer(os.path.join(self.testDataDir, "points.shp"), "points", "ogr", QgsVectorLayer.LayerOptions(False)) self.assertEqual(l1.isValid(), True) QgsProject.instance().addMapLayer(l1) l2 = QgsVectorLayer(os.path.join(self.testDataDir, "points_relations.shp"), "points_relations", "ogr", QgsVectorLayer.LayerOptions(False)) self.assertEqual(l2.isValid(), True) QgsProject.instance().addMapLayer(l2) ref_sum = sum(f.attributes()[1] for f in l2.getFeatures()) # use a temporary file query = toPercent("select id,Pilots,vtab1.geometry from vtab1,vtab2 where intersects(vtab1.geometry,vtab2.geometry)") l3 = QgsVectorLayer("?layer_ref=%s&layer_ref=%s&uid=id&query=%s&geometry=geometry:1:4326" % (l1.id(), l2.id(), query), "vtab", "virtual", QgsVectorLayer.LayerOptions(False)) self.assertEqual(l3.isValid(), True) self.assertEqual(l3.dataProvider().wkbType(), 1) self.assertEqual(l3.dataProvider().fields().count(), 2) ref_sum2 = sum(f.id() for f in l3.getFeatures()) self.assertEqual(ref_sum, ref_sum2) QgsProject.instance().removeMapLayer(l1) QgsProject.instance().removeMapLayer(l2)
def test_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()])
class TestQgsSymbolExpressionVariables(unittest.TestCase): def setUp(self): myShpFile = os.path.join(TEST_DATA_DIR, 'polys.shp') self.layer = QgsVectorLayer(myShpFile, 'Polys', 'ogr') QgsMapLayerRegistry.instance().addMapLayer(self.layer) self.iface = get_iface() rendered_layers = [self.layer.id()] self.mapsettings = self.iface.mapCanvas().mapSettings() self.mapsettings.setOutputSize(QSize(400, 400)) self.mapsettings.setOutputDpi(96) self.mapsettings.setExtent(QgsRectangle(-163, 22, -70, 52)) self.mapsettings.setLayers(rendered_layers) def tearDown(self): QgsMapLayerRegistry.instance().removeAllMapLayers() def testPartNum(self): # Create rulebased style sym1 = QgsFillSymbol.createSimple({'color': '#fdbf6f'}) renderer = QgsSingleSymbolRenderer(sym1) renderer.symbols( QgsRenderContext())[0].symbolLayers()[0].setDataDefinedProperty( 'color', QgsDataDefined( 'color_rgb( (@geometry_part_num - 1) * 200, 0, 0 )')) self.layer.setRenderer(renderer) # Setup rendering check renderchecker = QgsMultiRenderChecker() renderchecker.setMapSettings(self.mapsettings) renderchecker.setControlName('expected_geometry_part_num') result = renderchecker.runTest('part_geometry_part_num') self.assertTrue(result) def testPartCount(self): # Create rulebased style sym1 = QgsFillSymbol.createSimple({'color': '#fdbf6f'}) renderer = QgsSingleSymbolRenderer(sym1) renderer.symbols( QgsRenderContext())[0].symbolLayers()[0].setDataDefinedProperty( 'color', QgsDataDefined( 'color_rgb( (@geometry_part_count - 1) * 200, 0, 0 )')) self.layer.setRenderer(renderer) # Setup rendering check renderchecker = QgsMultiRenderChecker() renderchecker.setMapSettings(self.mapsettings) renderchecker.setControlName('expected_geometry_part_count') result = renderchecker.runTest('part_geometry_part_count') self.assertTrue(result) def testSymbolColor(self): # Create rulebased style sym1 = QgsFillSymbol.createSimple({'color': '#ff0000'}) renderer = QgsSingleSymbolRenderer(sym1) renderer.symbols( QgsRenderContext())[0].symbolLayers()[0].setDataDefinedProperty( 'color', QgsDataDefined( 'set_color_part( @symbol_color, \'value\', "Value" * 4)')) self.layer.setRenderer(renderer) # Setup rendering check renderchecker = QgsMultiRenderChecker() renderchecker.setMapSettings(self.mapsettings) renderchecker.setControlName('expected_symbol_color_variable') result = renderchecker.runTest('symbol_color_variable', 50) self.assertTrue(result)
def testMapTheme(self): canvas = QgsMapCanvas() canvas.setDestinationCrs(QgsCoordinateReferenceSystem(4326)) canvas.setFrameStyle(0) canvas.resize(600, 400) self.assertEqual(canvas.width(), 600) self.assertEqual(canvas.height(), 400) layer = QgsVectorLayer("Polygon?crs=epsg:4326&field=fldtxt:string", "layer", "memory") # add a polygon to layer f = QgsFeature() f.setGeometry(QgsGeometry.fromRect(QgsRectangle(5, 25, 25, 45))) self.assertTrue(layer.dataProvider().addFeatures([f])) # create a style sym1 = QgsFillSymbol.createSimple({'color': '#ffb200'}) renderer = QgsSingleSymbolRenderer(sym1) layer.setRenderer(renderer) canvas.setLayers([layer]) canvas.setExtent(QgsRectangle(10, 30, 20, 35)) canvas.show() # need to wait until first redraw can occur (note that we first need to wait till drawing starts!) while not canvas.isDrawing(): app.processEvents() canvas.waitWhileRendering() self.assertTrue(self.canvasImageCheck('theme1', 'theme1', canvas)) # add some styles layer.styleManager().addStyleFromLayer('style1') sym2 = QgsFillSymbol.createSimple({'color': '#00b2ff'}) renderer2 = QgsSingleSymbolRenderer(sym2) layer.setRenderer(renderer2) layer.styleManager().addStyleFromLayer('style2') canvas.refresh() canvas.waitWhileRendering() self.assertTrue(self.canvasImageCheck('theme2', 'theme2', canvas)) layer.styleManager().setCurrentStyle('style1') canvas.refresh() canvas.waitWhileRendering() self.assertTrue(self.canvasImageCheck('theme1', 'theme1', canvas)) # ok, so all good with setting/rendering map styles # try setting canvas to a particular theme # make some themes... theme1 = QgsMapThemeCollection.MapThemeRecord() record1 = QgsMapThemeCollection.MapThemeLayerRecord(layer) record1.currentStyle = 'style1' record1.usingCurrentStyle = True theme1.setLayerRecords([record1]) theme2 = QgsMapThemeCollection.MapThemeRecord() record2 = QgsMapThemeCollection.MapThemeLayerRecord(layer) record2.currentStyle = 'style2' record2.usingCurrentStyle = True theme2.setLayerRecords([record2]) QgsProject.instance().mapThemeCollection().insert('theme1', theme1) QgsProject.instance().mapThemeCollection().insert('theme2', theme2) canvas.setTheme('theme2') canvas.refresh() canvas.waitWhileRendering() self.assertTrue(self.canvasImageCheck('theme2', 'theme2', canvas)) canvas.setTheme('theme1') canvas.refresh() canvas.waitWhileRendering() self.assertTrue(self.canvasImageCheck('theme1', 'theme1', canvas)) # add another layer layer2 = QgsVectorLayer("Polygon?crs=epsg:4326&field=fldtxt:string", "layer2", "memory") f = QgsFeature() f.setGeometry(QgsGeometry.fromRect(QgsRectangle(5, 25, 25, 45))) self.assertTrue(layer2.dataProvider().addFeatures([f])) # create a style sym1 = QgsFillSymbol.createSimple({'color': '#b2ff00'}) renderer = QgsSingleSymbolRenderer(sym1) layer2.setRenderer(renderer) # rerender canvas - should NOT show new layer canvas.refresh() canvas.waitWhileRendering() self.assertTrue(self.canvasImageCheck('theme1', 'theme1', canvas)) # test again - this time refresh all layers canvas.refreshAllLayers() canvas.waitWhileRendering() self.assertTrue(self.canvasImageCheck('theme1', 'theme1', canvas)) # add layer 2 to theme1 record3 = QgsMapThemeCollection.MapThemeLayerRecord(layer2) theme1.setLayerRecords([record3]) QgsProject.instance().mapThemeCollection().update('theme1', theme1) canvas.refresh() canvas.waitWhileRendering() self.assertTrue(self.canvasImageCheck('theme3', 'theme3', canvas)) # change the appearance of an active style layer2.styleManager().addStyleFromLayer('original') layer2.styleManager().addStyleFromLayer('style4') record3.currentStyle = 'style4' record3.usingCurrentStyle = True theme1.setLayerRecords([record3]) QgsProject.instance().mapThemeCollection().update('theme1', theme1) canvas.refresh() canvas.waitWhileRendering() self.assertTrue(self.canvasImageCheck('theme3', 'theme3', canvas)) layer2.styleManager().setCurrentStyle('style4') sym3 = QgsFillSymbol.createSimple({'color': '#b200b2'}) layer2.renderer().setSymbol(sym3) canvas.refresh() canvas.waitWhileRendering() self.assertTrue(self.canvasImageCheck('theme4', 'theme4', canvas)) # try setting layers while a theme is in place canvas.setLayers([layer]) canvas.refresh() # should be no change... setLayers should be ignored if canvas is following a theme! canvas.waitWhileRendering() self.assertTrue(self.canvasImageCheck('theme4', 'theme4', canvas)) # setLayerStyleOverrides while theme is in place canvas.setLayerStyleOverrides({layer2.id(): 'original'}) # should be no change... setLayerStyleOverrides should be ignored if canvas is following a theme! canvas.refresh() canvas.waitWhileRendering() self.assertTrue(self.canvasImageCheck('theme4', 'theme4', canvas)) # clear theme canvas.setTheme('') canvas.refresh() canvas.waitWhileRendering() # should be different - we should now render project layers self.assertFalse(self.canvasImageCheck('theme4', 'theme4', canvas))
class TestQgsPointDisplacementRenderer(unittest.TestCase): def setUp(self): myShpFile = os.path.join(TEST_DATA_DIR, 'points.shp') self.layer = QgsVectorLayer(myShpFile, 'Points', 'ogr') QgsMapLayerRegistry.instance().addMapLayer(self.layer) self.renderer = QgsPointDisplacementRenderer() sym1 = QgsMarkerSymbol.createSimple({'color': '#ff00ff', 'size': '3', 'outline_style': 'no'}) renderer = QgsSingleSymbolRenderer(sym1) self.renderer.setEmbeddedRenderer(renderer) self.renderer.setCircleRadiusAddition(2) self.renderer.setCircleWidth(1) self.renderer.setCircleColor(QColor(0, 0, 0)) self.renderer.setCenterSymbol(QgsMarkerSymbol.createSimple({'color': '#ffff00', 'size': '3', 'outline_style': 'no'})) self.layer.setRenderer(self.renderer) rendered_layers = [self.layer.id()] self.mapsettings = QgsMapSettings() self.mapsettings.setOutputSize(QSize(400, 400)) self.mapsettings.setOutputDpi(96) self.mapsettings.setExtent(QgsRectangle(-123, 18, -70, 52)) self.mapsettings.setLayers(rendered_layers) def tearDown(self): QgsMapLayerRegistry.instance().removeAllMapLayers() def _setProperties(self, r): """ set properties for a renderer for testing with _checkProperties""" r.setLabelAttributeName('name') f = QgsFontUtils.getStandardTestFont('Bold Oblique', 14) r.setLabelFont(f) r.setMaxLabelScaleDenominator(50000) r.setLabelColor(QColor(255, 0, 0)) r.setTolerance(5) r.setToleranceUnit(QgsUnitTypes.RenderMapUnits) r.setToleranceMapUnitScale(QgsMapUnitScale(5, 15)) r.setCircleWidth(15) r.setCircleColor(QColor(0, 255, 0)) r.setCircleRadiusAddition(2.5) r.setPlacement(QgsPointDisplacementRenderer.ConcentricRings) m = QgsMarkerSymbol() m.setColor(QColor(0, 255, 0)) r.setCenterSymbol(m) sym1 = QgsMarkerSymbol.createSimple({'color': '#fdbf6f'}) renderer = QgsSingleSymbolRenderer(sym1) r.setEmbeddedRenderer(renderer) def _checkProperties(self, r): """ test properties of renderer against expected""" self.assertEqual(r.labelAttributeName(), 'name') f = QgsFontUtils.getStandardTestFont('Bold Oblique', 14) self.assertEqual(r.labelFont().styleName(), f.styleName()) self.assertEqual(r.maxLabelScaleDenominator(), 50000) self.assertEqual(r.labelColor(), QColor(255, 0, 0)) self.assertEqual(r.tolerance(), 5) self.assertEqual(r.toleranceUnit(), QgsUnitTypes.RenderMapUnits) self.assertEqual(r.toleranceMapUnitScale(), QgsMapUnitScale(5, 15)) self.assertEqual(r.circleWidth(), 15) self.assertEqual(r.circleColor(), QColor(0, 255, 0)) self.assertEqual(r.circleRadiusAddition(), 2.5) self.assertEqual(r.placement(), QgsPointDisplacementRenderer.ConcentricRings) self.assertEqual(r.centerSymbol().color(), QColor(0, 255, 0)) self.assertEqual(r.embeddedRenderer().symbol().color().name(), '#fdbf6f') def testGettersSetters(self): """ test getters and setters """ r = QgsPointDisplacementRenderer() self._setProperties(r) self._checkProperties(r) def testClone(self): """ test cloning renderer """ r = QgsPointDisplacementRenderer() self._setProperties(r) c = r.clone() self._checkProperties(c) def testSaveCreate(self): """ test saving and recreating from XML """ r = QgsPointDisplacementRenderer() self._setProperties(r) doc = QDomDocument("testdoc") elem = r.save(doc) c = QgsPointDisplacementRenderer.create(elem) self._checkProperties(c) def testConvert(self): """ test renderer conversion """ # same type, should clone r = QgsPointDisplacementRenderer() self._setProperties(r) c = QgsPointDisplacementRenderer.convertFromRenderer(r) self._checkProperties(c) # test conversion from cluster renderer r = QgsPointClusterRenderer() r.setTolerance(5) r.setToleranceUnit(QgsUnitTypes.RenderMapUnits) r.setToleranceMapUnitScale(QgsMapUnitScale(5, 15)) m = QgsMarkerSymbol() m.setColor(QColor(0, 255, 0)) r.setClusterSymbol(m) sym1 = QgsMarkerSymbol.createSimple({'color': '#fdbf6f'}) renderer = QgsSingleSymbolRenderer(sym1) r.setEmbeddedRenderer(renderer) # want to keep as many settings as possible when converting between cluster and displacement renderer d = QgsPointDisplacementRenderer.convertFromRenderer(r) self.assertEqual(d.tolerance(), 5) self.assertEqual(d.toleranceUnit(), QgsUnitTypes.RenderMapUnits) self.assertEqual(d.toleranceMapUnitScale(), QgsMapUnitScale(5, 15)) self.assertEqual(d.centerSymbol().color(), QColor(0, 255, 0)) self.assertEqual(d.embeddedRenderer().symbol().color().name(), '#fdbf6f') def testRenderNoCluster(self): self.layer.renderer().setTolerance(1) renderchecker = QgsMultiRenderChecker() renderchecker.setMapSettings(self.mapsettings) renderchecker.setControlPathPrefix('displacement_renderer') renderchecker.setControlName('expected_displacement_no_cluster') self.assertTrue(renderchecker.runTest('displacement_no_cluster')) def testRenderWithin(self): self.layer.renderer().setTolerance(10) renderchecker = QgsMultiRenderChecker() renderchecker.setMapSettings(self.mapsettings) renderchecker.setControlPathPrefix('displacement_renderer') renderchecker.setControlName('expected_displacement_cluster') self.assertTrue(renderchecker.runTest('expected_displacement_cluster')) def testRenderVariables(self): """ test rendering with expression variables in marker """ self.layer.renderer().setTolerance(10) old_marker = self.layer.renderer().centerSymbol().clone() new_marker = QgsMarkerSymbol.createSimple({'color': '#ffff00', 'size': '3', 'outline_style': 'no'}) new_marker.symbolLayer(0).setDataDefinedProperty('color', QgsDataDefined('@cluster_color')) new_marker.symbolLayer(0).setDataDefinedProperty('size', QgsDataDefined('@cluster_size*2')) self.layer.renderer().setCenterSymbol(new_marker) renderchecker = QgsMultiRenderChecker() renderchecker.setMapSettings(self.mapsettings) renderchecker.setControlPathPrefix('displacement_renderer') renderchecker.setControlName('expected_displacement_variables') result = renderchecker.runTest('expected_displacement_variables') self.layer.renderer().setCenterSymbol(old_marker) self.assertTrue(result)
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)
class TestQgsBlendModes(TestCase): def __init__(self, methodName): """Run once on class initialisation.""" unittest.TestCase.__init__(self, methodName) # initialize class MapRegistry, Canvas, MapRenderer, Map and PAL self.mMapRegistry = QgsMapLayerRegistry.instance() # create point layer myShpFile = os.path.join(TEST_DATA_DIR, 'points.shp') self.mPointLayer = QgsVectorLayer(myShpFile, 'Points', 'ogr') self.mMapRegistry.addMapLayer(self.mPointLayer) self.mSimplifyMethod = QgsVectorSimplifyMethod() self.mSimplifyMethod.setSimplifyHints( QgsVectorSimplifyMethod.NoSimplification) # create polygon layer myShpFile = os.path.join(TEST_DATA_DIR, 'polys.shp') self.mPolygonLayer = QgsVectorLayer(myShpFile, 'Polygons', 'ogr') self.mPolygonLayer.setSimplifyMethod(self.mSimplifyMethod) self.mMapRegistry.addMapLayer(self.mPolygonLayer) # create line layer myShpFile = os.path.join(TEST_DATA_DIR, 'lines.shp') self.mLineLayer = QgsVectorLayer(myShpFile, 'Lines', 'ogr') self.mLineLayer.setSimplifyMethod(self.mSimplifyMethod) self.mMapRegistry.addMapLayer(self.mLineLayer) # create two raster layers myRasterFile = os.path.join(TEST_DATA_DIR, 'landsat.tif') self.mRasterLayer1 = QgsRasterLayer(myRasterFile, "raster1") self.mRasterLayer2 = QgsRasterLayer(myRasterFile, "raster2") myMultiBandRenderer1 = QgsMultiBandColorRenderer( self.mRasterLayer1.dataProvider(), 2, 3, 4) self.mRasterLayer1.setRenderer(myMultiBandRenderer1) self.mMapRegistry.addMapLayer(self.mRasterLayer1) myMultiBandRenderer2 = QgsMultiBandColorRenderer( self.mRasterLayer2.dataProvider(), 2, 3, 4) self.mRasterLayer2.setRenderer(myMultiBandRenderer2) self.mMapRegistry.addMapLayer(self.mRasterLayer2) # to match blend modes test comparisons background self.mCanvas = CANVAS self.mCanvas.setCanvasColor(QColor(152, 219, 249)) self.mMap = self.mCanvas.map() self.mMap.resize(QSize(400, 400)) self.mMapRenderer = self.mCanvas.mapRenderer() self.mMapRenderer.setOutputSize(QSize(400, 400), 72) def testVectorBlending(self): """Test that blend modes work for vector layers.""" #Add vector layers to map myLayers = [] myLayers.append(self.mLineLayer.id()) myLayers.append(self.mPolygonLayer.id()) self.mMapRenderer.setLayerSet(myLayers) self.mMapRenderer.setExtent(self.mPointLayer.extent()) #Set blending modes for both layers self.mLineLayer.setBlendMode(QPainter.CompositionMode_Difference) self.mPolygonLayer.setBlendMode(QPainter.CompositionMode_Difference) checker = QgsRenderChecker() checker.setControlName("expected_vector_blendmodes") checker.setMapRenderer(self.mMapRenderer) myResult = checker.runTest("vector_blendmodes") myMessage = ('vector blending failed') assert myResult, myMessage #Reset layers self.mLineLayer.setBlendMode(QPainter.CompositionMode_SourceOver) self.mPolygonLayer.setBlendMode(QPainter.CompositionMode_SourceOver) def testVectorFeatureBlending(self): """Test that feature blend modes work for vector layers.""" #Add vector layers to map myLayers = [] myLayers.append(self.mLineLayer.id()) myLayers.append(self.mPolygonLayer.id()) self.mMapRenderer.setLayerSet(myLayers) self.mMapRenderer.setExtent(self.mPointLayer.extent()) #Set feature blending for line layer self.mLineLayer.setFeatureBlendMode(QPainter.CompositionMode_Plus) checker = QgsRenderChecker() checker.setControlName("expected_vector_featureblendmodes") checker.setMapRenderer(self.mMapRenderer) myResult = checker.runTest("vector_featureblendmodes") myMessage = ('vector feature blending failed') assert myResult, myMessage #Reset layers self.mLineLayer.setFeatureBlendMode( QPainter.CompositionMode_SourceOver) def testVectorLayerTransparency(self): """Test that layer transparency works for vector layers.""" #Add vector layers to map myLayers = [] myLayers.append(self.mLineLayer.id()) myLayers.append(self.mPolygonLayer.id()) self.mMapRenderer.setLayerSet(myLayers) self.mMapRenderer.setExtent(self.mPointLayer.extent()) #Set feature blending for line layer self.mLineLayer.setLayerTransparency(50) checker = QgsRenderChecker() checker.setControlName("expected_vector_layertransparency") checker.setMapRenderer(self.mMapRenderer) myResult = checker.runTest("vector_layertransparency") myMessage = ('vector layer transparency failed') assert myResult, myMessage def testRasterBlending(self): """Test that blend modes work for raster layers.""" #Add raster layers to map myLayers = [] myLayers.append(self.mRasterLayer1.id()) myLayers.append(self.mRasterLayer2.id()) self.mMapRenderer.setLayerSet(myLayers) self.mMapRenderer.setExtent(self.mRasterLayer1.extent()) #Set blending mode for top layer self.mRasterLayer1.setBlendMode(QPainter.CompositionMode_Plus) checker = QgsRenderChecker() checker.setControlName("expected_raster_blendmodes") checker.setMapRenderer(self.mMapRenderer) myResult = checker.runTest("raster_blendmodes") myMessage = ('raster blending failed') assert myResult, myMessage
def download_tiles(self, force=None): #calculate zoom_level con current canvas extents ex = self.iface.mapCanvas().extent() wgs84_minimum = self.transformToWGS84( QgsPointXY(ex.xMinimum(), ex.yMinimum())) wgs84_maximum = self.transformToWGS84( QgsPointXY(ex.xMaximum(), ex.yMaximum())) bounds = (wgs84_minimum.x(), wgs84_minimum.y(), wgs84_maximum.x(), wgs84_maximum.y()) map_units_per_pixel = (wgs84_maximum.x() - wgs84_minimum.x() ) / self.iface.mapCanvas().width() zoom_level = ZoomForPixelSize(map_units_per_pixel) if zoom_level > 14: zoom_level = 14 try: ranges = getTileRange(bounds, zoom_level) except ValueError: return if not self.actual_ranges or not ( ranges[0][0] == self.actual_ranges[0][0] and ranges[0][1] == self.actual_ranges[0][1] and ranges[1][0] == self.actual_ranges[1][0] and ranges[1][1] == self.actual_ranges[1][1]): #print ("ZOOM_LEVEL", zoom_level, "NEW RANGES", ranges, "LAST RANGES", self.actual_ranges) self.actual_ranges = ranges x_range = ranges[0] y_range = ranges[1] overview_features = [] sequences_features = [] images_features = [] progress = progressBar(self, 'go2mapillary') start_time = datetime.datetime.now() for y in range(y_range[0], y_range[1] + 1): for x in range(x_range[0], x_range[1] + 1): folderPath = os.path.join(self.cache_dir, str(zoom_level), str(x)) filePathMvt = os.path.join(folderPath, str(y) + '.mvt') #filePathJson = os.path.join(folderPath, str(y) + '.json') if not os.path.exists(folderPath): os.makedirs(folderPath) res = None if not os.path.exists(filePathMvt) or ( datetime.datetime.fromtimestamp( os.path.getmtime(filePathMvt)) < (datetime.datetime.now() - self.expire_time)): # make the URL url = getURL(x, y, zoom_level, SERVER_URL) with open(filePathMvt, 'wb') as f: response = requests.get(url, proxies=getProxiesConf(), stream=True) total_length = response.headers.get( 'content-length') if total_length is None: # no content length header f.write(response.content) else: dl = 0 total_length = int(total_length) progress.start( total_length, 'caching vector tile [%d,%d,%d]' % (x, y, zoom_level)) QgsMessageLog.logMessage("MISS [%d,%d,%d]" % (x, y, zoom_level), tag="go2mapillary", level=Qgis.Info) for data in response.iter_content( chunk_size=4096): dl += len(data) f.write(data) progress.setProgress(dl) if os.path.exists(filePathMvt): progress.start( 0, 'loading vector tile [%d,%d,%d]' % (x, y, zoom_level)) if not res: with open(filePathMvt, "rb") as f: mvt = f.read() QgsMessageLog.logMessage("CACHE [%d,%d,%d]" % (x, y, zoom_level), tag="go2mapillary", level=Qgis.Info) else: mvt = res.content bounds = mercantile.bounds(x, y, zoom_level) tile_box = (bounds.west, bounds.south, bounds.east, bounds.north) json_data = mapbox_vector_tile.decode( mvt, quantize_bounds=tile_box) if "mapillary-sequence-overview" in json_data: overview_features = overview_features + json_data[ "mapillary-sequence-overview"]["features"] elif "mapillary-sequences" in json_data: sequences_features = sequences_features + json_data[ "mapillary-sequences"]["features"] if "mapillary-images" in json_data and zoom_level == 14: images_features = images_features + json_data[ "mapillary-images"]["features"] print("loading time", datetime.datetime.now() - start_time) progress.stop('loading complete') for level in LAYER_LEVELS: geojson_file = os.path.join(self.cache_dir, "mapillary_%s.geojson" % level) try: QgsProject.instance().removeMapLayer( getattr(self, level + 'Layer').id()) except: pass if locals()[level + '_features']: setattr(self, level, True) geojson = { "type": "FeatureCollection", "features": locals()[level + '_features'] } with open(geojson_file, 'w') as outfile: json.dump(geojson, outfile) defLyr = QgsVectorLayer( os.path.join(self.cache_dir, 'mapillary_%s.geojson' % level), "Mapillary " + level, "ogr") defLyr.loadNamedStyle( os.path.join(os.path.dirname(__file__), "res", "mapillary_%s.qml" % level)) QgsExpressionContextUtils.setLayerVariable( defLyr, "mapillaryCurrentKey", self.module.viewer.locationKey) defLyr.setCrs(QgsCoordinateReferenceSystem(4326)) QgsProject.instance().addMapLayer(defLyr) self.iface.addCustomActionForLayerType( getattr(self.module, 'filterAction_' + level), None, QgsMapLayer.VectorLayer, allLayers=False) self.module.filterDialog.applySqlFilter(layer=defLyr) self.iface.addCustomActionForLayer( getattr(self.module, 'filterAction_' + level), defLyr) legendLayerNode = QgsProject.instance().layerTreeRoot( ).findLayer(defLyr.id()) legendLayerNode.setExpanded(False) setattr(self, level + 'Layer', defLyr) else: setattr(self, level, False) else: pass
class TestQgsArrowSymbolLayer(unittest.TestCase): def setUp(self): self.iface = get_iface() lines_shp = os.path.join(TEST_DATA_DIR, 'lines.shp') self.lines_layer = QgsVectorLayer(lines_shp, 'Lines', 'ogr') QgsMapLayerRegistry.instance().addMapLayer(self.lines_layer) # Create style sym2 = QgsLineSymbol.createSimple({'color': '#fdbf6f'}) self.lines_layer.setRenderer(QgsSingleSymbolRenderer(sym2)) self.mapsettings = self.iface.mapCanvas().mapSettings() self.mapsettings.setOutputSize(QSize(400, 400)) self.mapsettings.setOutputDpi(96) self.mapsettings.setExtent(QgsRectangle(-113, 28, -91, 40)) self.mapsettings.setBackgroundColor(QColor("white")) def tearDown(self): QgsMapLayerRegistry.instance().removeAllMapLayers() def test_1(self): sym = self.lines_layer.renderer().symbol() sym_layer = QgsArrowSymbolLayer.create({ 'head_length': '6.5', 'head_thickness': '6.5' }) dd = QgsDataDefined("(@geometry_point_num % 4) * 2") sym_layer.setDataDefinedProperty("arrow_width", dd) dd2 = QgsDataDefined("(@geometry_point_num % 4) * 2") sym_layer.setDataDefinedProperty("head_length", dd2) dd3 = QgsDataDefined("(@geometry_point_num % 4) * 2") sym_layer.setDataDefinedProperty("head_thickness", dd3) fill_sym = QgsFillSymbol.createSimple({ 'color': '#8bcfff', 'outline_color': '#000000', 'outline_style': 'solid', 'outline_width': '1' }) sym_layer.setSubSymbol(fill_sym) sym.changeSymbolLayer(0, sym_layer) rendered_layers = [self.lines_layer.id()] self.mapsettings.setLayers(rendered_layers) renderchecker = QgsMultiRenderChecker() renderchecker.setMapSettings(self.mapsettings) renderchecker.setControlName('expected_arrowsymbollayer_1') self.assertTrue(renderchecker.runTest('arrowsymbollayer_1')) def test_2(self): sym = self.lines_layer.renderer().symbol() # double headed sym_layer = QgsArrowSymbolLayer.create({ 'arrow_width': '5', 'head_length': '4', 'head_thickness': '6', 'head_type': '2' }) fill_sym = QgsFillSymbol.createSimple({ 'color': '#8bcfff', 'outline_color': '#000000', 'outline_style': 'solid', 'outline_width': '1' }) sym_layer.setSubSymbol(fill_sym) sym.changeSymbolLayer(0, sym_layer) rendered_layers = [self.lines_layer.id()] self.mapsettings.setLayers(rendered_layers) renderchecker = QgsMultiRenderChecker() renderchecker.setMapSettings(self.mapsettings) renderchecker.setControlName('expected_arrowsymbollayer_2') self.assertTrue(renderchecker.runTest('arrowsymbollayer_2')) def test_3(self): sym = self.lines_layer.renderer().symbol() # double headed sym_layer = QgsArrowSymbolLayer.create({ 'arrow_width': '7', 'head_length': '6', 'head_thickness': '8', 'head_type': '0', 'arrow_type': '1', 'is_curved': '0' }) fill_sym = QgsFillSymbol.createSimple({ 'color': '#8bcfff', 'outline_color': '#000000', 'outline_style': 'solid', 'outline_width': '1' }) sym_layer.setSubSymbol(fill_sym) sym.changeSymbolLayer(0, sym_layer) rendered_layers = [self.lines_layer.id()] self.mapsettings.setLayers(rendered_layers) renderchecker = QgsMultiRenderChecker() ms = self.mapsettings ms.setExtent(QgsRectangle(-101, 35, -99, 37)) renderchecker.setMapSettings(ms) renderchecker.setControlName('expected_arrowsymbollayer_3') self.assertTrue(renderchecker.runTest('arrowsymbollayer_3')) def test_unrepeated(self): sym = self.lines_layer.renderer().symbol() # double headed sym_layer = QgsArrowSymbolLayer.create({ 'arrow_width': '7', 'head_length': '6', 'head_thickness': '8', 'head_type': '0', 'arrow_type': '0' }) # no repetition sym_layer.setIsRepeated(False) fill_sym = QgsFillSymbol.createSimple({ 'color': '#8bcfff', 'outline_color': '#000000', 'outline_style': 'solid', 'outline_width': '1' }) sym_layer.setSubSymbol(fill_sym) sym.changeSymbolLayer(0, sym_layer) rendered_layers = [self.lines_layer.id()] self.mapsettings.setLayers(rendered_layers) renderchecker = QgsMultiRenderChecker() ms = self.mapsettings ms.setExtent(QgsRectangle(-119, 17, -82, 50)) renderchecker.setMapSettings(ms) renderchecker.setControlName('expected_arrowsymbollayer_4') self.assertTrue(renderchecker.runTest('arrowsymbollayer_4')) def testColors(self): """ Test colors, need to make sure colors are passed/retrieved from subsymbol """ sym_layer = QgsArrowSymbolLayer.create() sym_layer.setColor(QColor(150, 50, 100)) self.assertEqual(sym_layer.color(), QColor(150, 50, 100)) self.assertEqual(sym_layer.subSymbol().color(), QColor(150, 50, 100)) sym_layer.subSymbol().setColor(QColor(250, 150, 200)) self.assertEqual(sym_layer.subSymbol().color(), QColor(250, 150, 200)) self.assertEqual(sym_layer.color(), QColor(250, 150, 200))
def testInitialSizeSymbolMapUnits(self): """Test initial size of legend with a symbol size in map units""" point_path = os.path.join(TEST_DATA_DIR, 'points.shp') point_layer = QgsVectorLayer(point_path, 'points', 'ogr') QgsProject.instance().addMapLayers([point_layer]) marker_symbol = QgsMarkerSymbol.createSimple({ 'color': '#ff0000', 'outline_style': 'no', 'size': '5', 'size_unit': 'MapUnit' }) point_layer.setRenderer(QgsSingleSymbolRenderer(marker_symbol)) s = QgsMapSettings() s.setLayers([point_layer]) layout = QgsLayout(QgsProject.instance()) layout.initializeDefaults() map = QgsLayoutItemMap(layout) map.attemptSetSceneRect(QRectF(20, 20, 80, 80)) map.setFrameEnabled(True) map.setLayers([point_layer]) layout.addLayoutItem(map) map.setExtent(point_layer.extent()) legend = QgsLayoutItemLegend(layout) legend.attemptSetSceneRect(QRectF(120, 20, 80, 80)) legend.setFrameEnabled(True) legend.setFrameStrokeWidth(QgsLayoutMeasurement(2)) legend.setBackgroundColor(QColor(200, 200, 200)) legend.setTitle('') layout.addLayoutItem(legend) legend.setLinkedMap(map) checker = QgsLayoutChecker('composer_legend_mapunits', layout) checker.setControlPathPrefix("composer_legend") result, message = checker.testLayout() self.assertTrue(result, message) # resize with non-top-left reference point legend.setResizeToContents(False) legend.setReferencePoint(QgsLayoutItem.LowerRight) legend.attemptMove(QgsLayoutPoint(120, 90)) legend.attemptResize(QgsLayoutSize(50, 60)) self.assertEqual(legend.positionWithUnits().x(), 120.0) self.assertEqual(legend.positionWithUnits().y(), 90.0) self.assertAlmostEqual(legend.pos().x(), 70, -1) self.assertAlmostEqual(legend.pos().y(), 30, -1) legend.setResizeToContents(True) legend.updateLegend() self.assertEqual(legend.positionWithUnits().x(), 120.0) self.assertEqual(legend.positionWithUnits().y(), 90.0) self.assertAlmostEqual(legend.pos().x(), 91, -1) self.assertAlmostEqual(legend.pos().y(), 71, -1) QgsProject.instance().removeMapLayers([point_layer.id()])
class OutputTabManager(QtCore.QObject): ''' Class to hide managing of relative tab ''' projectModified = QtCore.pyqtSignal() def __init__(self, parent=None): '''constructor''' super(OutputTabManager, self).__init__(parent) # parent is the dock widget with all graphical elements self.gui = parent self.plugin = parent.parent # init some globals self.applicationPath = os.path.dirname(os.path.realpath(__file__)) self.project = None self.projectPath = None self.outLayer = None self.outLayerId = None self.outLayerRemoved = False # retrieve the current tab index self.initTabTabIndex() # disable tab at the beginning self.gui.tabWidget.setTabEnabled(self.tabIndex, False) # add some gui events self.gui.createNewLayer_RButton.toggled.connect(self.setInputLayer) self.gui.selectOutfile_TButton.clicked.connect(self.selectNewOutFile) self.gui.calculate_PButton.clicked.connect(self.calculate) def initTabTabIndex(self): ''' Retrieve what tab index refer the current tab manager ''' for tabIndex in range(self.gui.tabWidget.count()): if self.gui.tabWidget.tabText(tabIndex) == "Output": self.tabIndex = tabIndex def setProject(self, project=None): ''' setting the new project on which the tab is based ''' self.project = project if self.project: # write everything on disk self.project.sync() # set some globals confFileName = self.project.fileName() self.projectPath = os.path.dirname(confFileName) # emit configurationLoaded with the status of loading self.setTabGUIBasingOnProject() # enable current tab because project has been loaded self.gui.tabWidget.setTabEnabled(self.tabIndex, True) else: # disable current tab because no project has been loaded yet self.gui.tabWidget.setTabEnabled(self.tabIndex, False) def selectNewOutFile(self): ''' Select the the file ''' oldOutputLayer = self.gui.outFile_LEdit.text() # get last conf to start from its path startPath = self.projectPath newOutputLayer = self.project.value( 'Processing.OutputFileDefinition/newOutputLayer', '') if newOutputLayer: startPath = os.path.dirname(newOutputLayer) # ask for the new out file newOutputLayer = QtGui.QFileDialog.getSaveFileName( self.gui, "Select an autput file", startPath, self.plugin.tr("All (*)")) if not newOutputLayer: return if oldOutputLayer == newOutputLayer: return # add shp extension components = os.path.splitext(newOutputLayer) if len(components) == 1: newOutputLayer = newOutputLayer + '.shp' else: if components[1] != '.shp': newOutputLayer = components[0] + '.shp' # update gui self.gui.outFile_LEdit.setText(newOutputLayer) self.saveTabOnProject() def setInputLayer(self): ''' Set GUI basing on toggled ComboBox to set if the layer is the input one or have to select a new one ''' self.gui.outFile_LEdit.setEnabled( self.gui.createNewLayer_RButton.isChecked()) self.gui.selectOutfile_TButton.setEnabled( self.gui.createNewLayer_RButton.isChecked()) def setTabGUIBasingOnProject(self): '''Set tab basing on project conf ''' if not self.project: return # get conf parameters addToInputLayer = self.project.value( 'Processing.OutputFileDefinition/addToInputLayer', False, bool) newOutputLayer = self.project.value( 'Processing.OutputFileDefinition/newOutputLayer', '') Gasoline_Consumption = self.project.value( 'Processing.Parameters/Gasoline_Consumption', False, bool) Diesel_Consumption = self.project.value( 'Processing.Parameters/Diesel_Consumption', False, bool) LPG_Consumption = self.project.value( 'Processing.Parameters/LPG_Consumption', False, bool) NewFuel_Consumption = self.project.value( 'Processing.Parameters/NewFuel_Consumption', False, bool) Fuel_Consumption_Total = self.project.value( 'Processing.Parameters/Fuel_Consumption_Total', False, bool) Energy_Consumption = self.project.value( 'Processing.Parameters/Energy_Consumption', False, bool) CO = self.project.value('Processing.Parameters/CO', False, bool) NOx = self.project.value('Processing.Parameters/NOx', False, bool) NMVOC = self.project.value('Processing.Parameters/NMVOC', False, bool) CO2 = self.project.value('Processing.Parameters/CO2', False, bool) CH4 = self.project.value('Processing.Parameters/CH4', False, bool) N2O = self.project.value('Processing.Parameters/N2O', False, bool) NH3 = self.project.value('Processing.Parameters/NH3', False, bool) SO2 = self.project.value('Processing.Parameters/SO2', False, bool) PM25 = self.project.value('Processing.Parameters/PM', False, bool) C6H6 = self.project.value('Processing.Parameters/C6H6', False, bool) # avoid emitting signal in case of reset of indexes try: # to avoid add multiple listener, remove previous listener self.gui.addToOriginaLayer_RButton.toggled.disconnect( self.saveTabOnProject) self.gui.createNewLayer_RButton.toggled.disconnect( self.saveTabOnProject) self.gui.outFile_LEdit.returnPressed.disconnect( self.saveTabOnProject) self.gui.fuelEnergyConsumptionGasoline_CBox.clicked.disconnect( self.saveTabOnProject) self.gui.fuelEnergyConsumptionDiesel_CBox.clicked.disconnect( self.saveTabOnProject) self.gui.fuelEnergyConsumptionLPG_CBox.clicked.disconnect( self.saveTabOnProject) self.gui.fuelEnergyConsumptionNewFuels_CBox.clicked.disconnect( self.saveTabOnProject) self.gui.totalFuelConsumption_CBox.clicked.disconnect( self.saveTabOnProject) self.gui.energyConsumption_CBox.clicked.disconnect( self.saveTabOnProject) self.gui.pollutantsCO_CBox.clicked.disconnect( self.saveTabOnProject) self.gui.pollutantsNOx_CBox.clicked.disconnect( self.saveTabOnProject) self.gui.pollutantsNMVOCs_CBox.clicked.disconnect( self.saveTabOnProject) self.gui.pollutantsCO2_CBox.clicked.disconnect( self.saveTabOnProject) self.gui.pollutantsCH4_CBox.clicked.disconnect( self.saveTabOnProject) self.gui.pollutantsN2O_CBox.clicked.disconnect( self.saveTabOnProject) self.gui.pollutantsNH3_CBox.clicked.disconnect( self.saveTabOnProject) self.gui.pollutantsSO2_CBox.clicked.disconnect( self.saveTabOnProject) self.gui.pollutantsPM25_CBox.clicked.disconnect( self.saveTabOnProject) self.gui.pollutantsC6H6_CBox.clicked.disconnect( self.saveTabOnProject) except (Exception) as ex: pass # now populate interface self.gui.addToOriginaLayer_RButton.setChecked(addToInputLayer) self.gui.createNewLayer_RButton.setChecked(not addToInputLayer) self.gui.outFile_LEdit.setText(newOutputLayer) self.gui.fuelEnergyConsumptionGasoline_CBox.setChecked( Gasoline_Consumption) self.gui.fuelEnergyConsumptionDiesel_CBox.setChecked( Diesel_Consumption) self.gui.fuelEnergyConsumptionLPG_CBox.setChecked(LPG_Consumption) self.gui.fuelEnergyConsumptionNewFuels_CBox.setChecked( NewFuel_Consumption) self.gui.totalFuelConsumption_CBox.setChecked(Fuel_Consumption_Total) self.gui.energyConsumption_CBox.setChecked(Energy_Consumption) self.gui.pollutantsCO_CBox.setChecked(CO) self.gui.pollutantsNOx_CBox.setChecked(NOx) self.gui.pollutantsNMVOCs_CBox.setChecked(NMVOC) self.gui.pollutantsCO2_CBox.setChecked(CO2) self.gui.pollutantsCH4_CBox.setChecked(CH4) self.gui.pollutantsN2O_CBox.setChecked(N2O) self.gui.pollutantsNH3_CBox.setChecked(NH3) self.gui.pollutantsSO2_CBox.setChecked(SO2) self.gui.pollutantsPM25_CBox.setChecked(PM25) self.gui.pollutantsC6H6_CBox.setChecked(C6H6) # add all modification events to notify project modification self.gui.addToOriginaLayer_RButton.toggled.connect( self.saveTabOnProject) self.gui.createNewLayer_RButton.toggled.connect(self.saveTabOnProject) self.gui.outFile_LEdit.returnPressed.connect(self.saveTabOnProject) self.gui.fuelEnergyConsumptionGasoline_CBox.clicked.connect( self.saveTabOnProject) self.gui.fuelEnergyConsumptionDiesel_CBox.clicked.connect( self.saveTabOnProject) self.gui.fuelEnergyConsumptionLPG_CBox.clicked.connect( self.saveTabOnProject) self.gui.fuelEnergyConsumptionNewFuels_CBox.clicked.connect( self.saveTabOnProject) self.gui.totalFuelConsumption_CBox.clicked.connect( self.saveTabOnProject) self.gui.energyConsumption_CBox.clicked.connect(self.saveTabOnProject) self.gui.pollutantsCO_CBox.clicked.connect(self.saveTabOnProject) self.gui.pollutantsNOx_CBox.clicked.connect(self.saveTabOnProject) self.gui.pollutantsNMVOCs_CBox.clicked.connect(self.saveTabOnProject) self.gui.pollutantsCO2_CBox.clicked.connect(self.saveTabOnProject) self.gui.pollutantsCH4_CBox.clicked.connect(self.saveTabOnProject) self.gui.pollutantsN2O_CBox.clicked.connect(self.saveTabOnProject) self.gui.pollutantsNH3_CBox.clicked.connect(self.saveTabOnProject) self.gui.pollutantsSO2_CBox.clicked.connect(self.saveTabOnProject) self.gui.pollutantsPM25_CBox.clicked.connect(self.saveTabOnProject) self.gui.pollutantsC6H6_CBox.clicked.connect(self.saveTabOnProject) # if and output file is specified and it's available => load it if newOutputLayer and os.path.exists(newOutputLayer): # check if layer is already loaded in layer list checking it's source found = False for layerName, layer in QgsMapLayerRegistry.instance().mapLayers( ).items(): if newOutputLayer == layer.publicSource(): # set the found layer as roadLayer self.outLayer = layer self.outLayerId = self.outLayer.id() found = True break if not found: # get layer name to set as public name in the legend layerName = os.path.splitext( os.path.basename(newOutputLayer))[0] # load layer self.outLayer = QgsVectorLayer(newOutputLayer, layerName, 'ogr') if not self.outLayer.isValid(): message = self.tr( "Error loading layer: %s" % self.outLayer.error().message(QgsErrorMessage.Text)) iface.messageBar().pushMessage(message, QgsMessageBar.CRITICAL) return self.outLayerId = self.outLayer.id() # show layer in the canvas QgsMapLayerRegistry.instance().addMapLayer(self.outLayer) def saveTabOnProject(self): ''' Save tab configuration in the project basing on GUI values ''' # get values from the GUI addToInputLayer = self.gui.addToOriginaLayer_RButton.isChecked() newOutputLayer = self.gui.outFile_LEdit.text() Gasoline_Consumption = self.gui.fuelEnergyConsumptionGasoline_CBox.isChecked( ) Diesel_Consumption = self.gui.fuelEnergyConsumptionDiesel_CBox.isChecked( ) LPG_Consumption = self.gui.fuelEnergyConsumptionLPG_CBox.isChecked() NewFuel_Consumption = self.gui.fuelEnergyConsumptionNewFuels_CBox.isChecked( ) Fuel_Consumption_Total = self.gui.totalFuelConsumption_CBox.isChecked() Energy_Consumption = self.gui.energyConsumption_CBox.isChecked() CO = self.gui.pollutantsCO_CBox.isChecked() NOx = self.gui.pollutantsNOx_CBox.isChecked() NMVOC = self.gui.pollutantsNMVOCs_CBox.isChecked() CO2 = self.gui.pollutantsCO2_CBox.isChecked() CH4 = self.gui.pollutantsCH4_CBox.isChecked() N2O = self.gui.pollutantsN2O_CBox.isChecked() NH3 = self.gui.pollutantsNH3_CBox.isChecked() SO2 = self.gui.pollutantsSO2_CBox.isChecked() PM25 = self.gui.pollutantsPM25_CBox.isChecked() C6H6 = self.gui.pollutantsC6H6_CBox.isChecked() # set conf parameters self.project.setValue( 'Processing.OutputFileDefinition/addToInputLayer', int(addToInputLayer)) self.project.setValue('Processing.OutputFileDefinition/newOutputLayer', newOutputLayer) self.project.setValue('Processing.Parameters/Gasoline_Consumption', int(Gasoline_Consumption)) self.project.setValue('Processing.Parameters/Diesel_Consumption', int(Diesel_Consumption)) self.project.setValue('Processing.Parameters/LPG_Consumption', int(LPG_Consumption)) self.project.setValue('Processing.Parameters/NewFuel_Consumption', int(NewFuel_Consumption)) self.project.setValue('Processing.Parameters/Fuel_Consumption_Total', int(Fuel_Consumption_Total)) self.project.setValue('Processing.Parameters/Energy_Consumption', int(Energy_Consumption)) self.project.setValue('Processing.Parameters/CO', int(CO)) self.project.setValue('Processing.Parameters/NOx', int(NOx)) self.project.setValue('Processing.Parameters/NMVOC', int(NMVOC)) self.project.setValue('Processing.Parameters/CO2', int(CO2)) self.project.setValue('Processing.Parameters/CH4', int(CH4)) self.project.setValue('Processing.Parameters/N2O', int(N2O)) self.project.setValue('Processing.Parameters/NH3', int(NH3)) self.project.setValue('Processing.Parameters/SO2', int(SO2)) self.project.setValue('Processing.Parameters/PM', int(PM25)) self.project.setValue('Processing.Parameters/C6H6', int(C6H6)) # notify project modification self.projectModified.emit() def calculate(self): ''' Prepare environment to run the alg and run it. After run, merge produced data basing on plugin configuration. Before calculation a parametere validation will be executed ''' # perform validation if not self.gui.validate(): return else: # notify successful validation message = self.tr( "QTraffic: Parameters validation passed successfully") iface.messageBar().pushMessage(message, QgsMessageBar.SUCCESS) # set number of classes in the project config (that is the temporary one... but equal to the official one) fleetDistributionRoadTypes = self.gui.getRoadTypes() self.project.setValue('Processing.Parameters/maximum_type', len(fleetDistributionRoadTypes)) self.project.sync() # create the algorithm self.alg = Algorithm() roadLayer = self.gui.getRoadLayer() # prepare layer where to add result addToInputLayer = self.gui.addToOriginaLayer_RButton.isChecked() newOutputLayer = self.gui.outFile_LEdit.text() if addToInputLayer: self.outLayer = roadLayer self.outLayerId = self.outLayer.id() else: # if layer is present... remove it # out layer would not be the same of input road layer... in thi scase don't remove it if self.outLayer and self.outLayer.isValid(): # to be sure, remove only if roadLayer and outLayer are different if self.outLayer.publicSource() != roadLayer.publicSource(): self.outLayerRemoved = False QgsMapLayerRegistry.instance().layerRemoved.connect( self.checkOutLayerRemoved) QgsMapLayerRegistry.instance().removeMapLayer( self.outLayer.id()) # remove file when it has been removed from qgis while not self.outLayerRemoved: sleep(0.1) QgsMapLayerRegistry.instance().layerRemoved.disconnect( self.checkOutLayerRemoved) # reinit outLayer variables # If not, under windws remain a locking of the related file creating # an error during QgsVectorFileWriter.deleteShapeFile self.outLayer = None self.outLayerId = None if os.path.exists(newOutputLayer): if not QgsVectorFileWriter.deleteShapeFile( newOutputLayer): message = self.tr( "Error removing shape: {}".format( newOutputLayer)) iface.messageBar().pushMessage( message, QgsMessageBar.CRITICAL) return # copy input layer to the new one writeError = QgsVectorFileWriter.writeAsVectorFormat( roadLayer, newOutputLayer, 'utf-8', roadLayer.crs()) if writeError != QgsVectorFileWriter.NoError: message = self.tr( 'Error writing vector file {}'.format(newOutputLayer)) QgsMessageLog.logMessage(message, 'QTraffic', QgsMessageLog.CRITICAL) iface.messageBar().pushCritical('QTraffic', message) return # load the layer newLayerName = os.path.splitext( os.path.basename(newOutputLayer))[0] self.outLayer = QgsVectorLayer(newOutputLayer, newLayerName, 'ogr') if not self.outLayer.isValid(): message = self.tr( 'Error loading vector file {}'.format(newOutputLayer)) QgsMessageLog.logMessage(message, 'QTraffic', QgsMessageLog.CRITICAL) iface.messageBar().pushCritical('QTraffic', message) return self.outLayerId = self.outLayer.id() # prepare environment try: self.alg.setProject(self.project) self.alg.setLayer(roadLayer) self.alg.initConfig() self.alg.prepareRun() except Exception as ex: traceback.print_exc() message = self.tr( 'Error preparing running contex for the algoritm: %s' % str(ex)) QgsMessageLog.logMessage(message, 'QTraffic', QgsMessageLog.CRITICAL) iface.messageBar().pushCritical('QTraffic', message) return # run the self.alg self.thread = QtCore.QThread(self) self.thread.started.connect(self.alg.run) self.thread.finished.connect(self.threadCleanup) self.thread.terminated.connect(self.threadCleanup) self.alg.moveToThread(self.thread) self.alg.started.connect(self.manageStarted) self.alg.progress.connect(self.manageProgress) self.alg.message.connect(self.manageMessage) self.alg.error.connect(self.manageError) self.alg.finished.connect(self.manageFinished) # set wait cursor and start QgsApplication.instance().setOverrideCursor(QtCore.Qt.WaitCursor) self.thread.start() def checkOutLayerRemoved(self, layerId): ''' check when outLayer has been removed settign semaphore to True ''' if self.outLayerId == layerId: QgsMessageLog.logMessage('Completly removed outLayer', 'QTraffic', QgsMessageLog.INFO) self.outLayerRemoved = True def threadCleanup(self): ''' cleanup after thread run ''' # restore cursor QgsApplication.instance().restoreOverrideCursor() if self.alg: self.alg.deleteLater() self.alg = None self.thread.wait() self.thread.deleteLater() # remove progress bar if self.progressMessageBarItem: iface.messageBar().popWidget(self.progressMessageBarItem) self.progressMessageBarItem = None def manageStarted(self): ''' Setup GUI env to notify processing progress ''' message = self.tr('Processing started') QgsMessageLog.logMessage(message, 'QTraffic', QgsMessageLog.INFO) # create message bar to show progress self.progressMessageBarItem = iface.messageBar().createMessage( self.tr('Executing alg')) self.progress = QtGui.QProgressBar() self.progress.setMaximum(0) self.progress.setMinimum(0) self.progress.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter) self.progressMessageBarItem.layout().addWidget(self.progress) iface.messageBar().pushWidget(self.progressMessageBarItem, QgsMessageBar.INFO) def manageProgress(self, percentage): ''' Update progress bar basing on alg nofify ''' self.progress.setValue(percentage) def manageMessage(self, message, msgType): ''' expose alg thread messages to gui and log ''' QgsMessageLog.logMessage(message, 'QTraffic', msgType) duration = 0 if msgType == QgsMessageLog.INFO: return if msgType == QgsMessageLog.CRITICAL: msgType = QgsMessageBar.CRITICAL if msgType == QgsMessageLog.WARNING: duration = 3 msgType = QgsMessageBar.WARNING iface.messageBar().pushMessage(message, msgType, duration) def manageError(self, ex, exceptionMessage): ''' Do actions in case of alg thread error. Now only notify exception ''' QgsMessageLog.logMessage(exceptionMessage, 'QTraffic', QgsMessageLog.CRITICAL) iface.messageBar().pushMessage(exceptionMessage, QgsMessageBar.CRITICAL) def manageFinished(self, success, reason): ''' Do action after notify that alg is finished. These are the postprocessing steps 1) merge result to the output layer 2) add the layer to canvas in case it is new 3) notify edn of processing 4) terminate the thread ''' # finish the thread self.thread.quit() # check result if not success: QgsMessageLog.logMessage('Failed execution: {}'.format(reason), 'QTraffic', QgsMessageLog.CRITICAL) iface.messageBar().pushCritical( 'QTraffic', self.tr("Error executing the algorithm: {}".format(reason))) return # prepare result try: self.alg.addResultToLayer(self.outLayer) except Exception as ex: traceback.print_exc() QgsMessageLog.logMessage( 'Cannot add result to layer: {}'.format(str(ex)), 'QTraffic', QgsMessageLog.CRITICAL) iface.messageBar().pushCritical( 'QTraffic', self.tr("Cannot add result to layer")) return # add or refresh rsult vector layer addToInputLayer = self.gui.addToOriginaLayer_RButton.isChecked() if not addToInputLayer: QgsMapLayerRegistry.instance().addMapLayer(self.outLayer) iface.mapCanvas().refresh() # notify the user the end of process iface.messageBar().pushSuccess('QTraffic', self.tr('Alg terminated successfully')) def validate(self): ''' pre calcluation validation related only to this tab Mandatory: At least an output parameters have to be set if "create new layer" a new layer name have to be set ''' addToInputLayer = self.gui.addToOriginaLayer_RButton.isChecked() newOutputLayer = self.gui.outFile_LEdit.text() if (not addToInputLayer and not newOutputLayer): message = self.tr('No output vector specified') iface.messageBar().pushMessage(message, QgsMessageBar.CRITICAL) return False Gasoline_Consumption = self.gui.fuelEnergyConsumptionGasoline_CBox.isChecked( ) Diesel_Consumption = self.gui.fuelEnergyConsumptionDiesel_CBox.isChecked( ) LPG_Consumption = self.gui.fuelEnergyConsumptionLPG_CBox.isChecked() NewFuel_Consumption = self.gui.fuelEnergyConsumptionNewFuels_CBox.isChecked( ) Fuel_Consumption_Total = self.gui.totalFuelConsumption_CBox.isChecked() Energy_Consumption = self.gui.energyConsumption_CBox.isChecked() CO = self.gui.pollutantsCO_CBox.isChecked() NOx = self.gui.pollutantsNOx_CBox.isChecked() NMVOC = self.gui.pollutantsNMVOCs_CBox.isChecked() CO2 = self.gui.pollutantsCO2_CBox.isChecked() CH4 = self.gui.pollutantsCH4_CBox.isChecked() N2O = self.gui.pollutantsN2O_CBox.isChecked() NH3 = self.gui.pollutantsNH3_CBox.isChecked() SO2 = self.gui.pollutantsSO2_CBox.isChecked() PM25 = self.gui.pollutantsPM25_CBox.isChecked() C6H6 = self.gui.pollutantsC6H6_CBox.isChecked() if (not Gasoline_Consumption and not Diesel_Consumption and not LPG_Consumption and not NewFuel_Consumption and not Fuel_Consumption_Total and not Energy_Consumption and not CO and not NOx and not NMVOC and not CO2 and not CH4 and not N2O and not NH3 and not SO2 and not PM25 and not C6H6): message = self.tr( "Validation error: At least an output parameter have to be selected" ) iface.messageBar().pushMessage(message, QgsMessageBar.CRITICAL) return False return True def tr(self, string, context=''): if not context: context = 'QTraffic' return QtCore.QCoreApplication.translate(context, string)
def testCreateExpression(self): """ Test creating an expression using the widget""" layer = QgsVectorLayer( "Point?field=fldtxt:string&field=fldint:integer", "test", "memory") # setup value relation parent_layer = QgsVectorLayer( "Point?field=stringkey:string&field=intkey:integer&field=display:string", "parent", "memory") f1 = QgsFeature(parent_layer.fields(), 1) f1.setAttributes(['a', 1, 'value a']) f2 = QgsFeature(parent_layer.fields(), 2) f2.setAttributes(['b', 2, 'value b']) f3 = QgsFeature(parent_layer.fields(), 3) f3.setAttributes(['c', 3, 'value c']) parent_layer.dataProvider().addFeatures([f1, f2, f3]) QgsProject.instance().addMapLayers([layer, parent_layer]) config = { "Layer": parent_layer.id(), "Key": 'stringkey', "Value": 'display' } w = QgsValueRelationSearchWidgetWrapper(layer, 0) w.setConfig(config) c = w.widget() # first, set it to the "select value" item c.setCurrentIndex(0) self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.IsNull), '"fldtxt" IS NULL') self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.IsNotNull), '"fldtxt" IS NOT NULL') self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.EqualTo), '') self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.NotEqualTo), '') c.setCurrentIndex(1) self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.IsNull), '"fldtxt" IS NULL') self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.IsNotNull), '"fldtxt" IS NOT NULL') self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.EqualTo), '"fldtxt"=\'a\'') self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.NotEqualTo), '"fldtxt"<>\'a\'') c.setCurrentIndex(2) self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.IsNull), '"fldtxt" IS NULL') self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.IsNotNull), '"fldtxt" IS NOT NULL') self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.EqualTo), '"fldtxt"=\'b\'') self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.NotEqualTo), '"fldtxt"<>\'b\'') # try with numeric field w = QgsValueRelationSearchWidgetWrapper(layer, 1) config['Key'] = 'intkey' w.setConfig(config) c = w.widget() c.setCurrentIndex(c.findText('value c')) self.assertEqual(c.currentIndex(), 3) self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.IsNull), '"fldint" IS NULL') self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.IsNotNull), '"fldint" IS NOT NULL') self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.EqualTo), '"fldint"=3') self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.NotEqualTo), '"fldint"<>3') # try with allow null set w = QgsValueRelationSearchWidgetWrapper(layer, 1) config['AllowNull'] = True w.setConfig(config) c = w.widget() c.setCurrentIndex(c.findText('value c')) self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.IsNull), '"fldint" IS NULL') self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.IsNotNull), '"fldint" IS NOT NULL') self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.EqualTo), '"fldint"=3') self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.NotEqualTo), '"fldint"<>3') # try with line edit w = QgsValueRelationSearchWidgetWrapper(layer, 1) config['UseCompleter'] = True w.setConfig(config) l = w.widget() l.setText('value b') self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.IsNull), '"fldint" IS NULL') self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.IsNotNull), '"fldint" IS NOT NULL') self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.EqualTo), '"fldint"=2') self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.NotEqualTo), '"fldint"<>2')
class TestLayerDependencies(unittest.TestCase): @classmethod def setUpClass(cls): """Run before all tests""" # create a temp spatialite db with a trigger fo = tempfile.NamedTemporaryFile() fn = fo.name fo.close() cls.fn = fn con = spatialite_connect(fn) cur = con.cursor() cur.execute("SELECT InitSpatialMetadata(1)") cur.execute("create table node(id integer primary key autoincrement);") cur.execute("select AddGeometryColumn('node', 'geom', 4326, 'POINT');") cur.execute( "create table section(id integer primary key autoincrement, node1 integer, node2 integer);" ) cur.execute( "select AddGeometryColumn('section', 'geom', 4326, 'LINESTRING');") cur.execute( "create trigger add_nodes after insert on section begin insert into node (geom) values (st_startpoint(NEW.geom)); insert into node (geom) values (st_endpoint(NEW.geom)); end;" ) cur.execute( "insert into node (geom) values (geomfromtext('point(0 0)', 4326));" ) cur.execute( "insert into node (geom) values (geomfromtext('point(1 0)', 4326));" ) cur.execute( "create table node2(id integer primary key autoincrement);") cur.execute( "select AddGeometryColumn('node2', 'geom', 4326, 'POINT');") cur.execute( "create trigger add_nodes2 after insert on node begin insert into node2 (geom) values (st_translate(NEW.geom, 0.2, 0, 0)); end;" ) con.commit() con.close() cls.pointsLayer = QgsVectorLayer( "dbname='%s' table=\"node\" (geom) sql=" % fn, "points", "spatialite") assert (cls.pointsLayer.isValid()) cls.linesLayer = QgsVectorLayer( "dbname='%s' table=\"section\" (geom) sql=" % fn, "lines", "spatialite") assert (cls.linesLayer.isValid()) cls.pointsLayer2 = QgsVectorLayer( "dbname='%s' table=\"node2\" (geom) sql=" % fn, "_points2", "spatialite") assert (cls.pointsLayer2.isValid()) QgsProject.instance().addMapLayers( [cls.pointsLayer, cls.linesLayer, cls.pointsLayer2]) # save the project file fo = tempfile.NamedTemporaryFile() fn = fo.name fo.close() cls.projectFile = fn QgsProject.instance().setFileName(cls.projectFile) QgsProject.instance().write() @classmethod def tearDownClass(cls): """Run after all tests""" pass def setUp(self): """Run before each test.""" pass def tearDown(self): """Run after each test.""" pass def test_resetSnappingIndex(self): self.pointsLayer.setDependencies([]) self.linesLayer.setDependencies([]) self.pointsLayer2.setDependencies([]) ms = QgsMapSettings() ms.setOutputSize(QSize(100, 100)) ms.setExtent(QgsRectangle(0, 0, 1, 1)) self.assertTrue(ms.hasValidSettings()) u = QgsSnappingUtils() u.setMapSettings(ms) cfg = u.config() cfg.setEnabled(True) cfg.setMode(QgsSnappingConfig.AdvancedConfiguration) cfg.setIndividualLayerSettings( self.pointsLayer, QgsSnappingConfig.IndividualLayerSettings(True, QgsSnappingConfig.Vertex, 20, QgsTolerance.Pixels)) u.setConfig(cfg) m = u.snapToMap(QPoint(95, 100)) self.assertTrue(m.isValid()) self.assertTrue(m.hasVertex()) self.assertEqual(m.point(), QgsPoint(1, 0)) f = QgsFeature(self.linesLayer.fields()) f.setId(1) geom = QgsGeometry.fromWkt("LINESTRING(0 0,1 1)") f.setGeometry(geom) self.linesLayer.startEditing() self.linesLayer.addFeatures([f]) self.linesLayer.commitChanges() l1 = len([f for f in self.pointsLayer.getFeatures()]) self.assertEqual(l1, 4) m = u.snapToMap(QPoint(95, 0)) # snapping not updated self.pointsLayer.setDependencies([]) self.assertEqual(m.isValid(), False) # set layer dependencies self.pointsLayer.setDependencies( [QgsMapLayerDependency(self.linesLayer.id())]) # add another line f = QgsFeature(self.linesLayer.fields()) f.setId(2) geom = QgsGeometry.fromWkt("LINESTRING(0 0,0.5 0.5)") f.setGeometry(geom) self.linesLayer.startEditing() self.linesLayer.addFeatures([f]) self.linesLayer.commitChanges() # check the snapped point is ok m = u.snapToMap(QPoint(45, 50)) self.assertTrue(m.isValid()) self.assertTrue(m.hasVertex()) self.assertEqual(m.point(), QgsPoint(0.5, 0.5)) self.pointsLayer.setDependencies([]) # test chained layer dependencies A -> B -> C cfg.setIndividualLayerSettings( self.pointsLayer2, QgsSnappingConfig.IndividualLayerSettings(True, QgsSnappingConfig.Vertex, 20, QgsTolerance.Pixels)) u.setConfig(cfg) self.pointsLayer.setDependencies( [QgsMapLayerDependency(self.linesLayer.id())]) self.pointsLayer2.setDependencies( [QgsMapLayerDependency(self.pointsLayer.id())]) # add another line f = QgsFeature(self.linesLayer.fields()) f.setId(3) geom = QgsGeometry.fromWkt("LINESTRING(0 0.2,0.5 0.8)") f.setGeometry(geom) self.linesLayer.startEditing() self.linesLayer.addFeatures([f]) self.linesLayer.commitChanges() # check the second snapped point is ok m = u.snapToMap(QPoint(75, 100 - 80)) self.assertTrue(m.isValid()) self.assertTrue(m.hasVertex()) self.assertEqual(m.point(), QgsPoint(0.7, 0.8)) self.pointsLayer.setDependencies([]) self.pointsLayer2.setDependencies([]) def test_cycleDetection(self): self.assertTrue( self.pointsLayer.setDependencies( [QgsMapLayerDependency(self.linesLayer.id())])) self.assertFalse( self.linesLayer.setDependencies( [QgsMapLayerDependency(self.pointsLayer.id())])) self.pointsLayer.setDependencies([]) self.linesLayer.setDependencies([]) def test_layerDefinitionRewriteId(self): tmpfile = os.path.join(tempfile.tempdir, "test.qlr") ltr = QgsProject.instance().layerTreeRoot() self.pointsLayer.setDependencies( [QgsMapLayerDependency(self.linesLayer.id())]) QgsLayerDefinition.exportLayerDefinition(tmpfile, [ltr]) grp = ltr.addGroup("imported") QgsLayerDefinition.loadLayerDefinition(tmpfile, QgsProject.instance(), grp) newPointsLayer = None newLinesLayer = None for l in grp.findLayers(): if l.layerId().startswith('points'): newPointsLayer = l.layer() elif l.layerId().startswith('lines'): newLinesLayer = l.layer() self.assertIsNotNone(newPointsLayer) self.assertIsNotNone(newLinesLayer) self.assertTrue(newLinesLayer.id( ) in [dep.layerId() for dep in newPointsLayer.dependencies()]) self.pointsLayer.setDependencies([]) def test_signalConnection(self): # remove all layers QgsProject.instance().removeAllMapLayers() # set dependencies and add back layers self.pointsLayer = QgsVectorLayer( "dbname='%s' table=\"node\" (geom) sql=" % self.fn, "points", "spatialite") assert (self.pointsLayer.isValid()) self.linesLayer = QgsVectorLayer( "dbname='%s' table=\"section\" (geom) sql=" % self.fn, "lines", "spatialite") assert (self.linesLayer.isValid()) self.pointsLayer2 = QgsVectorLayer( "dbname='%s' table=\"node2\" (geom) sql=" % self.fn, "_points2", "spatialite") assert (self.pointsLayer2.isValid()) self.pointsLayer.setDependencies( [QgsMapLayerDependency(self.linesLayer.id())]) self.pointsLayer2.setDependencies( [QgsMapLayerDependency(self.pointsLayer.id())]) # this should update connections between layers QgsProject.instance().addMapLayers([self.pointsLayer]) QgsProject.instance().addMapLayers([self.linesLayer]) QgsProject.instance().addMapLayers([self.pointsLayer2]) ms = QgsMapSettings() ms.setOutputSize(QSize(100, 100)) ms.setExtent(QgsRectangle(0, 0, 1, 1)) self.assertTrue(ms.hasValidSettings()) u = QgsSnappingUtils() u.setMapSettings(ms) cfg = u.config() cfg.setEnabled(True) cfg.setMode(QgsSnappingConfig.AdvancedConfiguration) cfg.setIndividualLayerSettings( self.pointsLayer, QgsSnappingConfig.IndividualLayerSettings(True, QgsSnappingConfig.Vertex, 20, QgsTolerance.Pixels)) cfg.setIndividualLayerSettings( self.pointsLayer2, QgsSnappingConfig.IndividualLayerSettings(True, QgsSnappingConfig.Vertex, 20, QgsTolerance.Pixels)) u.setConfig(cfg) # add another line f = QgsFeature(self.linesLayer.fields()) f.setId(4) geom = QgsGeometry.fromWkt("LINESTRING(0.5 0.2,0.6 0)") f.setGeometry(geom) self.linesLayer.startEditing() self.linesLayer.addFeatures([f]) self.linesLayer.commitChanges() # check the second snapped point is ok m = u.snapToMap(QPoint(75, 100 - 0)) self.assertTrue(m.isValid()) self.assertTrue(m.hasVertex()) self.assertEqual(m.point(), QgsPoint(0.8, 0.0)) self.pointsLayer.setDependencies([]) self.pointsLayer2.setDependencies([])
def testExpressionInText(self): """Test expressions embedded in legend node text""" point_path = os.path.join(TEST_DATA_DIR, 'points.shp') point_layer = QgsVectorLayer(point_path, 'points', 'ogr') layout = QgsPrintLayout(QgsProject.instance()) layout.setName('LAYOUT') layout.initializeDefaults() map = QgsLayoutItemMap(layout) map.attemptSetSceneRect(QRectF(20, 20, 80, 80)) map.setFrameEnabled(True) map.setLayers([point_layer]) layout.addLayoutItem(map) map.setExtent(point_layer.extent()) legend = QgsLayoutItemLegend(layout) legend.setTitle("Legend") legend.attemptSetSceneRect(QRectF(120, 20, 100, 100)) legend.setFrameEnabled(True) legend.setFrameStrokeWidth(QgsLayoutMeasurement(2)) legend.setBackgroundColor(QColor(200, 200, 200)) legend.setTitle('') legend.setLegendFilterByMapEnabled(False) legend.setStyleFont(QgsLegendStyle.Title, QgsFontUtils.getStandardTestFont('Bold', 16)) legend.setStyleFont(QgsLegendStyle.Group, QgsFontUtils.getStandardTestFont('Bold', 16)) legend.setStyleFont(QgsLegendStyle.Subgroup, QgsFontUtils.getStandardTestFont('Bold', 16)) legend.setStyleFont(QgsLegendStyle.Symbol, QgsFontUtils.getStandardTestFont('Bold', 16)) legend.setStyleFont(QgsLegendStyle.SymbolLabel, QgsFontUtils.getStandardTestFont('Bold', 16)) legend.setAutoUpdateModel(False) QgsProject.instance().addMapLayers([point_layer]) s = QgsMapSettings() s.setLayers([point_layer]) group = legend.model().rootGroup().addGroup( "Group [% 1 + 5 %] [% @layout_name %]") layer_tree_layer = group.addLayer(point_layer) layer_tree_layer.setCustomProperty( "legend/title-label", 'bbbb [% 1+2 %] xx [% @layout_name %] [% @layer_name %]') QgsMapLayerLegendUtils.setLegendNodeUserLabel(layer_tree_layer, 0, 'xxxx') legend.model().refreshLayerLegend(layer_tree_layer) legend.model().layerLegendNodes(layer_tree_layer)[0].setUserLabel( 'bbbb [% 1+2 %] xx [% @layout_name %] [% @layer_name %]') layout.addLayoutItem(legend) legend.setLinkedMap(map) map.setExtent(QgsRectangle(-102.51, 41.16, -102.36, 41.30)) checker = QgsLayoutChecker('composer_legend_expressions', layout) checker.setControlPathPrefix("composer_legend") result, message = checker.testLayout() self.assertTrue(result, message) QgsProject.instance().removeMapLayers([point_layer.id()])
def testDistance(self): self.checkConstructWrapper(QgsProcessingParameterDistance('test'), DistanceWidgetWrapper) alg = QgsApplication.processingRegistry().algorithmById( 'native:centroids') dlg = AlgorithmDialog(alg) param = QgsProcessingParameterDistance('test') wrapper = DistanceWidgetWrapper(param, dlg) widget = wrapper.createWidget() # test units widget.show() # crs values widget.setUnitParameterValue('EPSG:3111') self.assertEqual(widget.label.text(), 'meters') self.assertFalse(widget.warning_label.isVisible()) self.assertTrue(widget.units_combo.isVisible()) self.assertFalse(widget.label.isVisible()) self.assertEqual(widget.units_combo.currentData(), QgsUnitTypes.DistanceMeters) widget.setUnitParameterValue('EPSG:4326') self.assertEqual(widget.label.text(), 'degrees') self.assertTrue(widget.warning_label.isVisible()) self.assertFalse(widget.units_combo.isVisible()) self.assertTrue(widget.label.isVisible()) widget.setUnitParameterValue(QgsCoordinateReferenceSystem('EPSG:3111')) self.assertEqual(widget.label.text(), 'meters') self.assertFalse(widget.warning_label.isVisible()) self.assertTrue(widget.units_combo.isVisible()) self.assertFalse(widget.label.isVisible()) self.assertEqual(widget.units_combo.currentData(), QgsUnitTypes.DistanceMeters) widget.setUnitParameterValue(QgsCoordinateReferenceSystem('EPSG:4326')) self.assertEqual(widget.label.text(), 'degrees') self.assertTrue(widget.warning_label.isVisible()) self.assertFalse(widget.units_combo.isVisible()) self.assertTrue(widget.label.isVisible()) # layer values vl = QgsVectorLayer("Polygon?crs=epsg:3111&field=pk:int", "vl", "memory") widget.setUnitParameterValue(vl) self.assertEqual(widget.label.text(), 'meters') self.assertFalse(widget.warning_label.isVisible()) self.assertTrue(widget.units_combo.isVisible()) self.assertFalse(widget.label.isVisible()) self.assertEqual(widget.units_combo.currentData(), QgsUnitTypes.DistanceMeters) vl2 = QgsVectorLayer("Polygon?crs=epsg:4326&field=pk:int", "vl", "memory") widget.setUnitParameterValue(vl2) self.assertEqual(widget.label.text(), 'degrees') self.assertTrue(widget.warning_label.isVisible()) self.assertFalse(widget.units_combo.isVisible()) self.assertTrue(widget.label.isVisible()) # unresolvable values widget.setUnitParameterValue(vl.id()) self.assertEqual(widget.label.text(), '<unknown>') self.assertFalse(widget.warning_label.isVisible()) self.assertFalse(widget.units_combo.isVisible()) self.assertTrue(widget.label.isVisible()) # resolvable text value QgsProject.instance().addMapLayer(vl) widget.setUnitParameterValue(vl.id()) self.assertEqual(widget.label.text(), 'meters') self.assertFalse(widget.warning_label.isVisible()) self.assertTrue(widget.units_combo.isVisible()) self.assertFalse(widget.label.isVisible()) self.assertEqual(widget.units_combo.currentData(), QgsUnitTypes.DistanceMeters) widget.setValue(5) self.assertEqual(widget.getValue(), 5) widget.units_combo.setCurrentIndex( widget.units_combo.findData(QgsUnitTypes.DistanceKilometers)) self.assertEqual(widget.getValue(), 5000) widget.setValue(2) self.assertEqual(widget.getValue(), 2000) widget.setUnitParameterValue(vl.id()) self.assertEqual(widget.getValue(), 2) widget.setValue(5) self.assertEqual(widget.getValue(), 5) widget.deleteLater()
def test_settings_round_trip(self): # pylint: disable=too-many-statements """ Test setting and retrieving settings results in identical results """ layer_path = os.path.join( os.path.dirname(__file__), 'test_layer.geojson') vl1 = QgsVectorLayer(layer_path, 'test_layer', 'ogr') vl2 = QgsVectorLayer(layer_path, 'test_layer1', 'ogr') vl3 = QgsVectorLayer(layer_path, 'test_layer2', 'ogr') QgsProject.instance().addMapLayers([vl1, vl2, vl3]) dialog = DataPlotlyPanelWidget(None, override_iface=IFACE) settings = dialog.get_settings() # default should be scatter plot self.assertEqual(settings.plot_type, 'scatter') # print('dialog loaded') # customise settings settings.plot_type = 'bar' settings.properties['name'] = 'my legend title' settings.properties['hover_text'] = 'y' settings.properties['box_orientation'] = 'h' settings.properties['normalization'] = 'probability' settings.properties['box_stat'] = 'sd' settings.properties['box_outliers'] = 'suspectedoutliers' settings.properties['violin_side'] = 'negative' settings.properties['show_mean_line'] = True settings.properties['cumulative'] = True settings.properties['invert_hist'] = 'decreasing' settings.source_layer_id = vl3.id() settings.properties['x_name'] = 'so4' settings.properties['y_name'] = 'ca' settings.properties['z_name'] = 'mg' settings.properties['color_scale'] = 'Earth' settings.properties['violin_box'] = True settings.properties['layout_filter_by_map'] = True settings.properties['layout_filter_by_atlas'] = True # TODO: likely need to test other settings.properties values here! settings.layout['legend'] = False settings.layout['legend_orientation'] = 'h' settings.layout['title'] = 'my title' settings.layout['x_title'] = 'my x title' settings.layout['y_title'] = 'my y title' settings.layout['z_title'] = 'my z title' settings.layout['range_slider']['visible'] = True settings.layout['bar_mode'] = 'overlay' settings.layout['x_type'] = 'log' settings.layout['y_type'] = 'category' settings.layout['x_inv'] = 'reversed' settings.layout['y_inv'] = 'reversed' settings.layout['bargaps'] = 0.8 settings.layout['additional_info_expression'] = '1+2' settings.layout['bins_check'] = True settings.layout['gridcolor'] = '#bdbfc0' settings.data_defined_properties.setProperty(PlotSettings.PROPERTY_FILTER, QgsProperty.fromExpression('"ap">50')) settings.data_defined_properties.setProperty(PlotSettings.PROPERTY_MARKER_SIZE, QgsProperty.fromExpression('5+64')) settings.data_defined_properties.setProperty(PlotSettings.PROPERTY_COLOR, QgsProperty.fromExpression("'red'")) settings.data_defined_properties.setProperty(PlotSettings.PROPERTY_STROKE_WIDTH, QgsProperty.fromExpression("12/2")) settings.data_defined_properties.setProperty(PlotSettings.PROPERTY_TITLE, QgsProperty.fromExpression("concat('my', '_title_', @some_var)")) settings.data_defined_properties.setProperty(PlotSettings.PROPERTY_LEGEND_TITLE, QgsProperty.fromExpression("concat('my', '_legend_', @some_var)")) settings.data_defined_properties.setProperty(PlotSettings.PROPERTY_X_TITLE, QgsProperty.fromExpression("concat('my', '_x_axis_', @some_var)")) settings.data_defined_properties.setProperty(PlotSettings.PROPERTY_Y_TITLE, QgsProperty.fromExpression("concat('my', '_y_axis_', @some_var)")) settings.data_defined_properties.setProperty(PlotSettings.PROPERTY_Z_TITLE, QgsProperty.fromExpression("concat('my', '_z_axis_', @some_var)")) settings.data_defined_properties.setProperty(PlotSettings.PROPERTY_X_MIN, QgsProperty.fromExpression("-1*10")) settings.data_defined_properties.setProperty(PlotSettings.PROPERTY_X_MAX, QgsProperty.fromExpression("+1*10")) settings.data_defined_properties.setProperty(PlotSettings.PROPERTY_Y_MIN, QgsProperty.fromExpression("-1*10")) settings.data_defined_properties.setProperty(PlotSettings.PROPERTY_Y_MAX, QgsProperty.fromExpression("+1*10")) dialog2 = DataPlotlyPanelWidget(None, override_iface=IFACE) dialog2.set_settings(settings) # print('set settings') self.assertEqual(dialog2.get_settings().plot_type, settings.plot_type) for k in settings.properties.keys(): # print(k) if k in ['x', 'y', 'z', 'additional_hover_text', 'featureIds', 'featureBox', 'custom']: continue self.assertEqual(dialog2.get_settings().properties[k], settings.properties[k]) for k in settings.layout.keys(): self.assertEqual(dialog2.get_settings().layout[k], settings.layout[k]) self.assertEqual(dialog2.get_settings().source_layer_id, vl3.id()) self.assertEqual(dialog2.get_settings().data_defined_properties.property(PlotSettings.PROPERTY_FILTER), settings.data_defined_properties.property(PlotSettings.PROPERTY_FILTER)) self.assertEqual(dialog2.get_settings().data_defined_properties.property(PlotSettings.PROPERTY_MARKER_SIZE), settings.data_defined_properties.property(PlotSettings.PROPERTY_MARKER_SIZE)) self.assertEqual(dialog2.get_settings().data_defined_properties.property(PlotSettings.PROPERTY_COLOR), settings.data_defined_properties.property(PlotSettings.PROPERTY_COLOR)) self.assertEqual(dialog2.get_settings().data_defined_properties.property(PlotSettings.PROPERTY_STROKE_WIDTH), settings.data_defined_properties.property(PlotSettings.PROPERTY_STROKE_WIDTH)) self.assertEqual(dialog2.get_settings().data_defined_properties.property(PlotSettings.PROPERTY_X_MIN), settings.data_defined_properties.property(PlotSettings.PROPERTY_X_MIN)) self.assertEqual(dialog2.get_settings().data_defined_properties.property(PlotSettings.PROPERTY_X_MAX), settings.data_defined_properties.property(PlotSettings.PROPERTY_X_MAX)) self.assertEqual(dialog2.get_settings().data_defined_properties.property(PlotSettings.PROPERTY_Y_MIN), settings.data_defined_properties.property(PlotSettings.PROPERTY_Y_MIN)) self.assertEqual(dialog2.get_settings().data_defined_properties.property(PlotSettings.PROPERTY_Y_MAX), settings.data_defined_properties.property(PlotSettings.PROPERTY_Y_MAX)) self.assertEqual(dialog2.get_settings().data_defined_properties.property(PlotSettings.PROPERTY_TITLE), settings.data_defined_properties.property(PlotSettings.PROPERTY_TITLE)) self.assertEqual(dialog2.get_settings().data_defined_properties.property(PlotSettings.PROPERTY_LEGEND_TITLE), settings.data_defined_properties.property(PlotSettings.PROPERTY_LEGEND_TITLE)) self.assertEqual(dialog2.get_settings().data_defined_properties.property(PlotSettings.PROPERTY_X_TITLE), settings.data_defined_properties.property(PlotSettings.PROPERTY_X_TITLE)) self.assertEqual(dialog2.get_settings().data_defined_properties.property(PlotSettings.PROPERTY_Y_TITLE), settings.data_defined_properties.property(PlotSettings.PROPERTY_Y_TITLE)) self.assertEqual(dialog2.get_settings().data_defined_properties.property(PlotSettings.PROPERTY_Z_TITLE), settings.data_defined_properties.property(PlotSettings.PROPERTY_Z_TITLE)) dialog2.deleteLater() del dialog2 settings = dialog.get_settings() dialog.deleteLater() del dialog dialog3 = DataPlotlyPanelWidget(None, override_iface=IFACE) # print('dialog 2') dialog3.set_settings(settings) # print('set settings') self.assertEqual(dialog3.get_settings().plot_type, settings.plot_type) for k in settings.properties.keys(): # print(k) self.assertEqual(dialog3.get_settings().properties[k], settings.properties[k]) self.assertEqual(dialog3.get_settings().properties, settings.properties) for k in settings.layout.keys(): # print(k) self.assertEqual(dialog3.get_settings().layout[k], settings.layout[k]) dialog3.deleteLater() del dialog3 # print('done') QgsProject.instance().clear()