def addParcelleMap(self): ''' Add content in the first page with a map and basic information ''' # First add headers for key, item in list(self.composerTemplates.items()): if 'sticky' in item: self.buildComposerLabel(key, item, 0) # Get feature extent exp = QgsExpression('"geo_parcelle" = \'%s\'' % self.geo_parcelle) request = QgsFeatureRequest(exp) extent = None features = self.layer.getFeatures(request) for feature in features: geom = feature.geometry() peri = geom.length() buf = peri / 20 extent = geom.buffer(buf,5).boundingBox() # Add memory layer to highlight parcelle if extent: if self.redlineLayer: self.mProject.removeMapLayer(self.redlineLayer.id()) crs = self.layer.crs().authid() vl = QgsVectorLayer("Polygon?crs=" + crs, "temporary", "memory") pr = vl.dataProvider() vl.startEditing() pr.addFeatures([f for f in self.layer.getFeatures(request)]) vl.commitChanges() vl.updateExtents() props = vl.renderer().symbol().symbolLayer(0).properties() props['outline_width'] = u'1' props['outline_color'] = u'0,85,255,255' props['outline_style'] = u'solid' props['style'] = u'no' vl.renderer().setSymbol(QgsFillSymbol.createSimple(props)) self.mProject.addMapLayer(vl) self.redlineLayer = vl # Add composer map & to parcelle miLayers = self.mInstance.layers() miLayers.insert( 0, vl ) cm = QgsLayoutItemMap(self.currentComposition) cm.updateBoundingRect() cm.setRect(QRectF(0, 0, 286, 190)) cm.setPos(6,15) cm.setLayers(self.mProject.mapThemeCollection().masterVisibleLayers()) if extent: cm.zoomToExtent(extent) cm.setFrameEnabled(True) cm.setBackgroundEnabled(True) self.currentComposition.addItem(cm)
def testSimpleMarkerRotation(self): """ Test if pointMarker property sld:Rotation value can be read if format is: <sld:Rotation>50.0</sld:Rotation> or <se:Rotation><ogc:Literal>50</ogc:Literal></se:Rotation> """ # technically it's not necessary to use a real shape, but a empty memory # layer. In case these tests will upgrate to a rendering where to # compare also rendering not only properties #myShpFile = os.path.join(unitTestDataPath(), 'points.shp') #layer = QgsVectorLayer(myShpFile, 'points', 'ogr') layer = QgsVectorLayer("Point", "addfeat", "memory") assert(layer.isValid()) # test if able to read <sld:Rotation>50.0</sld:Rotation> mFilePath = os.path.join(unitTestDataPath(), 'symbol_layer/external_sld/testSimpleMarkerRotation-directValue.sld') layer.loadSldStyle(mFilePath) props = layer.renderer().symbol().symbolLayers()[0].properties() self.assertEqual(props['angle'], '50') # test if able to read <se:Rotation><ogc:Literal>50</ogc:Literal></se:Rotation> mFilePath = os.path.join(unitTestDataPath(), 'symbol_layer/external_sld/testSimpleMarkerRotation-ogcLiteral.sld') layer.loadSldStyle(mFilePath) props = layer.renderer().symbol().symbolLayers()[0].properties() self.assertEqual(props['angle'], '50')
def _parseLayers(self): with change_directory(self.project_root): # remove map layers self.layerRegistry.removeMapLayers( self.layerRegistry.mapLayers().keys() ) for layer in self._iterateOverTagByName('maplayer'): layer_type = self._getAttr(layer, 'type').value() if layer_type == 'vector': qgsLayer = QgsVectorLayer() elif layer_type == 'raster': qgsLayer = QgsRasterLayer() # read layer from XML if not(qgsLayer.readLayerXML(layer.toElement())): raise RuntimeError( 'Layer is not readable: {}'.format( layer.firstChildElement('id').text() ) ) # get layer transparency if layer_type == 'vector': self.LAYERS_DATA[qgsLayer.id()].update({ 'transparency': qgsLayer.layerTransparency() }) elif layer_type == 'raster': qgsRasterRender = qgsLayer.renderer() self.LAYERS_DATA[qgsLayer.id()].update({ 'transparency': ( int((1 - qgsRasterRender.opacity()) * 100) ) }) del qgsRasterRender # record layer type self.LAYERS_DATA[qgsLayer.id()].update({ 'type': layer_type }) # add layer to the QgsMapLayerRegistry if qgsLayer.isValid(): self.layerRegistry.addMapLayer(qgsLayer, False) LOG.debug('Loaded layer: %s', qgsLayer.id())
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)
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") QgsProject.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): QgsProject.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] 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] 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] 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] 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))
class TestQgsGeometryGeneratorSymbolLayerV2(unittest.TestCase): def setUp(self): self.iface = get_iface() polys_shp = os.path.join(TEST_DATA_DIR, 'polys.shp') points_shp = os.path.join(TEST_DATA_DIR, 'points.shp') lines_shp = os.path.join(TEST_DATA_DIR, 'lines.shp') self.polys_layer = QgsVectorLayer(polys_shp, 'Polygons', 'ogr') self.points_layer = QgsVectorLayer(points_shp, 'Points', 'ogr') self.lines_layer = QgsVectorLayer(lines_shp, 'Lines', 'ogr') QgsProject.instance().addMapLayer(self.polys_layer) QgsProject.instance().addMapLayer(self.lines_layer) QgsProject.instance().addMapLayer(self.points_layer) # Create style sym1 = QgsFillSymbol.createSimple({'color': '#fdbf6f', 'outline_color': 'black'}) sym2 = QgsLineSymbol.createSimple({'color': '#fdbf6f'}) sym3 = QgsMarkerSymbol.createSimple({'color': '#fdbf6f', 'outline_color': 'black'}) self.polys_layer.setRenderer(QgsSingleSymbolRenderer(sym1)) self.lines_layer.setRenderer(QgsSingleSymbolRenderer(sym2)) self.points_layer.setRenderer(QgsSingleSymbolRenderer(sym3)) self.mapsettings = self.iface.mapCanvas().mapSettings() self.mapsettings.setOutputSize(QSize(400, 400)) self.mapsettings.setOutputDpi(96) self.mapsettings.setExtent(QgsRectangle(-133, 22, -70, 52)) def tearDown(self): QgsProject.instance().removeAllMapLayers() def test_marker(self): sym = self.polys_layer.renderer().symbol() sym_layer = QgsGeometryGeneratorSymbolLayer.create({'geometryModifier': 'centroid($geometry)'}) sym_layer.setSymbolType(QgsSymbol.Marker) sym_layer.subSymbol().symbolLayer(0).setStrokeColor(QColor(0, 0, 0)) sym.changeSymbolLayer(0, sym_layer) rendered_layers = [self.polys_layer] self.mapsettings.setLayers(rendered_layers) renderchecker = QgsMultiRenderChecker() renderchecker.setMapSettings(self.mapsettings) renderchecker.setControlName('expected_geometrygenerator_marker') self.assertTrue(renderchecker.runTest('geometrygenerator_marker')) def test_mixed(self): sym = self.polys_layer.renderer().symbol() buffer_layer = QgsGeometryGeneratorSymbolLayer.create({'geometryModifier': 'buffer($geometry, "value"/15)', 'outline_color': 'black'}) buffer_layer.setSymbolType(QgsSymbol.Fill) buffer_layer.subSymbol().symbolLayer(0).setStrokeColor(QColor(0, 0, 0)) self.assertIsNotNone(buffer_layer.subSymbol()) sym.appendSymbolLayer(buffer_layer) marker_layer = QgsGeometryGeneratorSymbolLayer.create({'geometryModifier': 'centroid($geometry)', 'outline_color': 'black'}) marker_layer.setSymbolType(QgsSymbol.Marker) marker_layer.subSymbol().symbolLayer(0).setStrokeColor(QColor(0, 0, 0)) sym.appendSymbolLayer(marker_layer) rendered_layers = [self.polys_layer] self.mapsettings.setLayers(rendered_layers) renderchecker = QgsMultiRenderChecker() renderchecker.setMapSettings(self.mapsettings) renderchecker.setControlName('expected_geometrygenerator_mixed') self.assertTrue(renderchecker.runTest('geometrygenerator_mixed')) def test_buffer_lines(self): sym = self.lines_layer.renderer().symbol() buffer_layer = QgsGeometryGeneratorSymbolLayer.create({'geometryModifier': 'buffer($geometry, "value"/15)', 'outline_color': 'black'}) buffer_layer.setSymbolType(QgsSymbol.Fill) self.assertIsNotNone(buffer_layer.subSymbol()) sym.appendSymbolLayer(buffer_layer) rendered_layers = [self.lines_layer] self.mapsettings.setLayers(rendered_layers) renderchecker = QgsMultiRenderChecker() renderchecker.setMapSettings(self.mapsettings) renderchecker.setControlName('expected_geometrygenerator_buffer_lines') self.assertTrue(renderchecker.runTest('geometrygenerator_buffer_lines')) def test_buffer_points(self): sym = self.points_layer.renderer().symbol() buffer_layer = QgsGeometryGeneratorSymbolLayer.create({'geometryModifier': 'buffer($geometry, "staff"/15)', 'outline_color': 'black'}) buffer_layer.setSymbolType(QgsSymbol.Fill) self.assertIsNotNone(buffer_layer.subSymbol()) sym.appendSymbolLayer(buffer_layer) rendered_layers = [self.points_layer] self.mapsettings.setLayers(rendered_layers) renderchecker = QgsMultiRenderChecker() renderchecker.setMapSettings(self.mapsettings) renderchecker.setControlName('expected_geometrygenerator_buffer_points') self.assertTrue(renderchecker.runTest('geometrygenerator_buffer_points'))
def testRenderer(self): """ Test that renderer is correctly acquired from provider """ endpoint = self.basetestpath + '/renderer_fake_qgis_http_endpoint' with open(sanitize(endpoint, '?f=json'), 'wb') as f: f.write(""" {"currentVersion":10.22,"id":1,"name":"QGIS Test","type":"Feature Layer","description": "QGIS Provider Test Layer","geometryType":"esriGeometryPoint","copyrightText":"not copyright","parentLayer":{"id":2,"name":"QGIS Tests"},"subLayers":[], "minScale":72225,"maxScale":0, "defaultVisibility":true, "extent":{"xmin":-71.123,"ymin":66.33,"xmax":-65.32,"ymax":78.3, "spatialReference":{"wkid":4326,"latestWkid":4326}}, "hasAttachments":false,"htmlPopupType":"esriServerHTMLPopupTypeAsHTMLText", "displayField":"LABEL","typeIdField":null, "fields":[{"name":"OBJECTID","type":"esriFieldTypeOID","alias":"OBJECTID","domain":null}], "relationships":[],"canModifyLayer":false,"canScaleSymbols":false,"hasLabels":false, "capabilities":"Map,Query,Data","maxRecordCount":1000,"supportsStatistics":true, "supportsAdvancedQueries":true,"supportedQueryFormats":"JSON, AMF", "drawingInfo":{"renderer": { "type": "uniqueValue", "field1": "COUNTRY", "uniqueValueInfos": [ { "value": "US", "symbol": { "color": [ 253, 127, 111, 255 ], "size": 12.75, "angle": 0, "xoffset": 0, "yoffset": 0, "type": "esriSMS", "style": "esriSMSCircle", "outline": { "color": [ 26, 26, 26, 255 ], "width": 0.75, "type": "esriSLS", "style": "esriSLSSolid" } }, "label": "US" }, { "value": "Canada", "symbol": { "color": [ 126, 176, 213, 255 ], "size": 12.75, "angle": 0, "xoffset": 0, "yoffset": 0, "type": "esriSMS", "style": "esriSMSCircle", "outline": { "color": [ 26, 26, 26, 255 ], "width": 0.75, "type": "esriSLS", "style": "esriSLSSolid" } }, "label": "Canada" }]}}, "ownershipBasedAccessControlForFeatures":{"allowOthersToQuery":true},"useStandardizedQueries":true}""".encode( 'UTF-8')) with open(sanitize(endpoint, '/query?f=json_where=OBJECTID=OBJECTID_returnIdsOnly=true'), 'wb') as f: f.write(""" { "objectIdFieldName": "OBJECTID", "objectIds": [ 1 ] } """.encode('UTF-8')) # Create test layer vl = QgsVectorLayer("url='http://" + endpoint + "' crs='epsg:4326'", 'test', 'arcgisfeatureserver') self.assertTrue(vl.isValid()) self.assertIsNotNone(vl.dataProvider().createRenderer()) self.assertIsInstance(vl.renderer(), QgsCategorizedSymbolRenderer) self.assertEqual(len(vl.renderer().categories()), 2) self.assertEqual(vl.renderer().categories()[0].value(), 'US') self.assertEqual(vl.renderer().categories()[1].value(), 'Canada')
def doMask(self, item): mapcrs = self.plugin.canvas.mapSettings().destinationCrs() ogrFeature = item.data(Qt.UserRole) layerName = "OSM "+ogrFeature.GetFieldAsString('id') geom = QgsGeometry.fromWkt(ogrFeature.GetGeometryRef().ExportToWkt()) if (geom.type() == QgsWkbTypes.PolygonGeometry): try: try: from mask import aeag_mask except: from mask_plugin import aeag_mask aeag_mask.do(mapcrs, {geom}, "Mask "+layerName) except: geom = QgsGeometry.fromWkt(ogrFeature.GetGeometryRef().ExportToWkt()) toCrs = self.plugin.canvas.mapSettings().destinationCrs() l = max(geom.boundingBox().width(), geom.boundingBox().height()) x = geom.boundingBox().center().x() y = geom.boundingBox().center().y() rect = QgsRectangle(x-l, y-l, x+l, y+l) # geom.boundingBox() rect.scale(4) mask = QgsGeometry.fromRect(rect) mask = mask.difference(geom) maskLayer = QgsVectorLayer("MultiPolygon", "Mask "+layerName, "memory") maskLayer.setCrs(toCrs) QgsProject.instance().addMapLayer(maskLayer) pr = maskLayer.dataProvider() fields = QgsFields() fields.append(QgsField("id", QVariant.String)) fields.append(QgsField("name", QVariant.String)) fet = QgsFeature() fet.initAttributes(2) fet.setGeometry(mask) fet.setFields(fields) fet.setAttribute("id", (ogrFeature.GetFieldAsString('id'))) fet.setAttribute("name", (ogrFeature.GetFieldAsString('name'))) pr.addAttributes(fields.toList()) maskLayer.startEditing() pr.addFeatures([fet]) maskLayer.commitChanges() maskLayer.updateExtents() # transparence, epaisseur renderer = maskLayer.renderer() s = renderer.symbol() s.setOpacity(0.90) s.setColor(QColor(255, 255, 255)) if isinstance(s, QgsLineSymbol): s.setWidth(0) layerTree = QgsProject.instance().layerTreeRoot().findLayer(maskLayer) if layerTree: self.plugin.iface.layerTreeView().layerTreeModel()\ .refreshLayerLegend(layerTree) # Refresh legend self.go(item)
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))
def post_process_layer(self, layer: QgsVectorLayer, position: int): if layer.geometryType() == QgsWkbTypes.PointGeometry: for symbol in layer.renderer().symbols(self.layer_context(layer)): symbol.symbolLayer(0).setShape( MARKER_SHAPE[position % (len(MARKER_SHAPE) - 1)])
def create_path_with_scratch_layer(self, path_links): # Create TSP route crs = self.link_layer.dataProvider().crs().authid() vl = QgsVectorLayer(f"LineString?crs={crs}", 'TSP Solution', "memory") pr = vl.dataProvider() # add fields pr.addAttributes(self.link_layer.dataProvider().fields()) vl.updateFields( ) # tell the vector layer to fetch changes from the provider idx = self.link_layer.dataProvider().fieldNameIndex('link_id') self.link_features = {} for feat in self.link_layer.getFeatures(): link_id = feat.attributes()[idx] self.link_features[link_id] = feat # add a feature all_links = [] for k in path_links: fet = self.link_features[k] all_links.append(fet) # add all links to the temp layer pr.addFeatures(all_links) # add layer to the map QgsProject.instance().addMapLayer(vl) symbol = vl.renderer().symbol() symbol.setWidth(1.6) qgis.utils.iface.mapCanvas().refresh() # Create TSP stops crs = self.node_layer.dataProvider().crs().authid() nl = QgsVectorLayer(f"Point?crs={crs}", 'TSP Stops', "memory") pn = nl.dataProvider() # add fields pn.addAttributes(self.node_layer.dataProvider().fields()) nl.updateFields( ) # tell the vector layer to fetch changes from the provider idx = self.node_layer.dataProvider().fieldNameIndex('node_id') self.node_features = {} for feat in self.node_layer.getFeatures(): node_id = feat.attributes()[idx] self.node_features[node_id] = feat # add the feature stop_nodes = [] seq = {} for i, k in enumerate(self.worker_thread.node_sequence[:-1]): fet = self.node_features[k] stop_nodes.append(fet) seq[k] = i + 1 # add all links to the temp layer pn.addFeatures(stop_nodes) # Goes back and adds the order of visitation for each node pn.addAttributes([QgsField('sequence', QVariant.Int)]) nl.updateFields() sdx = nl.dataProvider().fieldNameIndex('sequence') nl.startEditing() for feat in nl.getFeatures(): node_id = feat.attributes()[idx] nl.changeAttributeValue(feat.id(), sdx, seq[node_id]) nl.commitChanges() # add layer to the map QgsProject.instance().addMapLayer(nl) symbol = QgsMarkerSymbol.createSimple({'name': 'star', 'color': 'red'}) symbol.setSize(6) nl.renderer().setSymbol(symbol) qgis.utils.iface.mapCanvas().refresh()
def add_temp_layer(self, dialog, data, layer_name, force_tab=True, reset_text=True, tab_idx=1, del_old_layers=True, group='GW Temporal Layers', disable_tabs=True): """ Add QgsVectorLayer into TOC :param dialog: :param data: :param layer_name: :param force_tab: :param reset_text: :param tab_idx: :param del_old_layers: :param group: :param disable_tabs: set all tabs, except the last, enabled or disabled (boolean). :return: Dictionary with text as result of previuos data (String), and list of layers added (QgsVectorLayer). """ text_result = None temp_layers_added = [] srid = global_vars.srid for k, v in list(data.items()): if str(k) == "info": text_result = self.populate_info_text(dialog, data, force_tab, reset_text, tab_idx, disable_tabs) elif k in ('point', 'line', 'polygon'): if 'values' in data[k]: key = 'values' elif 'features' in data[k]: key = 'features' else: continue counter = len(data[k][key]) if counter > 0: counter = len(data[k][key]) geometry_type = data[k]['geometryType'] try: if not layer_name: layer_name = data[k]['layerName'] except KeyError: layer_name = 'Temporal layer' if del_old_layers: self.delete_layer_from_toc(layer_name) v_layer = QgsVectorLayer(f"{geometry_type}?crs=epsg:{srid}", layer_name, 'memory') layer_name = None # TODO This if controls if the function already works with GeoJson or is still to be refactored # once all are refactored the if should be: if 'feature' not in data [k]: continue if key == 'values': self.populate_vlayer_old(v_layer, data, k, counter, group) elif key == 'features': self.populate_vlayer(v_layer, data, k, counter, group) if 'qmlPath' in data[k] and data[k]['qmlPath']: qml_path = data[k]['qmlPath'] self.load_qml(v_layer, qml_path) elif 'category_field' in data[k] and data[k]['category_field']: cat_field = data[k]['category_field'] size = data[k]['size'] if 'size' in data[k] and data[k]['size'] else 2 color_values = {'NEW': QColor(0, 255, 0), 'DUPLICATED': QColor(255, 0, 0), 'EXISTS': QColor(240, 150, 0)} self.categoryze_layer(v_layer, cat_field, size, color_values) else: if geometry_type == 'Point': v_layer.renderer().symbol().setSize(3.5) v_layer.renderer().symbol().setColor(QColor("red")) elif geometry_type == 'LineString': v_layer.renderer().symbol().setWidth(1.5) v_layer.renderer().symbol().setColor(QColor("red")) v_layer.renderer().symbol().setOpacity(0.7) temp_layers_added.append(v_layer) self.iface.layerTreeView().refreshLayerSymbology(v_layer.id()) return {'text_result': text_result, 'temp_layers_added': temp_layers_added}
class WGS84Layer(object): "..." def __init__(self, iface, layer_name, layer_type, visible, group=None, show_count=True): "..." self.iface = iface self.layer_name = layer_name self.visible = visible self.layer = QgsVectorLayer(layer_type + "?crs=EPSG:4326", layer_name, "memory") self.provider = self.layer.dataProvider() self.layer = QgsProject.instance().addMapLayer(self.layer) self.canvas = iface.mapCanvas() if group is not None: layer_t = QgsProject.instance().mapLayersByName(layer_name)[0] root = QgsProject.instance().layerTreeRoot() myLayer = root.findLayer(layer_t.id()) myClone = myLayer.clone() parent = myLayer.parent() group.insertChildNode(0, myClone) parent.removeChildNode(myLayer) # collapse groups for child in QgsProject.instance().layerTreeRoot().children(): if isinstance(child, QgsLayerTreeGroup): child.setExpanded(False) if show_count: root = QgsProject.instance().layerTreeRoot() leaf = root.findLayer(self.layer.id()) leaf.setCustomProperty("showFeatureCount", True) def show(self, show_it): "..." node = QgsProject.instance().layerTreeRoot().findLayer(self.layer) if node: node.setItemVisibilityChecked(show_it) def remove(self): "..." # It seems QGis does already delete the layers # Ensure that the layer is still in the registry before calling removeMapLayer if self.layer is not None and len(QgsProject.instance().mapLayersByName(self.layer_name)) > 0: QgsProject.instance().removeMapLayer(self.layer) self.layer = None def refresh(self): "..." if not self.canvas.isDrawing(): self.layer.triggerRepaint(True) self.canvas.refresh() def refresh_legend(self): "..." root = QgsProject.instance().layerTreeRoot().findLayer(self.layer.id()) self.iface.layerTreeView().layerTreeModel().refreshLayerLegend(root) self.iface.mapCanvas().refresh() def poly_marker(self, placement, qcolor, width): "..." marker = QgsMarkerLineSymbolLayer() marker.setColor(qcolor) marker.setPlacement(placement) marker.setWidth(width) self.layer.renderer().symbol().appendSymbolLayer(marker) def poly_markers(self, qcolor, width): "..." self.poly_marker(QgsMarkerLineSymbolLayer.Vertex, qcolor, width * 1.33) self.poly_marker(QgsMarkerLineSymbolLayer.FirstVertex, qcolor, width * 2.25) self.poly_marker(QgsMarkerLineSymbolLayer.LastVertex, qcolor, width * 2.25) def set_attributes(self, attributes): "..." self.provider.addAttributes(attributes) self.layer.updateFields() def add_feature(self, geometry, attributes): "..." added_feature = QgsFeature() added_feature.setGeometry(geometry) added_feature.setAttributes(attributes) success, feat = self.provider.addFeatures([added_feature]) if success: self.layer.updateExtents() return feat[0] return None def remove_feature(self, feature): "..." self.provider.deleteFeatures([feature.id()]) def remove_all_features(self): "..." for feature in self.layer.getFeatures(): self.remove_feature(feature) def enable_labeling(self, field, font="Arial", size=10, weight=50, rgb=(0, 0, 0), placement=1): "..." self.layer.setCustomProperty("labeling", "pal") self.layer.setCustomProperty("labeling/enabled", "true") self.layer.setCustomProperty("labeling/fontFamily", font) self.layer.setCustomProperty("labeling/fontSize", str(size)) self.layer.setCustomProperty("labeling/fontWeight", str(weight)) self.layer.setCustomProperty("labeling/textColorR", str(rgb[0])) self.layer.setCustomProperty("labeling/textColorG", str(rgb[1])) self.layer.setCustomProperty("labeling/textColorB", str(rgb[2])) self.layer.setCustomProperty("labeling/placement", str(placement)) self.layer.setCustomProperty("labeling/fieldName", field)
def testMainAnnotationLayerRendered(self): """ test that main annotation layer is rendered above all other layers """ canvas = QgsMapCanvas() canvas.setDestinationCrs(QgsCoordinateReferenceSystem('EPSG: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") sym3 = QgsFillSymbol.createSimple({'color': '#b200b2'}) layer.renderer().setSymbol(sym3) 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('empty_canvas', 'empty_canvas', canvas)) # add polygon to layer f = QgsFeature() f.setGeometry(QgsGeometry.fromRect(QgsRectangle(5, 25, 25, 45))) self.assertTrue(layer.dataProvider().addFeatures([f])) # refresh canvas canvas.refresh() canvas.waitWhileRendering() # no annotation yet... self.assertFalse( self.canvasImageCheck('main_annotation_layer', 'main_annotation_layer', canvas, expect_fail=True)) annotation_layer = QgsProject.instance().mainAnnotationLayer() annotation_layer.setCrs(QgsCoordinateReferenceSystem('EPSG:4326')) annotation_geom = QgsGeometry.fromRect(QgsRectangle(12, 30, 18, 33)) annotation = QgsAnnotationPolygonItem( annotation_geom.constGet().clone()) sym3 = QgsFillSymbol.createSimple({ 'color': '#ff0000', 'outline_style': 'no' }) annotation.setSymbol(sym3) annotation_layer.addItem(annotation) # refresh canvas canvas.refresh() canvas.waitWhileRendering() # annotation must be rendered over other layers self.assertTrue( self.canvasImageCheck('main_annotation_layer', 'main_annotation_layer', canvas)) annotation_layer.clear()
def run(self): global almacen #coloco el puntero arriba del todo QgsProject.instance().layerTreeRegistryBridge().setLayerInsertionPoint( QgsProject.instance().layerTreeRoot(), 0) #genero una lista con los sistemas de referencia misdatos = [["Etrs89 Zona30 (25830)", "25830"], ["Etrs89 Zona29 (25829)", "25829"], ["ED50 Zona30 (23030)", "23030"], ["ED50_Zona29 (23029)", "23029"], ["WGS84 geograficas sexagesimales(4326)", "4326"], ["WGS84 geograficas centesimales(4326)", "4258"]] self.dlg.comboBox_src.clear() for element in misdatos: self.dlg.comboBox_src.addItem(element[0]) """Run method that performs all the real work""" # Create the dialog with elements (after translation) and keep reference # Only create GUI ONCE in callback, so that it will only load when the plugin is started if self.first_start == True: self.first_start = False #leo la cache rutacache = os.path.join(QgsApplication.qgisSettingsDirPath(), r"python\plugins\zoomSigmena\cache.txt") if os.path.isfile(rutacache) == True: filecache = open(rutacache, "r") filecacheleido = filecache.readlines() try: import ast almacen = ast.literal_eval((filecacheleido[0].replace( '\n', '')).replace(" [[", "[[").replace("]] ", "]]")) #.split(',')) cache_utm = int(almacen[0]) cache_geo = int(almacen[1]) cache_escala = almacen[2] print(cache_escala) print(almacen) #miscomarcas=(filecacheleido[3].replace('\n','')).strip('][').split(',') #convierto una str en una list #mismunicipios=ast.literal_eval((filecacheleido[4].replace('\n','')).replace(" [[","[[").replace("]] ","]]"))#.split(',')) #convierto una str en una list filecache.close() except: print("esta no encuentra el file cache") self.dlg.lineEdit_escala.setText(str(cache_escala)) self.dlg.checkBox_utm.setChecked(cache_utm) self.dlg.checkBox_geo.setChecked(cache_geo) # show the dialog self.dlg.show() # Run the dialog event loop result = self.dlg.exec_() # See if OK was pressed if result: # Do something useful here - delete the line containing pass and # substitute with your code. def deg_to_dms(deg, type='lat'): decimals, number = math.modf(deg) d = int(number) m = int(decimals * 60) s = (deg - d - m / 60) * 3600.00 compass = {'lat': ('N', 'S'), 'lon': ('E', 'W')} compass_str = compass[type][0 if d >= 0 else 1] return '{}º{}\'{:.2f}"{}'.format(abs(d), abs(m), abs(s), compass_str) #saco de aqui variables que estan en las cajitas src_seleccionado = self.dlg.comboBox_src.currentIndex() # Get the coordinates and scale factor from the dialog x = self.dlg.XX.text() ##displayText() y = self.dlg.YY.text() ##displayText() escala = self.dlg.lineEdit_escala.text() x = x.replace(',', '.') y = y.replace(',', '.') escala = int(escala.replace('.', '')) src = misdatos[int(src_seleccionado)][1] if src == "4326": latext = y longtext = x lag = float(latext.split()[0]) lam = float(latext.split()[1]) las = float(latext.split()[2]) log = float(longtext.split()[0]) lom = float(longtext.split()[1]) los = float(longtext.split()[2]) lon = -1 * (log + (lom / 60) + (los / 3600)) lat = lag + (lam / 60) + (las / 3600) x = float(lon) y = float(lat) print(x) print(y) huso = 30 destinoProj = pyproj.Proj(proj="utm", zone=huso, ellps="WGS84", units="m") origenProj = pyproj.Proj(proj='longlat', ellps='WGS84', datum='WGS84') UTM_X, UTM_Y = pyproj.transform(origenProj, destinoProj, lon, lat) if src == "4258": print("por el camino adecuado") lat = float(y) lonn = float(x) lon = -1.0 * lonn print(lat) print(lon) huso = 30 destinoProj = pyproj.Proj(proj="utm", zone=huso, ellps="WGS84", units="m") origenProj = pyproj.Proj(proj='longlat', ellps='WGS84', datum='WGS84') UTM_X, UTM_Y = pyproj.transform(origenProj, destinoProj, lon, lat) print(UTM_X) print(UTM_Y) x = lon y = lat #creo una capa temporal con las coordenadas # create layer vl2 = QgsVectorLayer("Point?crs=EPSG:" + src, "Zoom", "memory") pr2 = vl2.dataProvider() vl2.startEditing() # add fields pr2.addAttributes([ QgsField("x", QVariant.Double), QgsField("y", QVariant.Double), QgsField("xx", QVariant.String), QgsField("yy", QVariant.String), QgsField("xxx", QVariant.Double), QgsField("yyy", QVariant.Double) ]) vl2.updateFields() # tell the vector layer to fetch changes from the provider #$add a feature fet = QgsFeature() print("punto") print(x) print(y) fet.setGeometry( QgsGeometry.fromPointXY(QgsPointXY(float(x), float(y)))) if src == "25830": huso = 30 origenProj = pyproj.Proj(proj="utm", zone=huso, ellps="WGS84", units="m") destinoProj = pyproj.Proj(proj='longlat', ellps='WGS84', datum='WGS84') xxx, yyy = pyproj.transform(origenProj, destinoProj, x, y) xx = (deg_to_dms(xxx, 'lon')) yy = (deg_to_dms(yyy)) if src == "25829": huso = 29 origenProj = pyproj.Proj(proj="utm", zone=huso, ellps="WGS84", units="m") destinoProj = pyproj.Proj(proj='longlat', ellps='WGS84', datum='WGS84') xxx, yyy = pyproj.transform(origenProj, destinoProj, x, y) xx = (deg_to_dms(xxx, 'lon')) yy = (deg_to_dms(yyy)) if src == "23030": huso = 30 origenProj = pyproj.Proj(proj="utm", zone=huso, ellps="intl", units="m") destinoProj = pyproj.Proj(proj='longlat', ellps='WGS84', datum='WGS84') xxx, yyy = pyproj.transform(origenProj, destinoProj, x, y) xx = (deg_to_dms(xxx, 'lon')) yy = (deg_to_dms(yyy)) if src == "23029": huso = 29 origenProj = pyproj.Proj(proj="utm", zone=huso, ellps="intl", units="m") destinoProj = pyproj.Proj(proj='longlat', ellps='WGS84', datum='WGS84') xxx, yyy = pyproj.transform(origenProj, destinoProj, x, y) xx = (deg_to_dms(xxx, 'lon')) yy = (deg_to_dms(yyy)) #para que lo pase a utms en pantalla if src == "4326": x = int(UTM_X) y = int(UTM_Y) #xx=longtext #yy=latext huso = 30 origenProj = pyproj.Proj(proj="utm", zone=huso, ellps="intl", units="m") destinoProj = pyproj.Proj(proj='longlat', ellps='WGS84', datum='WGS84') xxx, yyy = pyproj.transform(origenProj, destinoProj, x, y) xx = (deg_to_dms(xxx, 'lon')) yy = (deg_to_dms(yyy)) #para que lo pase a utms en pantalla if src == "4258": x = int(UTM_X) y = int(UTM_Y) xxx = lon yyy = lat xx = (deg_to_dms(xxx, 'lon')) yy = (deg_to_dms(yyy)) fet.setAttributes( [float(x), float(y), str(xx), str(yy), float(xxx), float(yyy)]) pr2.addFeatures([fet]) #cambio la simbologia symbol = QgsMarkerSymbol.createSimple({ 'name': 'circle', 'color': 'red', 'size': '3', }) vl2.renderer().setSymbol(symbol) # update layer's extent when new features have been added # because change of extent in provider is not propagated to the layer layer_settings = QgsPalLayerSettings() text_format = QgsTextFormat() text_format.setFont(QFont("Arial", 12)) text_format.setSize(12) text_format.setColor(QColor("Orange")) layer_settings.setFormat(text_format) layer_settings.placement = 1 layer_settings.xOffset = 0.0 layer_settings.yOffset = 10.0 mostrar = True if self.dlg.checkBox_utm.isChecked( ) and self.dlg.checkBox_geo.isChecked(): layer_settings.fieldName = '''concat('X: ',"X",' Y: ',"Y",'\n','Lon: ',"xx",' Lat: ',"yy" )''' almacen = [1, 1] else: if self.dlg.checkBox_utm.isChecked(): layer_settings.fieldName = '''concat('X: ',"X",' Y: ',"Y" )''' almacen = [1, 0] print("caso1") if self.dlg.checkBox_geo.isChecked(): layer_settings.fieldName = '''concat('Lon: ',"xx",' Lat: ',"yy" )''' almacen = [0, 1] print("caso2") if not self.dlg.checkBox_utm.isChecked( ) and not self.dlg.checkBox_geo.isChecked(): mostrar = False almacen = [0, 0] print("caso3") print("almacen despues de etiquetar", almacen) layer_settings.isExpression = True print(mostrar) layer_settings.enabled = mostrar layer_settings = QgsVectorLayerSimpleLabeling(layer_settings) vl2.setLabelsEnabled(True) vl2.setLabeling(layer_settings) vl2.triggerRepaint() # update layer's extent when new features have been added # because change of extent in provider is not propagated to the layer vl2.updateExtents() vl2.commitChanges() vl2.updateExtents() canvas = self.iface.mapCanvas() canvas.setExtent(vl2.extent()) crsSrc = QgsCoordinateReferenceSystem('EPSG:' + str(src)) crsDest = QgsProject.instance().crs() if crsSrc != crsDest: xform = QgsCoordinateTransform(crsSrc, crsDest, QgsProject.instance()) canvas.setExtent(xform.transform(vl2.extent())) self.iface.mapCanvas().zoomScale(escala) #self.limpiar_pressed() almacen.append(escala) #lo escribo en el txt, mavhacando lo que ya tenia f = open(rutacache, "w") escribir = str(almacen) f.write(escribir) f.close() print(almacen) QgsProject.instance().addMapLayer(vl2)
def testRenderer(self): """ Test that renderer is correctly acquired from provider """ endpoint = self.basetestpath + '/renderer_fake_qgis_http_endpoint' with open(sanitize(endpoint, '?f=json'), 'wb') as f: f.write(""" {"currentVersion":10.22,"id":1,"name":"QGIS Test","type":"Feature Layer","description": "QGIS Provider Test Layer","geometryType":"esriGeometryPoint","copyrightText":"not copyright","parentLayer":{"id":2,"name":"QGIS Tests"},"subLayers":[], "minScale":72225,"maxScale":0, "defaultVisibility":true, "extent":{"xmin":-71.123,"ymin":66.33,"xmax":-65.32,"ymax":78.3, "spatialReference":{"wkid":4326,"latestWkid":4326}}, "hasAttachments":false,"htmlPopupType":"esriServerHTMLPopupTypeAsHTMLText", "displayField":"LABEL","typeIdField":null, "fields":[{"name":"OBJECTID","type":"esriFieldTypeOID","alias":"OBJECTID","domain":null}], "relationships":[],"canModifyLayer":false,"canScaleSymbols":false,"hasLabels":false, "capabilities":"Map,Query,Data","maxRecordCount":1000,"supportsStatistics":true, "supportsAdvancedQueries":true,"supportedQueryFormats":"JSON, AMF", "drawingInfo":{"renderer": { "type": "uniqueValue", "field1": "COUNTRY", "uniqueValueInfos": [ { "value": "US", "symbol": { "color": [ 253, 127, 111, 255 ], "size": 12.75, "angle": 0, "xoffset": 0, "yoffset": 0, "type": "esriSMS", "style": "esriSMSCircle", "outline": { "color": [ 26, 26, 26, 255 ], "width": 0.75, "type": "esriSLS", "style": "esriSLSSolid" } }, "label": "US" }, { "value": "Canada", "symbol": { "color": [ 126, 176, 213, 255 ], "size": 12.75, "angle": 0, "xoffset": 0, "yoffset": 0, "type": "esriSMS", "style": "esriSMSCircle", "outline": { "color": [ 26, 26, 26, 255 ], "width": 0.75, "type": "esriSLS", "style": "esriSLSSolid" } }, "label": "Canada" }]}}, "ownershipBasedAccessControlForFeatures":{"allowOthersToQuery":true},"useStandardizedQueries":true}""" .encode('UTF-8')) with open( sanitize( endpoint, '/query?f=json_where=OBJECTID=OBJECTID_returnIdsOnly=true' ), 'wb') as f: f.write(""" { "objectIdFieldName": "OBJECTID", "objectIds": [ 1 ] } """.encode('UTF-8')) # Create test layer vl = QgsVectorLayer("url='http://" + endpoint + "' crs='epsg:4326'", 'test', 'arcgisfeatureserver') self.assertTrue(vl.isValid()) self.assertIsNotNone(vl.dataProvider().createRenderer()) self.assertIsInstance(vl.renderer(), QgsCategorizedSymbolRenderer) self.assertEqual(len(vl.renderer().categories()), 2) self.assertEqual(vl.renderer().categories()[0].value(), 'US') self.assertEqual(vl.renderer().categories()[1].value(), 'Canada')
def search(self): try: # Current service service = self.tab.tabText(self.tab.currentIndex()) # Params params = {'geometry': self.polygonInput.text()} # Set auth and add params according to service if service == 'BaseMap': # ! Auth self.bmSetAuth() # Set request attributes url = 'https://view.geoapi-airbusds.com/api/v1/images' auth = self.bmAuth headers = None # Update params params.update({ 'size': self.maxResultsInput.value(), 'insertdtstart': '1970-01-01T00:00:00', 'insertdtend': self.now() }) # Dates if self.bmFromCheck.isChecked(): params['insertdtstart'] = self.bmFromInput.dateTime( ).toString(Qt.ISODate) if self.bmToCheck.isChecked(): params['insertdtend'] = self.bmToInput.dateTime().toString( Qt.ISODate) else: # ! Auth self.dtSetAuth() url = 'https://search.oneatlas.geoapi-airbusds.com/api/v1/opensearch' auth = None headers = self.dtHeaders # Constellations (at least one) constellations = [] if self.dtSpotCheck.isChecked(): constellations.append('SPOT') if self.dtPleiadesCheck.isChecked(): constellations.append('PHR') # Dates # MAYBE remove hours from dates dateFrom, dateTo = '1970-01-01T00:00:00', self.now() if self.dtFromCheck.isChecked(): dateFrom = self.dtFromInput.dateTime().toString(Qt.ISODate) if self.dtToCheck.isChecked(): dateTo = self.dtToInput.dateTime().toString(Qt.ISODate) # Angles angleMin, angleMax = 0, 30 if self.dtAngleMinCheck.isChecked(): angleMin = self.dtAngleMinInput.value() if self.dtAngleMaxCheck.isChecked(): angleMax = self.dtAngleMaxInput.value() # Covers (directlly update params) if self.dtCloudCheck.isChecked(): params['cloudCover'] = f'[0,{self.dtCloudInput.value()}]' if self.dtSnowCheck.isChecked(): params['snowCover'] = f'[0,{self.dtSnowInput.value()}]' # Workspaces (at leat one) workspaces = [] if self.dtPublicCheck.isChecked(): workspaces.append('0e33eb50-3404-48ad-b835-b0b4b72a5625') if self.dtPrivateCheck.isChecked(): workspaces.append(self.dtWorkspaceId) # Update all params with right format params.update({ 'itemsPerPage': self.maxResultsInput.value(), 'constellation': ','.join(constellations), 'acquisitionDate': f'[{dateFrom},{dateTo}]', 'incidenceAngle': f'[{angleMin},{angleMax}]', 'workspace': ','.join(workspaces) }) # Finally do the api call t = datetime.datetime.now() print(f'START {service} search') r = self.session.get(url, auth=auth, headers=headers, params=params) rSearch = r.json() # Exception request error if r.status_code != 200: self.error( f'{service} search error {r.status_code}\n{rSearch["message"]}' ) return # Create the search result layer with fields according to current service layer = QgsVectorLayer( f'Polygon?crs=epsg:4326&index=yes&{FIELDS[service]}', providerLib='memory', baseName=f'{service} search results') # Extract features features = [] self.errorFeatures = [] for rFeature in rSearch['features']: # Add a feature of the bbox on the new layer feature = QgsFeature(layer.fields()) # Try to get each attributes feature['service'] = service feature['constellation'] = self.getPropertie( rFeature, 'constellation') feature['incidenceAngle'] = self.getPropertie( rFeature, 'incidenceAngle') feature['cloudCover'] = self.getPropertie( rFeature, 'cloudCover') if service == 'BaseMap': feature['id'] = rFeature['id'] feature['insertionDate'] = self.getPropertie( rFeature, 'insertionDate') feature['wmts'] = self.getPropertie(rFeature, 'wmts') # Bbox fBbox = rFeature['properties']['bbox'] rectangle = QgsRectangle(fBbox[0], fBbox[1], fBbox[2], fBbox[3]) else: feature['id'] = self.getPropertie(rFeature, 'id') feature['acquisitionDate'] = self.getPropertie( rFeature, 'acquisitionDate') feature['snowCover'] = self.getPropertie( rFeature, 'snowCover') try: for json in rFeature['_links']['imagesWmts']: feature[f'wmts_{json["name"]}'] = json['href'] for json in rFeature['_links']['imagesWcs']: if 'buffer' in rFeature['rights']: feature[f'wcs_{json["name"]}'] = json['href'] else: feature[f'wcs_{json["name"]}'] = None except Exception as e: print( f'ERROR * eF = qgis.utils.plugins["OneAtlas"].mySearch.errorFeatures[{len(self.errorFeatures)}]' ) print(str(e)) self.errorFeatures.append(rFeature) continue # Bbox coordinates = rFeature['geometry']['coordinates'][0] rectangle = QgsRectangle(coordinates[0][0], coordinates[0][1], coordinates[2][0], coordinates[2][1]) # Add geometry from rectangle feature.setGeometry( QgsGeometry.fromWkt(rectangle.asWktPolygon())) # Add feature to list features.append(feature) # Total if service == 'BaseMap': # Note : rSearch['totalResults'] is maybe the number of total element in bbox ? # and numberOfElements is the true total result total = rSearch['numberOfElements'] color = QColor.fromRgb(0, 250, 0) else: total = rSearch['totalResults'] color = QColor.fromRgb(0, 250, 250) if len(self.errorFeatures) > 0: total -= len(self.errorFeatures) print(f'* {len(self.errorFeatures)} error feature') # Notification for number of total results msgBox = QMessageBox() msgBox.setWindowTitle(WINDOW_TITLE) msgBox.setText(f'There are {total} results') if total > len(features): msgBox.setIcon(QMessageBox.Warning) msgBox.setInformativeText( f'The maximum is configured to {self.maxResultsInput.value()}\nPlease refine your criteria or your AOI' ) msgBox.setStandardButtons(QMessageBox.Retry | QMessageBox.Ignore) msgBox.setDefaultButton(QMessageBox.Retry) else: msgBox.setIcon(QMessageBox.Information) msgBox.setStandardButtons(QMessageBox.Retry | QMessageBox.Ok) msgBox.setDefaultButton(QMessageBox.Ok) msgBox.button(QMessageBox.Retry).setText('Refine') msgBox.button(QMessageBox.Retry).setIcon( QIcon(os.path.dirname(__file__) + f'/search.png')) reply = msgBox.exec_() if reply == QMessageBox.Retry or len(features) == 0: return # Add result feature to the new layer (res, outFeats) = layer.dataProvider().addFeatures(features) # Change layer syle programmatically # Note : if we styling before save and add layer, we avoid to update legend style # => self.iface.layerTreeView().refreshLayerSymbology(vlayer.id()) symbol = layer.renderer().symbol() symbol.setOpacity(0.2) symbol.setColor(color) QgsProject.instance().addMapLayer(layer) # And refresh view layer.triggerRepaint() self.close() except: return
def draw(self): rb = self.tool.rb g = rb.asGeometry() ok = True warning = False errBuffer_noAtt = False errBuffer_Vertices = False layer = self.iface.layerTreeView().currentLayer() if self.toolname == 'drawBuffer': if self.bGeom is None: warning = True errBuffer_noAtt = True else: perim, ok = QInputDialog.getDouble( self.iface.mainWindow(), self.tr('Perimeter'), self.tr('Give a perimeter in m:') + '\n'+self.tr('(works only with metric crs)'), min=0) g = self.bGeom.buffer(perim, 40) rb.setToGeometry(g, QgsVectorLayer( "Polygon?crs="+layer.crs().authid(), "", "memory")) if g.length() == 0 and ok: warning = True errBuffer_Vertices = True if self.toolname == 'drawCopies': if g.length() < 0: warning = True errBuffer_noAtt = True if ok and not warning: name = '' ok = True add = False index = 0 layers = [] while not name.strip() and not add and ok: dlg = QDrawLayerDialog(self.iface, self.drawShape) name, add, index, layers, ok = dlg.getName( self.iface, self.drawShape) if ok and not warning: layer = None if add: layer = layers[index] if self.drawShape in ['point', 'XYpoint']: g = g.centroid() else: if self.drawShape == 'point': layer = QgsVectorLayer("Point?crs="+self.iface.mapCanvas().mapSettings().destinationCrs().authid()+"&field="+self.tr('Drawings')+":string(255)", name, "memory") g = g.centroid() # force geometry as point elif self.drawShape == 'XYpoint': layer = QgsVectorLayer("Point?crs="+self.XYcrs.authid()+"&field="+self.tr('Drawings')+":string(255)", name, "memory") g = g.centroid() elif self.drawShape == 'line': layer = QgsVectorLayer("LineString?crs="+self.iface.mapCanvas().mapSettings().destinationCrs().authid()+"&field="+self.tr('Drawings')+":string(255)", name, "memory") # fix_print_with_import print("LineString?crs="+self.iface.mapCanvas().mapSettings().destinationCrs().authid()+"&field="+self.tr('Drawings')+":string(255)") else: layer = QgsVectorLayer("Polygon?crs="+self.iface.mapCanvas().mapSettings().destinationCrs().authid()+"&field="+self.tr('Drawings')+":string(255)", name, "memory") layer.startEditing() symbols = layer.renderer().symbols(QgsRenderContext()) # todo which context ? symbols[0].setColor(self.settings.getColor()) feature = QgsFeature() feature.setGeometry(g) feature.setAttributes([name]) layer.dataProvider().addFeatures([feature]) layer.commitChanges() if not add: pjt = QgsProject.instance() pjt.addMapLayer(layer, False) if pjt.layerTreeRoot().findGroup(self.tr('Drawings')) is None: pjt.layerTreeRoot().insertChildNode( 0, QgsLayerTreeGroup(self.tr('Drawings'))) group = pjt.layerTreeRoot().findGroup( self.tr('Drawings')) group.insertLayer(0, layer) self.iface.layerTreeView().refreshLayerSymbology(layer.id()) self.iface.mapCanvas().refresh() else: if warning: if errBuffer_noAtt: self.iface.messageBar().pushWarning( self.tr('Warning'), self.tr('You didn\'t click on a layer\'s attribute !')) elif errBuffer_Vertices: self.iface.messageBar().pushWarning( self.tr('Warning'), self.tr('You must give a non-null value for a \ point\'s or line\'s perimeter !')) else: self.iface.messageBar().pushWarning( self.tr('Warning'), self.tr('There is no selected layer, or it is not \ vector nor visible !')) self.tool.reset() self.resetSB() self.bGeom = None
class TestQgsGeometryGeneratorSymbolLayerV2(unittest.TestCase): def setUp(self): self.iface = get_iface() polys_shp = os.path.join(TEST_DATA_DIR, 'polys.shp') points_shp = os.path.join(TEST_DATA_DIR, 'points.shp') lines_shp = os.path.join(TEST_DATA_DIR, 'lines.shp') self.polys_layer = QgsVectorLayer(polys_shp, 'Polygons', 'ogr') self.points_layer = QgsVectorLayer(points_shp, 'Points', 'ogr') self.lines_layer = QgsVectorLayer(lines_shp, 'Lines', 'ogr') QgsProject.instance().addMapLayer(self.polys_layer) QgsProject.instance().addMapLayer(self.lines_layer) QgsProject.instance().addMapLayer(self.points_layer) # Create style sym1 = QgsFillSymbol.createSimple({ 'color': '#fdbf6f', 'outline_color': 'black' }) sym2 = QgsLineSymbol.createSimple({'color': '#fdbf6f'}) sym3 = QgsMarkerSymbol.createSimple({ 'color': '#fdbf6f', 'outline_color': 'black' }) self.polys_layer.setRenderer(QgsSingleSymbolRenderer(sym1)) self.lines_layer.setRenderer(QgsSingleSymbolRenderer(sym2)) self.points_layer.setRenderer(QgsSingleSymbolRenderer(sym3)) self.mapsettings = self.iface.mapCanvas().mapSettings() self.mapsettings.setOutputSize(QSize(400, 400)) self.mapsettings.setOutputDpi(96) self.mapsettings.setExtent(QgsRectangle(-133, 22, -70, 52)) self.report = "<h1>Python QgsGeometryGeneratorSymbolLayer Tests</h1>\n" def tearDown(self): QgsProject.instance().removeAllMapLayers() report_file_path = "%s/qgistest.html" % QDir.tempPath() with open(report_file_path, 'a') as report_file: report_file.write(self.report) def test_basic(self): """ Test getters/setters """ sym_layer = QgsGeometryGeneratorSymbolLayer.create( {'geometryModifier': 'centroid($geometry)'}) self.assertEqual(sym_layer.geometryExpression(), 'centroid($geometry)') sym_layer.setGeometryExpression('project($geometry, 4, 5)') self.assertEqual(sym_layer.geometryExpression(), 'project($geometry, 4, 5)') sym_layer.setSymbolType(Qgis.SymbolType.Marker) self.assertEqual(sym_layer.symbolType(), Qgis.SymbolType.Marker) sym_layer.setUnits(QgsUnitTypes.RenderMillimeters) self.assertEqual(sym_layer.units(), QgsUnitTypes.RenderMillimeters) def test_clone(self): """ Test cloning layer """ sym_layer = QgsGeometryGeneratorSymbolLayer.create( {'geometryModifier': 'centroid($geometry)'}) sym_layer.setSymbolType(Qgis.SymbolType.Marker) sym_layer.setUnits(QgsUnitTypes.RenderMillimeters) sym_layer.subSymbol().symbolLayer(0).setStrokeColor(QColor( 0, 255, 255)) layer2 = sym_layer.clone() self.assertEqual(layer2.symbolType(), Qgis.SymbolType.Marker) self.assertEqual(layer2.units(), QgsUnitTypes.RenderMillimeters) self.assertEqual(layer2.geometryExpression(), 'centroid($geometry)') self.assertEqual(layer2.subSymbol()[0].strokeColor(), QColor(0, 255, 255)) def test_properties_create(self): """ Test round trip through properties and create """ sym_layer = QgsGeometryGeneratorSymbolLayer.create( {'geometryModifier': 'centroid($geometry)'}) sym_layer.setSymbolType(Qgis.SymbolType.Marker) sym_layer.setUnits(QgsUnitTypes.RenderMillimeters) layer2 = QgsGeometryGeneratorSymbolLayer.create(sym_layer.properties()) self.assertEqual(layer2.symbolType(), Qgis.SymbolType.Marker) self.assertEqual(layer2.units(), QgsUnitTypes.RenderMillimeters) self.assertEqual(layer2.geometryExpression(), 'centroid($geometry)') def test_color(self): """ Test that subsymbol color is returned for symbol layer """ sym_layer = QgsGeometryGeneratorSymbolLayer.create( {'geometryModifier': 'buffer($geometry, 2)'}) sym_layer.setSymbolType(Qgis.SymbolType.Fill) sym_layer.setUnits(QgsUnitTypes.RenderMillimeters) sym_layer.subSymbol().symbolLayer(0).setColor(QColor(0, 255, 255)) self.assertEqual(sym_layer.color(), QColor(0, 255, 255)) def test_marker(self): sym = self.polys_layer.renderer().symbol() sym_layer = QgsGeometryGeneratorSymbolLayer.create( {'geometryModifier': 'centroid($geometry)'}) sym_layer.setSymbolType(QgsSymbol.Marker) sym_layer.subSymbol().symbolLayer(0).setStrokeColor(QColor(0, 0, 0)) sym.changeSymbolLayer(0, sym_layer) rendered_layers = [self.polys_layer] self.mapsettings.setLayers(rendered_layers) renderchecker = QgsMultiRenderChecker() renderchecker.setMapSettings(self.mapsettings) renderchecker.setControlName('expected_geometrygenerator_marker') res = renderchecker.runTest('geometrygenerator_marker') self.report += renderchecker.report() self.assertTrue(res) def test_mixed(self): sym = self.polys_layer.renderer().symbol() buffer_layer = QgsGeometryGeneratorSymbolLayer.create({ 'geometryModifier': 'buffer($geometry, "value"/15)', 'outline_color': 'black' }) buffer_layer.setSymbolType(QgsSymbol.Fill) buffer_layer.subSymbol().symbolLayer(0).setStrokeColor(QColor(0, 0, 0)) self.assertIsNotNone(buffer_layer.subSymbol()) sym.appendSymbolLayer(buffer_layer) marker_layer = QgsGeometryGeneratorSymbolLayer.create({ 'geometryModifier': 'centroid($geometry)', 'outline_color': 'black' }) marker_layer.setSymbolType(QgsSymbol.Marker) marker_layer.subSymbol().symbolLayer(0).setStrokeColor(QColor(0, 0, 0)) sym.appendSymbolLayer(marker_layer) rendered_layers = [self.polys_layer] self.mapsettings.setLayers(rendered_layers) renderchecker = QgsMultiRenderChecker() renderchecker.setMapSettings(self.mapsettings) renderchecker.setControlName('expected_geometrygenerator_mixed') res = renderchecker.runTest('geometrygenerator_mixed') self.report += renderchecker.report() self.assertTrue(res) def test_buffer_lines(self): sym = self.lines_layer.renderer().symbol() buffer_layer = QgsGeometryGeneratorSymbolLayer.create({ 'geometryModifier': 'buffer($geometry, "value"/15)', 'outline_color': 'black' }) buffer_layer.setSymbolType(QgsSymbol.Fill) self.assertIsNotNone(buffer_layer.subSymbol()) sym.appendSymbolLayer(buffer_layer) rendered_layers = [self.lines_layer] self.mapsettings.setLayers(rendered_layers) renderchecker = QgsMultiRenderChecker() renderchecker.setMapSettings(self.mapsettings) renderchecker.setControlName('expected_geometrygenerator_buffer_lines') res = renderchecker.runTest('geometrygenerator_buffer_lines') self.report += renderchecker.report() self.assertTrue(res) def test_buffer_points(self): sym = self.points_layer.renderer().symbol() buffer_layer = QgsGeometryGeneratorSymbolLayer.create({ 'geometryModifier': 'buffer($geometry, "staff"/15)', 'outline_color': 'black' }) buffer_layer.setSymbolType(QgsSymbol.Fill) self.assertIsNotNone(buffer_layer.subSymbol()) sym.appendSymbolLayer(buffer_layer) rendered_layers = [self.points_layer] self.mapsettings.setLayers(rendered_layers) renderchecker = QgsMultiRenderChecker() renderchecker.setMapSettings(self.mapsettings) renderchecker.setControlName( 'expected_geometrygenerator_buffer_points') res = renderchecker.runTest('geometrygenerator_buffer_points') self.report += renderchecker.report() self.assertTrue(res) def test_units_millimeters(self): sym = self.points_layer.renderer().symbol() buffer_layer = QgsGeometryGeneratorSymbolLayer.create({ 'geometryModifier': 'buffer($geometry, "staff")', 'outline_color': 'black' }) buffer_layer.setSymbolType(QgsSymbol.Fill) buffer_layer.setUnits(QgsUnitTypes.RenderMillimeters) self.assertIsNotNone(buffer_layer.subSymbol()) sym.appendSymbolLayer(buffer_layer) rendered_layers = [self.points_layer] self.mapsettings.setLayers(rendered_layers) renderchecker = QgsMultiRenderChecker() renderchecker.setMapSettings(self.mapsettings) renderchecker.setControlName('expected_geometrygenerator_millimeters') res = renderchecker.runTest('geometrygenerator_millimeters') self.report += renderchecker.report() self.assertTrue(res) def test_multi_poly_opacity(self): # test that multi-type features are only rendered once multipoly = QgsVectorLayer( os.path.join(TEST_DATA_DIR, 'multipatch.shp'), 'Polygons', 'ogr') sym = QgsFillSymbol.createSimple({ 'color': '#77fdbf6f', 'outline_color': 'black' }) buffer_layer = QgsGeometryGeneratorSymbolLayer.create({ 'geometryModifier': 'buffer($geometry, -0.01)', 'outline_color': 'black' }) buffer_layer.setSymbolType(QgsSymbol.Fill) buffer_layer.setSubSymbol(sym) geom_symbol = QgsFillSymbol() geom_symbol.changeSymbolLayer(0, buffer_layer) multipoly.renderer().setSymbol(geom_symbol) mapsettings = QgsMapSettings(self.mapsettings) mapsettings.setExtent(multipoly.extent()) mapsettings.setLayers([multipoly]) renderchecker = QgsMultiRenderChecker() renderchecker.setMapSettings(mapsettings) renderchecker.setControlName('expected_geometrygenerator_opacity') res = renderchecker.runTest('geometrygenerator_opacity') self.report += renderchecker.report() self.assertTrue(res) def test_no_feature(self): """ Test rendering as a pure symbol, no feature associated """ buffer_layer = QgsGeometryGeneratorSymbolLayer.create( {'geometryModifier': 'buffer($geometry, 5)'}) buffer_layer.setSymbolType(QgsSymbol.Fill) buffer_layer.setUnits(QgsUnitTypes.RenderMillimeters) self.assertIsNotNone(buffer_layer.subSymbol()) symbol = QgsLineSymbol() symbol.changeSymbolLayer(0, buffer_layer) image = QImage(400, 400, QImage.Format_RGB32) image.fill(QColor(255, 255, 255)) painter = QPainter(image) context = QgsRenderContext.fromQPainter(painter) symbol.startRender(context) symbol.renderPolyline( QPolygonF([QPointF(50, 200), QPointF(100, 170), QPointF(350, 270)]), None, context) symbol.stopRender(context) painter.end() self.assertTrue( self.imageCheck('geometrygenerator_nofeature', 'geometrygenerator_nofeature', image)) def test_no_feature_coordinate_transform(self): """ Test rendering as a pure symbol, no feature associated, with coordinate transform """ buffer_layer = QgsGeometryGeneratorSymbolLayer.create( {'geometryModifier': 'buffer($geometry, 5)'}) buffer_layer.setSymbolType(QgsSymbol.Fill) buffer_layer.setUnits(QgsUnitTypes.RenderMillimeters) self.assertIsNotNone(buffer_layer.subSymbol()) symbol = QgsLineSymbol() symbol.changeSymbolLayer(0, buffer_layer) image = QImage(400, 400, QImage.Format_RGB32) image.fill(QColor(255, 255, 255)) painter = QPainter(image) context = QgsRenderContext.fromQPainter(painter) context.setCoordinateTransform( QgsCoordinateTransform(QgsCoordinateReferenceSystem('EPSG:4326'), QgsCoordinateReferenceSystem('EPSG:3857'), QgsProject.instance().transformContext())) symbol.startRender(context) symbol.renderPolyline( QPolygonF([QPointF(50, 200), QPointF(100, 170), QPointF(350, 270)]), None, context) symbol.stopRender(context) painter.end() self.assertTrue( self.imageCheck('geometrygenerator_nofeature', 'geometrygenerator_nofeature', image)) def imageCheck(self, name, reference_image, image): self.report += "<h2>Render {}</h2>\n".format(name) temp_dir = QDir.tempPath() + '/' file_name = temp_dir + name + ".png" image.save(file_name, "PNG") checker = QgsRenderChecker() checker.setControlName("expected_" + reference_image) checker.setRenderedImage(file_name) checker.setColorTolerance(2) result = checker.compareImages(name, 0) self.report += checker.report() print((self.report)) return result
def run(self): """Run method that performs all the real work""" # Create the dialog with elements (after translation) and keep reference # Only create GUI ONCE in callback, so that it will only load when the plugin is started if self.first_start == True: self.first_start = False self.dlg = HealthSIGDialog() # Clear the contents of the comboBox from previous runs self.dlg.comboBox.clear() # Populate the comboBox self.dlg.comboBox.addItems(["Hospitais", "ACES", "Farmácias"]) # show the dialog self.dlg.show() # Run the dialog event loop result = self.dlg.exec_() # See if OK was pressed and check index index = self.dlg.comboBox.currentIndex() # file directory for relative paths dirn = os.path.dirname(__file__) # escolheu unidades de saude if result and index == 1: # create layer vl = QgsVectorLayer("Point?crs=epsg:3763&index=yes", "aces", "memory") pr = vl.dataProvider() # Enter editing mode vl.startEditing() # add fields pr.addAttributes([ QgsField("ACES", QVariant.String), QgsField("ARS", QVariant.String), QgsField("Coord_X", QVariant.Double), QgsField("Coord_Y", QVariant.Double), QgsField("Num_USF", QVariant.Int) ]) vl.updateFields( ) # tell the vector layer to fetch changes from the provider # add features ---> IR BUSCAR AO JSON.... filename = os.path.join(dirn, 'unidades_saude.json') #with open("/home/skywalker/.local/share/QGIS/QGIS3/profiles/default/python/plugins/health_sig/unidades_saude.json", # "r") as read_file: with open(filename, "r") as read_file: json_file = json.load(read_file) # transformar coordenadas gps para as pretendidas crsSrc = QgsCoordinateReferenceSystem(4326) # gps crsDest = QgsCoordinateReferenceSystem(3763) # pt xform = QgsCoordinateTransform(crsSrc, crsDest, QgsProject.instance()) # addfeatures for entry in json_file: if entry["fields"]["tempo"] == "2019-01": # valores recentes x_coord = float(entry["geometry"]["coordinates"][0]) y_coord = float(entry["geometry"]["coordinates"][1]) num_usf = int( entry["fields"] ["total_usf"]) #numero de unidades de saude familiares entidade = entry["fields"]["entidade"] ars = entry["fields"]["ars"] fet = QgsFeature() fet.setGeometry(QgsGeometry().buffer( distance=num_usf * 10, segments=100).fromPointXY( xform.transform(QgsPointXY(x_coord, y_coord)))) fet.setAttributes([ QVariant(entidade), QVariant(ars), QVariant(x_coord), QVariant(y_coord), QVariant(num_usf) ]) pr.addFeatures([fet]) vl.updateExtents() vl.commitChanges() # fazer render categorizado features = vl.getFeatures() categories = [] for feat in features: f = feat.attributes()[4] # num_usf entidade = feat.attributes()[0] # entidade symbol = QgsSymbol.defaultSymbol(vl.geometryType()) svgStyle = {} path_uni = os.path.join(dirn, 'medicine.svg') svgStyle['name'] = path_uni svgStyle['size'] = str((f / 10) + 1) symbol_layer = QgsSvgMarkerSymbolLayer.create(svgStyle) if symbol_layer is not None: symbol.changeSymbolLayer(0, symbol_layer) # create renderer object category = QgsRendererCategory(f, symbol, str(entidade)) # entry for the list of category items categories.append(category) # create renderer object renderer = QgsCategorizedSymbolRenderer('Num_USF', categories) # assign the created renderer to the layer if renderer is not None: vl.setRenderer(renderer) vl.triggerRepaint() QgsProject.instance().addMapLayer(vl) # hospitais elif result and index == 0: vl = QgsVectorLayer("Point?crs=epsg:3763&index=yes", "hospitais", "memory") pr = vl.dataProvider() # Enter editing mode vl.startEditing() # add fields pr.addAttributes([ QgsField("Hospital", QVariant.String), QgsField("Morada", QVariant.String), QgsField("Coord_X", QVariant.Double), QgsField("Coord_Y", QVariant.Double) ]) vl.updateFields( ) # tell the vector layer to fetch changes from the provider # add features ---> IR BUSCAR AO JSON.... filename = os.path.join(dirn, 'hospitais.json') with open(filename, "r") as read_file: json_file = json.load(read_file) # transformar coordenadas gps para as pretendidas crsSrc = QgsCoordinateReferenceSystem(4326) # gps crsDest = QgsCoordinateReferenceSystem(3763) # pt xform = QgsCoordinateTransform(crsSrc, crsDest, QgsProject.instance()) # addfeatures for entry in json_file.keys(): x_coord = float(json_file[entry][1][1]) y_coord = float(json_file[entry][1][0]) morada = json_file[entry][0] fet = QgsFeature() fet.setGeometry(QgsGeometry().fromPointXY( xform.transform(QgsPointXY(x_coord, y_coord)))) fet.setAttributes([ QVariant(entry), QVariant(morada), QVariant(x_coord), QVariant(y_coord) ]) pr.addFeatures([fet]) vl.updateExtents() vl.commitChanges() #symbol = QgsMarkerSymbol.createSimple({'name': 'square', 'color': 'red'}) svgStyle = {} path_hosp = os.path.join(dirn, 'hospital.svg') svgStyle['name'] = path_hosp svgStyle['size'] = '6' symbol_layer = QgsSvgMarkerSymbolLayer.create(svgStyle) symbol = QgsSymbol.defaultSymbol(vl.geometryType()) #vl.renderer().setSymbol(symbol) symbol.changeSymbolLayer(0, symbol_layer) vl.renderer().setSymbol(symbol) # show the change vl.triggerRepaint() QgsProject.instance().addMapLayer(vl) # farmacias elif result and index == 2: vl = QgsVectorLayer("Point?crs=epsg:3763&index=yes", "farmacias", "memory") pr = vl.dataProvider() # Enter editing mode vl.startEditing() # add fields pr.addAttributes([ QgsField("Farmácia", QVariant.String), QgsField("Morada", QVariant.String), QgsField("Coord_X", QVariant.Double), QgsField("Coord_Y", QVariant.Double) ]) vl.updateFields( ) # tell the vector layer to fetch changes from the provider # add features ---> IR BUSCAR AO JSON.... filename = os.path.join(dirn, 'farmacias.json') with open(filename, "r") as read_file: json_file = json.load(read_file) # transformar coordenadas gps para as pretendidas crsSrc = QgsCoordinateReferenceSystem(4326) # gps crsDest = QgsCoordinateReferenceSystem(3763) # pt xform = QgsCoordinateTransform(crsSrc, crsDest, QgsProject.instance()) # addfeatures for entry in json_file.keys(): x_coord = float(json_file[entry][1][1]) y_coord = float(json_file[entry][1][0]) morada = json_file[entry][0] fet = QgsFeature() fet.setGeometry(QgsGeometry().fromPointXY( xform.transform(QgsPointXY(x_coord, y_coord)))) fet.setAttributes([ QVariant(entry), QVariant(morada), QVariant(x_coord), QVariant(y_coord) ]) pr.addFeatures([fet]) vl.updateExtents() vl.commitChanges() #symbol = QgsMarkerSymbol.createSimple({'name': 'square', 'color': 'purplet'}) #vl.renderer().setSymbol(symbol) svgStyle = {} path_farm = os.path.join(dirn, 'pharmacy.svg') svgStyle['name'] = path_farm svgStyle['size'] = '4' symbol_layer = QgsSvgMarkerSymbolLayer.create(svgStyle) symbol = QgsSymbol.defaultSymbol(vl.geometryType()) # vl.renderer().setSymbol(symbol) symbol.changeSymbolLayer(0, symbol_layer) vl.renderer().setSymbol(symbol) # show the change vl.triggerRepaint() QgsProject.instance().addMapLayer(vl)
def saveToLayer(self): units = self.unitDesignator() canvasCrs = self.canvas.mapSettings().destinationCrs() fields = QgsFields() fields.append(QgsField("label", QVariant.String)) fields.append(QgsField("value", QVariant.Double)) fields.append(QgsField("units", QVariant.String)) fields.append(QgsField("heading_to", QVariant.Double)) fields.append(QgsField("heading_from", QVariant.Double)) fields.append(QgsField("total_dist", QVariant.Double)) layer = QgsVectorLayer("LineString?crs={}".format(canvasCrs.authid()), "Measurements", "memory") dp = layer.dataProvider() dp.addAttributes(fields) layer.updateFields() num = len(self.capturedPoints) total = 0.0 for i in range(1, num): (distance, startA, endA) = self.calcParameters(self.capturedPoints[i - 1], self.capturedPoints[i]) total += distance total = self.unitDistance(total) for i in range(1, num): (distance, startA, endA) = self.calcParameters(self.capturedPoints[i - 1], self.capturedPoints[i]) pts = self.getLinePts(distance, self.capturedPoints[i - 1], self.capturedPoints[i]) distance = self.unitDistance(distance) feat = QgsFeature(layer.fields()) feat.setAttribute(0, "{:.2f} {}".format(distance, units)) feat.setAttribute(1, distance) feat.setAttribute(2, units) feat.setAttribute(3, startA) feat.setAttribute(4, endA) feat.setAttribute(5, total) feat.setGeometry(QgsGeometry.fromPolylineXY(pts)) dp.addFeatures([feat]) label = QgsPalLayerSettings() label.fieldName = 'label' try: label.placement = QgsPalLayerSettings.Line except Exception: label.placement = QgsPalLayerSettings.AboveLine format = label.format() format.setColor(settings.measureTextColor) format.setNamedStyle('Bold') label.setFormat(format) labeling = QgsVectorLayerSimpleLabeling(label) layer.setLabeling(labeling) layer.setLabelsEnabled(True) renderer = layer.renderer() renderer.symbol().setColor(settings.measureLineColor) renderer.symbol().setWidth(0.5) layer.updateExtents() QgsProject.instance().addMapLayer(layer)
class Geonet: """QGIS Plugin Implementation.""" def __init__(self, iface): """Constructor. :param iface: An interface instance that will be passed to this class which provides the hook by which you can manipulate the QGIS application at run time. :type iface: QgsInterface """ # Save reference to the QGIS interface self.iface = iface # initialize plugin directory self.plugin_dir = os.path.dirname(__file__) # initialize locale locale = QSettings().value('locale/userLocale')[0:2] locale_path = os.path.join(self.plugin_dir, 'i18n', 'Geonet_{}.qm'.format(locale)) if os.path.exists(locale_path): self.translator = QTranslator() self.translator.load(locale_path) if qVersion() > '4.3.3': QCoreApplication.installTranslator(self.translator) # Declare instance attributes self.actions = [] self.menu = self.tr(u'&Geonet') # Check if plugin was started the first time in current QGIS session # Must be set in initGui() to survive plugin reloads self.first_start = None # noinspection PyMethodMayBeStatic def tr(self, message): """Get the translation for a string using Qt translation API. We implement this ourselves since we do not inherit QObject. :param message: String for translation. :type message: str, QString :returns: Translated version of message. :rtype: QString """ # noinspection PyTypeChecker,PyArgumentList,PyCallByClass return QCoreApplication.translate('Geonet', message) def add_action(self, icon_path, text, callback, enabled_flag=True, add_to_menu=True, add_to_toolbar=True, status_tip=None, whats_this=None, parent=None): """Add a toolbar icon to the toolbar. :param icon_path: Path to the icon for this action. Can be a resource path (e.g. ':/plugins/foo/bar.png') or a normal file system path. :type icon_path: str :param text: Text that should be shown in menu items for this action. :type text: str :param callback: Function to be called when the action is triggered. :type callback: function :param enabled_flag: A flag indicating if the action should be enabled by default. Defaults to True. :type enabled_flag: bool :param add_to_menu: Flag indicating whether the action should also be added to the menu. Defaults to True. :type add_to_menu: bool :param add_to_toolbar: Flag indicating whether the action should also be added to the toolbar. Defaults to True. :type add_to_toolbar: bool :param status_tip: Optional text to show in a popup when mouse pointer hovers over the action. :type status_tip: str :param parent: Parent widget for the new action. Defaults None. :type parent: QWidget :param whats_this: Optional text to show in the status bar when the mouse pointer hovers over the action. :returns: The action that was created. Note that the action is also added to self.actions list. :rtype: QAction """ icon = QIcon(icon_path) action = QAction(icon, text, parent) action.triggered.connect(callback) action.setEnabled(enabled_flag) if status_tip is not None: action.setStatusTip(status_tip) if whats_this is not None: action.setWhatsThis(whats_this) if add_to_toolbar: # Adds plugin icon to Plugins toolbar self.iface.addToolBarIcon(action) if add_to_menu: self.iface.addPluginToMenu(self.menu, action) self.actions.append(action) return action def initGui(self): """Create the menu entries and toolbar icons inside the QGIS GUI.""" self.add_action('D:/Code/QGIS_Plugin/geonet/feature.png', text=self.tr(u'Import feaure'), callback=self.import_feature, parent=self.iface.mainWindow()) self.add_action('D:/Code/QGIS_Plugin/geonet/dangle.png', text=self.tr(u'Clean dangle nodes'), callback=self.dangle_clean, parent=self.iface.mainWindow()) self.add_action('D:/Code/QGIS_Plugin/geonet/pseudo.png', text=self.tr(u'Clean pseudo nodes'), callback=self.pseudo_clean, parent=self.iface.mainWindow()) self.add_action('D:/Code/QGIS_Plugin/geonet/graph.png', text=self.tr(u'Build graph'), callback=self.graph_build, parent=self.iface.mainWindow()) self.add_action('D:/Code/QGIS_Plugin/geonet/shortpath.png', text=self.tr(u'Shortest Path'), callback=self.shortest_path, parent=self.iface.mainWindow()) # init params self.resDlg = GeonetTableView() self.model = QStandardItemModel() self.resDlg.tView.verticalHeader().hide() self.resDlg.tView.setSelectionBehavior(QAbstractItemView.SelectRows) self.resDlg.tView.setSelectionMode(QAbstractItemView.SingleSelection) self.resDlg.tView.setEditTriggers(QAbstractItemView.NoEditTriggers) self.resDlg.tView.clicked.connect(self._zoom_to_feat) self.canvas = self.iface.mapCanvas() self.corrSet = set() self.errSet = set() self.errFeatMap = defaultdict(set) self.errPointList = [] self.newFeatMap = {} self._id = 0 self.iNode = [] self.featLayer = None self.g = None self.tool = PointTool(self.iface.mapCanvas()) self.tool.trigger.connect(self._add_node_selected) self.iface.mapCanvas().setMapTool(self.tool) # will be set False in run() self.first_start = True def unload(self): """Removes the plugin menu item and icon from QGIS GUI.""" for action in self.actions: self.iface.removePluginMenu(self.tr(u'&Geonet'), action) self.iface.removeToolBarIcon(action) def import_feature(self): """Run method that performs all the real work""" # Create the dialog with elements (after translation) and keep reference # Only create GUI ONCE in callback, so that it will only load when the plugin is started if self.first_start == True: self.first_start = False self.dlg = FeatInputDialog() self.dlg.mLayerComboBox.clear() self.errFeatMap.clear() self.newFeatMap.clear() layers = list(QgsProject.instance().mapLayers().values()) for layer in layers: if layer.type() == layer.VectorLayer: self.dlg.mLayerComboBox.addItem(layer.name()) # show the dialog self.dlg.show() # Run the dialog event loop result = self.dlg.exec_() # See if OK was pressed if result: self.featLayer = layers[self.dlg.mLayerComboBox.currentIndex()] lineFeatIter = self.featLayer.getFeatures() # Find pseudo points list(map(self._map_point_to_feat, lineFeatIter)) self.tool.activate() def dangle_clean(self): if self.featLayer is None: QMessageBox.warning(None, "Warning", "Please choose a feature first!") return self.model.setHorizontalHeaderLabels( ["Point_X", "Point_Y", "Feature ID"]) self.dangleList = [] for (point, feat_ids) in self.errFeatMap.items(): if len(feat_ids) == 1: # Pseudo node self.dangleList.extend(map(lambda x: (point, x), feat_ids)) self._render_table(self.dangleList) self._render_err_layer("dangle", [x for (x, _) in self.dangleList]) self.resDlg.show() result = self.resDlg.exec_() if result: pass self.model.clear() def pseudo_clean(self): if self.featLayer is None: QMessageBox.warning(None, "Warning", "Please choose a feature first!") return self.model.setHorizontalHeaderLabels( ["Point_X", "Point_Y", "Feature ID"]) self.pseduoList = [] for (point, feat_ids) in self.errFeatMap.items(): if len(feat_ids) == 2: # Pseudo node self.pseduoList.extend(map(lambda x: (point, x), feat_ids)) self._render_table(self.pseduoList) self._render_err_layer("pseudo", [x for (x, _) in self.pseduoList]) self.resDlg.show() result = self.resDlg.exec_() if result: self.pBar = WaitProgressDialog() self.thread = WorkThread(net=self) cancelButton = QPushButton("Cancel") self.pBar.setCancelButton(cancelButton) cancelButton.clicked.connect(self.thread.terminate) cancelButton.setGeometry(100, 100, 100, 100) self.pBar.show() self.thread.start() # self._render_corr_layer("pseudo", feat_set.values()) self.model.clear() def graph_build(self): if self.featLayer is None: QMessageBox.warning(None, "Warning", "Please choose a feature first!") return self.g = nx.Graph() featIter = self.featLayer.getFeatures() self.node_map = {} self.node_set = set() self.weighted_edges = [] self.node_id = 0 list(map(self._map_point_to_edge, featIter)) self.g.add_weighted_edges_from(self.weighted_edges) self._render_node_layer(self.g.nodes()) # self.tool.activate() def shortest_path(self): if self.g is None: QMessageBox.warning(None, "Warning", "Please build the graph first!") return if len(self.iNode) > 1: startNode, endNode = self.iNode[0].geometry().asPoint( ), self.iNode[1].geometry().asPoint() _route = nx.shortest_path(self.g, startNode, endNode) self.iNode.clear() self.featLayer.removeSelection() self.canvas.refresh() self._render_route_layer(_route) # self.tool.deactivate() def _clean_work_by_thread(self): print("----- Clean work start -----") # Union find feature set featCount = len(self.newFeatMap) _father = [i for i in range(0, featCount)] _rank = [0] * featCount def _find(x): if _father[x] != x: _father[x] = _find(_father[x]) return _father[x] def _union(x, y): _x = _find(x) _y = _find(y) if _x == _y: return if _rank[_x] < _rank[_y]: _father[_x] = _y elif _rank[_x] > _rank[_y]: _father[_y] = _x else: _father[_y] = _x _rank[x] += 1 for (_, feat_ids) in self.errFeatMap.items(): feat_ids = list(feat_ids) for feat_id in feat_ids[1:]: _union(feat_id, feat_ids[0]) feat_set = defaultdict(list) for idx, feat in enumerate(_father): feat_set[feat].append(idx) print('----- Render work start -----') self._render_corr_layer("pseudo", feat_set.values()) def _map_point_to_feat(self, feat): geom = feat.geometry() # Map features as point to id if geom.isMultipart(): for line in geom.asGeometryCollection(): new_feat = QgsFeature(self._id) new_feat.setGeometry(line) self._id += 1 startPoint, endPoint = line.asPolyline()[0], line.asPolyline( )[-1] self.newFeatMap[new_feat.id()] = new_feat self.errFeatMap[startPoint].add(new_feat.id()) self.errFeatMap[endPoint].add(new_feat.id()) else: new_feat = QgsFeature(self._id) new_feat.setGeometry(geom) self._id += 1 startPoint, endPoint = geom.asPolyline()[0], geom.asPolyline()[-1] self.newFeatMap[new_feat.id()] = new_feat self.errFeatMap[startPoint].add(new_feat.id()) self.errFeatMap[endPoint].add(new_feat.id()) def _map_point_to_edge(self, feat): geom = feat.geometry() weighted_edges = [] if geom.isMultipart(): for line in geom.asGeometryCollection(): startPoint, endPoint = line.asPolyline()[0], line.asPolyline( )[-1] startNode = QgsFeature() startNode.setGeometry(QgsGeometry.fromPointXY(startPoint)) # self.node_id += 1 endNode = QgsFeature() endNode.setGeometry(QgsGeometry.fromPointXY(endPoint)) # self.node_id += 1 self.weighted_edges.append( (startPoint, endPoint, line.length())) else: startPoint, endPoint = geom.asPolyline()[0], geom.asPolyline()[-1] startNode = QgsFeature(self.node_id) startNode.setGeometry(QgsGeometry.fromPointXY(startPoint)) self.node_id += 1 endNode = QgsFeature(self.node_id) endNode.setGeometry(QgsGeometry.fromPointXY(endPoint)) self.node_id += 1 self.weighted_edges.append((startNode, endNode, geom.length())) def _zoom_to_feat(self, item): # Clear previous selection for layer in self.canvas.layers(): if layer.type() == layer.VectorLayer: layer.removeSelection() self.canvas.refresh() # Get id of feature selected feat_id = self.model.item(item.row(), 2).data(0) self.featLayer.select(int(feat_id)) # Zoom canvas self.canvas.zoomToSelected(self.featLayer) self.canvas.refresh() def _render_table(self, list): for (idx, err) in enumerate(list): self.model.setItem(idx, 0, QStandardItem(str(err[0].x()))) self.model.setItem(idx, 1, QStandardItem(str(err[0].y()))) self.model.setItem(idx, 2, QStandardItem(str(err[1]))) self.resDlg.tView.setModel(self.model) # self.resDlg.tView.selectionModel().currentRowChanged.connect(self.zoom_to_feature) w = self.resDlg.tView.width() self.resDlg.tView.setColumnWidth(0, w / 3 - 1) self.resDlg.tView.setColumnWidth(1, w / 3 - 1) self.resDlg.tView.setColumnWidth(2, w - 2 * w / 3 - 2) def _render_err_layer(self, name, _list): self.errLayer = QgsVectorLayer( "Point?crs=" + self.featLayer.crs().authid(), self.featLayer.name() + "_" + name + "_Nodes", "memory") errPr = self.errLayer.dataProvider() self.errLayer.startEditing() feats = map(self._gen_point_feats, _list) errPr.addFeatures(feats) self.errLayer.commitChanges() self._add_layer(self.errLayer) def _render_corr_layer(self, name, _list): # Init correct layer self.corrLayer = QgsVectorLayer( "LineString?crs=" + self.featLayer.crs().authid(), self.featLayer.name() + "_" + name + "_Correct", "memory") corrPr = self.corrLayer.dataProvider() self.corrLayer.startEditing() # Generate new features feats = map(self._gen_corr_feats, _list) corrPr.addFeatures(feats) self.corrLayer.commitChanges() # self._add_layer(self.corrLayer) def _render_route_layer(self, _list): self.routeLayer = QgsVectorLayer( "LineString?crs=" + self.featLayer.crs().authid(), self.featLayer.name() + "_Route", "memory") routePr = self.routeLayer.dataProvider() self.routeLayer.startEditing() _symbol = QgsLineSymbol() _symbol.appendSymbolLayer(QgsArrowSymbolLayer()) self.routeLayer.renderer().setSymbol(_symbol) for idx in range(len(_list) - 1): route_seg = [_list[idx], _list[idx + 1]] feat = QgsFeature() feat.setGeometry(QgsGeometry.fromPolylineXY(route_seg)) routePr.addFeatures([feat]) self.routeLayer.commitChanges() self._add_layer(self.routeLayer) # self.canvas.refresh() def _render_node_layer(self, _list): self.nodeLayer = QgsVectorLayer( "Point?crs=" + self.featLayer.crs().authid(), self.featLayer.name() + "_Graph_Vertex", "memory") nodePr = self.nodeLayer.dataProvider() self.nodeLayer.startEditing() # Generate new features feats = map(self._gen_point_feats, _list) # feats = _list nodePr.addFeatures(feats) self.nodeLayer.commitChanges() self._add_layer(self.nodeLayer) def _add_layer(self, layer): QgsProject.instance().addMapLayer(layer) def _add_node_selected(self, node): self.iNode.append(node) self.nodeLayer.select([x.id() for x in self.iNode]) def _gen_point_feats(self, p): feat = QgsFeature() feat.setGeometry(QgsGeometry.fromPointXY(p)) return feat def _gen_corr_feats(self, feat_ids): new_feat = QgsFeature() geom = new_feat.geometry() # Combine features for idx, feat_id in enumerate(feat_ids): feat = self.newFeatMap[feat_id] if idx == 0: new_feat.setGeometry(feat.geometry()) geom = new_feat.geometry() else: geom = geom.combine(feat.geometry()) new_feat.setGeometry(geom) return new_feat def _add_corr_layer(self): QgsProject.instance().addMapLayer(self.corrLayer)
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') QgsProject.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): QgsProject.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 = QgsProperty.fromExpression("(@geometry_point_num % 4) * 2") sym_layer.setDataDefinedProperty(QgsSymbolLayer.PropertyArrowWidth, dd) dd2 = QgsProperty.fromExpression("(@geometry_point_num % 4) * 2") sym_layer.setDataDefinedProperty(QgsSymbolLayer.PropertyArrowHeadLength, dd2) dd3 = QgsProperty.fromExpression("(@geometry_point_num % 4) * 2") sym_layer.setDataDefinedProperty(QgsSymbolLayer.PropertyArrowHeadThickness, 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] 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] 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] 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] 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))
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') QgsProject.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): QgsProject.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 = QgsProperty.fromExpression("(@geometry_point_num % 4) * 2") sym_layer.setDataDefinedProperty(QgsSymbolLayer.PropertyArrowWidth, dd) dd2 = QgsProperty.fromExpression("(@geometry_point_num % 4) * 2") sym_layer.setDataDefinedProperty( QgsSymbolLayer.PropertyArrowHeadLength, dd2) dd3 = QgsProperty.fromExpression("(@geometry_point_num % 4) * 2") sym_layer.setDataDefinedProperty( QgsSymbolLayer.PropertyArrowHeadThickness, 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] 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] 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] 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] 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))
class TestQgsPointClusterRenderer(unittest.TestCase): def setUp(self): myShpFile = os.path.join(TEST_DATA_DIR, 'points.shp') self.layer = QgsVectorLayer(myShpFile, 'Points', 'ogr') QgsProject.instance().addMapLayer(self.layer) self.renderer = QgsPointClusterRenderer() sym1 = QgsMarkerSymbol.createSimple({'color': '#ff00ff', 'size': '3', 'outline_style': 'no'}) renderer = QgsSingleSymbolRenderer(sym1) self.renderer.setEmbeddedRenderer(renderer) self.renderer.setClusterSymbol(QgsMarkerSymbol.createSimple({'color': '#ffff00', 'size': '3', 'outline_style': 'no'})) self.layer.setRenderer(self.renderer) rendered_layers = [self.layer] 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): QgsProject.instance().removeAllMapLayers() def _setProperties(self, r): """ set properties for a renderer for testing with _checkProperties""" 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) def _checkProperties(self, r): """ test properties of renderer against expected""" self.assertEqual(r.tolerance(), 5) self.assertEqual(r.toleranceUnit(), QgsUnitTypes.RenderMapUnits) self.assertEqual(r.toleranceMapUnitScale(), QgsMapUnitScale(5, 15)) self.assertEqual(r.clusterSymbol().color(), QColor(0, 255, 0)) self.assertEqual(r.embeddedRenderer().symbol().color().name(), '#fdbf6f') def testGettersSetters(self): """ test getters and setters """ r = QgsPointClusterRenderer() self._setProperties(r) self._checkProperties(r) def testClone(self): """ test cloning renderer """ r = QgsPointClusterRenderer() self._setProperties(r) c = r.clone() self._checkProperties(c) def testSaveCreate(self): """ test saving and recreating from XML """ r = QgsPointClusterRenderer() self._setProperties(r) doc = QDomDocument("testdoc") elem = r.save(doc, QgsReadWriteContext()) c = QgsPointClusterRenderer.create(elem, QgsReadWriteContext()) self._checkProperties(c) def testConvert(self): """ test renderer conversion """ # same type, should clone r = QgsPointClusterRenderer() self._setProperties(r) c = QgsPointClusterRenderer.convertFromRenderer(r) self._checkProperties(c) # test conversion from displacement renderer r = QgsPointDisplacementRenderer() r.setTolerance(5) r.setToleranceUnit(QgsUnitTypes.RenderMapUnits) r.setToleranceMapUnitScale(QgsMapUnitScale(5, 15)) m = QgsMarkerSymbol() m.setColor(QColor(0, 255, 0)) r.setCenterSymbol(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 = QgsPointClusterRenderer.convertFromRenderer(r) self.assertEqual(d.tolerance(), 5) self.assertEqual(d.toleranceUnit(), QgsUnitTypes.RenderMapUnits) self.assertEqual(d.toleranceMapUnitScale(), QgsMapUnitScale(5, 15)) self.assertEqual(d.clusterSymbol().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('cluster_renderer') renderchecker.setControlName('expected_cluster_no_cluster') self.assertTrue(renderchecker.runTest('cluster_no_cluster')) def testRenderWithin(self): self.layer.renderer().setTolerance(10) renderchecker = QgsMultiRenderChecker() renderchecker.setMapSettings(self.mapsettings) renderchecker.setControlPathPrefix('cluster_renderer') renderchecker.setControlName('expected_cluster_cluster') self.assertTrue(renderchecker.runTest('expected_cluster_cluster')) def testRenderVariables(self): """ test rendering with expression variables in marker """ self.layer.renderer().setTolerance(10) old_marker = self.layer.renderer().clusterSymbol().clone() new_marker = QgsMarkerSymbol.createSimple({'color': '#ffff00', 'size': '3', 'outline_style': 'no'}) new_marker.symbolLayer(0).setDataDefinedProperty(QgsSymbolLayer.PropertyFillColor, QgsProperty.fromExpression('@cluster_color')) new_marker.symbolLayer(0).setDataDefinedProperty(QgsSymbolLayer.PropertySize, QgsProperty.fromExpression('@cluster_size*2')) self.layer.renderer().setClusterSymbol(new_marker) renderchecker = QgsMultiRenderChecker() renderchecker.setMapSettings(self.mapsettings) renderchecker.setControlPathPrefix('cluster_renderer') renderchecker.setControlName('expected_cluster_variables') result = renderchecker.runTest('expected_cluster_variables') self.layer.renderer().setClusterSymbol(old_marker) self.assertTrue(result)
class TestQgsGeometryGeneratorSymbolLayerV2(unittest.TestCase): def setUp(self): self.iface = get_iface() polys_shp = os.path.join(TEST_DATA_DIR, "polys.shp") points_shp = os.path.join(TEST_DATA_DIR, "points.shp") lines_shp = os.path.join(TEST_DATA_DIR, "lines.shp") self.polys_layer = QgsVectorLayer(polys_shp, "Polygons", "ogr") self.points_layer = QgsVectorLayer(points_shp, "Points", "ogr") self.lines_layer = QgsVectorLayer(lines_shp, "Lines", "ogr") QgsMapLayerRegistry.instance().addMapLayer(self.polys_layer) QgsMapLayerRegistry.instance().addMapLayer(self.lines_layer) QgsMapLayerRegistry.instance().addMapLayer(self.points_layer) # Create style sym1 = QgsFillSymbol.createSimple({"color": "#fdbf6f"}) sym2 = QgsLineSymbol.createSimple({"color": "#fdbf6f"}) sym3 = QgsMarkerSymbol.createSimple({"color": "#fdbf6f"}) self.polys_layer.setRenderer(QgsSingleSymbolRenderer(sym1)) self.lines_layer.setRenderer(QgsSingleSymbolRenderer(sym2)) self.points_layer.setRenderer(QgsSingleSymbolRenderer(sym3)) self.mapsettings = self.iface.mapCanvas().mapSettings() self.mapsettings.setOutputSize(QSize(400, 400)) self.mapsettings.setOutputDpi(96) self.mapsettings.setExtent(QgsRectangle(-133, 22, -70, 52)) def tearDown(self): QgsMapLayerRegistry.instance().removeAllMapLayers() def test_marker(self): sym = self.polys_layer.renderer().symbol() sym_layer = QgsGeometryGeneratorSymbolLayer.create({"geometryModifier": "centroid($geometry)"}) sym_layer.setSymbolType(QgsSymbol.Marker) sym.changeSymbolLayer(0, sym_layer) rendered_layers = [self.polys_layer.id()] self.mapsettings.setLayers(rendered_layers) renderchecker = QgsMultiRenderChecker() renderchecker.setMapSettings(self.mapsettings) renderchecker.setControlName("expected_geometrygenerator_marker") self.assertTrue(renderchecker.runTest("geometrygenerator_marker")) def test_mixed(self): sym = self.polys_layer.renderer().symbol() buffer_layer = QgsGeometryGeneratorSymbolLayer.create({"geometryModifier": 'buffer($geometry, "value"/15)'}) buffer_layer.setSymbolType(QgsSymbol.Fill) self.assertIsNotNone(buffer_layer.subSymbol()) sym.appendSymbolLayer(buffer_layer) marker_layer = QgsGeometryGeneratorSymbolLayer.create({"geometryModifier": "centroid($geometry)"}) marker_layer.setSymbolType(QgsSymbol.Marker) sym.appendSymbolLayer(marker_layer) rendered_layers = [self.polys_layer.id()] self.mapsettings.setLayers(rendered_layers) renderchecker = QgsMultiRenderChecker() renderchecker.setMapSettings(self.mapsettings) renderchecker.setControlName("expected_geometrygenerator_mixed") self.assertTrue(renderchecker.runTest("geometrygenerator_mixed")) def test_buffer_lines(self): sym = self.lines_layer.renderer().symbol() buffer_layer = QgsGeometryGeneratorSymbolLayer.create({"geometryModifier": 'buffer($geometry, "value"/15)'}) buffer_layer.setSymbolType(QgsSymbol.Fill) self.assertIsNotNone(buffer_layer.subSymbol()) sym.appendSymbolLayer(buffer_layer) rendered_layers = [self.lines_layer.id()] self.mapsettings.setLayers(rendered_layers) renderchecker = QgsMultiRenderChecker() renderchecker.setMapSettings(self.mapsettings) renderchecker.setControlName("expected_geometrygenerator_buffer_lines") self.assertTrue(renderchecker.runTest("geometrygenerator_buffer_lines")) def test_buffer_points(self): sym = self.points_layer.renderer().symbol() buffer_layer = QgsGeometryGeneratorSymbolLayer.create({"geometryModifier": 'buffer($geometry, "staff"/15)'}) buffer_layer.setSymbolType(QgsSymbol.Fill) self.assertIsNotNone(buffer_layer.subSymbol()) sym.appendSymbolLayer(buffer_layer) rendered_layers = [self.points_layer.id()] self.mapsettings.setLayers(rendered_layers) renderchecker = QgsMultiRenderChecker() renderchecker.setMapSettings(self.mapsettings) renderchecker.setControlName("expected_geometrygenerator_buffer_points") self.assertTrue(renderchecker.runTest("geometrygenerator_buffer_points"))