def testSymbolColor(self): # Create rulebased style sym1 = QgsFillSymbol.createSimple({'color': '#ff0000', 'outline_color': 'black'}) renderer = QgsSingleSymbolRenderer(sym1) renderer.symbols(QgsRenderContext())[0].symbolLayers()[0].setDataDefinedProperty(QgsSymbolLayer.PropertyFillColor, QgsProperty.fromExpression('set_color_part( @symbol_color, \'value\', "Value" * 4)')) self.layer.setRenderer(renderer) # Setup rendering check renderchecker = QgsMultiRenderChecker() renderchecker.setMapSettings(self.mapsettings) renderchecker.setControlName('expected_symbol_color_variable') result = renderchecker.runTest('symbol_color_variable', 50) self.assertTrue(result)
def testPartCount(self): # Create rulebased style sym1 = QgsFillSymbol.createSimple({'color': '#fdbf6f', 'outline_color': 'black'}) renderer = QgsSingleSymbolRenderer(sym1) renderer.symbols(QgsRenderContext())[0].symbolLayers()[0].setDataDefinedProperty(QgsSymbolLayer.PropertyFillColor, QgsProperty.fromExpression('color_rgb( (@geometry_part_count - 1) * 200, 0, 0 )')) self.layer.setRenderer(renderer) # Setup rendering check renderchecker = QgsMultiRenderChecker() renderchecker.setMapSettings(self.mapsettings) renderchecker.setControlName('expected_geometry_part_count') result = renderchecker.runTest('part_geometry_part_count') self.assertTrue(result)
def testSymbolColor(self): # Create rulebased style sym1 = QgsFillSymbol.createSimple({"color": "#ff0000"}) renderer = QgsSingleSymbolRenderer(sym1) renderer.symbols()[0].symbolLayers()[0].setDataDefinedProperty( "color", "set_color_part( @symbol_color, 'value', \"Value\" * 4)" ) self.layer.setRenderer(renderer) # Setup rendering check renderchecker = QgsMultiRenderChecker() renderchecker.setMapSettings(self.mapsettings) renderchecker.setControlName("expected_symbol_color_variable") result = renderchecker.runTest("symbol_color_variable", 50) self.assertTrue(result)
def testPartCount(self): # Create rulebased style sym1 = QgsFillSymbol.createSimple({"color": "#fdbf6f"}) renderer = QgsSingleSymbolRenderer(sym1) renderer.symbols()[0].symbolLayers()[0].setDataDefinedProperty( "color", "color_rgb( (@geometry_part_count - 1) * 200, 0, 0 )" ) self.layer.setRenderer(renderer) # Setup rendering check renderchecker = QgsMultiRenderChecker() renderchecker.setMapSettings(self.mapsettings) renderchecker.setControlName("expected_geometry_part_count") result = renderchecker.runTest("part_geometry_part_count") self.assertTrue(result)
class TestQgsSingleSymbolRenderer(unittest.TestCase): def setUp(self): self.iface = get_iface() myShpFile = os.path.join(TEST_DATA_DIR, 'polys_overlapping.shp') layer = QgsVectorLayer(myShpFile, 'Polys', 'ogr') QgsProject.instance().addMapLayer(layer) # Create rulebased style sym1 = QgsFillSymbol.createSimple({'color': '#fdbf6f', 'outline_color': 'black'}) self.renderer = QgsSingleSymbolRenderer(sym1) layer.setRenderer(self.renderer) rendered_layers = [layer] self.mapsettings = self.iface.mapCanvas().mapSettings() self.mapsettings.setOutputSize(QSize(400, 400)) self.mapsettings.setOutputDpi(96) self.mapsettings.setExtent(QgsRectangle(-163, 22, -70, 52)) self.mapsettings.setLayers(rendered_layers) def testOrderBy(self): self.renderer.setOrderBy(QgsFeatureRequest.OrderBy([QgsFeatureRequest.OrderByClause('Value', False)])) self.renderer.setOrderByEnabled(True) # Setup rendering check renderchecker = QgsMultiRenderChecker() renderchecker.setMapSettings(self.mapsettings) renderchecker.setControlName('expected_singlesymbol_orderby') self.assertTrue(renderchecker.runTest('singlesymbol_orderby')) # disable order by and retest self.renderer.setOrderByEnabled(False) self.assertTrue(renderchecker.runTest('single'))
def setUp(self): self.iface = get_iface() myShpFile = os.path.join(TEST_DATA_DIR, 'polys_overlapping.shp') layer = QgsVectorLayer(myShpFile, 'Polys', 'ogr') QgsProject.instance().addMapLayer(layer) # Create rulebased style sym1 = QgsFillSymbol.createSimple({'color': '#fdbf6f', 'outline_color': 'black'}) self.renderer = QgsSingleSymbolRenderer(sym1) layer.setRenderer(self.renderer) rendered_layers = [layer] self.mapsettings = self.iface.mapCanvas().mapSettings() self.mapsettings.setOutputSize(QSize(400, 400)) self.mapsettings.setOutputDpi(96) self.mapsettings.setExtent(QgsRectangle(-163, 22, -70, 52)) self.mapsettings.setLayers(rendered_layers)
def _setUp(self): myShpFile = os.path.join(TEST_DATA_DIR, 'points.shp') layer = QgsVectorLayer(myShpFile, 'Points', 'ogr') QgsProject.instance().addMapLayer(layer) renderer = QgsPointDisplacementRenderer() sym1 = QgsMarkerSymbol.createSimple({'color': '#ff00ff', 'size': '3', 'outline_style': 'no'}) sym_renderer = QgsSingleSymbolRenderer(sym1) renderer.setEmbeddedRenderer(sym_renderer) renderer.setCircleRadiusAddition(2) renderer.setCircleWidth(1) renderer.setCircleColor(QColor(0, 0, 0)) renderer.setCenterSymbol(QgsMarkerSymbol.createSimple({'color': '#ffff00', 'size': '3', 'outline_style': 'no'})) layer.setRenderer(renderer) rendered_layers = [layer] mapsettings = QgsMapSettings() mapsettings.setOutputSize(QSize(400, 400)) mapsettings.setOutputDpi(96) mapsettings.setExtent(QgsRectangle(-123, 18, -70, 52)) mapsettings.setLayers(rendered_layers) return layer, renderer, mapsettings
def test_point_ordered_symbol_bound_offset(self): # Test ordered placements for point using symbol bounds offset self.layer = TestQgsPalLabeling.loadFeatureLayer( 'point_ordered_placement') # Make a big symbol symbol = QgsMarkerSymbol.createSimple({ 'color': '31,120,180,255', 'outline_color': '0,0,0,0', 'outline_style': 'solid', 'size': '10', 'name': 'rectangle', 'size_unit': 'MM' }) renderer = QgsSingleSymbolRenderer(symbol) self.layer.setRenderer(renderer) self._TestMapSettings = self.cloneMapSettings(self._MapSettings) self.lyr.placement = QgsPalLayerSettings.OrderedPositionsAroundPoint self.lyr.dist = 2 self.lyr.offsetType = QgsPalLayerSettings.FromSymbolBounds self.checkTest() self.removeMapLayer(self.layer) self.layer = None
def testInitialSizeSymbolMapUnits(self): """Test initial size of legend with a symbol size in map units""" point_path = os.path.join(TEST_DATA_DIR, 'points.shp') point_layer = QgsVectorLayer(point_path, 'points', 'ogr') QgsProject.instance().addMapLayers([point_layer]) marker_symbol = QgsMarkerSymbol.createSimple({'color': '#ff0000', 'outline_style': 'no', 'size': '5', 'size_unit': 'MapUnit'}) point_layer.setRenderer(QgsSingleSymbolRenderer(marker_symbol)) s = QgsMapSettings() s.setLayers([point_layer]) layout = QgsLayout(QgsProject.instance()) layout.initializeDefaults() map = QgsLayoutItemMap(layout) map.attemptSetSceneRect(QRectF(20, 20, 80, 80)) map.setFrameEnabled(True) map.setLayers([point_layer]) layout.addLayoutItem(map) map.setExtent(point_layer.extent()) legend = QgsLayoutItemLegend(layout) legend.attemptSetSceneRect(QRectF(120, 20, 80, 80)) legend.setFrameEnabled(True) legend.setFrameStrokeWidth(QgsLayoutMeasurement(2)) legend.setBackgroundColor(QColor(200, 200, 200)) legend.setTitle('') layout.addLayoutItem(legend) legend.setMap(map) checker = QgsLayoutChecker( 'composer_legend_mapunits', layout) checker.setControlPathPrefix("composer_legend") result, message = checker.testLayout() self.assertTrue(result, message) QgsProject.instance().removeMapLayers([point_layer.id()])
def test_multiple_masks_same_symbol_layer(self): """Test multiple masks that occlude the same symbol layer""" # # 1. a symbol layer mask # p = QgsMarkerSymbol.createSimple({'color': '#fdbf6f', 'size': "7"}) self.points_layer.setRenderer(QgsSingleSymbolRenderer(p)) circle_symbol = QgsMarkerSymbol.createSimple({'size': '10'}) mask_layer = QgsMaskMarkerSymbolLayer() mask_layer.setSubSymbol(circle_symbol) mask_layer.setMasks([ # the black part of roads QgsSymbolLayerReference(self.lines_layer.id(), QgsSymbolLayerId("", 0)), ]) # add this mask layer to the point layer self.points_layer.renderer().symbol().appendSymbolLayer(mask_layer) # # 2. a label mask # # modify labeling settings label_settings = self.polys_layer.labeling().settings() fmt = label_settings.format() # enable a mask fmt.mask().setEnabled(True) fmt.mask().setSize(4.0) # and mask other symbol layers underneath fmt.mask().setMaskedSymbolLayers([ # the black part of roads QgsSymbolLayerReference(self.lines_layer.id(), QgsSymbolLayerId("", 0)) ]) label_settings.setFormat(fmt) self.polys_layer.labeling().setSettings(label_settings) self.check_renderings(self.map_settings, "multiple_masks_same_sl")
def testInitialSizeSymbolMapUnits(self): """Test initial size of legend with a symbol size in map units""" point_path = os.path.join(TEST_DATA_DIR, 'points.shp') point_layer = QgsVectorLayer(point_path, 'points', 'ogr') QgsProject.instance().addMapLayers([point_layer]) marker_symbol = QgsMarkerSymbol.createSimple({'color': '#ff0000', 'outline_style': 'no', 'size': '5', 'size_unit': 'MapUnit'}) point_layer.setRenderer(QgsSingleSymbolRenderer(marker_symbol)) s = QgsMapSettings() s.setLayers([point_layer]) composition = QgsComposition(QgsProject.instance()) composition.setPaperSize(297, 210) composer_map = QgsComposerMap(composition, 20, 20, 80, 80) composer_map.setFrameEnabled(True) composer_map.setLayers([point_layer]) composition.addComposerMap(composer_map) composer_map.setNewExtent(point_layer.extent()) legend = QgsComposerLegend(composition) legend.setSceneRect(QRectF(120, 20, 80, 80)) legend.setFrameEnabled(True) legend.setFrameStrokeWidth(2) legend.setBackgroundColor(QColor(200, 200, 200)) legend.setTitle('') composition.addComposerLegend(legend) legend.setComposerMap(composer_map) checker = QgsCompositionChecker( 'composer_legend_mapunits', composition) checker.setControlPathPrefix("composer_legend") result, message = checker.testComposition() self.assertTrue(result, message) QgsProject.instance().removeMapLayers([point_layer.id()])
def testSingleLines(self): source = QgsVectorLayer(os.path.join(TEST_DATA_DIR, 'lines_touching.shp')) self.assertTrue(source.isValid()) map_settings = QgsMapSettings() map_settings.setExtent(source.extent().buffered(2)) map_settings.setDestinationCrs(source.crs()) map_settings.setLayers([source]) layer = QgsSimpleLineSymbolLayer() layer.setColor(QColor(0, 0, 0)) layer.setWidth(1) symbol = QgsLineSymbol([layer]) layer2 = QgsMarkerLineSymbolLayer() layer2.setPlacement(QgsTemplatedLineSymbolLayerBase.FirstVertex) marker = QgsMarkerSymbol.createSimple({'size': '4', 'color': '255,0,0', 'outline_style': 'no'}) layer2.setSubSymbol(marker) symbol.appendSymbolLayer(layer2) sub_renderer = QgsSingleSymbolRenderer(symbol) source.setRenderer(QgsMergedFeatureRenderer(sub_renderer)) self.assertTrue(self.imageCheck('lines_single_subrenderer', 'lines_single_subrenderer', map_settings))
def addFlowLayerLineWidth(layerpath, fieldname, colour, transparent, layername, widthscale=1): vlayer = QgsVectorLayer(layerpath, layername, "ogr") if not vlayer.isValid(): feedback.pushInfo("Layer failed to load: " + layerpath) else: context.temporaryLayerStore().addMapLayer(vlayer) maxvalue = getMaxValue(vlayer, fieldname) symbol = QgsLineSymbol.createSimple({ 'color': colour, 'size': '1' }) objTransf = QgsSizeScaleTransformer( QgsSizeScaleTransformer.Flannery, 0, #minvalue maxvalue, #maxvalue 0.1, #minsize 5 * widthscale, #maxsize 0, #nullsize 1) #exponent objProp = QgsProperty() objProp.setField(fieldname) objProp.setTransformer(objTransf) symbol.setDataDefinedWidth(objProp) renderer = QgsSingleSymbolRenderer(symbol) vlayer.setRenderer(renderer) vlayer.setOpacity(1 - transparent) project.addMapLayer(vlayer) feedback.pushInfo("Loaded " + layerpath)
def SetDefaultPointStyle(layer): ''' Point Symbol ''' style = S.getDrawingPoint() symbol = QgsMarkerSymbol.createSimple({ 'name': style["NAME"], 'line_color': style["LINE_COLOR"], 'line_width': style["LINE_WIDTH"], 'size': style["SIZE"] }) renderer = QgsSingleSymbolRenderer(symbol) layer.setRenderer(renderer) layer_settings = QgsPalLayerSettings() text_format = QgsTextFormat() text_format.setFont(QFont(style["LABEL_FONT"], style["LABEL_FONT_SIZE"])) text_format.setColor(QColor(style["LABEL_FONT_COLOR"])) text_format.setSize(style["LABEL_SIZE"]) buffer_settings = QgsTextBufferSettings() buffer_settings.setEnabled(True) buffer_settings.setSize(1) buffer_settings.setColor(QColor(style["LABEL_BUFFER_COLOR"])) text_format.setBuffer(buffer_settings) layer_settings.setFormat(text_format) layer_settings.fieldName = "number" layer_settings.placement = 2 layer_settings.enabled = True layer_settings = QgsVectorLayerSimpleLabeling(layer_settings) layer.setLabelsEnabled(True) layer.setLabeling(layer_settings) return
def style_curves(self): registry = QgsApplication.symbolLayerRegistry() symbol_props = { 'name': 'cross2', 'color': '0,0,0', 'color_border': '0,0,0', 'offset': '0,0', 'size': '1.5', 'angle': '0', } opacity = 0.7 cross = registry.symbolLayerMetadata("SimpleMarker").createSymbolLayer( symbol_props) # NOTE: Cross symbols rendered for OQ-Engine disaggregation outputs are # opaque, wider and thicker than those used for other outputs (e.g. # hcurves) if self.output_type == 'disagg': cross.setSize(3) cross.setStrokeWidth(0.5) opacity = 1 symbol = QgsSymbol.defaultSymbol(self.layer.geometryType()).clone() symbol.deleteSymbolLayer(0) symbol.appendSymbolLayer(cross) renderer = QgsSingleSymbolRenderer(symbol) effect = QgsOuterGlowEffect() effect.setSpread(0.5) effect.setOpacity(opacity) effect.setColor(QColor(255, 255, 255)) effect.setBlurLevel(1) renderer.paintEffect().appendEffect(effect) renderer.paintEffect().setEnabled(True) self.layer.setRenderer(renderer) self.layer.setOpacity(opacity) self.layer.triggerRepaint() # NOTE QGIS3: probably not needed # self.iface.layerTreeView().refreshLayerSymbology(self.layer.id()) self.iface.mapCanvas().refresh()
class TestQgsSingleSymbolRenderer(unittest.TestCase): def setUp(self): self.iface = get_iface() myShpFile = os.path.join(TEST_DATA_DIR, 'polys_overlapping.shp') layer = QgsVectorLayer(myShpFile, 'Polys', 'ogr') QgsProject.instance().addMapLayer(layer) # Create rulebased style sym1 = QgsFillSymbol.createSimple({ 'color': '#fdbf6f', 'outline_color': 'black' }) self.renderer = QgsSingleSymbolRenderer(sym1) layer.setRenderer(self.renderer) rendered_layers = [layer] self.mapsettings = self.iface.mapCanvas().mapSettings() self.mapsettings.setOutputSize(QSize(400, 400)) self.mapsettings.setOutputDpi(96) self.mapsettings.setExtent(QgsRectangle(-163, 22, -70, 52)) self.mapsettings.setLayers(rendered_layers) def testOrderBy(self): self.renderer.setOrderBy( QgsFeatureRequest.OrderBy( [QgsFeatureRequest.OrderByClause('Value', False)])) self.renderer.setOrderByEnabled(True) # Setup rendering check renderchecker = QgsMultiRenderChecker() renderchecker.setMapSettings(self.mapsettings) renderchecker.setControlName('expected_singlesymbol_orderby') self.assertTrue(renderchecker.runTest('singlesymbol_orderby')) # disable order by and retest self.renderer.setOrderByEnabled(False) self.assertTrue(renderchecker.runTest('single'))
def generateIsochrones(point, profile, costingOptions, intervals, colors, basename, overwrite=True): response = valhalla.isochrones(point, profile, costingOptions, intervals, colors) features = getFeaturesFromResponse(response) if costingOptions.get("shortest"): suffix = "km" else: suffix = "min" for interval, feature in zip(intervals[::-1], features): # FIXME: we should use the 'contour' property in the feature to be sure of the contour line that we are # drawing, but due to a bug in qgis json parser, this property appears to be always set to '0' layername = "{} {} - {}".format(interval, suffix, basename) try: # FIXME: we do not consider if there are several layers with the same name here existinglayer = QgsProject.instance().mapLayersByName(layername)[0] if overwrite: QgsProject.instance().removeMapLayer(existinglayer.id()) else: raise OverwriteError( tr("layer {layername} already exists and overwrite is {overwrite}" ).format(layername=layername, overwrite=overwrite)) except IndexError: LOG.debug("this layer was not found: {}".format(layername)) layer = QgsVectorLayer( "Polygon?crs=epsg:4326&field=centerx:double&field=centery:double&field=interval:double", layername, "memory", ) pr = layer.dataProvider() qgsfeature = QgsFeature() qgsfeature.setAttributes([point.x(), point.y(), interval]) qgsfeature.setGeometry(feature.geometry()) pr.addFeatures([qgsfeature]) layer.updateExtents() QgsProject.instance().addMapLayer(layer) outlineColor = QColor(0, 0, 0) # Set opacity to 40% or 66 in hex (65% transparency) fillColor = QColor("#66" + feature["color"][1:]) renderer = QgsSingleSymbolRenderer.defaultRenderer( QgsWkbTypes.PolygonGeometry) symbol = renderer.symbol() symbol.setColor(fillColor) symbol.symbolLayer(0).setStrokeColor(outlineColor) layer.setRenderer(renderer) # Add center of reachability center_point_layer_name = tr("Center of {basename}").format( basename=basename) try: existinglayer = QgsProject.instance().mapLayersByName( center_point_layer_name)[0] if overwrite: QgsProject.instance().removeMapLayer(existinglayer.id()) else: raise OverwriteError( tr("layer {layername} already exists and overwrite is {overwrite}" ).format(layername=center_point_layer_name, overwrite=overwrite)) except IndexError: LOG.debug( "this layer was not found: {}".format(center_point_layer_name)) center_point = QgsVectorLayer( "Point?crs=epsg:4326", center_point_layer_name, "memory", ) pr = center_point.dataProvider() qgsfeature = QgsFeature() qgsfeature.setGeometry(QgsGeometry.fromPointXY(point)) pr.addFeatures([qgsfeature]) # symbology path = ":/kadas/icons/pin_red" symbol = QgsSvgMarkerSymbolLayer(path) symbol.setSize(10) symbol.setVerticalAnchorPoint(QgsMarkerSymbolLayer.Bottom) center_point.renderer().symbol().changeSymbolLayer(0, symbol) QgsProject.instance().addMapLayer(center_point)
def run(self): layer = self.iface.mapCanvas().currentLayer() layerHint = "\n\nPlease select a Vector layer of geometry type Line." if layer is None: QMessageBox.information(None, "Chinese Postman", "No layer selected." + layerHint) return if layer.type() != QgsMapLayer.VectorLayer: QMessageBox.information( None, "Chinese Postman", "The selected layer is not of type Vector." + layerHint) return if layer.geometryType() != QgsWkbTypes.LineGeometry: QMessageBox.information( None, "Chinese Postman", "The selected layer's geometry type is not Line. " + "Chinese Postman cannot work on Point or Polygon." + layerHint) return features = layer.selectedFeatures() if len(features) == 0: QMessageBox.information( None, "Chinese Postman", "Please select an area. The 'Select Features by Polygon' tool " + "works well for this.") return graph = build_graph(features) components = postman.graph_components(graph) if len(components) > 1: QMessageBox.information( None, "Chinese Postman", "Warning: the selected area contains multiple disconnected " + "components - only the largest one will be used.") if len(components) == 0: QMessageBox.information( None, "Chinese Postman", "Error: Could not find any components. Try selecting different features." ) return component = components[0] eulerian_graph, nodes = postman.single_chinese_postman_path(component) in_length = postman.edge_sum(component) / 1000.0 path_length = postman.edge_sum(eulerian_graph) / 1000.0 duplicate_length = path_length - in_length newlayer = build_layer(eulerian_graph, nodes, layer.crs()) symbol = build_symbol(newlayer) newlayer.setRenderer(QgsSingleSymbolRenderer(symbol)) QgsProject.instance().addMapLayer(newlayer) info = "" info += "Total length of roads: %.3f km\n" % in_length info += "Total length of path: %.3f km\n" % path_length info += "Length of sections visited twice: %.3f km\n" % duplicate_length info += "\n" info += "(If the above values do not make sense, consider changing CRS.)\n" QMessageBox.information(None, "Chinese Postman", info)
def testLegendRenderWithMapTheme(self): """Test rendering legends linked to map themes""" QgsProject.instance().removeAllMapLayers() point_path = os.path.join(TEST_DATA_DIR, 'points.shp') point_layer = QgsVectorLayer(point_path, 'points', 'ogr') line_path = os.path.join(TEST_DATA_DIR, 'lines.shp') line_layer = QgsVectorLayer(line_path, 'lines', 'ogr') QgsProject.instance().clear() QgsProject.instance().addMapLayers([point_layer, line_layer]) marker_symbol = QgsMarkerSymbol.createSimple({ 'color': '#ff0000', 'outline_style': 'no', 'size': '5' }) point_layer.setRenderer(QgsSingleSymbolRenderer(marker_symbol)) point_layer.styleManager().addStyleFromLayer("red") line_symbol = QgsLineSymbol.createSimple({ 'color': '#ff0000', 'line_width': '2' }) line_layer.setRenderer(QgsSingleSymbolRenderer(line_symbol)) line_layer.styleManager().addStyleFromLayer("red") red_record = QgsMapThemeCollection.MapThemeRecord() point_red_record = QgsMapThemeCollection.MapThemeLayerRecord( point_layer) point_red_record.usingCurrentStyle = True point_red_record.currentStyle = 'red' red_record.addLayerRecord(point_red_record) line_red_record = QgsMapThemeCollection.MapThemeLayerRecord(line_layer) line_red_record.usingCurrentStyle = True line_red_record.currentStyle = 'red' red_record.addLayerRecord(line_red_record) QgsProject.instance().mapThemeCollection().insert('red', red_record) marker_symbol1 = QgsMarkerSymbol.createSimple({ 'color': '#0000ff', 'outline_style': 'no', 'size': '5' }) marker_symbol2 = QgsMarkerSymbol.createSimple({ 'color': '#0000ff', 'name': 'diamond', 'outline_style': 'no', 'size': '5' }) marker_symbol3 = QgsMarkerSymbol.createSimple({ 'color': '#0000ff', 'name': 'rectangle', 'outline_style': 'no', 'size': '5' }) point_layer.setRenderer( QgsCategorizedSymbolRenderer('Class', [ QgsRendererCategory('B52', marker_symbol1, ''), QgsRendererCategory('Biplane', marker_symbol2, ''), QgsRendererCategory('Jet', marker_symbol3, ''), ])) point_layer.styleManager().addStyleFromLayer("blue") line_symbol = QgsLineSymbol.createSimple({ 'color': '#0000ff', 'line_width': '2' }) line_layer.setRenderer(QgsSingleSymbolRenderer(line_symbol)) line_layer.styleManager().addStyleFromLayer("blue") blue_record = QgsMapThemeCollection.MapThemeRecord() point_blue_record = QgsMapThemeCollection.MapThemeLayerRecord( point_layer) point_blue_record.usingCurrentStyle = True point_blue_record.currentStyle = 'blue' blue_record.addLayerRecord(point_blue_record) line_blue_record = QgsMapThemeCollection.MapThemeLayerRecord( line_layer) line_blue_record.usingCurrentStyle = True line_blue_record.currentStyle = 'blue' blue_record.addLayerRecord(line_blue_record) QgsProject.instance().mapThemeCollection().insert('blue', blue_record) layout = QgsLayout(QgsProject.instance()) layout.initializeDefaults() map1 = QgsLayoutItemMap(layout) map1.attemptSetSceneRect(QRectF(20, 20, 80, 80)) map1.setFrameEnabled(True) map1.setLayers([point_layer, line_layer]) layout.addLayoutItem(map1) map1.setExtent(point_layer.extent()) map1.setFollowVisibilityPreset(True) map1.setFollowVisibilityPresetName('red') map2 = QgsLayoutItemMap(layout) map2.attemptSetSceneRect(QRectF(20, 120, 80, 80)) map2.setFrameEnabled(True) map2.setLayers([point_layer, line_layer]) layout.addLayoutItem(map2) map2.setExtent(point_layer.extent()) map2.setFollowVisibilityPreset(True) map2.setFollowVisibilityPresetName('blue') legend = QgsLayoutItemLegend(layout) legend.setTitle("Legend") legend.attemptSetSceneRect(QRectF(120, 20, 80, 80)) legend.setFrameEnabled(True) legend.setFrameStrokeWidth(QgsLayoutMeasurement(2)) legend.setBackgroundColor(QColor(200, 200, 200)) legend.setTitle('') layout.addLayoutItem(legend) legend.setLinkedMap(map1) legend2 = QgsLayoutItemLegend(layout) legend2.setTitle("Legend") legend2.attemptSetSceneRect(QRectF(120, 120, 80, 80)) legend2.setFrameEnabled(True) legend2.setFrameStrokeWidth(QgsLayoutMeasurement(2)) legend2.setBackgroundColor(QColor(200, 200, 200)) legend2.setTitle('') layout.addLayoutItem(legend2) legend2.setLinkedMap(map2) checker = QgsLayoutChecker('composer_legend_theme', layout) checker.setControlPathPrefix("composer_legend") result, message = checker.testLayout() self.report += checker.report() self.assertTrue(result, message) QgsProject.instance().clear()
def testRenderMultipleRenderersSelection(self): """ Test that selection colors only apply to main renderer :return: """ poly_layer = QgsVectorLayer(os.path.join(TEST_DATA_DIR, 'polys.shp')) self.assertTrue(poly_layer.isValid()) poly_layer.selectAll() sym1 = QgsFillSymbol.createSimple({'color': '#ffaaff', 'outline_color': '#000000', 'outline_style': 'no'}) renderer = QgsSingleSymbolRenderer(sym1) poly_layer.setRenderer(renderer) # add secondary renderer, for rendering below class Gen1(QgsFeatureRendererGenerator): def id(self): return 'Gen1' def level(self): return -2 def createRenderer(self): renderer = QgsCategorizedSymbolRenderer() renderer.setClassAttribute('Name') sym1 = QgsFillSymbol.createSimple( {'color': '#ffaaff', 'outline_color': '#33aa33', 'outline_width': '3'}) sym2 = QgsFillSymbol.createSimple( {'color': '#ffaaff', 'outline_color': '#aa33aa', 'outline_width': '3'}) renderer.addCategory(QgsRendererCategory('Dam', sym1, 'Dam')) renderer.addCategory(QgsRendererCategory('Lake', sym2, 'Lake')) return renderer poly_layer.addFeatureRendererGenerator(Gen1()) mapsettings = QgsMapSettings() mapsettings.setOutputSize(QSize(400, 400)) mapsettings.setOutputDpi(96) mapsettings.setDestinationCrs(QgsCoordinateReferenceSystem('EPSG:3857')) mapsettings.setExtent(QgsRectangle(-13875783.2, 2266009.4, -8690110.7, 6673344.5)) mapsettings.setLayers([poly_layer]) renderchecker = QgsMultiRenderChecker() renderchecker.setMapSettings(mapsettings) renderchecker.setControlPathPrefix('vectorlayerrenderer') renderchecker.setControlName('expected_multiple_renderers_selection') result = renderchecker.runTest('expected_multiple_renderers_selection') self.report += renderchecker.report() self.assertTrue(result) # also try with symbol levels renderer.setUsingSymbolLevels(True) poly_layer.setRenderer(renderer) renderchecker = QgsMultiRenderChecker() renderchecker.setMapSettings(mapsettings) renderchecker.setControlPathPrefix('vectorlayerrenderer') renderchecker.setControlName('expected_multiple_renderers_selection') result = renderchecker.runTest('expected_multiple_renderers_selection') self.report += renderchecker.report() self.assertTrue(result)
def testMapTheme(self): canvas = QgsMapCanvas() canvas.setDestinationCrs(QgsCoordinateReferenceSystem(4326)) canvas.setFrameStyle(0) canvas.resize(600, 400) self.assertEqual(canvas.width(), 600) self.assertEqual(canvas.height(), 400) layer = QgsVectorLayer("Polygon?crs=epsg:4326&field=fldtxt:string", "layer", "memory") # add a polygon to layer f = QgsFeature() f.setGeometry(QgsGeometry.fromRect(QgsRectangle(5, 25, 25, 45))) self.assertTrue(layer.dataProvider().addFeatures([f])) # create a style sym1 = QgsFillSymbol.createSimple({'color': '#ffb200'}) renderer = QgsSingleSymbolRenderer(sym1) layer.setRenderer(renderer) canvas.setLayers([layer]) canvas.setExtent(QgsRectangle(10, 30, 20, 35)) canvas.show() # need to wait until first redraw can occur (note that we first need to wait till drawing starts!) while not canvas.isDrawing(): app.processEvents() canvas.waitWhileRendering() self.assertTrue(self.canvasImageCheck('theme1', 'theme1', canvas)) # add some styles layer.styleManager().addStyleFromLayer('style1') sym2 = QgsFillSymbol.createSimple({'color': '#00b2ff'}) renderer2 = QgsSingleSymbolRenderer(sym2) layer.setRenderer(renderer2) layer.styleManager().addStyleFromLayer('style2') canvas.refresh() canvas.waitWhileRendering() self.assertTrue(self.canvasImageCheck('theme2', 'theme2', canvas)) layer.styleManager().setCurrentStyle('style1') canvas.refresh() canvas.waitWhileRendering() self.assertTrue(self.canvasImageCheck('theme1', 'theme1', canvas)) # ok, so all good with setting/rendering map styles # try setting canvas to a particular theme # make some themes... theme1 = QgsMapThemeCollection.MapThemeRecord() record1 = QgsMapThemeCollection.MapThemeLayerRecord(layer) record1.currentStyle = 'style1' record1.usingCurrentStyle = True theme1.setLayerRecords([record1]) theme2 = QgsMapThemeCollection.MapThemeRecord() record2 = QgsMapThemeCollection.MapThemeLayerRecord(layer) record2.currentStyle = 'style2' record2.usingCurrentStyle = True theme2.setLayerRecords([record2]) QgsProject.instance().mapThemeCollection().insert('theme1', theme1) QgsProject.instance().mapThemeCollection().insert('theme2', theme2) canvas.setTheme('theme2') canvas.refresh() canvas.waitWhileRendering() self.assertTrue(self.canvasImageCheck('theme2', 'theme2', canvas)) canvas.setTheme('theme1') canvas.refresh() canvas.waitWhileRendering() self.assertTrue(self.canvasImageCheck('theme1', 'theme1', canvas)) # add another layer layer2 = QgsVectorLayer("Polygon?crs=epsg:4326&field=fldtxt:string", "layer2", "memory") f = QgsFeature() f.setGeometry(QgsGeometry.fromRect(QgsRectangle(5, 25, 25, 45))) self.assertTrue(layer2.dataProvider().addFeatures([f])) # create a style sym1 = QgsFillSymbol.createSimple({'color': '#b2ff00'}) renderer = QgsSingleSymbolRenderer(sym1) layer2.setRenderer(renderer) # rerender canvas - should NOT show new layer canvas.refresh() canvas.waitWhileRendering() self.assertTrue(self.canvasImageCheck('theme1', 'theme1', canvas)) # test again - this time refresh all layers canvas.refreshAllLayers() canvas.waitWhileRendering() self.assertTrue(self.canvasImageCheck('theme1', 'theme1', canvas)) # add layer 2 to theme1 record3 = QgsMapThemeCollection.MapThemeLayerRecord(layer2) theme1.setLayerRecords([record3]) QgsProject.instance().mapThemeCollection().update('theme1', theme1) canvas.refresh() canvas.waitWhileRendering() self.assertTrue(self.canvasImageCheck('theme3', 'theme3', canvas)) # change the appearance of an active style layer2.styleManager().addStyleFromLayer('original') layer2.styleManager().addStyleFromLayer('style4') record3.currentStyle = 'style4' record3.usingCurrentStyle = True theme1.setLayerRecords([record3]) QgsProject.instance().mapThemeCollection().update('theme1', theme1) canvas.refresh() canvas.waitWhileRendering() self.assertTrue(self.canvasImageCheck('theme3', 'theme3', canvas)) layer2.styleManager().setCurrentStyle('style4') sym3 = QgsFillSymbol.createSimple({'color': '#b200b2'}) layer2.renderer().setSymbol(sym3) canvas.refresh() canvas.waitWhileRendering() self.assertTrue(self.canvasImageCheck('theme4', 'theme4', canvas)) # try setting layers while a theme is in place canvas.setLayers([layer]) canvas.refresh() # should be no change... setLayers should be ignored if canvas is following a theme! canvas.waitWhileRendering() self.assertTrue(self.canvasImageCheck('theme4', 'theme4', canvas)) # setLayerStyleOverrides while theme is in place canvas.setLayerStyleOverrides({layer2.id(): 'original'}) # should be no change... setLayerStyleOverrides should be ignored if canvas is following a theme! canvas.refresh() canvas.waitWhileRendering() self.assertTrue(self.canvasImageCheck('theme4', 'theme4', canvas)) # clear theme canvas.setTheme('') canvas.refresh() canvas.waitWhileRendering() # should be different - we should now render project layers self.assertFalse(self.canvasImageCheck('theme4', 'theme4', canvas))
def setStyle(self, layer, name): if name == "": return stylePath = os.path.join(os.path.dirname(os.path.dirname(__file__)), "layerStyles") # user style qmlPath = os.path.join(stylePath, name + "_user.qml") if os.path.exists(qmlPath): layer.loadNamedStyle(qmlPath) return # default style qmlPath = os.path.join(stylePath, name + ".qml.bak") if os.path.exists(qmlPath): layer.loadNamedStyle(qmlPath) svgPath = os.path.join(stylePath, name + ".svg") if os.path.exists(svgPath): if layer.geometryType() == 0: # Point svg_style = dict() svg_style['name'] = svgPath svg_style['size'] = str(7) if name == "demands": svg_style['fill'] = '#9a1313' symbol_layer = QgsSvgMarkerSymbolLayer.create(svg_style) symbol = QgsSymbol.defaultSymbol(layer.geometryType()) symbol.changeSymbolLayer(0, symbol_layer) renderer = QgsSingleSymbolRenderer(symbol) else: # Line symbol = QgsLineSymbol().createSimple({}) symbol.deleteSymbolLayer(0) # Line lineSymbol = QgsSimpleLineSymbolLayer() lineSymbol.setWidthUnit(2) # Pixels lineSymbol.setWidth(1.5) if name == "pipes": lineSymbol.setColor(QColor("#0f1291")) symbol.appendSymbolLayer(lineSymbol) # Symbol marker = QgsMarkerSymbol.createSimple({}) marker.deleteSymbolLayer(0) svg_props = dict() svg_props['name'] = svgPath size = 5 if name == "pipes": size = 0 svg_props['size'] = str(size) svg_props['offset'] = '-0.5,-0.5' svg_props['offset_unit'] = 'Pixel' markerSymbol = QgsSvgMarkerSymbolLayer.create(svg_props) marker.appendSymbolLayer(markerSymbol) # Final Symbol finalMarker = QgsMarkerLineSymbolLayer() finalMarker.setSubSymbol(marker) finalMarker.setPlacement(QgsMarkerLineSymbolLayer.CentralPoint) symbol.appendSymbolLayer(finalMarker) if name == "pipes": prop = QgsProperty() prop.setExpressionString( "if(IniStatus is NULL, 0,if(IniStatus !='CV', 0,5))") symbol.symbolLayer(1).setDataDefinedProperty( 9, prop) # 9 = PropertyWidth renderer = QgsSingleSymbolRenderer(symbol) layer.setRenderer(renderer)
def style_maps(layer, style_by, iface, output_type='damages-rlzs', perils=None, add_null_class=False, render_higher_on_top=False, repaint=True, use_sgc_style=False): symbol = QgsSymbol.defaultSymbol(layer.geometryType()) # see properties at: # https://qgis.org/api/qgsmarkersymbollayerv2_8cpp_source.html#l01073 symbol.setOpacity(1) if isinstance(symbol, QgsMarkerSymbol): # do it only for the layer with points symbol.symbolLayer(0).setStrokeStyle(Qt.PenStyle(Qt.NoPen)) style = get_style(layer, iface.messageBar()) # this is the default, as specified in the user settings ramp = QgsGradientColorRamp(style['color_from'], style['color_to']) style_mode = style['style_mode'] # in most cases, we override the user-specified setting, and use # instead a setting that was required by scientists if output_type in OQ_TO_LAYER_TYPES: default_qgs_style = QgsStyle().defaultStyle() default_color_ramp_names = default_qgs_style.colorRampNames() if output_type in ( 'damages-rlzs', 'avg_losses-rlzs', 'avg_losses-stats', ): # options are EqualInterval, Quantile, Jenks, StdDev, Pretty # jenks = natural breaks if Qgis.QGIS_VERSION_INT < 31000: style_mode = QgsGraduatedSymbolRenderer.Jenks else: style_mode = 'Jenks' ramp_type_idx = default_color_ramp_names.index('Reds') symbol.setColor(QColor(RAMP_EXTREME_COLORS['Reds']['top'])) inverted = False elif (output_type in ('gmf_data', 'ruptures') or (output_type == 'hmaps' and not use_sgc_style)): # options are EqualInterval, Quantile, Jenks, StdDev, Pretty # jenks = natural breaks if output_type == 'ruptures': if Qgis.QGIS_VERSION_INT < 31000: style_mode = QgsGraduatedSymbolRenderer.Pretty else: style_mode = 'PrettyBreaks' else: if Qgis.QGIS_VERSION_INT < 31000: style_mode = QgsGraduatedSymbolRenderer.EqualInterval else: style_mode = 'EqualInterval' ramp_type_idx = default_color_ramp_names.index('Spectral') inverted = True symbol.setColor(QColor(RAMP_EXTREME_COLORS['Reds']['top'])) elif output_type == 'hmaps' and use_sgc_style: # FIXME: for SGC they were using size 10000 map units # options are EqualInterval, Quantile, Jenks, StdDev, Pretty # jenks = natural breaks if Qgis.QGIS_VERSION_INT < 31000: style_mode = QgsGraduatedSymbolRenderer.Pretty else: style_mode = 'PrettyBreaks' try: ramp_type_idx = default_color_ramp_names.index( 'SGC_Green2Red_Hmap_Color_Ramp') except ValueError: raise ValueError( 'Color ramp SGC_Green2Red_Hmap_Color_Ramp was ' 'not found. Please import it from ' 'Settings -> Style Manager, loading ' 'svir/resources/sgc_green2red_hmap_color_ramp.xml') inverted = False registry = QgsApplication.symbolLayerRegistry() symbol_props = { 'name': 'square', 'color': '0,0,0', 'color_border': '0,0,0', 'offset': '0,0', 'size': '1.5', # FIXME 'angle': '0', } square = registry.symbolLayerMetadata( "SimpleMarker").createSymbolLayer(symbol_props) symbol = QgsSymbol.defaultSymbol(layer.geometryType()).clone() symbol.deleteSymbolLayer(0) symbol.appendSymbolLayer(square) symbol.symbolLayer(0).setStrokeStyle(Qt.PenStyle(Qt.NoPen)) elif output_type in ['asset_risk', 'input']: # options are EqualInterval, Quantile, Jenks, StdDev, Pretty # jenks = natural breaks if Qgis.QGIS_VERSION_INT < 31000: style_mode = QgsGraduatedSymbolRenderer.EqualInterval else: style_mode = 'EqualInterval' # exposure_strings = ['number', 'occupants', 'value'] # setting exposure colors by default colors = { 'single': RAMP_EXTREME_COLORS['Blues']['top'], 'ramp_name': 'Blues' } inverted = False if output_type == 'asset_risk': damage_strings = perils for damage_string in damage_strings: if damage_string in style_by: colors = { 'single': RAMP_EXTREME_COLORS['Spectral']['top'], 'ramp_name': 'Spectral' } inverted = True break else: # 'input' colors = { 'single': RAMP_EXTREME_COLORS['Greens']['top'], 'ramp_name': 'Greens' } symbol.symbolLayer(0).setShape( QgsSimpleMarkerSymbolLayerBase.Square) single_color = colors['single'] ramp_name = colors['ramp_name'] ramp_type_idx = default_color_ramp_names.index(ramp_name) symbol.setColor(QColor(single_color)) else: raise NotImplementedError( 'Undefined color ramp for output type %s' % output_type) ramp = default_qgs_style.colorRamp( default_color_ramp_names[ramp_type_idx]) if inverted: ramp.invert() # get unique values fni = layer.fields().indexOf(style_by) unique_values = layer.dataProvider().uniqueValues(fni) num_unique_values = len(unique_values - {NULL}) if num_unique_values > 2: if Qgis.QGIS_VERSION_INT < 31000: renderer = QgsGraduatedSymbolRenderer.createRenderer( layer, style_by, min(num_unique_values, style['classes']), style_mode, symbol.clone(), ramp) else: renderer = QgsGraduatedSymbolRenderer(style_by, []) # NOTE: the following returns an instance of one of the # subclasses of QgsClassificationMethod classification_method = \ QgsApplication.classificationMethodRegistry().method( style_mode) renderer.setClassificationMethod(classification_method) renderer.updateColorRamp(ramp) renderer.updateSymbols(symbol.clone()) renderer.updateClasses( layer, min(num_unique_values, style['classes'])) if not use_sgc_style: if Qgis.QGIS_VERSION_INT < 31000: label_format = renderer.labelFormat() # NOTE: the following line might be useful # label_format.setTrimTrailingZeroes(True) label_format.setPrecision(2) renderer.setLabelFormat(label_format, updateRanges=True) else: renderer.classificationMethod().setLabelPrecision(2) renderer.calculateLabelPrecision() elif num_unique_values == 2: categories = [] for unique_value in unique_values: symbol = symbol.clone() try: symbol.setColor( QColor(RAMP_EXTREME_COLORS[ramp_name] ['bottom' if unique_value == min(unique_values) else 'top'])) except Exception: symbol.setColor( QColor(style['color_from'] if unique_value == min(unique_values) else style['color_to'])) category = QgsRendererCategory(unique_value, symbol, str(unique_value)) # entry for the list of category items categories.append(category) renderer = QgsCategorizedSymbolRenderer(style_by, categories) else: renderer = QgsSingleSymbolRenderer(symbol.clone()) if add_null_class and NULL in unique_values: # add a class for NULL values rule_renderer = QgsRuleBasedRenderer(symbol.clone()) root_rule = rule_renderer.rootRule() not_null_rule = root_rule.children()[0].clone() # strip parentheses from stringified color HSL not_null_rule.setFilterExpression( '%s IS NOT NULL' % QgsExpression.quotedColumnRef(style_by)) not_null_rule.setLabel('%s:' % style_by) root_rule.appendChild(not_null_rule) null_rule = root_rule.children()[0].clone() null_rule.setSymbol( QgsFillSymbol.createSimple({ 'color': '160,160,160', 'style': 'diagonal_x' })) null_rule.setFilterExpression( '%s IS NULL' % QgsExpression.quotedColumnRef(style_by)) null_rule.setLabel(tr('No points')) root_rule.appendChild(null_rule) if isinstance(renderer, QgsGraduatedSymbolRenderer): # create value ranges rule_renderer.refineRuleRanges(not_null_rule, renderer) # remove default rule elif isinstance(renderer, QgsCategorizedSymbolRenderer): rule_renderer.refineRuleCategoris(not_null_rule, renderer) for rule in rule_renderer.rootRule().children()[1].children(): label = rule.label() # by default, labels are like: # ('"collapse-structural-ASH_DRY_sum" >= 0.0000 AND # "collapse-structural-ASH_DRY_sum" <= 2.3949') first, second = label.split(" AND ") bottom = first.rsplit(" ", 1)[1] top = second.rsplit(" ", 1)[1] simplified = "%s - %s" % (bottom, top) rule.setLabel(simplified) root_rule.removeChildAt(0) renderer = rule_renderer if render_higher_on_top: renderer.setUsingSymbolLevels(True) symbol_items = [item for item in renderer.legendSymbolItems()] for i in range(len(symbol_items)): sym = symbol_items[i].symbol().clone() key = symbol_items[i].ruleKey() for lay in range(sym.symbolLayerCount()): sym.symbolLayer(lay).setRenderingPass(i) renderer.setLegendSymbolItem(key, sym) layer.setRenderer(renderer) if not use_sgc_style: layer.setOpacity(0.7) if repaint: layer.triggerRepaint() iface.setActiveLayer(layer) iface.zoomToActiveLayer() # NOTE QGIS3: probably not needed # iface.layerTreeView().refreshLayerSymbology(layer.id()) iface.mapCanvas().refresh()
def testLegendRenderLinkedMapScale(self): """Test rendering legends linked to maps follow scale correctly""" QgsProject.instance().removeAllMapLayers() line_path = os.path.join(TEST_DATA_DIR, 'lines.shp') line_layer = QgsVectorLayer(line_path, 'lines', 'ogr') QgsProject.instance().clear() QgsProject.instance().addMapLayers([line_layer]) line_symbol = QgsLineSymbol.createSimple({ 'color': '#ff0000', 'width_unit': 'mapunits', 'width': '0.0001' }) line_layer.setRenderer(QgsSingleSymbolRenderer(line_symbol)) layout = QgsLayout(QgsProject.instance()) layout.initializeDefaults() map1 = QgsLayoutItemMap(layout) map1.attemptSetSceneRect(QRectF(20, 20, 80, 80)) map1.setFrameEnabled(True) map1.setLayers([line_layer]) layout.addLayoutItem(map1) map1.setExtent(line_layer.extent()) map1.setScale(2000) map2 = QgsLayoutItemMap(layout) map2.attemptSetSceneRect(QRectF(20, 120, 80, 80)) map2.setFrameEnabled(True) map2.setLayers([line_layer]) layout.addLayoutItem(map2) map2.setExtent(line_layer.extent()) map2.setScale(5000) legend = QgsLayoutItemLegend(layout) legend.setTitle("Legend") legend.attemptSetSceneRect(QRectF(120, 20, 80, 80)) legend.setFrameEnabled(True) legend.setFrameStrokeWidth(QgsLayoutMeasurement(2)) legend.setBackgroundColor(QColor(200, 200, 200)) legend.setTitle('') layout.addLayoutItem(legend) legend.setLinkedMap(map1) legend2 = QgsLayoutItemLegend(layout) legend2.setTitle("Legend") legend2.attemptSetSceneRect(QRectF(120, 120, 80, 80)) legend2.setFrameEnabled(True) legend2.setFrameStrokeWidth(QgsLayoutMeasurement(2)) legend2.setBackgroundColor(QColor(200, 200, 200)) legend2.setTitle('') layout.addLayoutItem(legend2) legend2.setLinkedMap(map2) checker = QgsLayoutChecker('composer_legend_scale_map', layout) checker.setControlPathPrefix("composer_legend") result, message = checker.testLayout() TestQgsLayoutItemLegend.report += checker.report() self.assertTrue(result, message) QgsProject.instance().clear()
def testCase(self): self.TEST_DATA_DIR = unitTestDataPath() tmppath = tempfile.mkdtemp() for file in glob.glob( os.path.join(self.TEST_DATA_DIR, 'france_parts.*')): shutil.copy(os.path.join(self.TEST_DATA_DIR, file), tmppath) vectorFileInfo = QFileInfo(tmppath + "/france_parts.shp") mVectorLayer = QgsVectorLayer(vectorFileInfo.filePath(), vectorFileInfo.completeBaseName(), "ogr") QgsMapLayerRegistry.instance().addMapLayers([mVectorLayer]) # create composition with composer map self.mapSettings = QgsMapSettings() layerStringList = [] layerStringList.append(mVectorLayer.id()) self.mapSettings.setLayers(layerStringList) self.mapSettings.setCrsTransformEnabled(True) self.mapSettings.setMapUnits(QgsUnitTypes.DistanceMeters) # select epsg:2154 crs = QgsCoordinateReferenceSystem() crs.createFromSrid(2154) self.mapSettings.setDestinationCrs(crs) self.mComposition = QgsComposition(self.mapSettings) self.mComposition.setPaperSize(297, 210) # fix the renderer, fill with green props = {"color": "0,127,0"} fillSymbol = QgsFillSymbol.createSimple(props) renderer = QgsSingleSymbolRenderer(fillSymbol) mVectorLayer.setRenderer(renderer) # the atlas map self.mAtlasMap = QgsComposerMap(self.mComposition, 20, 20, 130, 130) self.mAtlasMap.setFrameEnabled(True) self.mComposition.addComposerMap(self.mAtlasMap) # the atlas self.mAtlas = self.mComposition.atlasComposition() self.mAtlas.setCoverageLayer(mVectorLayer) self.mAtlas.setEnabled(True) self.mComposition.setAtlasMode(QgsComposition.ExportAtlas) # an overview mOverview = QgsComposerMap(self.mComposition, 180, 20, 50, 50) mOverview.setFrameEnabled(True) mOverview.overview().setFrameMap(self.mAtlasMap.id()) self.mComposition.addComposerMap(mOverview) nextent = QgsRectangle(49670.718, 6415139.086, 699672.519, 7065140.887) mOverview.setNewExtent(nextent) # set the fill symbol of the overview map props2 = {"color": "127,0,0,127"} fillSymbol2 = QgsFillSymbol.createSimple(props2) mOverview.overview().setFrameSymbol(fillSymbol2) # header label self.mLabel1 = QgsComposerLabel(self.mComposition) self.mComposition.addComposerLabel(self.mLabel1) self.mLabel1.setText("[% \"NAME_1\" %] area") self.mLabel1.setFont(QgsFontUtils.getStandardTestFont()) self.mLabel1.adjustSizeToText() self.mLabel1.setSceneRect(QRectF(150, 5, 60, 15)) qWarning( "header label font: %s exactMatch:%s" % (self.mLabel1.font().toString(), self.mLabel1.font().exactMatch())) # feature number label self.mLabel2 = QgsComposerLabel(self.mComposition) self.mComposition.addComposerLabel(self.mLabel2) self.mLabel2.setText( "# [%@atlas_featurenumber || ' / ' || @atlas_totalfeatures%]") self.mLabel2.setFont(QgsFontUtils.getStandardTestFont()) self.mLabel2.adjustSizeToText() self.mLabel2.setSceneRect(QRectF(150, 200, 60, 15)) qWarning( "feature number label font: %s exactMatch:%s" % (self.mLabel2.font().toString(), self.mLabel2.font().exactMatch())) self.filename_test() self.autoscale_render_test() self.fixedscale_render_test() self.predefinedscales_render_test() self.hidden_render_test() self.legend_test() shutil.rmtree(tmppath, True)
def download(self, url): # Test if permalink is valid pattern = r"^(https?:\/\/(\w+[\w\-\.\:\/])+)\?((\&+)?(\w+)\=?([\w\-\.\:\,]+?)?)+(\&+)?$" if not re.match(pattern, self.url): raise Exception("Le permalien n'est pas valide.") # Extract params from url params = parse_qs(urlparse(self.url).query) # Check mandatory parameters try: context = str(params[r"context"][0]) center = params[r"centre"][0] except: raise Exception( "Les paramètres \'Context\' et \'Centre\' sont obligatoires.") auth_contexts = [ r"metropole", r"guadeloupe", r"stmartin", r"stbarthelemy", r"guyane", r"reunion", r"mayotte", r"martinique" ] # Check scale parameter try: scale = int(params[r"echelle"][0]) except: raise Exception("Le paramètre \'Echelle\' est obligatoire.") else: if scale > scale_limit: raise Exception(wrong_scale_txt.format(str(scale_limit))) # Check if context is valid if context not in auth_contexts: raise Exception( "La valeur \'%s\' est incorrecte.\n\n" "\'Context\' doit prentre une des %s valeurs suivantes: " "%s" % (context, len(auth_contexts), ", ".join(auth_contexts))) self.zone = context if self.zone in [ r"guadeloupe", r"stmartin", r"stbarthelemy", r"martinique" ]: self.zone = r"antilles" # Check if XY are valid if not re.match(r"^\-?\d+,\-?\d+$", center): raise Exception("Les coordonnées XY du centre sont incorrectes.") # Extract XY (¢re) xcenter = int(center.split(r",")[0]) ycenter = int(center.split(r",")[1]) # Compute the bbox xmin = xcenter - self.conn.extract_lim / 2 xmax = xcenter + self.conn.extract_lim / 2 ymin = ycenter - self.conn.extract_lim / 2 ymax = ycenter + self.conn.extract_lim / 2 # Transform coordinates in WGS84 bbox = tools.reproj(QgsRectangle(xmin, ymin, xmax, ymax), 3857, 4326, self.project) # Extract RFU (Send the request) resp = self.conn.extraction(bbox.xMinimum(), bbox.yMinimum(), bbox.xMaximum(), bbox.yMaximum()) resp_read = resp.read() # DEBUG: Export response as a text file # urlresp_to_file(resp_read) if resp.code != 200: raise Exception(resp_read) tree = EltTree.fromstring(resp_read) # Check if error err = tree.find(r"./erreur") if err: raise Exception(err.text) # Create the layer: "Masque d'extraction" self.l_bbox = QgsVectorLayer(r"Polygon?crs=epsg:4326&index=yes", "Zone de travail", r"memory") p_bbox = self.l_bbox.dataProvider() simple_symbol = QgsFillSymbol.createSimple({ r"color": r"116,97,87,255", r"style": r"b_diagonal", r"outline_style": r"no" }) renderer_bbox = QgsInvertedPolygonRenderer( QgsSingleSymbolRenderer(simple_symbol)) self.l_bbox.setRenderer(renderer_bbox) self.ft_bbox = QgsFeature() self.limit_area = QgsRectangle(bbox.xMinimum(), bbox.yMinimum(), bbox.xMaximum(), bbox.yMaximum()) self.ft_bbox.setGeometry(QgsGeometry.fromRect(self.limit_area)) p_bbox.addFeatures([self.ft_bbox]) self.l_bbox.updateFields() self.l_bbox.updateExtents() # Create layers.. self.layers = self.extract_layers(tree) self.l_vertex = self.layers[0] self.l_edge = self.layers[1] # Add layer to the registry self.project.addMapLayers([self.l_vertex, self.l_edge, self.l_bbox]) # Set extent # self.canvas.setExtent(QgsRectangle(bbox.xMinimum(), bbox.yMinimum(), # bbox.xMaximum(), bbox.yMaximum())) self.features_vertex_backed_up = \ dict((ft[r"fid"], ft) for ft in self.get_features(self.l_vertex)) self.features_edge_backed_up = \ dict((ft[r"fid"], ft) for ft in self.get_features(self.l_edge)) # Get Capabitilies resp = self.conn.get_capabilities(self.zone) resp_read = resp.read() # DEBUG # urlresp_to_file(resp_read) if resp.code != 200: raise Exception(resp_read) tree = EltTree.fromstring(resp_read) # Find tolerance to determine if 2 points are equals for entry in tree.findall(r"./tolerance"): self.tol_same_pt = float(entry.text) err = tree.find(r"./erreur") if err: raise Exception(err.text) for entry in tree.findall(r"./classe_rattachement/classe"): t = (entry.attrib[r"som_precision_rattachement"], entry.text) self.precision_class.append(t) for entry in tree.findall( r"./representation_plane_sommet_autorise/representation_plane_sommet" ): t = (entry.attrib[r"som_representation_plane"], entry.attrib[r"epsg_crs_id"], entry.text) self.ellips_acronym.append(t) # Added v2.1 << for entry in tree.findall(r"./typologie_nature_sommet/nature"): self.typo_nature_som.append(entry.text) for entry in tree.findall(r"./nature_sommet_conseille/nature"): self.nature.append(entry.text) for entry in tree.findall(r"./typologie_nature_limite/nature"): self.typo_nature_lim.append(entry.text) # >> for entry in tree.findall( r"./som_ge_createur_autorise/som_ge_createur"): t = (entry.attrib[r"num_ge"], entry.text) self.auth_creator.append(t) try: ft = next(ft for ft in self.l_vertex.getFeatures()) ft_attrib = tools.attrib_as_kv(ft.fields(), ft.attributes()) self.dflt_ellips_acronym = ft_attrib[r"som_representation_plane"] except: self.dflt_ellips_acronym = None for i, e in enumerate(self.ellips_acronym): self.projComboBox.addItem(e[2]) if not self.dflt_ellips_acronym and i == 0: self.project_crs = int(e[1]) if self.dflt_ellips_acronym == e[0]: # Check projection in combobox self.projComboBox.setCurrentIndex(i) # Then change the CRS in canvas epsg_str = "EPSG:" + str(int(e[1])) crs = QgsCoordinateReferenceSystem(epsg_str) self.project.setCrs(crs) self.project_crs = int(e[1]) # Calculate bbox in the project CRS (used for the scale limitation of the canvas) self.bbox_crsproject = tools.reproj( QgsRectangle(xmin, ymin, xmax, ymax), 3857, self.project_crs, self.project) # Zoom to bbox extents self.zoom_bbox() self.canvas.refresh() # Modified in v2.1 << # Add the list of possible values to the field som_nature map_predefined_vals_to_fld(self.l_vertex, "som_typologie_nature", self.typo_nature_som) # Add the list of possible values to the field som_precision_rattachement map_predefined_vals_to_fld(self.l_vertex, "som_precision_rattachement", self.precision_class, 0, 1) # Add the list of possible values to the field som_precision_rattachement map_predefined_vals_to_fld(self.l_vertex, "som_representation_plane", self.ellips_acronym, 0, 2) # Add the list of possible values to the field lim_typologie_nature map_predefined_vals_to_fld(self.l_edge, "lim_typologie_nature", self.typo_nature_lim) # Add the list of possible values to the field som_delimitation_publique false_true_lst = [('False', 'Faux'), ('True', 'Vrai')] map_predefined_vals_to_fld(self.l_vertex, "som_delimitation_publique", false_true_lst, 0, 1) # Add the list of possible values to the field lim_delimitation_publique map_predefined_vals_to_fld(self.l_edge, "lim_delimitation_publique", false_true_lst, 0, 1) # >> # Then, start editing mode.. for idx, layer in enumerate(self.layers): if not layer.isEditable(): layer.startEditing() if idx == 0: self.iface.setActiveLayer(layer) self.projComboBox.setDisabled(False) self.permalinkCmb.setDisabled(True) self.downloadPushButton.setDisabled(True) self.resetPushButton.setDisabled(False) self.uploadPushButton.setDisabled(False) self.downloadPushButton.clicked.disconnect(self.on_downloaded) # self.permalinkLineEdit.returnPressed.disconnect(self.on_downloaded) self.resetPushButton.clicked.connect(self.on_reset) self.uploadPushButton.clicked.connect(self.on_uploaded) # Activate the scale limitation for the canvas self.canvas.scaleChanged.connect(self.limit_cvs_scale) self.downloaded.emit() return True
def testRenderMultipleRenderersAboveAndBelow(self): poly_layer = QgsVectorLayer(os.path.join(TEST_DATA_DIR, 'polys.shp')) self.assertTrue(poly_layer.isValid()) sym1 = QgsFillSymbol.createSimple({'color': '#ffaaff', 'outline_color': '#000000', 'outline_width': '1'}) renderer = QgsSingleSymbolRenderer(sym1) poly_layer.setRenderer(renderer) # add secondary renderer, for rendering below class Gen1(QgsFeatureRendererGenerator): def id(self): return 'Gen1' def level(self): return 3 def createRenderer(self): renderer = QgsCategorizedSymbolRenderer() renderer.setClassAttribute('Name') cf1 = QgsCentroidFillSymbolLayer() cf1.setSubSymbol(QgsMarkerSymbol.createSimple( {'color': '#33aa33', 'outline_style': 'no', 'size': '5'})) sym1 = QgsFillSymbol([cf1]) cf2 = QgsCentroidFillSymbolLayer() cf2.setSubSymbol(QgsMarkerSymbol.createSimple( {'color': '#aa33aa', 'outline_style': 'no', 'size': '5'})) sym2 = QgsFillSymbol([cf2]) renderer.addCategory(QgsRendererCategory('Dam', sym1, 'Dam')) renderer.addCategory(QgsRendererCategory('Lake', sym2, 'Lake')) return renderer # add secondary renderer, for rendering below class Gen2(QgsFeatureRendererGenerator): def id(self): return 'Gen2' def level(self): return 2 def createRenderer(self): renderer = QgsCategorizedSymbolRenderer() renderer.setClassAttribute('Value < 12') cf1 = QgsCentroidFillSymbolLayer() cf1.setSubSymbol(QgsMarkerSymbol.createSimple( {'color': '#aa1111', 'outline_style': 'no', 'size': '8'})) sym1 = QgsFillSymbol([cf1]) cf2 = QgsCentroidFillSymbolLayer() cf2.setSubSymbol(QgsMarkerSymbol.createSimple( {'color': '#1111dd', 'outline_style': 'no', 'size': '8'})) sym2 = QgsFillSymbol([cf2]) renderer.addCategory(QgsRendererCategory('1', sym1, '1')) renderer.addCategory(QgsRendererCategory('0', sym2, '0')) return renderer # add secondary renderer, for rendering below class Gen1b(QgsFeatureRendererGenerator): def id(self): return 'Gen1b' def level(self): return -2 def createRenderer(self): renderer = QgsCategorizedSymbolRenderer() renderer.setClassAttribute('Name') sym1 = QgsFillSymbol.createSimple( {'color': '#ffaaff', 'outline_color': '#33aa33', 'outline_width': '3'}) sym2 = QgsFillSymbol.createSimple( {'color': '#ffaaff', 'outline_color': '#aa33aa', 'outline_width': '3'}) renderer.addCategory(QgsRendererCategory('Dam', sym1, 'Dam')) renderer.addCategory(QgsRendererCategory('Lake', sym2, 'Lake')) return renderer # add secondary renderer, for rendering below class Gen2b(QgsFeatureRendererGenerator): def id(self): return 'Gen2b' def level(self): return -3 def createRenderer(self): renderer = QgsCategorizedSymbolRenderer() renderer.setClassAttribute('Value < 12') sym1 = QgsFillSymbol.createSimple( {'color': '#ffaaff', 'outline_color': '#aa1111', 'outline_width': '5'}) sym2 = QgsFillSymbol.createSimple( {'color': '#ffaaff', 'outline_color': '#1111dd', 'outline_width': '5'}) renderer.addCategory(QgsRendererCategory('1', sym1, '1')) renderer.addCategory(QgsRendererCategory('0', sym2, '0')) return renderer poly_layer.addFeatureRendererGenerator(Gen1()) poly_layer.addFeatureRendererGenerator(Gen2()) poly_layer.addFeatureRendererGenerator(Gen1b()) poly_layer.addFeatureRendererGenerator(Gen2b()) mapsettings = QgsMapSettings() mapsettings.setOutputSize(QSize(400, 400)) mapsettings.setOutputDpi(96) mapsettings.setDestinationCrs(QgsCoordinateReferenceSystem('EPSG:3857')) mapsettings.setExtent(QgsRectangle(-13875783.2, 2266009.4, -8690110.7, 6673344.5)) mapsettings.setLayers([poly_layer]) renderchecker = QgsMultiRenderChecker() renderchecker.setMapSettings(mapsettings) renderchecker.setControlPathPrefix('vectorlayerrenderer') renderchecker.setControlName('expected_multiple_renderers_both_above_below') result = renderchecker.runTest('expected_multiple_renderers_both_above_below') self.report += renderchecker.report() self.assertTrue(result) # also try with symbol levels renderer.setUsingSymbolLevels(True) poly_layer.setRenderer(renderer) renderchecker = QgsMultiRenderChecker() renderchecker.setMapSettings(mapsettings) renderchecker.setControlPathPrefix('vectorlayerrenderer') renderchecker.setControlName('expected_multiple_renderers_both_above_below') result = renderchecker.runTest('expected_multiple_renderers_both_above_below') self.report += renderchecker.report() self.assertTrue(result)
def testInitialSizeSymbolMapUnits(self): """Test initial size of legend with a symbol size in map units""" point_path = os.path.join(TEST_DATA_DIR, 'points.shp') point_layer = QgsVectorLayer(point_path, 'points', 'ogr') QgsProject.instance().addMapLayers([point_layer]) marker_symbol = QgsMarkerSymbol.createSimple({ 'color': '#ff0000', 'outline_style': 'no', 'size': '5', 'size_unit': 'MapUnit' }) point_layer.setRenderer(QgsSingleSymbolRenderer(marker_symbol)) s = QgsMapSettings() s.setLayers([point_layer]) layout = QgsLayout(QgsProject.instance()) layout.initializeDefaults() map = QgsLayoutItemMap(layout) map.attemptSetSceneRect(QRectF(20, 20, 80, 80)) map.setFrameEnabled(True) map.setLayers([point_layer]) layout.addLayoutItem(map) map.setExtent(point_layer.extent()) legend = QgsLayoutItemLegend(layout) legend.attemptSetSceneRect(QRectF(120, 20, 80, 80)) legend.setFrameEnabled(True) legend.setFrameStrokeWidth(QgsLayoutMeasurement(2)) legend.setBackgroundColor(QColor(200, 200, 200)) legend.setTitle('') layout.addLayoutItem(legend) legend.setLinkedMap(map) checker = QgsLayoutChecker('composer_legend_mapunits', layout) checker.setControlPathPrefix("composer_legend") result, message = checker.testLayout() self.assertTrue(result, message) # resize with non-top-left reference point legend.setResizeToContents(False) legend.setReferencePoint(QgsLayoutItem.LowerRight) legend.attemptMove(QgsLayoutPoint(120, 90)) legend.attemptResize(QgsLayoutSize(50, 60)) self.assertEqual(legend.positionWithUnits().x(), 120.0) self.assertEqual(legend.positionWithUnits().y(), 90.0) self.assertAlmostEqual(legend.pos().x(), 70, -1) self.assertAlmostEqual(legend.pos().y(), 30, -1) legend.setResizeToContents(True) legend.updateLegend() self.assertEqual(legend.positionWithUnits().x(), 120.0) self.assertEqual(legend.positionWithUnits().y(), 90.0) self.assertAlmostEqual(legend.pos().x(), 91, -1) self.assertAlmostEqual(legend.pos().y(), 71, -1) QgsProject.instance().removeMapLayers([point_layer.id()])
def testClippingHideClipSource(self): """ When an item is set to be the clip source, it shouldn't render anything itself """ format = QgsTextFormat() format.setFont(QgsFontUtils.getStandardTestFont("Bold")) format.setSize(30) format.setNamedStyle("Bold") format.setColor(QColor(0, 0, 0)) settings = QgsPalLayerSettings() settings.setFormat(format) settings.fieldName = "'XXXX'" settings.isExpression = True settings.placement = QgsPalLayerSettings.OverPoint vl = QgsVectorLayer("Polygon?crs=epsg:4326&field=id:integer", "vl", "memory") props = { "color": "127,255,127", 'outline_style': 'solid', 'outline_width': '1', 'outline_color': '0,0,255' } fillSymbol = QgsFillSymbol.createSimple(props) renderer = QgsSingleSymbolRenderer(fillSymbol) vl.setRenderer(renderer) f = QgsFeature(vl.fields(), 1) for x in range(0, 15, 3): for y in range(0, 15, 3): f.setGeometry(QgsGeometry(QgsPoint(x, y)).buffer(1, 3)) vl.dataProvider().addFeature(f) vl.setLabeling(QgsVectorLayerSimpleLabeling(settings)) vl.setLabelsEnabled(True) p = QgsProject() p.addMapLayer(vl) layout = QgsLayout(p) layout.initializeDefaults() p.setCrs(QgsCoordinateReferenceSystem('EPSG:4326')) map = QgsLayoutItemMap(layout) map.attemptSetSceneRect(QRectF(10, 10, 180, 180)) map.setFrameEnabled(False) map.zoomToExtent(vl.extent()) map.setLayers([vl]) layout.addLayoutItem(map) shape = QgsLayoutItemShape(layout) layout.addLayoutItem(shape) shape.setShapeType(QgsLayoutItemShape.Ellipse) shape.attemptSetSceneRect(QRectF(10, 10, 180, 180)) map.itemClippingSettings().setEnabled(True) map.itemClippingSettings().setSourceItem(shape) map.itemClippingSettings().setForceLabelsInsideClipPath(False) map.itemClippingSettings().setFeatureClippingType( QgsMapClippingRegion.FeatureClippingType.ClipToIntersection) checker = QgsLayoutChecker('composermap_itemclip_nodrawsource', layout) checker.setControlPathPrefix("composer_map") result, message = checker.testLayout() TestQgsLayoutMap.report += checker.report() self.assertTrue(result, message)
def testCase(self): self.TEST_DATA_DIR = unitTestDataPath() tmppath = tempfile.mkdtemp() for file in glob.glob(os.path.join(self.TEST_DATA_DIR, 'france_parts.*')): shutil.copy(os.path.join(self.TEST_DATA_DIR, file), tmppath) vectorFileInfo = QFileInfo(tmppath + "/france_parts.shp") mVectorLayer = QgsVectorLayer(vectorFileInfo.filePath(), vectorFileInfo.completeBaseName(), "ogr") QgsProject.instance().addMapLayers([mVectorLayer]) self.layers = [mVectorLayer] # create layout with layout map # select epsg:2154 crs = QgsCoordinateReferenceSystem() crs.createFromSrid(2154) QgsProject.instance().setCrs(crs) self.layout = QgsPrintLayout(QgsProject.instance()) self.layout.initializeDefaults() # fix the renderer, fill with green props = {"color": "0,127,0", 'outline_color': 'black'} fillSymbol = QgsFillSymbol.createSimple(props) renderer = QgsSingleSymbolRenderer(fillSymbol) mVectorLayer.setRenderer(renderer) # the atlas map self.atlas_map = QgsLayoutItemMap(self.layout) self.atlas_map.attemptSetSceneRect(QRectF(20, 20, 130, 130)) self.atlas_map.setFrameEnabled(True) self.atlas_map.setLayers([mVectorLayer]) self.layout.addLayoutItem(self.atlas_map) # the atlas self.atlas = self.layout.atlas() self.atlas.setCoverageLayer(mVectorLayer) self.atlas.setEnabled(True) # an overview self.overview = QgsLayoutItemMap(self.layout) self.overview.attemptSetSceneRect(QRectF(180, 20, 50, 50)) self.overview.setFrameEnabled(True) self.overview.overview().setLinkedMap(self.atlas_map) self.overview.setLayers([mVectorLayer]) self.layout.addLayoutItem(self.overview) nextent = QgsRectangle(49670.718, 6415139.086, 699672.519, 7065140.887) self.overview.setExtent(nextent) # set the fill symbol of the overview map props2 = {"color": "127,0,0,127", 'outline_color': 'black'} fillSymbol2 = QgsFillSymbol.createSimple(props2) self.overview.overview().setFrameSymbol(fillSymbol2) # header label self.mLabel1 = QgsLayoutItemLabel(self.layout) self.layout.addLayoutItem(self.mLabel1) self.mLabel1.setText("[% \"NAME_1\" %] area") self.mLabel1.setFont(QgsFontUtils.getStandardTestFont()) self.mLabel1.adjustSizeToText() self.mLabel1.attemptSetSceneRect(QRectF(150, 5, 60, 15)) self.mLabel1.setMarginX(1) self.mLabel1.setMarginY(1) # feature number label self.mLabel2 = QgsLayoutItemLabel(self.layout) self.layout.addLayoutItem(self.mLabel2) self.mLabel2.setText("# [%@atlas_featurenumber || ' / ' || @atlas_totalfeatures%]") self.mLabel2.setFont(QgsFontUtils.getStandardTestFont()) self.mLabel2.adjustSizeToText() self.mLabel2.attemptSetSceneRect(QRectF(150, 200, 60, 15)) self.mLabel2.setMarginX(1) self.mLabel2.setMarginY(1) self.filename_test() self.autoscale_render_test() self.fixedscale_render_test() self.predefinedscales_render_test() self.hidden_render_test() self.legend_test() self.rotation_test() shutil.rmtree(tmppath, True)
def run(self): print ("paso por el run") #coloco el puntero arriba del todo QgsProject.instance().layerTreeRegistryBridge().setLayerInsertionPoint( QgsProject.instance().layerTreeRoot(), 0 ) """Run method that performs all the real work""" #genero una lista con las columnas de la capa de puntos vl2=iface.activeLayer() if vl2 is None: iface.messageBar().pushMessage("ATENCION", "Selecciona una capa de puntos", duration=10) #if vl2.wkbType()< 1 or vl2.wkbType() > 1: #iface.messageBar().pushMessage("ATENCION", "Selecciona una capa de puntos", duration=10) #else: if vl2.wkbType()== 1 or vl2.wkbType()==1001: misdatos=[] misdatos = [f.name() for f in vl2.fields()] #trato de rellenar el desplegable con las columnas #anado un elemneto en blanco en el desplegable self.dlg.cb1.clear() self.dlg.cb1.addItem( "") for element in misdatos: self.dlg.cb1.addItem( element) # 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 # show the dialog self.dlg.show() # Run the dialog event loop result = self.dlg.exec_() # See if OK was pressed if result: column = self.dlg.cb1.currentIndex() columna=misdatos[int(column)-1] #parece que lo mejor sera la seleccion de una capa y dentro de ella de los elementos en ella seleccionados solo. Para ello habria que crear una capa temporal con solo los seleccioandos #if vl2.wkbType()== 1 or vl2.wkbType()==1001: selection = vl2.selectedFeatures() elementosseleccionados=len(selection) if elementosseleccionados ==0: vl2.selectAll() if elementosseleccionados ==1 or elementosseleccionados ==2: iface.messageBar().pushMessage("ATENCION", "Tienes algun elemento seleccionado pero no los suficientes para crear un poligono", duration=10) #onlySelectedFeatures results0=processing.run("native:saveselectedfeatures", {'INPUT':vl2,'OUTPUT':'memory:puntos_seleccionados_ptos2pol'}) result_layer0 = results0['OUTPUT'] entrada=result_layer0 QgsProject.instance().addMapLayer(result_layer0) #hay que hacer que cree una columna con el orden el solo por si por defecto no se pone ninguna params={'INPUT':entrada,'GROUP_FIELD':None,'ORDER_FIELD':columna,'DATE_FORMAT':'', 'OUTPUT':'memory:lineas_ptos2pol'} results=processing.run("qgis:pointstopath", params) result_layer = results['OUTPUT'] QgsProject.instance().addMapLayer(result_layer) params={'INPUT':result_layer,'OUTPUT':'memory:poligono_ptos2pol '} results2=processing.run("qgis:linestopolygons", params ) result_layer2 = results2['OUTPUT'] #por el mismo precio calculo la superficie #ADDING NEW FIELD layer_provider=result_layer2.dataProvider() layer_provider.addAttributes([QgsField("hectarea",QVariant.Double, "double", 10, 4)]) result_layer2.updateFields() #UPDATING/ADD ATTRIBUTE VALUE result_layer2.startEditing() features = result_layer2.getFeatures() for f in features: id=f.id() area=f.geometry().area()/10000 fieldindex = result_layer2.dataProvider().fieldNameIndex("hectarea") attr_value={fieldindex:area}#fieldindex, antes era 2 layer_provider.changeAttributeValues({id:attr_value}) result_layer2.commitChanges() #tendra que etiquetar la superficie con dos decimales y cambiar la simbologia, ya que estamos. sym1 = QgsFillSymbol.createSimple({'style': 'vertical','color': '0,0,0,0', 'outline_color': 'red'}) renderer=QgsSingleSymbolRenderer(sym1) #etiqueto layer_settings = QgsPalLayerSettings() text_format = QgsTextFormat() text_format.setFont(QFont("Arial", 12)) text_format.setSize(12) text_format.setColor(QColor("Red")) layer_settings.setFormat(text_format) layer_settings.fieldName = '''concat(round("hectarea",2),' ha.')''' layer_settings.isExpression = True layer_settings.enabled = True layer_settings = QgsVectorLayerSimpleLabeling(layer_settings) result_layer2.setLabelsEnabled(True) result_layer2.setLabeling(layer_settings) result_layer2.triggerRepaint() result_layer2.setRenderer(renderer) QgsProject.instance().addMapLayer(result_layer2) else: print(vl2.wkbType()) iface.messageBar().pushMessage("ATENCION", "Selecciona una capa de puntos", duration=10)