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 testHashAverageAngle(self): s = QgsLineSymbol() s.deleteSymbolLayer(0) hash_line = QgsHashedLineSymbolLayer(True) hash_line.setPlacement(QgsTemplatedLineSymbolLayerBase.CentralPoint) simple_line = QgsSimpleLineSymbolLayer() simple_line.setColor(QColor(0, 255, 0)) simple_line.setWidth(1) line_symbol = QgsLineSymbol() line_symbol.changeSymbolLayer(0, simple_line) hash_line.setSubSymbol(line_symbol) hash_line.setHashLength(7) hash_line.setHashAngle(45) hash_line.setAverageAngleLength(30) s.appendSymbolLayer(hash_line.clone()) g = QgsGeometry.fromWkt('LineString(0 0, 10 10, 10 0)') rendered_image = self.renderGeometry(s, g) assert self.imageCheck('line_hash_center_average_angle', 'line_hash_center_average_angle', rendered_image)
def testSimpleLineWithOffset(self): """ test that rendering a polygon with simple line symbol with offset results in closed line""" layer = QgsSimpleLineSymbolLayer() layer.setOffset(-1) layer.setColor(QColor(0, 0, 0)) symbol = QgsFillSymbol() symbol.changeSymbolLayer(0, layer) image = QImage(200, 200, QImage.Format_RGB32) painter = QPainter() ms = QgsMapSettings() geom = QgsGeometry.fromWkt('Polygon((0 0, 10 0, 10 10, 0 10, 0 0))') f = QgsFeature() f.setGeometry(geom) extent = geom.constGet().boundingBox() # buffer extent by 10% extent = extent.buffered((extent.height() + extent.width()) / 20.0) ms.setExtent(extent) ms.setOutputSize(image.size()) context = QgsRenderContext.fromMapSettings(ms) context.setPainter(painter) context.setScaleFactor(96 / 25.4) # 96 DPI painter.begin(image) image.fill(QColor(255, 255, 255)) symbol.startRender(context) symbol.renderFeature(f, context) symbol.stopRender(context) painter.end() self.assertTrue( self.imageCheck('symbol_layer', 'fill_simpleline_offset', image))
def testHashPlacement(self): s = QgsLineSymbol() s.deleteSymbolLayer(0) hash_line = QgsHashedLineSymbolLayer(True) hash_line.setPlacement(QgsTemplatedLineSymbolLayerBase.Vertex) hash_line.setInterval(6) simple_line = QgsSimpleLineSymbolLayer() simple_line.setColor(QColor(0, 255, 0)) simple_line.setWidth(1) line_symbol = QgsLineSymbol() line_symbol.changeSymbolLayer(0, simple_line) hash_line.setSubSymbol(line_symbol) hash_line.setHashLength(7) s.appendSymbolLayer(hash_line.clone()) g = QgsGeometry.fromWkt('LineString(0 0, 10 10, 10 0)') rendered_image = self.renderGeometry(s, g) assert self.imageCheck('line_hash_vertex', 'line_hash_vertex', rendered_image) s.symbolLayer(0).setPlacement( QgsTemplatedLineSymbolLayerBase.FirstVertex) g = QgsGeometry.fromWkt('LineString(0 0, 10 10, 10 0)') rendered_image = self.renderGeometry(s, g) assert self.imageCheck('line_hash_first', 'line_hash_first', rendered_image) s.symbolLayer(0).setPlacement( QgsTemplatedLineSymbolLayerBase.LastVertex) g = QgsGeometry.fromWkt('LineString(0 0, 10 10, 10 0)') rendered_image = self.renderGeometry(s, g) assert self.imageCheck('line_hash_last', 'line_hash_last', rendered_image)
def testRenderLineLayerDisabled(self): """ test that rendering a line symbol with disabled layer works""" layer = QgsSimpleLineSymbolLayer() layer.setEnabled(False) symbol = QgsLineSymbol() symbol.changeSymbolLayer(0, layer) image = QImage(200, 200, QImage.Format_RGB32) painter = QPainter() ms = QgsMapSettings() geom = QgsGeometry.fromWkt('LineString (0 0,3 4,4 3)') f = QgsFeature() f.setGeometry(geom) extent = geom.constGet().boundingBox() # buffer extent by 10% extent = extent.buffered((extent.height() + extent.width()) / 20.0) ms.setExtent(extent) ms.setOutputSize(image.size()) context = QgsRenderContext.fromMapSettings(ms) context.setPainter(painter) context.setScaleFactor(96 / 25.4) # 96 DPI painter.begin(image) image.fill(QColor(255, 255, 255)) symbol.startRender(context) symbol.renderFeature(f, context) symbol.stopRender(context) painter.end() self.assertTrue( self.imageCheck('symbol_layer', 'symbollayer_disabled', image))
def testPointNumInterval(self): s = QgsLineSymbol() s.deleteSymbolLayer(0) hash_line = QgsHashedLineSymbolLayer(True) hash_line.setPlacement(QgsTemplatedLineSymbolLayerBase.Interval) hash_line.setInterval(6) simple_line = QgsSimpleLineSymbolLayer() simple_line.setColor(QColor(0, 255, 0)) simple_line.setWidth(1) line_symbol = QgsLineSymbol() line_symbol.changeSymbolLayer(0, simple_line) hash_line.setSubSymbol(line_symbol) hash_line.setHashLength(10) s.appendSymbolLayer(hash_line.clone()) s.symbolLayer(0).setDataDefinedProperty( QgsSymbolLayer.PropertyLineDistance, QgsProperty.fromExpression("@geometry_point_num * 2")) g = QgsGeometry.fromWkt('LineString(0 0, 10 10, 10 0)') rendered_image = self.renderGeometry(s, g) assert self.imageCheck('line_dd_size', 'line_dd_size', rendered_image)
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 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 editNetworkLayer(self, progressBar, layerName, scenariosExpression, networkExpression, variable, level, projectPath, group, networkLinkShapePath, method, layerId, expressionNetworkText, color): """ @summary: Get operators dictionary @param layerName: Layer name @type layerName: String @param scenariosExpression: Scenarios expression @type scenariosExpression: Stack object @param networkExpression: Network expression @type networkExpression: Stack object @param variable: Variable to evaluate @type variable: String @param level: Level to evaluate (Total, Routes, Operators) @type level: Level object @param projectPath: Project path @type projectPath: String @param group: Project group @type group: Layer group @param networkLinkShapePath: Network link shape path @type networkLinkShapePath: String @return: Result of the layer creation """ if scenariosExpression is None: QMessageBox.warning(None, "Network expression", "There is not scenarios information.") print("There is not scenarios information.") return False registry = QgsProject.instance() layersCount = len(registry.mapLayers()) result, resultData, minValue, maxValue = self.network_data_access.create_network_memory( layerName, scenariosExpression, networkExpression, variable, level, projectPath) progressBar.setValue(15) if result: # Source shape, name of the new shape, providerLib layer = QgsVectorLayer(networkLinkShapePath, layerName + "_network", 'ogr') epsg = layer.crs().postgisSrid() intMethod = 0 if method == "Color" else 1 rowCounter = len(resultData) if not layer.isValid(): return False feats = [feat for feat in layer.getFeatures()] # Create a vector layer with data on Memory memoryLayer = registry.mapLayer(layerId) memory_data = memoryLayer.dataProvider() joinedFieldName = "Result" shpField = "Id" attr = layer.dataProvider().fields().toList() attr += [QgsField(joinedFieldName, QVariant.Double)] progressBar.setValue(25) memory_data.addAttributes(attr) memory_data.addFeatures(feats) num = 30 progressBar.setValue(num) progressInterval = 70 / len(resultData) memoryLayer.startEditing() for rowItem in np.nditer(resultData): value = 0 num += progressInterval progressBar.setValue(num) it = memoryLayer.getFeatures("LINKID = '{0}'".format( str(rowItem['Id']).replace("b", "").replace("'", ""))) for id_feature in it: memoryLayer.changeAttributeValue( id_feature.id(), memory_data.fieldNameIndex(joinedFieldName), QVariant(round(float(rowItem['Result']), 2))) memoryLayer.commitChanges() myStyle = QgsStyle().defaultStyle() defaultColorRampNames = myStyle.colorRampNames() ramp = myStyle.colorRamp(defaultColorRampNames[0]) ranges = [] nCats = ramp.count() rng = maxValue - minValue nCats = 8 scale = QgsMapUnitScale(minValue, maxValue) if method == "Color": color1 = list( map(lambda x: int(x), color['color1'].split(",")[0:3])) color2 = list( map(lambda x: int(x), color['color2'].split(",")[0:3])) interpolatedColors = HP.linear_gradient(color1, color2, nCats) for i in range(0, nCats): v0 = minValue + rng / float(nCats) * i v1 = minValue + rng / float(nCats) * (i + 1) if method == "Color": line = QgsSimpleLineSymbolLayer( QColor(interpolatedColors['r'][i], interpolatedColors['g'][i], interpolatedColors['b'][i])) line.setOffsetUnit(2) line.setOffset(2) line.setWidth(0.8) symbol = QgsLineSymbol() symbol.changeSymbolLayer(0, line) myRange = QgsRendererRange(v0, v1, symbol, "") elif method == "Size": qcolor = QColor() qcolor.setRgb(color) line = QgsSimpleLineSymbolLayer(qcolor) line.setOffsetUnit(2) line.setOffset(0.7) # Symbol # symbolLine = QgsSimpleMarkerSymbolLayer(QgsSimpleMarkerSymbolLayerBase.ArrowHead) # Mark line # markLine = QgsMarkerLineSymbolLayer() # markLine.setPlacement(4) symbolo = QgsLineSymbol() symbolo.changeSymbolLayer(0, line) # symbolo.appendSymbolLayer(line) myRange = QgsRendererRange(v0, v1, symbolo, "") ranges.append(myRange) # The first parameter refers to the name of the field that contains the calculated value (expression) modeRender = QgsGraduatedSymbolRenderer.Mode(2) renderer = QgsGraduatedSymbolRenderer(joinedFieldName, ranges) renderer.setMode(modeRender) renderer.setGraduatedMethod(intMethod) if method == "Size": renderer.setSymbolSizes(0.200000, 2.60000) renderer.setSourceColorRamp(ramp) memoryLayer.setRenderer(renderer) typeLayer = "network" fieldName = "LINKID" networkExpressionText = str(scenariosExpression) # Create XML File ".qtranus" with the parameters of the executions if FileMXML.if_exist_xml_layers(projectPath): if FileMXML.if_exist_layer(projectPath, memoryLayer.id()): FileMXML.update_xml_file(memoryLayer.name(), memoryLayer.id(), scenariosExpression, variable, networkExpression, projectPath, expressionNetworkText, method, level, color) else: FileMXML.add_layer_xml_file(memoryLayer.name(), memoryLayer.id(), scenariosExpression, variable, networkExpression, projectPath, expressionNetworkText, shpField, typeLayer, method, level, color) else: FileMXML.create_xml_file(memoryLayer.name(), memoryLayer.id(), scenariosExpression, variable, networkExpression, projectPath, expressionNetworkText, shpField, typeLayer, method, level, color) #group.insertLayer((layersCount+1), memoryLayer) progressBar.setValue(100) return True