def testQgsMarkerLineSymbolLayer(self): """ Create a new style from a .sld file and match test """ mTestName = 'QgsMarkerLineSymbolLayer' mFilePath = QDir.toNativeSeparators('%s/symbol_layer/%s.sld' % (unitTestDataPath(), mTestName)) mDoc = QDomDocument(mTestName) mFile = QFile(mFilePath) mFile.open(QIODevice.ReadOnly) mDoc.setContent(mFile, True) mFile.close() mSymbolLayer = QgsMarkerLineSymbolLayer.createFromSld( mDoc.elementsByTagName('LineSymbolizer').item(0).toElement()) mExpectedValue = type(QgsMarkerLineSymbolLayer()) mValue = type(mSymbolLayer) mMessage = 'Expected "%s" got "%s"' % (mExpectedValue, mValue) assert mExpectedValue == mValue, mMessage mExpectedValue = QgsMarkerLineSymbolLayer.CentralPoint mValue = mSymbolLayer.placement() mMessage = 'Expected "%s" got "%s"' % (mExpectedValue, mValue) assert mExpectedValue == mValue, mMessage mExpectedValue = QgsSimpleMarkerSymbolLayerBase.Circle mValue = mSymbolLayer.subSymbol().symbolLayer(0).shape() mMessage = 'Expected "%s" got "%s"' % (mExpectedValue, mValue) assert mExpectedValue == mValue, mMessage mExpectedValue = '#000000' mValue = mSymbolLayer.subSymbol().symbolLayer(0).strokeColor().name() mMessage = 'Expected "%s" got "%s"' % (mExpectedValue, mValue) assert mExpectedValue == mValue, mMessage mExpectedValue = '#ff0000' mValue = mSymbolLayer.subSymbol().symbolLayer(0).color().name() mMessage = 'Expected "%s" got "%s"' % (mExpectedValue, mValue) assert mExpectedValue == mValue, mMessage # test colors, need to make sure colors are passed/retrieved from subsymbol mSymbolLayer.setColor(QColor(150, 50, 100)) self.assertEqual(mSymbolLayer.color(), QColor(150, 50, 100)) self.assertEqual(mSymbolLayer.subSymbol().color(), QColor(150, 50, 100)) mSymbolLayer.subSymbol().setColor(QColor(250, 150, 200)) self.assertEqual(mSymbolLayer.subSymbol().color(), QColor(250, 150, 200)) self.assertEqual(mSymbolLayer.color(), QColor(250, 150, 200))
def testMarkLineUnitDefault(self): symbol = QgsMarkerLineSymbolLayer() symbol.setSubSymbol( QgsMarkerSymbol.createSimple({'color': '#ffffff', 'size': '3'})) symbol.setInterval(5) symbol.setOffset(5) dom, root = self.symbolToSld(symbol) # print ("Mark line mm: \n" + dom.toString()) # size of the mark self.assertStaticSize(root, '11') # gap and offset self.assertStaticGap(root, '18') self.assertStaticPerpendicularOffset(root, '18')
def testDataDefinedOpacity(self): line_shp = os.path.join(TEST_DATA_DIR, 'lines.shp') line_layer = QgsVectorLayer(line_shp, 'Lines', 'ogr') self.assertTrue(line_layer.isValid()) s = QgsLineSymbol() s.deleteSymbolLayer(0) marker_line = QgsMarkerLineSymbolLayer(True) marker_line.setPlacement(QgsTemplatedLineSymbolLayerBase.CentralPoint) simple_marker = QgsSimpleMarkerSymbolLayer( QgsSimpleMarkerSymbolLayer.Circle, 10) simple_marker.setColor(QColor(0, 255, 0)) simple_marker.setStrokeColor(QColor(255, 0, 0)) simple_marker.setStrokeWidth(1) simple_marker.setDataDefinedProperty( QgsSymbolLayer.PropertyFillColor, QgsProperty.fromExpression("if(Name='Arterial', 'red', 'green')")) simple_marker.setDataDefinedProperty( QgsSymbolLayer.PropertyStrokeColor, QgsProperty.fromExpression( "if(Name='Arterial', 'magenta', 'blue')")) marker_symbol = QgsMarkerSymbol() marker_symbol.changeSymbolLayer(0, simple_marker) marker_symbol.setOpacity(0.5) marker_line.setSubSymbol(marker_symbol) s.appendSymbolLayer(marker_line.clone()) s.setDataDefinedProperty( QgsSymbol.PropertyOpacity, QgsProperty.fromExpression("if(\"Value\" = 1, 25, 50)")) line_layer.setRenderer(QgsSingleSymbolRenderer(s)) ms = QgsMapSettings() ms.setOutputSize(QSize(400, 400)) ms.setOutputDpi(96) ms.setExtent(QgsRectangle(-118.5, 19.0, -81.4, 50.4)) ms.setLayers([line_layer]) # Test rendering renderchecker = QgsMultiRenderChecker() renderchecker.setMapSettings(ms) renderchecker.setControlPathPrefix('symbol_markerline') renderchecker.setControlName('expected_markerline_ddopacity') res = renderchecker.runTest('expected_markerline_ddopacity') self.report += renderchecker.report() self.assertTrue(res)
def testMarkLineUnitPixels(self): symbol = QgsMarkerLineSymbolLayer() symbol.setSubSymbol( QgsMarkerSymbol.createSimple({'color': '#ffffff', 'size': '3'})) symbol.setInterval(5) symbol.setOffset(5) symbol.setOutputUnit(QgsUnitTypes.RenderPixels) dom, root = self.symbolToSld(symbol) # print ("Mark line px: \n" + dom.toString()) # size of the mark self.assertStaticSize(root, '3') # gap and offset self.assertStaticGap(root, '5') self.assertStaticPerpendicularOffset(root, '5')
def testInnerVerticesPolygon(self): fill_symbol = QgsFillSymbol() fill_symbol.deleteSymbolLayer(0) fill_symbol.appendSymbolLayer( QgsMarkerLineSymbolLayer()) fill_symbol[0].setPlacements(Qgis.MarkerLinePlacements(Qgis.MarkerLinePlacement.InnerVertices)) marker = QgsSimpleMarkerSymbolLayer(QgsSimpleMarkerSymbolLayer.Triangle, 4) marker.setColor(QColor(255, 0, 0)) marker.setStrokeStyle(Qt.NoPen) marker_symbol = QgsMarkerSymbol() marker_symbol.changeSymbolLayer(0, marker) fill_symbol[0].setSubSymbol(marker_symbol) g = QgsGeometry.fromWkt('Polygon((0 0, 10 0, 10 10, 0 10, 0 0))') rendered_image = self.renderGeometry(fill_symbol, g) assert self.imageCheck('markerline_inner_vertices_polygon', 'markerline_inner_vertices_polygon', rendered_image)
def testMultiplePlacements(self): line_symbol = QgsLineSymbol() line_symbol.deleteSymbolLayer(0) line_symbol.appendSymbolLayer( QgsMarkerLineSymbolLayer()) line_symbol[0].setPlacements(Qgis.MarkerLinePlacements(Qgis.MarkerLinePlacement.FirstVertex | Qgis.MarkerLinePlacement.LastVertex)) marker = QgsSimpleMarkerSymbolLayer(QgsSimpleMarkerSymbolLayer.Triangle, 4) marker.setColor(QColor(255, 0, 0)) marker.setStrokeStyle(Qt.NoPen) marker_symbol = QgsMarkerSymbol() marker_symbol.changeSymbolLayer(0, marker) line_symbol[0].setSubSymbol(marker_symbol) g = QgsGeometry.fromWkt('LineString(0 0, 10 0, 10 10, 0 10)') rendered_image = self.renderGeometry(line_symbol, g) assert self.imageCheck('markerline_multiple_placement', 'markerline_multiple_placement', rendered_image)
def testFirstLastVertexRespectMultipart(self): line_symbol = QgsLineSymbol() line_symbol.deleteSymbolLayer(0) line_symbol.appendSymbolLayer( QgsMarkerLineSymbolLayer()) line_symbol[0].setPlacements(Qgis.MarkerLinePlacements(Qgis.MarkerLinePlacement.FirstVertex | Qgis.MarkerLinePlacement.LastVertex)) marker = QgsSimpleMarkerSymbolLayer(QgsSimpleMarkerSymbolLayer.Triangle, 4) marker.setColor(QColor(255, 0, 0)) marker.setStrokeStyle(Qt.NoPen) marker_symbol = QgsMarkerSymbol() marker_symbol.changeSymbolLayer(0, marker) line_symbol[0].setSubSymbol(marker_symbol) line_symbol[0].setPlaceOnEveryPart(False) g = QgsGeometry.fromWkt('MultiLineString((0 0, 10 0, 10 10, 0 10),(3 3, 7 3, 7 7, 3 7))') rendered_image = self.renderGeometry(line_symbol, g) assert self.imageCheck('markerline_first_last_respect_multipart', 'markerline_first_last_respect_multipart', rendered_image)
def testRingNumberVariable(self): # test test geometry_ring_num variable s3 = QgsFillSymbol() s3.deleteSymbolLayer(0) s3.appendSymbolLayer(QgsMarkerLineSymbolLayer()) s3.symbolLayer(0).subSymbol()[0].setDataDefinedProperty( QgsSymbolLayer.PropertyFillColor, QgsProperty.fromExpression( 'case when @geometry_ring_num=0 then \'green\' when @geometry_ring_num=1 then \'blue\' when @geometry_ring_num=2 then \'red\' end' )) s3.symbolLayer(0).setAverageAngleLength(0) g = QgsGeometry.fromWkt( 'Polygon((0 0, 10 0, 10 10, 0 10, 0 0),(1 1, 1 2, 2 2, 2 1, 1 1),(8 8, 9 8, 9 9, 8 9, 8 8))' ) rendered_image = self.renderGeometry(s3, g) assert self.imageCheck('markerline_ring_num', 'markerline_ring_num', rendered_image)
def append_MarkerLineSymbolLayer(symbol, layer: MarkerLineSymbolLayer, context: Context): """ Appends a MarkerLineSymbolLayer to a symbol """ template = layer.template # first work out total length of pattern current_length = 0 for t in template.pattern_parts: current_length += t[0] current_length += t[1] total_length = current_length * template.pattern_interval marker = Symbol_to_QgsSymbol(layer.pattern_marker, context) marker.setAngle(90) current_offset_from_start = 0 for t in template.pattern_parts: if t[0]: # marker line = QgsMarkerLineSymbolLayer(True) start_marker = marker.clone() start_marker.setAngle(start_marker.angle() - 90) line.setSubSymbol(start_marker) line.setOffset(-context.convert_size(layer.offset)) line.setOffsetUnit(context.units) line.setInterval(context.convert_size(total_length)) line.setIntervalUnit(context.units) line.setOffsetAlongLine( context.convert_size(current_offset_from_start + template.pattern_interval / 2)) line.setOffsetAlongLineUnit(context.units) symbol.appendSymbolLayer(line) current_offset_from_start += template.pattern_interval * t[0] if t[1]: # space current_offset_from_start += template.pattern_interval * t[1] if layer.decoration is not None: append_Decorations(symbol, layer.decoration, context)
def __init__(self, source: QgsFeatureSource, layer_type: QgsWkbTypes.GeometryType, selection: list, vertex_number=Optional[int], topological_geometries: Optional[Dict[int, QgsGeometry]] = None): if layer_type == QgsWkbTypes.LineGeometry: symbol = QgsLineSymbol() else: symbol = QgsFillSymbol() marker_line = QgsMarkerLineSymbolLayer() marker_line.setRotateMarker(False) marker_line.setPlacement(QgsMarkerLineSymbolLayer.Vertex) vertex_marker_symbol = SettingsRegistry.vertex_symbol() # not so nice, but required to allow us to dynamically change this color mid-way through rendering for layer in vertex_marker_symbol: layer.setDataDefinedProperty(QgsSymbolLayer.PropertyFillColor, QgsProperty.fromValue(None)) font_marker_symbol = QgsMarkerSymbol() text_format = SettingsRegistry.vertex_format() font_marker = TextRendererMarkerSymbolLayer(text_format, vertex_number) font_marker.setSubSymbol(vertex_marker_symbol) font_marker_symbol.changeSymbolLayer(0, font_marker) marker_line.setSubSymbol(font_marker_symbol) symbol.changeSymbolLayer(0, marker_line) symbol.setClipFeaturesToExtent(False) super().__init__(symbol) self.selection = sorted(selection) self.feature_index = 0 self.vertex_number = vertex_number self.source = source self.topological_geometries = topological_geometries
def testForceRHR(self): # test forcing right hand rule during rendering s = QgsFillSymbol() s.deleteSymbolLayer(0) s.appendSymbolLayer( QgsSimpleFillSymbolLayer(color=QColor(255, 0, 0), strokeColor=QColor(0, 255, 0))) self.assertFalse(s.forceRHR()) s.setForceRHR(True) self.assertTrue(s.forceRHR()) s.setForceRHR(False) self.assertFalse(s.forceRHR()) s.setForceRHR(True) doc = QDomDocument() context = QgsReadWriteContext() element = QgsSymbolLayerUtils.saveSymbol('test', s, doc, context) s2 = QgsSymbolLayerUtils.loadSymbol(element, context) self.assertTrue(s2.forceRHR()) # rendering test s3 = QgsFillSymbol() s3.deleteSymbolLayer(0) s3.appendSymbolLayer( QgsSimpleFillSymbolLayer(color=QColor(255, 200, 200), strokeColor=QColor(0, 255, 0), strokeWidth=2)) marker_line = QgsMarkerLineSymbolLayer(True) marker_line.setPlacement(QgsMarkerLineSymbolLayer.FirstVertex) marker = QgsSimpleMarkerSymbolLayer(QgsSimpleMarkerSymbolLayer.Triangle, 4) marker.setColor(QColor(255, 0, 0)) marker.setStrokeStyle(Qt.NoPen) marker_symbol = QgsMarkerSymbol() marker_symbol.changeSymbolLayer(0, marker) marker_line.setSubSymbol(marker_symbol) s3.appendSymbolLayer(marker_line) g = QgsGeometry.fromWkt('Polygon((0 0, 10 0, 10 10, 0 10, 0 0),(1 1, 1 2, 2 2, 2 1, 1 1),(8 8, 9 8, 9 9, 8 9, 8 8))') rendered_image = self.renderGeometry(s3, g) assert self.imageCheck('force_rhr_off', 'polygon_forcerhr_off', rendered_image) s3.setForceRHR(True) rendered_image = self.renderGeometry(s3, g) assert self.imageCheck('force_rhr_on', 'polygon_forcerhr_on', rendered_image)
def testPartNumPolygon(self): # test geometry_part_num variable s = QgsFillSymbol() marker_line = QgsMarkerLineSymbolLayer(False) marker_line.setPlacement(QgsMarkerLineSymbolLayer.FirstVertex) f = QgsFontUtils.getStandardTestFont('Bold', 24) marker = QgsFontMarkerSymbolLayer(f.family(), 'x', 24, QColor(255, 255, 0)) marker.setDataDefinedProperty(QgsSymbolLayer.PropertyCharacter, QgsProperty.fromExpression('@geometry_part_num')) marker_symbol = QgsMarkerSymbol() marker_symbol.changeSymbolLayer(0, marker) marker_line.setSubSymbol(marker_symbol) marker_line.setAverageAngleLength(0) s.changeSymbolLayer(0, marker_line) # rendering test - a polygon with a smaller part first g = QgsGeometry.fromWkt('MultiPolygon(((0 0, 2 0, 2 2, 0 0)),((10 0, 10 10, 0 10, 10 0)))') rendered_image = self.renderGeometry(s, g, buffer=4) assert self.imageCheck('poly_part_num_variable', 'poly_part_num_variable', rendered_image)
def testCenterSegment(self): s = QgsLineSymbol() s.deleteSymbolLayer(0) marker_line = QgsMarkerLineSymbolLayer(True) marker_line.setPlacement(QgsTemplatedLineSymbolLayerBase.SegmentCenter) marker = QgsSimpleMarkerSymbolLayer(QgsSimpleMarkerSymbolLayer.Triangle, 4) marker.setColor(QColor(255, 0, 0)) marker.setStrokeStyle(Qt.NoPen) marker_symbol = QgsMarkerSymbol() marker_symbol.changeSymbolLayer(0, marker) marker_line.setSubSymbol(marker_symbol) line_symbol = QgsLineSymbol() line_symbol.changeSymbolLayer(0, marker_line) s.appendSymbolLayer(marker_line.clone()) g = QgsGeometry.fromWkt('LineString(0 0, 10 0, 0 10)') rendered_image = self.renderGeometry(s, g) assert self.imageCheck('markerline_segmentcenter', 'markerline_segmentcenter', rendered_image)
def testPartNum(self): # test geometry_part_num variable s = QgsLineSymbol() s.deleteSymbolLayer(0) sym_layer = QgsGeometryGeneratorSymbolLayer.create( {'geometryModifier': 'segments_to_lines($geometry)'}) sym_layer.setSymbolType(QgsSymbol.Line) s.appendSymbolLayer(sym_layer) marker_line = QgsMarkerLineSymbolLayer(False) marker_line.setPlacement(QgsMarkerLineSymbolLayer.FirstVertex) f = QgsFontUtils.getStandardTestFont('Bold', 24) marker = QgsFontMarkerSymbolLayer(f.family(), 'x', 24, QColor(255, 255, 0)) marker.setDataDefinedProperty( QgsSymbolLayer.PropertyCharacter, QgsProperty.fromExpression('@geometry_part_num')) marker_symbol = QgsMarkerSymbol() marker_symbol.changeSymbolLayer(0, marker) marker_line.setSubSymbol(marker_symbol) marker_line.setAverageAngleLength(0) line_symbol = QgsLineSymbol() line_symbol.changeSymbolLayer(0, marker_line) sym_layer.setSubSymbol(line_symbol) # rendering test g = QgsGeometry.fromWkt('LineString(0 0, 10 0, 10 10, 0 10)') rendered_image = self.renderGeometry(s, g, buffer=4) assert self.imageCheck('part_num_variable', 'part_num_variable', rendered_image) marker.setDataDefinedProperty( QgsSymbolLayer.PropertyCharacter, QgsProperty.fromExpression('@geometry_part_count')) # rendering test g = QgsGeometry.fromWkt('LineString(0 0, 10 0, 10 10, 0 10)') rendered_image = self.renderGeometry(s, g, buffer=4) assert self.imageCheck('part_count_variable', 'part_count_variable', rendered_image)
def testCompoundCurveInnerVertices(self): # test rendering compound curve with markers at inner vertices and curve points s = QgsLineSymbol() s.deleteSymbolLayer(0) marker_line = QgsMarkerLineSymbolLayer(True) marker_line.setPlacement(QgsMarkerLineSymbolLayer.InnerVertices) marker = QgsSimpleMarkerSymbolLayer(QgsSimpleMarkerSymbolLayer.Triangle, 4) marker.setColor(QColor(255, 0, 0)) marker.setStrokeStyle(Qt.NoPen) marker_symbol = QgsMarkerSymbol() marker_symbol.changeSymbolLayer(0, marker) marker_line.setSubSymbol(marker_symbol) s.appendSymbolLayer(marker_line.clone()) # rendering test g = QgsGeometry.fromWkt('CompoundCurve (CircularString (2606642.3863534671254456 1228883.61571401031687856, 2606656.45901552261784673 1228882.30281259422190487, 2606652.60236761253327131 1228873.80998155777342618, 2606643.65822671446949244 1228875.45110832806676626, 2606642.3863534671254456 1228883.65674217976629734))') self.assertFalse(g.isNull()) rendered_image = self.renderGeometry(s, g) self.assertTrue(self.imageCheck('markerline_compoundcurve_inner_vertices', 'markerline_compoundcurve_inner_vertices', rendered_image))
def testNoPoint(self): s = QgsLineSymbol() s.deleteSymbolLayer(0) marker_line = QgsMarkerLineSymbolLayer(True) marker_line.setPlacement(QgsTemplatedLineSymbolLayerBase.Interval) marker_line.setOffsetAlongLine(1000) marker_line.setIntervalUnit(QgsUnitTypes.RenderMapUnits) marker = QgsSimpleMarkerSymbolLayer(QgsSimpleMarkerSymbolLayer.Circle, 4) marker.setColor(QColor(255, 0, 0, 100)) marker.setStrokeStyle(Qt.NoPen) marker_symbol = QgsMarkerSymbol() marker_symbol.changeSymbolLayer(0, marker) marker_line.setSubSymbol(marker_symbol) line_symbol = QgsLineSymbol() line_symbol.changeSymbolLayer(0, marker_line) s.appendSymbolLayer(marker_line.clone()) g = QgsGeometry.fromWkt('LineString(0 0, 0 10, 10 10)') rendered_image = self.renderGeometry(s, g) assert self.imageCheck('markerline_none', 'markerline_none', rendered_image)
def testMarkerAverageAngleRing(self): s = QgsLineSymbol() s.deleteSymbolLayer(0) marker_line = QgsMarkerLineSymbolLayer(True) marker_line.setPlacement(QgsTemplatedLineSymbolLayerBase.Interval) marker_line.setInterval(6) marker = QgsSimpleMarkerSymbolLayer(QgsSimpleMarkerSymbolLayer.Triangle, 4) marker.setColor(QColor(255, 0, 0)) marker.setStrokeStyle(Qt.NoPen) marker_symbol = QgsMarkerSymbol() marker_symbol.changeSymbolLayer(0, marker) marker_line.setSubSymbol(marker_symbol) marker_line.setAverageAngleLength(60) line_symbol = QgsLineSymbol() line_symbol.changeSymbolLayer(0, marker_line) s.appendSymbolLayer(marker_line.clone()) g = QgsGeometry.fromWkt('LineString(0 0, 0 10, 10 10, 10 0, 0 0)') rendered_image = self.renderGeometry(s, g) assert self.imageCheck('markerline_ring_average_angle', 'markerline_ring_average_angle', rendered_image)
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 make_flow_sym_renderer(self, layer, field_name, ranges_colors=None): feats = layer.getFeatures() min_val = sys.float_info.max max_val = -min_val # Find values range for feat in feats: attr = feat.attribute(field_name) val = float(attr) if val < min_val: min_val = val if val > max_val: max_val = val # Define colors if ranges_colors is None: ranges_colors = [] colors = [ QColor(0, 255, 0), QColor(128, 255, 0), QColor(255, 255, 0), QColor(255, 128, 0), QColor(255, 0, 0)] intv_nr = len(colors) intv = (max_val - min_val) / intv_nr for c in range(intv_nr): vrange = [min_val + intv * c, min_val + intv * (c + 1)] if c == len(colors) - 1: vrange[1] = max_val ranges_colors.append([vrange, colors[c]]) range_list = [] for range_col in ranges_colors: r_min = range_col[0][0] r_max = range_col[0][1] title = str(r_min) + ' - ' + str(r_max) range_list.append(symbology_from_range(layer, r_min, r_max, range_col[1], title)) renderer = QgsGraduatedSymbolRenderer(field_name, range_list) # Line symbol = QgsLineSymbol().createSimple({}) symbol.deleteSymbolLayer(0) line_sym_lay = QgsSimpleLineSymbolLayer() line_sym_lay.setWidth(0.2) symbol.appendSymbolLayer(line_sym_lay) # Define arrows for flow and velocities if u'Link flow' in layer.name() in layer.name(): self.marker_sym = QgsMarkerSymbol.createSimple({'name': 'triangle', 'color': 'black'}) data_def_angle = QgsProperty() data_def_angle_exp =\ 'case ' \ 'when "' + field_name + '" >= 0 ' \ 'then degrees(azimuth( start_point( $geometry), end_point($geometry))) ' \ 'else ' \ 'case ' \ 'when degrees(azimuth( start_point( $geometry), end_point($geometry))) < 180 ' \ 'then degrees(azimuth( start_point( $geometry), end_point($geometry))) + 180 ' \ 'else ' \ 'degrees(azimuth( start_point( $geometry), end_point($geometry))) - 180 ' \ 'end ' \ 'end' data_def_angle.setExpressionString(data_def_angle_exp) data_def_angle.setActive(True) self.marker_sym.setDataDefinedAngle(data_def_angle) # Size: 0 if attribute = 0 data_def_size = QgsProperty() data_def_size_exp =\ 'case ' \ 'when "' + field_name + '" = 0 ' \ 'then 0 ' \ 'else ' \ '2 ' \ 'end' data_def_size.setExpressionString(data_def_size_exp) data_def_size.setActive(True) self.marker_sym.setDataDefinedSize(data_def_size) marker_sym_lay = QgsMarkerLineSymbolLayer() marker_sym_lay.setColor(QColor(0, 0, 0)) marker_sym_lay.setFillColor(QColor(0, 0, 0)) marker_sym_lay.setPlacement(QgsMarkerLineSymbolLayer.CentralPoint) marker_sym_lay.setRotateMarker(False) marker_sym_lay.setSubSymbol(self.marker_sym) self.marker_sym.appendSymbolLayer(marker_sym_lay) symbol.appendSymbolLayer(marker_sym_lay) # renderer.setSourceSymbol(symbol) renderer.updateSymbols(symbol) return renderer
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 testCondenseFillAndOutline(self): """ Test QgsSymbolLayerUtils.condenseFillAndOutline """ self.assertFalse(QgsSymbolLayerUtils.condenseFillAndOutline( None, None)) # not simple fill or line self.assertFalse( QgsSymbolLayerUtils.condenseFillAndOutline( QgsShapeburstFillSymbolLayer(), QgsSimpleLineSymbolLayer())) self.assertFalse( QgsSymbolLayerUtils.condenseFillAndOutline( QgsSimpleFillSymbolLayer(), QgsMarkerLineSymbolLayer())) # simple fill/line fill = QgsSimpleFillSymbolLayer() line = QgsSimpleLineSymbolLayer() # set incompatible settings on outline line.setUseCustomDashPattern(True) self.assertFalse(QgsSymbolLayerUtils.condenseFillAndOutline( fill, line)) line = QgsSimpleLineSymbolLayer() line.setDashPatternOffset(1) self.assertFalse(QgsSymbolLayerUtils.condenseFillAndOutline( fill, line)) line = QgsSimpleLineSymbolLayer() line.setAlignDashPattern(True) self.assertFalse(QgsSymbolLayerUtils.condenseFillAndOutline( fill, line)) line = QgsSimpleLineSymbolLayer() line.setTweakDashPatternOnCorners(True) self.assertFalse(QgsSymbolLayerUtils.condenseFillAndOutline( fill, line)) line = QgsSimpleLineSymbolLayer() line.setTrimDistanceStart(1) self.assertFalse(QgsSymbolLayerUtils.condenseFillAndOutline( fill, line)) line = QgsSimpleLineSymbolLayer() line.setTrimDistanceEnd(1) self.assertFalse(QgsSymbolLayerUtils.condenseFillAndOutline( fill, line)) line = QgsSimpleLineSymbolLayer() line.setDrawInsidePolygon(True) self.assertFalse(QgsSymbolLayerUtils.condenseFillAndOutline( fill, line)) line = QgsSimpleLineSymbolLayer() line.setRingFilter(QgsSimpleLineSymbolLayer.ExteriorRingOnly) self.assertFalse(QgsSymbolLayerUtils.condenseFillAndOutline( fill, line)) line = QgsSimpleLineSymbolLayer() line.setOffset(1) self.assertFalse(QgsSymbolLayerUtils.condenseFillAndOutline( fill, line)) line = QgsSimpleLineSymbolLayer() line.setDataDefinedProperty(QgsSymbolLayer.PropertyTrimEnd, QgsProperty.fromValue(4)) self.assertFalse(QgsSymbolLayerUtils.condenseFillAndOutline( fill, line)) # compatible! line = QgsSimpleLineSymbolLayer() line.setColor(QColor(255, 0, 0)) line.setWidth(1.2) line.setWidthUnit(QgsUnitTypes.RenderPoints) line.setWidthMapUnitScale(QgsMapUnitScale(1, 2)) line.setPenJoinStyle(Qt.MiterJoin) line.setPenStyle(Qt.DashDotDotLine) self.assertTrue(QgsSymbolLayerUtils.condenseFillAndOutline(fill, line)) self.assertEqual(fill.strokeColor(), QColor(255, 0, 0)) self.assertEqual(fill.strokeWidth(), 1.2) self.assertEqual(fill.strokeWidthUnit(), QgsUnitTypes.RenderPoints) self.assertEqual(fill.strokeWidthMapUnitScale(), QgsMapUnitScale(1, 2)) self.assertEqual(fill.penJoinStyle(), Qt.MiterJoin) self.assertEqual(fill.strokeStyle(), Qt.DashDotDotLine)
def append_decoration( symbol, # pylint: disable=too-many-branches,too-many-statements decoration: SimpleLineDecorationElement, context: Context, enabled: bool, locked: bool): """ Appends decorations to the given symbol """ positions = decoration.marker_positions[:] from .symbols import SymbolConverter # pylint: disable=import-outside-toplevel,cyclic-import marker = SymbolConverter.Symbol_to_QgsSymbol(decoration.marker, context) if decoration.flip_all: for layer_index in range(marker.symbolLayerCount()): layer = marker.symbolLayer(layer_index) layer.setAngle(layer.angle() + 180) if 0 in positions: # start marker line = QgsMarkerLineSymbolLayer(not decoration.fixed_angle) start_marker = marker.clone() if decoration.flip_first: for layer_index in range(marker.symbolLayerCount()): layer = start_marker.symbolLayer(layer_index) layer.setAngle(layer.angle() + 180) for layer_index in range(start_marker.symbolLayerCount()): layer = start_marker.symbolLayer(layer_index) if layer.offset().x() or layer.offset().y(): # adjust marker offset to account for rotation of line markers offset = ConversionUtils.adjust_offset_for_rotation( layer.offset(), layer.angle()) if decoration.flip_first or decoration.flip_all: offset.setY(-offset.y()) layer.setOffset(offset) line.setSubSymbol(start_marker) line.setEnabled(enabled) line.setLocked(locked) # TODO - maybe need to offset this by marker width / 4? seems a better match to ESRI line.setPlacement(QgsMarkerLineSymbolLayer.FirstVertex) symbol.appendSymbolLayer(line) if 1 in positions: # end marker line = QgsMarkerLineSymbolLayer(not decoration.fixed_angle) end_marker = marker.clone() for layer_index in range(end_marker.symbolLayerCount()): layer = end_marker.symbolLayer(layer_index) if layer.offset().x() or layer.offset().y(): # adjust marker offset to account for rotation of line markers offset = ConversionUtils.adjust_offset_for_rotation( layer.offset(), layer.angle()) if decoration.flip_all: offset.setY(-offset.y()) layer.setOffset(offset) line.setSubSymbol(end_marker) line.setPlacement(QgsMarkerLineSymbolLayer.LastVertex) line.setEnabled(enabled) line.setLocked(locked) # TODO - maybe need to offset this by marker width / 4? seems a better match to ESRI symbol.appendSymbolLayer(line) if 0.5 in positions: # mid marker line = QgsMarkerLineSymbolLayer(not decoration.fixed_angle) end_marker = marker.clone() for layer_index in range(end_marker.symbolLayerCount()): layer = end_marker.symbolLayer(layer_index) if layer.offset().x() or layer.offset().y(): # adjust marker offset to account for rotation of line markers offset = ConversionUtils.adjust_offset_for_rotation( layer.offset(), layer.angle()) if decoration.flip_all: offset.setY(-offset.y()) layer.setOffset(offset) line.setSubSymbol(end_marker) line.setPlacement(QgsMarkerLineSymbolLayer.CentralPoint) line.setEnabled(enabled) line.setLocked(locked) symbol.appendSymbolLayer(line) # TODO other positions other_positions = [p for p in positions if p not in (0, 0.5, 1)] if other_positions: # Would need to use data defined marker placement distance, e.g. $length/3 # and offset first marker by $length/3 to avoid placing a marker at the start # of the line raise NotImplementedException( 'Non start/end decoration positions are not implemented (need {})' .format(other_positions))
def append_Decorations(symbol, decorations: LineDecoration, context: Context): """ Appends decorations to the given symbol """ if len(decorations.decorations) > 1: raise NotImplementedException( 'Multiple line decorations are not yet supported') elif not decorations.decorations: return decoration = decorations.decorations[0] positions = decoration.marker_positions[:] marker = Symbol_to_QgsSymbol(decoration.marker, context) if decoration.flip_all: marker.setAngle(270) else: marker.setAngle(90) if 0 in positions: # start marker line = QgsMarkerLineSymbolLayer(not decoration.fixed_angle) start_marker = marker.clone() if decoration.flip_first: start_marker.setAngle(270) for l in range(start_marker.symbolLayerCount()): layer = start_marker.symbolLayer(l) if layer.offset().x() or layer.offset().y(): # adjust marker offset to account for rotation of line markers layer.setOffset(adjust_offset_for_rotation(layer.offset(), 90)) line.setSubSymbol(start_marker) # TODO - maybe need to offset this by marker width / 4? seems a better match to ESRI line.setPlacement(QgsMarkerLineSymbolLayer.FirstVertex) symbol.appendSymbolLayer(line) if 1 in positions: # end marker line = QgsMarkerLineSymbolLayer(not decoration.fixed_angle) end_marker = marker.clone() for l in range(end_marker.symbolLayerCount()): layer = end_marker.symbolLayer(l) if layer.offset().x() or layer.offset().y(): # adjust marker offset to account for rotation of line markers layer.setOffset(adjust_offset_for_rotation( layer.offset(), 270)) line.setSubSymbol(end_marker) line.setPlacement(QgsMarkerLineSymbolLayer.LastVertex) # TODO - maybe need to offset this by marker width / 4? seems a better match to ESRI symbol.appendSymbolLayer(line) # TODO other positions other_positions = [p for p in positions if p not in (0, 1)] if other_positions: # Would need to use data defined marker placement distance, e.g. $length/3 # and offset first marker by $length/3 to avoid placing a marker at the start # of the line raise NotImplementedException( 'Non start/end decoration positions are not implemented')