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 testRenderLineLayerDataDefined(self): """ test that rendering a line symbol with data defined enabled layer works""" lines_shp = os.path.join(TEST_DATA_DIR, 'lines.shp') lines_layer = QgsVectorLayer(lines_shp, 'Lines', 'ogr') QgsProject.instance().addMapLayer(lines_layer) layer = QgsSimpleLineSymbolLayer() layer.setDataDefinedProperty(QgsSymbolLayer.PropertyLayerEnabled, QgsProperty.fromExpression("Name='Highway'")) layer.setColor(QColor(100, 150, 150)) layer.setWidth(5) symbol = QgsLineSymbol() symbol.changeSymbolLayer(0, layer) lines_layer.setRenderer(QgsSingleSymbolRenderer(symbol)) ms = QgsMapSettings() ms.setOutputSize(QSize(400, 400)) ms.setOutputDpi(96) ms.setExtent(QgsRectangle(-133, 22, -70, 52)) ms.setLayers([lines_layer]) renderchecker = QgsMultiRenderChecker() renderchecker.setMapSettings(ms) renderchecker.setControlPathPrefix('symbol_layer') renderchecker.setControlName('expected_linelayer_ddenabled') self.assertTrue(renderchecker.runTest('linelayer_ddenabled')) QgsProject.instance().removeMapLayer(lines_layer)
def testLinkedColorButton(self): definition = QgsPropertyDefinition('test', 'test', QgsPropertyDefinition.ColorWithAlpha) button = QgsPropertyOverrideButton() button.init(0, QgsProperty(), definition) cb = QgsColorButton() button.registerLinkedWidget(cb) project_scheme = [s for s in QgsApplication.colorSchemeRegistry().schemes() if isinstance(s, QgsProjectColorScheme)][0] project_scheme.setColors([[QColor(255, 0, 0), 'col1'], [QColor(0, 255, 0), 'col2']]) button.setToProperty(QgsProperty.fromValue('#ff0000')) self.assertTrue(cb.isEnabled()) self.assertFalse(cb.linkedProjectColorName()) button.setActive(False) self.assertTrue(cb.isEnabled()) self.assertFalse(cb.linkedProjectColorName()) button.setToProperty(QgsProperty.fromExpression('project_color(\'Cthulhu\'s delight\')')) self.assertTrue(cb.isEnabled()) self.assertFalse(cb.linkedProjectColorName()) button.setToProperty(QgsProperty.fromExpression('project_color(\'col1\')')) self.assertTrue(cb.isEnabled()) self.assertEqual(cb.linkedProjectColorName(), 'col1') button.setActive(False) self.assertTrue(cb.isEnabled()) self.assertFalse(cb.linkedProjectColorName()) button.setActive(True) self.assertTrue(cb.isEnabled()) self.assertEqual(cb.linkedProjectColorName(), 'col1')
def test_property(self): """ Test that QgsProperty values are correctly loaded and written """ doc = QDomDocument("properties") prop = QgsProperty.fromValue(1001) elem = QgsXmlUtils.writeVariant(prop, doc) prop2 = QgsXmlUtils.readVariant(elem) self.assertEqual(prop, prop2) prop = QgsProperty.fromExpression('1+2=5') elem = QgsXmlUtils.writeVariant(prop, doc) prop2 = QgsXmlUtils.readVariant(elem) self.assertEqual(prop, prop2) prop = QgsProperty.fromField('oid') elem = QgsXmlUtils.writeVariant(prop, doc) prop2 = QgsXmlUtils.readVariant(elem) self.assertEqual(prop, prop2)
def getParamValues(self): if self.mUpdateExistingGroupBox.isChecked(): fieldName = self.mExistingFieldComboBox.currentText() else: fieldName = self.mOutputFieldNameLineEdit.text() layer = self.cmbInputLayer.currentLayer() context = dataobjects.createContext() parameters = {} parameters['INPUT'] = layer parameters['FIELD_NAME'] = fieldName parameters['FIELD_TYPE'] = self.mOutputFieldTypeComboBox.currentIndex() parameters['FIELD_LENGTH'] = self.mOutputFieldWidthSpinBox.value() parameters['FIELD_PRECISION'] = self.mOutputFieldPrecisionSpinBox.value() parameters['NEW_FIELD'] = self.mNewFieldGroupBox.isChecked() parameters['FORMULA'] = self.builder.expressionText() output = QgsProcessingOutputLayerDefinition() if self.leOutputFile.text().strip(): output.sink = QgsProperty.fromValue(self.leOutputFile.text().strip()) else: output.sink = QgsProperty.fromValue('memory:') output.destinationProject = context.project() parameters['OUTPUT'] = output ok, msg = self.alg.checkParameterValues(parameters, context) if not ok: QMessageBox.warning( self, self.tr('Unable to execute algorithm'), msg) return {} return parameters
def testRenderMarkerLayerDataDefined(self): """ test that rendering a marker symbol with data defined enabled layer works""" points_shp = os.path.join(TEST_DATA_DIR, 'points.shp') points_layer = QgsVectorLayer(points_shp, 'Points', 'ogr') QgsProject.instance().addMapLayer(points_layer) layer = QgsSimpleMarkerSymbolLayer() layer.setDataDefinedProperty(QgsSymbolLayer.PropertyLayerEnabled, QgsProperty.fromExpression("Class='Biplane'")) layer.setColor(QColor(100, 150, 150)) layer.setSize(5) layer.setStrokeStyle(Qt.NoPen) symbol = QgsMarkerSymbol() symbol.changeSymbolLayer(0, layer) points_layer.setRenderer(QgsSingleSymbolRenderer(symbol)) ms = QgsMapSettings() ms.setOutputSize(QSize(400, 400)) ms.setOutputDpi(96) ms.setExtent(QgsRectangle(-133, 22, -70, 52)) ms.setLayers([points_layer]) renderchecker = QgsMultiRenderChecker() renderchecker.setMapSettings(ms) renderchecker.setControlPathPrefix('symbol_layer') renderchecker.setControlName('expected_markerlayer_ddenabled') self.assertTrue(renderchecker.runTest('markerlayer_ddenabled')) QgsProject.instance().removeMapLayer(points_layer)
def getConsoleCommands(self, parameters, context, feedback): arguments = [] arguments.append('-resolution') arguments.append(self.RESOLUTION_OPTIONS[self.parameterAsEnum(parameters, self.RESOLUTION, context)]) if self.parameterAsBool(parameters, buildvrt.SEPARATE, context): arguments.append('-separate') if self.parameterAsBool(parameters, buildvrt.PROJ_DIFFERENCE, context): arguments.append('-allow_projection_difference') # Always write input files to a text file in case there are many of them and the # length of the command will be longer then allowed in command prompt listFile = os.path.join(QgsProcessingUtils.tempFolder(), 'buildvrtInputFiles.txt') with open(listFile, 'w') as f: layers = [] for l in self.parameterAsLayerList(parameters, self.INPUT, context): layers.append(l.source()) f.write('\n'.join(layers)) arguments.append('-input_file_list') arguments.append(listFile) out = self.parameterAsOutputLayer(parameters, self.OUTPUT, context) # Ideally the file extensions should be limited to just .vrt but I'm not sure how # to do it simply so instead a check is performed. _, ext = os.path.splitext(out) if not ext.lower() == '.vrt': out = out[:-len(ext)] + '.vrt' if isinstance(parameters[self.OUTPUT], QgsProcessingOutputLayerDefinition): output_def = QgsProcessingOutputLayerDefinition(parameters[self.OUTPUT]) output_def.sink = QgsProperty.fromValue(out) self.setOutputValue(self.OUTPUT, output_def) else: self.setOutputValue(self.OUTPUT, out) arguments.append(out) return ['gdalbuildvrt', GdalUtils.escapeAndJoin(arguments)]
def testProjectColor(self): scheme = [s for s in QgsApplication.colorSchemeRegistry().schemes() if isinstance(s, QgsProjectColorScheme)][0] scheme.setColors([]) definition = QgsPropertyDefinition('test', 'test', QgsPropertyDefinition.ColorWithAlpha) button = QgsPropertyOverrideButton() button.init(0, QgsProperty(), definition) button.aboutToShowMenu() self.assertIn('Project Color', [a.text() for a in button.menu().actions()]) self.assertIn('Color', [a.text() for a in button.menu().actions()]) color_action = [a for a in button.menu().actions() if a.text() == 'Color'][0] self.assertEqual([a.text() for a in color_action.menu().actions()][0], 'No colors set') # add some project colors scheme.setColors([[QColor(255, 0, 0), 'color 1'], [QColor(255, 255, 0), 'burnt marigold']]) button.aboutToShowMenu() self.assertIn('Project Color', [a.text() for a in button.menu().actions()]) self.assertIn('Color', [a.text() for a in button.menu().actions()]) color_action = [a for a in button.menu().actions() if a.text() == 'Color'][0] self.assertEqual([a.text() for a in color_action.menu().actions()], ['color 1', 'burnt marigold']) button.menuActionTriggered(color_action.menu().actions()[1]) self.assertTrue(button.toProperty().isActive()) self.assertEqual(button.toProperty().asExpression(), 'project_color(\'burnt marigold\')') button.menuActionTriggered(color_action.menu().actions()[0]) self.assertTrue(button.toProperty().isActive()) self.assertEqual(button.toProperty().asExpression(), 'project_color(\'color 1\')') button.setToProperty(QgsProperty.fromExpression('project_color(\'burnt marigold\')')) button.aboutToShowMenu() color_action = [a for a in button.menu().actions() if a.text() == 'Color'][0] self.assertTrue(color_action.isChecked()) self.assertEqual([a.isChecked() for a in color_action.menu().actions()], [False, True]) # should also see color menu for ColorNoAlpha properties definition = QgsPropertyDefinition('test', 'test', QgsPropertyDefinition.ColorNoAlpha) button = QgsPropertyOverrideButton() button.init(0, QgsProperty(), definition) button.aboutToShowMenu() self.assertIn('Project Color', [a.text() for a in button.menu().actions()]) self.assertIn('Color', [a.text() for a in button.menu().actions()]) # but no color menu for other types definition = QgsPropertyDefinition('test', 'test', QgsPropertyDefinition.Double) button = QgsPropertyOverrideButton() button.init(0, QgsProperty(), definition) button.aboutToShowMenu() self.assertNotIn('Project Color', [a.text() for a in button.menu().actions()]) self.assertNotIn('Color', [a.text() for a in button.menu().actions()])
def testDataDefinedSize(self): p = QgsProject() l = QgsLayout(p) collection = l.pageCollection() # add some pages page = QgsLayoutItemPage(l) page.setPageSize('A4') collection.addPage(page) page2 = QgsLayoutItemPage(l) page2.setPageSize('A5') collection.addPage(page2) page3 = QgsLayoutItemPage(l) page3.setPageSize('A5') collection.addPage(page3) self.assertEqual(page.pos().x(), 0) self.assertEqual(page.pos().y(), 0) self.assertEqual(page2.pos().x(), 0) self.assertEqual(page2.pos().y(), 307) self.assertEqual(page3.pos().x(), 0) self.assertEqual(page3.pos().y(), 527) page.dataDefinedProperties().setProperty(QgsLayoutObject.ItemHeight, QgsProperty.fromExpression('50*3')) page.refresh() collection.reflow() self.assertEqual(page.pos().x(), 0) self.assertEqual(page.pos().y(), 0) self.assertEqual(page2.pos().x(), 0) self.assertEqual(page2.pos().y(), 160) self.assertEqual(page3.pos().x(), 0) self.assertEqual(page3.pos().y(), 380) page2.dataDefinedProperties().setProperty(QgsLayoutObject.ItemHeight, QgsProperty.fromExpression('50-20')) page2.refresh() collection.reflow() self.assertEqual(page.pos().x(), 0) self.assertEqual(page.pos().y(), 0) self.assertEqual(page2.pos().x(), 0) self.assertEqual(page2.pos().y(), 160) self.assertEqual(page3.pos().x(), 0) self.assertEqual(page3.pos().y(), 200)
def test_1(self): sym = self.lines_layer.renderer().symbol() sym_layer = QgsArrowSymbolLayer.create({'head_length': '6.5', 'head_thickness': '6.5'}) dd = QgsProperty.fromExpression("(@geometry_point_num % 4) * 2") sym_layer.setDataDefinedProperty(QgsSymbolLayer.PropertyArrowWidth, dd) dd2 = QgsProperty.fromExpression("(@geometry_point_num % 4) * 2") sym_layer.setDataDefinedProperty(QgsSymbolLayer.PropertyArrowHeadLength, dd2) dd3 = QgsProperty.fromExpression("(@geometry_point_num % 4) * 2") sym_layer.setDataDefinedProperty(QgsSymbolLayer.PropertyArrowHeadThickness, dd3) fill_sym = QgsFillSymbol.createSimple({'color': '#8bcfff', 'outline_color': '#000000', 'outline_style': 'solid', 'outline_width': '1'}) sym_layer.setSubSymbol(fill_sym) sym.changeSymbolLayer(0, sym_layer) rendered_layers = [self.lines_layer] self.mapsettings.setLayers(rendered_layers) renderchecker = QgsMultiRenderChecker() renderchecker.setMapSettings(self.mapsettings) renderchecker.setControlName('expected_arrowsymbollayer_1') self.assertTrue(renderchecker.runTest('arrowsymbollayer_1'))
def testDataDefinedBackgroundColor(self): layout = QgsLayout(QgsProject.instance()) item = QgsLayoutItemMap(layout) item.setBackgroundColor(QColor(255, 0, 0)) self.assertEqual(item.backgroundColor(), QColor(255, 0, 0)) self.assertEqual(item.brush().color().name(), QColor(255, 0, 0).name()) item.dataDefinedProperties().setProperty(QgsLayoutObject.BackgroundColor, QgsProperty.fromExpression("'blue'")) item.refreshDataDefinedProperty() self.assertEqual(item.backgroundColor(), QColor(255, 0, 0)) # should not change self.assertEqual(item.brush().color().name(), QColor(0, 0, 255).name())
def testContainsAdvancedEffectsAndRasterization(self): layout = QgsLayout(QgsProject.instance()) item = QgsLayoutItemLabel(layout) self.assertFalse(item.containsAdvancedEffects()) # item opacity requires that the individual item be flattened to a raster item item.setItemOpacity(0.5) self.assertTrue(item.containsAdvancedEffects()) # but not the WHOLE layout self.assertFalse(item.requiresRasterization()) item.dataDefinedProperties().setProperty(QgsLayoutObject.Opacity, QgsProperty.fromExpression('100')) item.refresh() self.assertFalse(item.containsAdvancedEffects()) self.assertFalse(item.requiresRasterization()) item.dataDefinedProperties().setProperty(QgsLayoutObject.Opacity, QgsProperty()) item.refresh() self.assertTrue(item.containsAdvancedEffects()) self.assertFalse(item.requiresRasterization()) item.setItemOpacity(1.0) self.assertFalse(item.containsAdvancedEffects()) self.assertFalse(item.requiresRasterization()) # item blend mode is NOT an advanced effect -- rather it requires that the WHOLE layout be rasterized to achieve item.setBlendMode(QPainter.CompositionMode_DestinationAtop) self.assertFalse(item.containsAdvancedEffects()) self.assertTrue(item.requiresRasterization()) map = QgsLayoutItemMap(layout) # map items are different -- because they override paint, they don't get the auto-flattening and rasterization map.setItemOpacity(0.5) self.assertFalse(map.containsAdvancedEffects()) # rather, a map with opacity requires the WHOLE layout to be rasterized self.assertTrue(map.requiresRasterization()) map.dataDefinedProperties().setProperty(QgsLayoutObject.Opacity, QgsProperty.fromExpression('100')) map.refresh() self.assertFalse(map.containsAdvancedEffects()) self.assertTrue(map.requiresRasterization())
def add_mask_filter(layer): if not isinstance(layer, QgsVectorLayer): return False # check if a layer has already a mask filter enabled if layer.labeling() is None: return False try: expr = "%s(%d)" % (SPATIAL_FILTER, layer.crs().postgisSrid()) prop = QgsProperty() prop.setExpressionString(expr) # new settings settings = QgsPalLayerSettings(layer.labeling().settings()) settings.dataDefinedProperties().setProperty(QgsPalLayerSettings.Show, prop) if isinstance(layer.labeling(), QgsVectorLayerSimpleLabeling): layer.setLabeling(QgsVectorLayerSimpleLabeling(settings)) except Exception as e: for m in e.args: QgsMessageLog.logMessage(m, 'Extensions')
def testDataDefinedFrameColor(self): layout = QgsLayout(QgsProject.instance()) item = QgsLayoutItemMap(layout) item.setFrameEnabled(True) item.setFrameStrokeColor(QColor(255, 0, 0)) self.assertEqual(item.frameStrokeColor(), QColor(255, 0, 0)) self.assertEqual(item.pen().color().name(), QColor(255, 0, 0).name()) item.dataDefinedProperties().setProperty(QgsLayoutObject.FrameColor, QgsProperty.fromExpression("'blue'")) item.refreshDataDefinedProperty() self.assertEqual(item.frameStrokeColor(), QColor(255, 0, 0)) # should not change self.assertEqual(item.pen().color().name(), QColor(0, 0, 255).name())
def testDataDefinedTitle(self): layout = QgsLayout(QgsProject.instance()) layout.initializeDefaults() legend = QgsLayoutItemLegend(layout) layout.addLayoutItem(legend) legend.setTitle('original') self.assertEqual(legend.title(), 'original') self.assertEqual(legend.legendSettings().title(), 'original') legend.dataDefinedProperties().setProperty(QgsLayoutObject.LegendTitle, QgsProperty.fromExpression("'new'")) legend.refreshDataDefinedProperty() self.assertEqual(legend.title(), 'original') self.assertEqual(legend.legendSettings().title(), 'new')
def testDataDefinedBackgroundColor(self): mapSettings = QgsMapSettings() # NOQA composition = QgsComposition(QgsProject.instance()) composition.setPaperSize(297, 210) item = QgsComposerLabel(composition) composition.addComposerLabel(item) item.setBackgroundColor(QColor(255, 0, 0)) self.assertEqual(item.backgroundColor(), QColor(255, 0, 0)) self.assertEqual(item.brush().color().name(), QColor(255, 0, 0).name()) item.dataDefinedProperties().setProperty(QgsComposerObject.BackgroundColor, QgsProperty.fromExpression("'blue'")) item.refreshDataDefinedProperty() self.assertEqual(item.backgroundColor(), QColor(255, 0, 0)) # should not change self.assertEqual(item.brush().color().name(), QColor(0, 0, 255).name())
def testDataDefinedTitle(self): mapSettings = QgsMapSettings() # NOQA composition = QgsComposition(QgsProject.instance()) composition.setPaperSize(297, 210) legend = QgsComposerLegend(composition) composition.addComposerLegend(legend) legend.setTitle('original') self.assertEqual(legend.title(), 'original') self.assertEqual(legend.legendSettings().title(), 'original') legend.dataDefinedProperties().setProperty(QgsComposerObject.LegendTitle, QgsProperty.fromExpression("'new'")) legend.refreshDataDefinedProperty() self.assertEqual(legend.title(), 'original') self.assertEqual(legend.legendSettings().title(), 'new')
def test_datadefined_margin(self): polygonLayer = QgsVectorLayer('Polygon?field=margin:int', 'test_polygon', 'memory') poly = QgsFeature(polygonLayer.fields()) poly.setAttributes([0]) poly.setGeometry(QgsGeometry.fromWkt('Polygon((30 30, 40 30, 40 40, 30 40, 30 30))')) polygonLayer.dataProvider().addFeatures([poly]) poly = QgsFeature(polygonLayer.fields()) poly.setAttributes([10]) poly.setGeometry(QgsGeometry.fromWkt('Polygon((10 10, 20 10, 20 20, 10 20, 10 10))')) polygonLayer.dataProvider().addFeatures([poly]) poly = QgsFeature(polygonLayer.fields()) poly.setAttributes([20]) poly.setGeometry(QgsGeometry.fromWkt('Polygon((50 50, 60 50, 60 60, 50 60, 50 50))')) polygonLayer.dataProvider().addFeatures([poly]) QgsProject.instance().addMapLayer(polygonLayer) layout = QgsPrintLayout(QgsProject.instance()) map = QgsLayoutItemMap(layout) map.setCrs(polygonLayer.crs()) map.attemptSetSceneRect(QRectF(20, 20, 130, 130)) map.setFrameEnabled(True) map.setLayers([polygonLayer]) map.setExtent(QgsRectangle(0, 0, 100, 50)) layout.addLayoutItem(map) atlas = layout.atlas() atlas.setCoverageLayer(polygonLayer) atlas.setEnabled(True) map.setAtlasDriven(True) map.setAtlasScalingMode(QgsLayoutItemMap.Auto) map.setAtlasMargin(77.0) map.dataDefinedProperties().setProperty(QgsLayoutObject.MapAtlasMargin, QgsProperty.fromExpression('margin/2')) atlas.beginRender() atlas.first() self.assertEqual(map.extent(), QgsRectangle(25, 30, 45, 40)) self.assertTrue(atlas.next()) self.assertEqual(map.extent(), QgsRectangle(4.5, 9.75, 25.5, 20.25)) self.assertTrue(atlas.next()) self.assertEqual(map.extent(), QgsRectangle(44, 49.5, 66, 60.5)) QgsProject.instance().removeMapLayer(polygonLayer)
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) hash_line.setAverageAngleLength(0) 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 testRenderVariables(self): """ test rendering with expression variables in marker """ self.layer.renderer().setTolerance(10) old_marker = self.layer.renderer().clusterSymbol().clone() new_marker = QgsMarkerSymbol.createSimple({'color': '#ffff00', 'size': '3', 'outline_style': 'no'}) new_marker.symbolLayer(0).setDataDefinedProperty(QgsSymbolLayer.PropertyFillColor, QgsProperty.fromExpression('@cluster_color')) new_marker.symbolLayer(0).setDataDefinedProperty(QgsSymbolLayer.PropertySize, QgsProperty.fromExpression('@cluster_size*2')) self.layer.renderer().setClusterSymbol(new_marker) renderchecker = QgsMultiRenderChecker() renderchecker.setMapSettings(self.mapsettings) renderchecker.setControlPathPrefix('cluster_renderer') renderchecker.setControlName('expected_cluster_variables') result = renderchecker.runTest('expected_cluster_variables') self.layer.renderer().setClusterSymbol(old_marker) self.assertTrue(result)
def testLabelMargin(self): """ Test rendering map item with a label margin set """ format = QgsTextFormat() format.setFont(QgsFontUtils.getStandardTestFont("Bold")) format.setSize(20) format.setNamedStyle("Bold") format.setColor(QColor(0, 0, 0)) settings = QgsPalLayerSettings() settings.setFormat(format) settings.fieldName = "'X'" settings.isExpression = True settings.placement = QgsPalLayerSettings.OverPoint vl = QgsVectorLayer("Point?crs=epsg:4326&field=id:integer", "vl", "memory") vl.setRenderer(QgsNullSymbolRenderer()) f = QgsFeature(vl.fields(), 1) for x in range(15): for y in range(15): f.setGeometry(QgsPoint(x, y)) vl.dataProvider().addFeature(f) vl.setLabeling(QgsVectorLayerSimpleLabeling(settings)) vl.setLabelsEnabled(True) p = QgsProject() engine_settings = QgsLabelingEngineSettings() engine_settings.setFlag(QgsLabelingEngineSettings.UsePartialCandidates, False) engine_settings.setFlag(QgsLabelingEngineSettings.DrawLabelRectOnly, True) p.setLabelingEngineSettings(engine_settings) 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(True) map.zoomToExtent(vl.extent()) map.setLayers([vl]) layout.addLayoutItem(map) checker = QgsLayoutChecker('composermap_label_nomargin', layout) checker.setControlPathPrefix("composer_map") result, message = checker.testLayout() self.report += checker.report() self.assertTrue(result, message) map.setLabelMargin(QgsLayoutMeasurement(15, QgsUnitTypes.LayoutMillimeters)) checker = QgsLayoutChecker('composermap_label_margin', layout) checker.setControlPathPrefix("composer_map") result, message = checker.testLayout() self.report += checker.report() self.assertTrue(result, message) map.setLabelMargin(QgsLayoutMeasurement(3, QgsUnitTypes.LayoutCentimeters)) checker = QgsLayoutChecker('composermap_label_cm_margin', layout) checker.setControlPathPrefix("composer_map") result, message = checker.testLayout() self.report += checker.report() self.assertTrue(result, message) map.setMapRotation(45) map.zoomToExtent(vl.extent()) map.setScale(map.scale() * 1.2) checker = QgsLayoutChecker('composermap_rotated_label_margin', layout) checker.setControlPathPrefix("composer_map") result, message = checker.testLayout() self.report += checker.report() self.assertTrue(result, message) # data defined map.setMapRotation(0) map.zoomToExtent(vl.extent()) map.dataDefinedProperties().setProperty(QgsLayoutObject.MapLabelMargin, QgsProperty.fromExpression('1+3')) map.refresh() checker = QgsLayoutChecker('composermap_dd_label_margin', layout) checker.setControlPathPrefix("composer_map") result, message = checker.testLayout() self.report += checker.report() self.assertTrue(result, message)
def processAlgorithm(self, parameters, context, feedback): """ Here is where the processing itself takes place. """ #vector layer given by the user input_layer = self.parameterAsVectorLayer( parameters, self.INPUT, context ) #the field within previous layer. Should contain numeral codes #that identify each traffic sign value_field = self.parameterAsString( parameters, self.SIGN_CODE_FIELD, context) speed_field = self.parameterAsString( parameters, self.SPEED_LIMIT_FIELD, context) old_or_new_selection = self.parameterAsString( parameters, self.OLD_OR_NEW, context) # read user selection on whether to use old or new signs # transform this into a usable string if old_or_new_selection == "1": old_or_new_selection="uudet" else: old_or_new_selection="vanhat" #if the SVG's are installed via Resource sharing, they should be here path = (QgsApplication.qgisSettingsDirPath() + "resource_sharing/collections/Väylävirasto"+ " {} liikennemerkit (Liikennemerkit)/svg/").format(old_or_new_selection) #Windows path hijinks resource_path = path.replace("\\", "/") # creating a dummy symbol layer, which will be styled later svg_layer = QgsSvgMarkerSymbolLayer("circle") # creating two expressions, one for defining the path to each SVG image # the other for scaling image size based on current map scale # the syntax of these strings is the one used in QGIS's Expression bulder if (speed_field and old_or_new_selection=="vanhat"): path_exp = ("CASE WHEN \"{1}\"=361 AND \"{2}\"=50 THEN concat(\'{0}\', \"{1}\", \'-1.svg\')"+ " WHEN \"{1}\"=361 AND \"{2}\"=20 THEN concat(\'{0}\', \"{1}\", \'-2.svg\')"+ " WHEN \"{1}\"=361 AND \"{2}\"=70 THEN concat(\'{0}\', \"{1}\", \'-3.svg\')"+ " WHEN \"{1}\"=361 AND \"{2}\"=80 THEN concat(\'{0}\', \"{1}\", \'-4.svg\')"+ " WHEN \"{1}\"=361 AND \"{2}\"=100 THEN concat(\'{0}\', \"{1}\", \'-5.svg\')"+ " WHEN \"{1}\"=361 AND \"{2}\"=120 THEN concat(\'{0}\', \"{1}\", \'-6.svg\')"+ " WHEN \"{1}\"=361 AND \"{2}\"=30 THEN concat(\'{0}\', \"{1}\", \'-7.svg\')"+ " WHEN \"{1}\"=361 AND \"{2}\"=40 THEN concat(\'{0}\', \"{1}\", \'-8.svg\')"+ " ELSE concat(\'{0}\', \"{1}\", \'.svg\') END").format(resource_path, value_field, speed_field) elif (speed_field and old_or_new_selection=="uudet"): path_exp = ("CASE WHEN \"{1}\"= \'C32\' AND \"{2}\"=20 THEN concat(\'{0}\', \"{1}\", \'_2.svg\')"+ " WHEN \"{1}\"=\'C32\' AND \"{2}\"=30 THEN concat(\'{0}\', \"{1}\", \'_3.svg\')"+ " WHEN \"{1}\"=\'C32\'AND \"{2}\"=40 THEN concat(\'{0}\', \"{1}\", \'_4.svg\')"+ " WHEN \"{1}\"=\'C32\' AND \"{2}\"=50 THEN concat(\'{0}\', \"{1}\", \'_5.svg\')"+ " WHEN \"{1}\"=\'C32\' AND \"{2}\"=70 THEN concat(\'{0}\', \"{1}\", \'_6.svg\')"+ " WHEN \"{1}\"=\'C32\' AND \"{2}\"=80 THEN concat(\'{0}\', \"{1}\", \'_7.svg\')"+ " WHEN \"{1}\"=\'C32\' AND \"{2}\"=100 THEN concat(\'{0}\', \"{1}\", \'_8.svg\')"+ " WHEN \"{1}\"=\'C32\' AND \"{2}\"=120 THEN concat(\'{0}\', \"{1}\", \'_9.svg\')"+ " ELSE concat(\'{0}\', \"{1}\", \'.svg\') END").format(resource_path, value_field, speed_field) else: path_exp = "concat(\'{0}\', \"{1}\", \'.svg\')".format(resource_path, value_field) size_exp = ("CASE WHEN @map_scale < 10000 THEN 11 WHEN @map_scale < 50000 THEN 8" + " WHEN @map_scale < 100000 THEN 7 WHEN @map_scale < 150000 THEN 6 WHEN @map_scale < 500000"+ " THEN 4 ELSE 3 END") # taking a version of the renderer, which houses the symbol layers rend = input_layer.renderer().clone() rend.symbol().changeSymbolLayer(0, svg_layer) # defining the image path expression rend.symbol().symbolLayer(0).setDataDefinedProperty(QgsSymbolLayer.PropertyName, QgsProperty.fromExpression(path_exp)) rend.symbol().symbolLayer(0).setDataDefinedProperty( QgsSymbolLayer.PropertySize, QgsProperty.fromExpression(size_exp) ) # setting the new renderer to layer input_layer.setRenderer(rend) # updating so that the results are shown to the user input_layer.triggerRepaint() return {"Styling":"complete"}
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 test_settings_round_trip(self): # pylint: disable=too-many-statements """ Test setting and retrieving settings results in identical results """ layer_path = os.path.join( os.path.dirname(__file__), 'test_layer.geojson') vl1 = QgsVectorLayer(layer_path, 'test_layer', 'ogr') vl2 = QgsVectorLayer(layer_path, 'test_layer1', 'ogr') vl3 = QgsVectorLayer(layer_path, 'test_layer2', 'ogr') QgsProject.instance().addMapLayers([vl1, vl2, vl3]) dialog = DataPlotlyPanelWidget(None, iface=IFACE) settings = dialog.get_settings() # default should be scatter plot self.assertEqual(settings.plot_type, 'scatter') # customise settings settings.plot_type = 'violin' settings.properties['name'] = 'my legend title' settings.properties['hover_text'] = 'y' settings.properties['box_orientation'] = 'h' settings.properties['normalization'] = 'probability' settings.properties['box_stat'] = 'sd' settings.properties['box_outliers'] = 'suspectedoutliers' settings.properties['violin_side'] = 'negative' settings.properties['show_mean_line'] = True settings.properties['cumulative'] = True settings.properties['invert_hist'] = 'decreasing' settings.source_layer_id = vl3.id() settings.properties['x_name'] = 'so4' settings.properties['y_name'] = 'ca' settings.properties['z_name'] = 'mg' settings.properties['in_color_value'] = '100,150,180,50' settings.properties['in_color_property'] = QgsProperty.fromExpression('5+6').toVariant() settings.properties['size_property'] = QgsProperty.fromExpression('5+64').toVariant() settings.properties['color_scale'] = 'Earth' settings.properties['colorscale_in'] = 'Earth' # TODO: likely need to test other settings.properties values here! settings.layout['legend'] = False settings.layout['legend_orientation'] = 'h' settings.layout['title'] = 'my title' settings.layout['x_title'] = 'my x title' settings.layout['y_title'] = 'my y title' settings.layout['z_title'] = 'my z title' settings.layout['range_slider']['visible'] = True settings.layout['bar_mode'] = 'overlay' settings.layout['x_type'] = 'log' settings.layout['y_type'] = 'category' settings.layout['x_inv'] = 'reversed' settings.layout['y_inv'] = 'reversed' settings.layout['bargaps'] = 0.8 settings.layout['additional_info_expression'] = '1+2' settings.layout['bins_check'] = True dialog2 = DataPlotlyPanelWidget(None, iface=IFACE) dialog2.set_settings(settings) self.assertEqual(dialog2.get_settings().plot_type, settings.plot_type) for k in settings.properties.keys(): if k in ['x', 'y', 'z', 'additional_hover_text', 'featureIds', 'featureBox', 'custom', 'in_color', 'marker_size']: continue print(k) self.assertEqual(dialog2.get_settings().properties[k], settings.properties[k]) for k in settings.layout.keys(): print(k) self.assertEqual(dialog2.get_settings().layout[k], settings.layout[k]) self.assertEqual(dialog2.get_settings().source_layer_id, vl3.id()) settings = dialog.get_settings() dialog3 = DataPlotlyPanelWidget(None, iface=IFACE) dialog3.set_settings(settings) self.assertEqual(dialog3.get_settings().plot_type, settings.plot_type) for k in settings.properties.keys(): print(k) self.assertEqual(dialog3.get_settings().properties[k], settings.properties[k]) self.assertEqual(dialog3.get_settings().properties, settings.properties) for k in settings.layout.keys(): print(k) self.assertEqual(dialog3.get_settings().layout[k], settings.layout[k]) QgsProject.instance().clear()
def testPointsUsedAttributes(self): points_shp = os.path.join(TEST_DATA_DIR, 'points.shp') points_layer = QgsVectorLayer(points_shp, 'Points', 'ogr') QgsProject.instance().addMapLayer(points_layer) # Create rulebased style sym1 = QgsMarkerSymbol() l1 = QgsSimpleMarkerSymbolLayer(QgsSimpleMarkerSymbolLayer.Triangle, 5) l1.setColor(QColor(255, 0, 0)) l1.setStrokeStyle(Qt.NoPen) l1.setDataDefinedProperty(QgsSymbolLayer.PropertyAngle, QgsProperty.fromField("Heading")) sym1.changeSymbolLayer(0, l1) sym2 = QgsMarkerSymbol() l2 = QgsSimpleMarkerSymbolLayer(QgsSimpleMarkerSymbolLayer.Triangle, 5) l2.setColor(QColor(0, 255, 0)) l2.setStrokeStyle(Qt.NoPen) l2.setDataDefinedProperty(QgsSymbolLayer.PropertyAngle, QgsProperty.fromField("Heading")) sym2.changeSymbolLayer(0, l2) sym3 = QgsMarkerSymbol() l3 = QgsSimpleMarkerSymbolLayer(QgsSimpleMarkerSymbolLayer.Triangle, 5) l3.setColor(QColor(0, 0, 255)) l3.setStrokeStyle(Qt.NoPen) l3.setDataDefinedProperty(QgsSymbolLayer.PropertyAngle, QgsProperty.fromField("Heading")) sym3.changeSymbolLayer(0, l3) r1 = QgsRuleBasedRenderer.Rule(sym1, 0, 0, '"Class" = \'B52\'') r2 = QgsRuleBasedRenderer.Rule(sym2, 0, 0, '"Class" = \'Biplane\'') r3 = QgsRuleBasedRenderer.Rule(sym3, 0, 0, '"Class" = \'Jet\'') rootrule = QgsRuleBasedRenderer.Rule(None) rootrule.appendChild(r1) rootrule.appendChild(r2) rootrule.appendChild(r3) renderer = QgsRuleBasedRenderer(rootrule) points_layer.setRenderer(renderer) ms = QgsMapSettings() ms.setOutputSize(QSize(400, 400)) ms.setOutputDpi(96) ms.setExtent(QgsRectangle(-133, 22, -70, 52)) ms.setLayers([points_layer]) ctx = QgsRenderContext.fromMapSettings(ms) ctx.expressionContext().appendScope( points_layer.createExpressionContextScope()) # for symbol layer self.assertCountEqual(l1.usedAttributes(ctx), {'Heading'}) # for symbol self.assertCountEqual(sym1.usedAttributes(ctx), {'Heading'}) # for symbol renderer self.assertCountEqual(renderer.usedAttributes(ctx), {'Class', 'Heading'}) QgsProject.instance().removeMapLayer(points_layer)
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 processAlgorithm(self, parameters, context, feedback): project = QgsProject() project.setFileName( os.path.join(parameters[self.FOLDER], "all-outputs-qgis.qgs")) project.setCrs(QgsCoordinateReferenceSystem('EPSG:27700')) def getMaxValue(layer, fieldname): maxfound = float("-inf") for f in layer.getFeatures(): attr = f.attribute(fieldname) assert attr >= 0 if attr > maxfound: maxfound = attr return maxfound with open( os.path.join(parameters[self.FOLDER], "all-town-metadata.json")) as f: metadata = json.load(f) classmethods = { 'quantile': QgsClassificationQuantile, 'jenks': QgsClassificationJenks, 'equal': QgsClassificationEqualInterval } html = "" output = [] views_sorted_by_mode = sorted(metadata["views"], key=lambda v: v["mode"]) for view in views_sorted_by_mode: keysymbol = u'🔑' viewname = view["label"] keysign = "" if viewname.find(keysymbol) != -1: viewname = viewname.replace(keysymbol, '', 1) keysign = "*** " viewname = keysign + view["mode"] + " " + viewname html += f""" <h2>{viewname}</h2> {view["description"]} <ul> """ for layer in view["layers"]: layername = viewname + " - " + layer["scalar_field_units"] layerpath = os.path.join(parameters[self.FOLDER], layer["file"]) vlayer = QgsVectorLayer(layerpath, layername, "ogr") if not vlayer.isValid(): feedback.pushInfo("Layer failed to load: " + layerpath) else: context.temporaryLayerStore().addMapLayer(vlayer) html += f"""<li><b>file:</b> {layer["file"]}""" if "symbol_field" in layer: html += f"""<ul> <li><b>symbol field:</b> {layer["symbol_field"]} </ul> """ categories = [] scalar_fieldname = layer["scalar_field"] maxvalue = getMaxValue(vlayer, scalar_fieldname) feedback.pushInfo("Max value for %s is %f" % (scalar_fieldname, maxvalue)) for formality in ["I", "F"]: for severity, colour in [(3, 'red'), (2, 'yellow'), (1, 'green')]: colour = { ("I", "red"): "#FF0000", ("I", "yellow"): "#FFFF00", ("I", "green"): "#00FF00", ("F", "red"): "#FF9999", ("F", "yellow"): "#FFFF66", ("F", "green"): "#99FF99", }[(formality, colour)] symbol_code = "%s%d" % (formality, severity) if formality == "F": symbol = QgsMarkerSymbol.createSimple({ 'color': colour, 'size': '3', 'outline_color': '#888888' }) else: assert (formality == "I") symbol = QgsMarkerSymbol.createSimple({ 'color': colour, 'size': '3', 'outline_color': '#000000', 'name': 'star' }) objTransf = QgsSizeScaleTransformer( QgsSizeScaleTransformer.Flannery, 0, #minvalue maxvalue, #maxvalue 3, #minsize 10, #maxsize 0, #nullsize 1) #exponent objProp = QgsProperty() objProp.setField(scalar_fieldname) objProp.setTransformer(objTransf) symbol.setDataDefinedSize(objProp) label = { "F": "Formal", "I": "Informal" }[formality] + " " + { 3: "Major", 2: "Secondary", 1: "Tertiary" }[severity] cat = QgsRendererCategory( symbol_code, symbol, label, True) categories.append(cat) renderer = QgsCategorizedSymbolRenderer( "Crossings", categories) renderer.setClassAttribute(layer["symbol_field"]) vlayer.setRenderer(renderer) else: html += f"""<ul> <li><b>field:</b> {layer["scalar_field"]} <li><b>units:</b> {layer["scalar_field_units"]} <li><b>recommended classification:</b> {layer["classes"]} </ul> """ default_style = QgsStyle().defaultStyle() color_ramp = default_style.colorRamp('bt') renderer = QgsGraduatedSymbolRenderer() renderer.setClassAttribute(layer["scalar_field"]) classmethod = classmethods[layer["classes"]]() renderer.setClassificationMethod(classmethod) renderer.updateClasses(vlayer, 5) renderer.updateColorRamp(color_ramp) vlayer.setRenderer(renderer) project.addMapLayer(vlayer) feedback.pushInfo("Loaded " + layerpath) html += "</ul>" project.write() town = views_sorted_by_mode[0]["town"] with open(os.path.join(parameters[self.FOLDER], "metadata.html"), "w") as htmlfile: htmlfile.write( f"<html><head><title>{town} metadata</title></head><body><h1>{town}</h1>{html}</body></html>" ) return {self.OUTPUT: output}
def __init__(self, param): super(NumberInputPanel, self).__init__(None) self.setupUi(self) self.spnValue.setExpressionsEnabled(True) self.param = param if self.param.dataType() == QgsProcessingParameterNumber.Integer: self.spnValue.setDecimals(0) else: # Guess reasonable step value if self.param.maximum() is not None and self.param.minimum() is not None: try: self.spnValue.setSingleStep(self.calculateStep(float(self.param.minimum()), float(self.param.maximum()))) except: pass if self.param.maximum() is not None: self.spnValue.setMaximum(self.param.maximum()) else: self.spnValue.setMaximum(999999999) if self.param.minimum() is not None: self.spnValue.setMinimum(self.param.minimum()) else: self.spnValue.setMinimum(-999999999) self.allowing_null = False # set default value if param.flags() & QgsProcessingParameterDefinition.FlagOptional: self.spnValue.setShowClearButton(True) min = self.spnValue.minimum() - 1 self.spnValue.setMinimum(min) self.spnValue.setValue(min) self.spnValue.setSpecialValueText(self.tr('Not set')) self.allowing_null = True if param.defaultValue() is not None: self.setValue(param.defaultValue()) if not self.allowing_null: try: self.spnValue.setClearValue(float(param.defaultValue())) except: pass elif self.param.minimum() is not None: try: self.setValue(float(self.param.minimum())) if not self.allowing_null: self.spnValue.setClearValue(float(self.param.minimum())) except: pass elif not self.allowing_null: self.setValue(0) self.spnValue.setClearValue(0) # we don't show the expression button outside of modeler self.layout().removeWidget(self.btnSelect) sip.delete(self.btnSelect) self.btnSelect = None if not self.param.isDynamic(): # only show data defined button for dynamic properties self.layout().removeWidget(self.btnDataDefined) sip.delete(self.btnDataDefined) self.btnDataDefined = None else: self.btnDataDefined.init(0, QgsProperty(), self.param.dynamicPropertyDefinition()) self.btnDataDefined.registerEnabledWidget(self.spnValue, False) self.spnValue.valueChanged.connect(lambda: self.hasChanged.emit())
def testProperties(self): model = QgsFieldMappingModel(self.source_fields, self.destination_fields) model.setDestinationFields( self.destination_fields, { 'destination_field1': '5', 'destination_field2': 'source_field2', 'destination_field3': 'source_field2 * @myvar' }) mapping = model.mapping() self.assertEqual(mapping[0].field.name(), 'destination_field1') self.assertEqual(mapping[1].field.name(), 'destination_field2') self.assertEqual(mapping[2].field.name(), 'destination_field3') self.assertEqual(mapping[0].expression, '5') self.assertEqual(mapping[1].expression, 'source_field2') self.assertEqual(mapping[2].expression, 'source_field2 * @myvar') self.assertEqual( model.fieldPropertyMap(), { 'destination_field1': QgsProperty.fromExpression('5'), 'destination_field2': QgsProperty.fromField('source_field2'), 'destination_field3': QgsProperty.fromExpression('source_field2 * @myvar'), }) model = QgsFieldMappingModel(self.source_fields, self.destination_fields) self.assertEqual( model.fieldPropertyMap(), { 'destination_field1': QgsProperty.fromField('source_field2'), 'destination_field2': QgsProperty.fromField('source_field1'), 'destination_field3': QgsProperty.fromExpression(''), }) model.setFieldPropertyMap({ 'destination_field1': QgsProperty.fromField('source_field1'), 'destination_field2': QgsProperty.fromExpression('55*6'), 'destination_field3': QgsProperty.fromValue(6), }) self.assertEqual( model.fieldPropertyMap(), { 'destination_field1': QgsProperty.fromField('source_field1'), 'destination_field2': QgsProperty.fromExpression('55*6'), 'destination_field3': QgsProperty.fromExpression('6'), })
def test_data_defined_layout_properties(self): # pylint: disable=too-many-statements """ Test data defined stroke color """ layer_path = os.path.join(os.path.dirname(__file__), 'test_layer.shp') vl1 = QgsVectorLayer(layer_path, 'test_layer', 'ogr') vl1.setSubsetString('id < 10') self.assertTrue(vl1.isValid()) QgsProject.instance().addMapLayer(vl1) settings = PlotSettings('scatter') settings.source_layer_id = vl1.id() settings.properties['x_name'] = 'so4' settings.properties['y_name'] = 'mg' settings.layout['title'] = 'title' settings.layout['legend_title'] = 'legend_title' settings.layout['x_title'] = 'x_title' settings.layout['y_title'] = 'y_title' settings.layout['z_title'] = 'z_title' settings.layout['x_min'] = 0 settings.layout['x_max'] = 1 settings.layout['y_min'] = 0 settings.layout['y_max'] = 1 factory = PlotFactory(settings) # should be empty, not using data defined size self.assertEqual(factory.settings.x, [98, 88, 267, 329, 319, 137, 350, 151, 203]) self.assertEqual( factory.settings.y, [72.31, 86.03, 85.26, 81.11, 131.59, 95.36, 112.88, 80.55, 78.34]) self.assertEqual(factory.settings.data_defined_title, '') self.assertEqual(factory.settings.data_defined_legend_title, '') self.assertEqual(factory.settings.data_defined_x_title, '') self.assertEqual(factory.settings.data_defined_y_title, '') self.assertEqual(factory.settings.data_defined_z_title, '') self.assertEqual(factory.settings.data_defined_x_min, None) self.assertEqual(factory.settings.data_defined_x_max, None) self.assertEqual(factory.settings.data_defined_y_min, None) self.assertEqual(factory.settings.data_defined_y_max, None) class TestGenerator(QgsExpressionContextGenerator): # pylint: disable=missing-docstring, too-few-public-methods def createExpressionContext(self) -> QgsExpressionContext: # pylint: disable=missing-docstring, no-self-use context = QgsExpressionContext() scope = QgsExpressionContextScope() scope.setVariable('some_var', 10) context.appendScope(scope) context.appendScope(vl1.createExpressionContextScope()) return context generator = TestGenerator() settings.data_defined_properties.setProperty( PlotSettings.PROPERTY_TITLE, QgsProperty.fromExpression("concat('my', '_title_', @some_var)")) settings.data_defined_properties.setProperty( PlotSettings.PROPERTY_LEGEND_TITLE, QgsProperty.fromExpression("concat('my', '_legend_', @some_var)")) settings.data_defined_properties.setProperty( PlotSettings.PROPERTY_X_TITLE, QgsProperty.fromExpression("concat('my', '_x_axis_', @some_var)")) settings.data_defined_properties.setProperty( PlotSettings.PROPERTY_Y_TITLE, QgsProperty.fromExpression("concat('my', '_y_axis_', @some_var)")) settings.data_defined_properties.setProperty( PlotSettings.PROPERTY_Z_TITLE, QgsProperty.fromExpression("concat('my', '_z_axis_', @some_var)")) settings.data_defined_properties.setProperty( PlotSettings.PROPERTY_X_MIN, QgsProperty.fromExpression("-1*@some_var")) settings.data_defined_properties.setProperty( PlotSettings.PROPERTY_X_MAX, QgsProperty.fromExpression("+1*@some_var")) settings.data_defined_properties.setProperty( PlotSettings.PROPERTY_Y_MIN, QgsProperty.fromExpression("-1*@some_var")) settings.data_defined_properties.setProperty( PlotSettings.PROPERTY_Y_MAX, QgsProperty.fromExpression("+1*@some_var")) factory = PlotFactory(settings, context_generator=generator) self.assertEqual(factory.settings.x, [98, 88, 267, 329, 319, 137, 350, 151, 203]) self.assertEqual( factory.settings.y, [72.31, 86.03, 85.26, 81.11, 131.59, 95.36, 112.88, 80.55, 78.34]) self.assertEqual(factory.settings.data_defined_title, 'my_title_10') self.assertEqual(factory.settings.data_defined_legend_title, 'my_legend_10') self.assertEqual(factory.settings.data_defined_x_title, 'my_x_axis_10') self.assertEqual(factory.settings.data_defined_y_title, 'my_y_axis_10') self.assertEqual(factory.settings.data_defined_z_title, 'my_z_axis_10') self.assertEqual(factory.settings.data_defined_x_min, -10) self.assertEqual(factory.settings.data_defined_x_max, 10) self.assertEqual(factory.settings.data_defined_y_min, -10) self.assertEqual(factory.settings.data_defined_y_max, 10)
def testProjectColor(self): scheme = [ s for s in QgsApplication.colorSchemeRegistry().schemes() if isinstance(s, QgsProjectColorScheme) ][0] scheme.setColors([]) definition = QgsPropertyDefinition( 'test', 'test', QgsPropertyDefinition.ColorWithAlpha) button = QgsPropertyOverrideButton() button.init(0, QgsProperty(), definition) button.aboutToShowMenu() self.assertIn('Project Color', [a.text() for a in button.menu().actions()]) self.assertIn('Color', [a.text() for a in button.menu().actions()]) color_action = [ a for a in button.menu().actions() if a.text() == 'Color' ][0] self.assertEqual([a.text() for a in color_action.menu().actions()][0], 'No colors set') # add some project colors scheme.setColors([[QColor(255, 0, 0), 'color 1'], [QColor(255, 255, 0), 'burnt marigold']]) button.aboutToShowMenu() self.assertIn('Project Color', [a.text() for a in button.menu().actions()]) self.assertIn('Color', [a.text() for a in button.menu().actions()]) color_action = [ a for a in button.menu().actions() if a.text() == 'Color' ][0] self.assertEqual([a.text() for a in color_action.menu().actions()], ['color 1', 'burnt marigold']) button.menuActionTriggered(color_action.menu().actions()[1]) self.assertTrue(button.toProperty().isActive()) self.assertEqual(button.toProperty().asExpression(), 'project_color(\'burnt marigold\')') button.menuActionTriggered(color_action.menu().actions()[0]) self.assertTrue(button.toProperty().isActive()) self.assertEqual(button.toProperty().asExpression(), 'project_color(\'color 1\')') button.setToProperty( QgsProperty.fromExpression('project_color(\'burnt marigold\')')) button.aboutToShowMenu() color_action = [ a for a in button.menu().actions() if a.text() == 'Color' ][0] self.assertTrue(color_action.isChecked()) self.assertEqual( [a.isChecked() for a in color_action.menu().actions()], [False, True]) # should also see color menu for ColorNoAlpha properties definition = QgsPropertyDefinition('test', 'test', QgsPropertyDefinition.ColorNoAlpha) button = QgsPropertyOverrideButton() button.init(0, QgsProperty(), definition) button.aboutToShowMenu() self.assertIn('Project Color', [a.text() for a in button.menu().actions()]) self.assertIn('Color', [a.text() for a in button.menu().actions()]) # but no color menu for other types definition = QgsPropertyDefinition('test', 'test', QgsPropertyDefinition.Double) button = QgsPropertyOverrideButton() button.init(0, QgsProperty(), definition) button.aboutToShowMenu() self.assertNotIn('Project Color', [a.text() for a in button.menu().actions()]) self.assertNotIn('Color', [a.text() for a in button.menu().actions()])
def testDataDefinedColumnCount(self): mapSettings = QgsMapSettings() # NOQA composition = QgsComposition(QgsProject.instance()) composition.setPaperSize(297, 210) legend = QgsComposerLegend(composition) composition.addComposerLegend(legend) legend.setColumnCount(2) self.assertEqual(legend.columnCount(), 2) self.assertEqual(legend.legendSettings().columnCount(), 2) legend.dataDefinedProperties().setProperty(QgsComposerObject.LegendColumnCount, QgsProperty.fromExpression("5")) legend.refreshDataDefinedProperty() self.assertEqual(legend.columnCount(), 2) self.assertEqual(legend.legendSettings().columnCount(), 5)
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 testDataDefinedTicksAndAnnotationDisplay(self): layout = QgsLayout(QgsProject.instance()) layout.initializeDefaults() map = QgsLayoutItemMap(layout) map.attemptSetSceneRect(QRectF(40, 20, 200, 100)) map.setFrameEnabled(True) map.setBackgroundColor(QColor(150, 100, 100)) layout.addLayoutItem(map) myRectangle = QgsRectangle(0.5, -5.5, 10.5, 0.5) map.setExtent(myRectangle) map.setMapRotation(45) map.grid().setEnabled(True) map.grid().setIntervalX(1) map.grid().setIntervalY(1) map.grid().setAnnotationEnabled(True) map.grid().setGridLineColor(QColor(0, 255, 0)) map.grid().setGridLineWidth(0.5) map.grid().setFrameStyle(QgsLayoutItemMapGrid.ExteriorTicks) map.grid().setFrameWidth(4) map.grid().setFramePenSize(1) map.grid().setFramePenColor(QColor(0, 0, 255)) map.grid().setAnnotationFrameDistance(5) format = QgsTextFormat.fromQFont(getTestFont('Bold', 20)) format.setColor(QColor(255, 0, 0)) format.setOpacity(150 / 255) map.grid().setAnnotationTextFormat(format) map.grid().setAnnotationPrecision(0) map.grid().setRotatedTicksEnabled(True) map.grid().setRotatedAnnotationsEnabled(True) map.grid().setAnnotationDirection(QgsLayoutItemMapGrid.OnTick) map.grid().dataDefinedProperties().setProperty( QgsLayoutObject.MapGridAnnotationDisplayLeft, QgsProperty.fromValue("x_only")) map.grid().dataDefinedProperties().setProperty( QgsLayoutObject.MapGridAnnotationDisplayRight, QgsProperty.fromValue("Y_ONLY")) map.grid().dataDefinedProperties().setProperty( QgsLayoutObject.MapGridAnnotationDisplayTop, QgsProperty.fromValue("disabled")) map.grid().dataDefinedProperties().setProperty( QgsLayoutObject.MapGridAnnotationDisplayBottom, QgsProperty.fromValue("ALL")) map.grid().dataDefinedProperties().setProperty( QgsLayoutObject.MapGridFrameDivisionsLeft, QgsProperty.fromValue("X_ONLY")) map.grid().dataDefinedProperties().setProperty( QgsLayoutObject.MapGridFrameDivisionsRight, QgsProperty.fromValue("y_only")) map.grid().dataDefinedProperties().setProperty( QgsLayoutObject.MapGridFrameDivisionsTop, QgsProperty.fromValue("DISABLED")) map.grid().dataDefinedProperties().setProperty( QgsLayoutObject.MapGridFrameDivisionsBottom, QgsProperty.fromValue("all")) map.grid().refresh() checker = QgsLayoutChecker( 'composermap_datadefined_ticksandannotationdisplay', layout) checker.setControlPathPrefix("composer_mapgrid") myTestResult, myMessage = checker.testLayout() self.report += checker.report() self.assertTrue(myTestResult, myMessage)
def testDataDefinedAnnotationDistance(self): layout = QgsLayout(QgsProject.instance()) layout.initializeDefaults() map = QgsLayoutItemMap(layout) map.attemptSetSceneRect(QRectF(20, 20, 200, 100)) map.setFrameEnabled(True) map.setBackgroundColor(QColor(150, 100, 100)) layout.addLayoutItem(map) myRectangle = QgsRectangle(781662.375, 3339523.125, 793062.375, 3345223.125) map.setExtent(myRectangle) map.grid().setEnabled(True) map.grid().setIntervalX(2000) map.grid().setIntervalY(2000) map.grid().setAnnotationEnabled(True) map.grid().setGridLineColor(QColor(0, 255, 0)) map.grid().setGridLineWidth(0.5) format = QgsTextFormat.fromQFont(getTestFont('Bold', 20)) format.setColor(QColor(255, 0, 0)) format.setOpacity(150 / 255) map.grid().setAnnotationTextFormat(format) map.grid().setAnnotationPrecision(0) map.grid().setAnnotationDisplay(QgsLayoutItemMapGrid.HideAll, QgsLayoutItemMapGrid.Left) map.grid().setAnnotationPosition(QgsLayoutItemMapGrid.OutsideMapFrame, QgsLayoutItemMapGrid.Right) map.grid().setAnnotationDisplay(QgsLayoutItemMapGrid.HideAll, QgsLayoutItemMapGrid.Top) map.grid().setAnnotationPosition(QgsLayoutItemMapGrid.OutsideMapFrame, QgsLayoutItemMapGrid.Bottom) map.grid().setAnnotationDirection(QgsLayoutItemMapGrid.Horizontal, QgsLayoutItemMapGrid.Right) map.grid().setAnnotationDirection(QgsLayoutItemMapGrid.Horizontal, QgsLayoutItemMapGrid.Bottom) map.grid().setBlendMode(QPainter.CompositionMode_Overlay) map.updateBoundingRect() map.grid().dataDefinedProperties().setProperty(QgsLayoutObject.MapGridLabelDistance, QgsProperty.fromValue(10)) map.grid().refresh() checker = QgsLayoutChecker('composermap_datadefined_annotationdistance', layout) checker.setControlPathPrefix("composer_mapgrid") myTestResult, myMessage = checker.testLayout() self.report += checker.report() self.assertTrue(myTestResult, myMessage)
def testDataDefinedColumnCount(self): layout = QgsLayout(QgsProject.instance()) layout.initializeDefaults() legend = QgsLayoutItemLegend(layout) legend.setTitle("Legend") layout.addLayoutItem(legend) legend.setColumnCount(2) self.assertEqual(legend.columnCount(), 2) self.assertEqual(legend.legendSettings().columnCount(), 2) legend.dataDefinedProperties().setProperty(QgsLayoutObject.LegendColumnCount, QgsProperty.fromExpression("5")) legend.refreshDataDefinedProperty() self.assertEqual(legend.columnCount(), 2) self.assertEqual(legend.legendSettings().columnCount(), 5)
def testDataDefinedFrameThickness(self): layout = QgsLayout(QgsProject.instance()) layout.initializeDefaults() map = QgsLayoutItemMap(layout) map.attemptSetSceneRect(QRectF(20, 20, 200, 100)) map.setFrameEnabled(True) map.setBackgroundColor(QColor(150, 100, 100)) layout.addLayoutItem(map) myRectangle = QgsRectangle(781662.375, 3339523.125, 793062.375, 3345223.125) map.setExtent(myRectangle) map.grid().setEnabled(True) map.grid().setIntervalX(2000) map.grid().setIntervalY(2000) map.grid().setAnnotationEnabled(False) map.grid().setGridLineColor(QColor(0, 255, 0)) map.grid().setGridLineWidth(0.5) map.grid().setFrameStyle(QgsLayoutItemMapGrid.Zebra) map.grid().setFrameWidth(10) map.grid().setFramePenSize(1) map.grid().setGridLineWidth(0.5) map.grid().setFramePenColor(QColor(0, 0, 0)) map.grid().setFrameFillColor1(QColor(0, 0, 0)) map.grid().setFrameFillColor2(QColor(255, 255, 255)) map.grid().setBlendMode(QPainter.CompositionMode_Overlay) map.updateBoundingRect() map.grid().dataDefinedProperties().setProperty(QgsLayoutObject.MapGridFrameLineThickness, QgsProperty.fromValue(4)) map.grid().refresh() checker = QgsLayoutChecker('composermap_datadefined_framethickness', layout) checker.setControlPathPrefix("composer_mapgrid") myTestResult, myMessage = checker.testLayout() self.report += checker.report() self.assertTrue(myTestResult, myMessage)
def processAlgorithm(self, parameters, context, model_feedback): # Check if homogenize # Use a multi-step feedback, so that individual child algorithm progress reports are adjusted for the # overall progress through the model if parameters[self.HOMOGENIZE_Z_VALUES]: feedback = QgsProcessingMultiStepFeedback(4, model_feedback) else: feedback = QgsProcessingMultiStepFeedback(2, model_feedback) results = {} outputs = {} # Convert enumerator to zero based index value valor_tipo_curva = self.parameterAsEnum( parameters, self.VALOR_TIPO_CURVA, context) + 1 # Refactor fields alg_params = { 'FIELDS_MAPPING': [{ 'expression': 'now()', 'length': -1, 'name': 'inicio_objeto', 'precision': -1, 'type': 14 }, { 'expression': str(valor_tipo_curva), 'length': 255, 'name': 'valor_tipo_curva', 'precision': -1, 'type': 10 }], 'INPUT': parameters['INPUT'], 'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT } outputs['RefactorFields'] = processing.run('qgis:refactorfields', alg_params, context=context, feedback=feedback, is_child_algorithm=True) feedback.setCurrentStep(1) if feedback.isCanceled(): return {} if parameters[self.HOMOGENIZE_Z_VALUES]: # If Homogenize Z Values option is checked # Correct possible wrong Z values along lines # Extract Z values alg_params = { 'COLUMN_PREFIX': 'z_', 'INPUT': outputs['RefactorFields']['OUTPUT'], 'SUMMARIES': [11], 'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT } outputs['ExtractZValues'] = processing.run('native:extractzvalues', alg_params, context=context, feedback=feedback, is_child_algorithm=True) feedback.setCurrentStep(2) if feedback.isCanceled(): return {} # Set Z value alg_params = { 'INPUT': outputs['ExtractZValues']['OUTPUT'], 'Z_VALUE': QgsProperty.fromExpression('"z_majority"'), 'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT } outputs['SetZValue'] = processing.run('qgis:setzvalue', alg_params, context=context, feedback=feedback, is_child_algorithm=True) feedback.setCurrentStep(3) if feedback.isCanceled(): return {} else: outputs['SetZValue'] = outputs['RefactorFields'] # Export to PostgreSQL (available connections) idx = self.parameterAsEnum(parameters, self.POSTGRES_CONNECTION, context) postgres_connection = self.postgres_connections_list[idx] alg_params = { 'ADDFIELDS': True, 'APPEND': True, 'A_SRS': None, 'CLIP': False, 'DATABASE': postgres_connection, 'DIM': 1, 'GEOCOLUMN': 'geometria', 'GT': '', 'GTYPE': 4, 'INDEX': True, 'INPUT': outputs['SetZValue']['OUTPUT'], 'LAUNDER': True, 'OPTIONS': '', 'OVERWRITE': False, 'PK': '', 'PRECISION': True, 'PRIMARY_KEY': 'identificador', 'PROMOTETOMULTI': True, 'SCHEMA': 'public', 'SEGMENTIZE': '', 'SHAPE_ENCODING': '', 'SIMPLIFY': '', 'SKIPFAILURES': False, 'SPAT': None, 'S_SRS': None, 'TABLE': 'curva_de_nivel', 'T_SRS': None, 'WHERE': '' } outputs['ExportToPostgresqlAvailableConnections'] = processing.run( 'gdal:importvectorintopostgisdatabaseavailableconnections', alg_params, context=context, feedback=feedback, is_child_algorithm=True) return results
def test_point_dd_ordered_placement1(self): # Test ordered placements for point with data defined order and obstacle self.layer = TestQgsPalLabeling.loadFeatureLayer('point_ordered_placement') obstacleLayer = TestQgsPalLabeling.loadFeatureLayer('point_ordered_obstacle_top') self._TestMapSettings = self.cloneMapSettings(self._MapSettings) self.lyr.placement = QgsPalLayerSettings.OrderedPositionsAroundPoint self.lyr.dist = 2 self.lyr.dataDefinedProperties().setProperty(QgsPalLayerSettings.PredefinedPositionOrder, QgsProperty.fromExpression("'T,B'")) self.checkTest() self.removeMapLayer(obstacleLayer) self.removeMapLayer(self.layer) self.lyr.dataDefinedProperties().setProperty(QgsPalLayerSettings.PredefinedPositionOrder, QgsProperty()) self.layer = None
def test_read_write_project2(self): """ Test reading and writing to project, signals based """ p = QgsProject() original = PlotSettings('test', properties={ 'marker_width': 2, 'marker_size': 5 }, layout={ 'title': 'my plot', 'legend_orientation': 'v' }) original.data_defined_properties.setProperty( PlotSettings.PROPERTY_FILTER, QgsProperty.fromExpression('"ap">50')) original.data_defined_properties.setProperty( PlotSettings.PROPERTY_MARKER_SIZE, QgsProperty.fromExpression('5+6')) original.data_defined_properties.setProperty( PlotSettings.PROPERTY_COLOR, QgsProperty.fromExpression("'red'")) original.data_defined_properties.setProperty( PlotSettings.PROPERTY_STROKE_WIDTH, QgsProperty.fromExpression('12/2')) self.test_read_write_project2_written = False def write(doc): self.test_read_write_project2_written = True original.write_to_project(doc) p.writeProject.connect(write) path = os.path.join(tempfile.gettempdir(), 'test_dataplotly_project.qgs') self.assertTrue(p.write(path)) for _ in range(100): QCoreApplication.processEvents() self.assertTrue(self.test_read_write_project2_written) p2 = QgsProject() res = PlotSettings('gg') self.test_read_write_project2_read = False def read(doc): res.read_from_project(doc) self.test_read_write_project2_read = True p2.readProject.connect(read) self.assertTrue(p2.read(path)) for _ in range(100): QCoreApplication.processEvents() self.assertTrue(self.test_read_write_project2_read) self.assertEqual(res.plot_type, original.plot_type) self.assertEqual(res.properties, original.properties) self.assertEqual(res.layout, original.layout) self.assertEqual( res.data_defined_properties.property(PlotSettings.PROPERTY_FILTER), original.data_defined_properties.property( PlotSettings.PROPERTY_FILTER)) self.assertEqual( res.data_defined_properties.property( PlotSettings.PROPERTY_MARKER_SIZE), original.data_defined_properties.property( PlotSettings.PROPERTY_MARKER_SIZE)) self.assertEqual( res.data_defined_properties.property(PlotSettings.PROPERTY_COLOR), original.data_defined_properties.property( PlotSettings.PROPERTY_COLOR)) self.assertEqual( res.data_defined_properties.property( PlotSettings.PROPERTY_STROKE_WIDTH), original.data_defined_properties.property( PlotSettings.PROPERTY_STROKE_WIDTH))
def test_settings_round_trip(self): # pylint: disable=too-many-statements """ Test setting and retrieving settings results in identical results """ layer_path = os.path.join(os.path.dirname(__file__), 'test_layer.geojson') vl1 = QgsVectorLayer(layer_path, 'test_layer', 'ogr') vl2 = QgsVectorLayer(layer_path, 'test_layer1', 'ogr') vl3 = QgsVectorLayer(layer_path, 'test_layer2', 'ogr') QgsProject.instance().addMapLayers([vl1, vl2, vl3]) dialog = DataPlotlyPanelWidget(None, override_iface=IFACE) settings = dialog.get_settings() # default should be scatter plot self.assertEqual(settings.plot_type, 'scatter') print('dialog loaded') # customise settings settings.plot_type = 'bar' settings.properties['name'] = 'my legend title' settings.properties['hover_text'] = 'y' settings.properties['box_orientation'] = 'h' settings.properties['normalization'] = 'probability' settings.properties['box_stat'] = 'sd' settings.properties['box_outliers'] = 'suspectedoutliers' settings.properties['violin_side'] = 'negative' settings.properties['show_mean_line'] = True settings.properties['cumulative'] = True settings.properties['invert_hist'] = 'decreasing' settings.source_layer_id = vl3.id() settings.properties['x_name'] = 'so4' settings.properties['y_name'] = 'ca' settings.properties['z_name'] = 'mg' settings.properties['color_scale'] = 'Earth' settings.properties['violin_box'] = True # TODO: likely need to test other settings.properties values here! settings.layout['legend'] = False settings.layout['legend_orientation'] = 'h' settings.layout['title'] = 'my title' settings.layout['x_title'] = 'my x title' settings.layout['y_title'] = 'my y title' settings.layout['z_title'] = 'my z title' settings.layout['range_slider']['visible'] = True settings.layout['bar_mode'] = 'overlay' settings.layout['x_type'] = 'log' settings.layout['y_type'] = 'category' settings.layout['x_inv'] = 'reversed' settings.layout['y_inv'] = 'reversed' settings.layout['bargaps'] = 0.8 settings.layout['additional_info_expression'] = '1+2' settings.layout['bins_check'] = True settings.data_defined_properties.setProperty( PlotSettings.PROPERTY_FILTER, QgsProperty.fromExpression('"ap">50')) settings.data_defined_properties.setProperty( PlotSettings.PROPERTY_MARKER_SIZE, QgsProperty.fromExpression('5+64')) settings.data_defined_properties.setProperty( PlotSettings.PROPERTY_COLOR, QgsProperty.fromExpression("'red'")) settings.data_defined_properties.setProperty( PlotSettings.PROPERTY_STROKE_WIDTH, QgsProperty.fromExpression("12/2")) settings.data_defined_properties.setProperty( PlotSettings.PROPERTY_TITLE, QgsProperty.fromExpression("concat('my', '_title_', @some_var)")) settings.data_defined_properties.setProperty( PlotSettings.PROPERTY_LEGEND_TITLE, QgsProperty.fromExpression("concat('my', '_legend_', @some_var)")) settings.data_defined_properties.setProperty( PlotSettings.PROPERTY_X_TITLE, QgsProperty.fromExpression("concat('my', '_x_axis_', @some_var)")) settings.data_defined_properties.setProperty( PlotSettings.PROPERTY_Y_TITLE, QgsProperty.fromExpression("concat('my', '_y_axis_', @some_var)")) settings.data_defined_properties.setProperty( PlotSettings.PROPERTY_Z_TITLE, QgsProperty.fromExpression("concat('my', '_z_axis_', @some_var)")) settings.data_defined_properties.setProperty( PlotSettings.PROPERTY_X_MIN, QgsProperty.fromExpression("-1*10")) settings.data_defined_properties.setProperty( PlotSettings.PROPERTY_X_MAX, QgsProperty.fromExpression("+1*10")) settings.data_defined_properties.setProperty( PlotSettings.PROPERTY_Y_MIN, QgsProperty.fromExpression("-1*10")) settings.data_defined_properties.setProperty( PlotSettings.PROPERTY_Y_MAX, QgsProperty.fromExpression("+1*10")) dialog2 = DataPlotlyPanelWidget(None, override_iface=IFACE) dialog2.set_settings(settings) print('set settings') self.assertEqual(dialog2.get_settings().plot_type, settings.plot_type) for k in settings.properties.keys(): print(k) if k in [ 'x', 'y', 'z', 'additional_hover_text', 'featureIds', 'featureBox', 'custom' ]: continue self.assertEqual(dialog2.get_settings().properties[k], settings.properties[k]) for k in settings.layout.keys(): self.assertEqual(dialog2.get_settings().layout[k], settings.layout[k]) self.assertEqual(dialog2.get_settings().source_layer_id, vl3.id()) self.assertEqual( dialog2.get_settings().data_defined_properties.property( PlotSettings.PROPERTY_FILTER), settings.data_defined_properties.property( PlotSettings.PROPERTY_FILTER)) self.assertEqual( dialog2.get_settings().data_defined_properties.property( PlotSettings.PROPERTY_MARKER_SIZE), settings.data_defined_properties.property( PlotSettings.PROPERTY_MARKER_SIZE)) self.assertEqual( dialog2.get_settings().data_defined_properties.property( PlotSettings.PROPERTY_COLOR), settings.data_defined_properties.property( PlotSettings.PROPERTY_COLOR)) self.assertEqual( dialog2.get_settings().data_defined_properties.property( PlotSettings.PROPERTY_STROKE_WIDTH), settings.data_defined_properties.property( PlotSettings.PROPERTY_STROKE_WIDTH)) self.assertEqual( dialog2.get_settings().data_defined_properties.property( PlotSettings.PROPERTY_X_MIN), settings.data_defined_properties.property( PlotSettings.PROPERTY_X_MIN)) self.assertEqual( dialog2.get_settings().data_defined_properties.property( PlotSettings.PROPERTY_X_MAX), settings.data_defined_properties.property( PlotSettings.PROPERTY_X_MAX)) self.assertEqual( dialog2.get_settings().data_defined_properties.property( PlotSettings.PROPERTY_Y_MIN), settings.data_defined_properties.property( PlotSettings.PROPERTY_Y_MIN)) self.assertEqual( dialog2.get_settings().data_defined_properties.property( PlotSettings.PROPERTY_Y_MAX), settings.data_defined_properties.property( PlotSettings.PROPERTY_Y_MAX)) self.assertEqual( dialog2.get_settings().data_defined_properties.property( PlotSettings.PROPERTY_TITLE), settings.data_defined_properties.property( PlotSettings.PROPERTY_TITLE)) self.assertEqual( dialog2.get_settings().data_defined_properties.property( PlotSettings.PROPERTY_LEGEND_TITLE), settings.data_defined_properties.property( PlotSettings.PROPERTY_LEGEND_TITLE)) self.assertEqual( dialog2.get_settings().data_defined_properties.property( PlotSettings.PROPERTY_X_TITLE), settings.data_defined_properties.property( PlotSettings.PROPERTY_X_TITLE)) self.assertEqual( dialog2.get_settings().data_defined_properties.property( PlotSettings.PROPERTY_Y_TITLE), settings.data_defined_properties.property( PlotSettings.PROPERTY_Y_TITLE)) self.assertEqual( dialog2.get_settings().data_defined_properties.property( PlotSettings.PROPERTY_Z_TITLE), settings.data_defined_properties.property( PlotSettings.PROPERTY_Z_TITLE)) dialog2.deleteLater() del dialog2 settings = dialog.get_settings() dialog.deleteLater() del dialog dialog3 = DataPlotlyPanelWidget(None, override_iface=IFACE) print('dialog 2') dialog3.set_settings(settings) print('set settings') self.assertEqual(dialog3.get_settings().plot_type, settings.plot_type) for k in settings.properties.keys(): print(k) self.assertEqual(dialog3.get_settings().properties[k], settings.properties[k]) self.assertEqual(dialog3.get_settings().properties, settings.properties) for k in settings.layout.keys(): print(k) self.assertEqual(dialog3.get_settings().layout[k], settings.layout[k]) dialog3.deleteLater() del dialog3 print('done') QgsProject.instance().clear() print('clear done')
def testDataDefinedColumnCount(self): layout = QgsLayout(QgsProject.instance()) layout.initializeDefaults() legend = QgsLayoutItemLegend(layout) layout.addLayoutItem(legend) legend.setColumnCount(2) self.assertEqual(legend.columnCount(), 2) self.assertEqual(legend.legendSettings().columnCount(), 2) legend.dataDefinedProperties().setProperty(QgsLayoutObject.LegendColumnCount, QgsProperty.fromExpression("5")) legend.refreshDataDefinedProperty() self.assertEqual(legend.columnCount(), 2) self.assertEqual(legend.legendSettings().columnCount(), 5)
layer_name='104_verif_entreemo_diff_rcb', visibility=False, control_layer=True), LayerInfo(display_name='Lien entre les entrées et les localisations', layer_name='109_VERIF_Entree_Vers_Localisation', control_layer=True), LayerInfo(display_name='Sens du tronçon', layer_name='009_ITF_BAT_Troncon_rue', control_layer=True), LayerInfo(display_name='Nom des rues', layer_name='009_ITF_BAT_Troncon_rue', symbology_type=SymbologyType.RANDOM_CATEGORIZED, category_field='texte', symbology_data_defined_properties={ QgsSymbolLayer.PropertyStrokeWidth: QgsProperty.fromValue(3), QgsSymbolLayer.PropertyCapStyle: QgsProperty.fromValue(Qt.RoundCap), QgsSymbolLayer.PropertyJoinStyle: QgsProperty.fromValue(Qt.RoundJoin), }, control_layer=True), LayerInfo(display_name='Lieu dénommé', layer_name='009_ITF_BAT_Lieu_denomme'), LayerInfo(display_name='Habitation sans adresse', layer_name='108_VERIF_Habitation_sans_adresse', symbology_type=SymbologyType.SIMPLE, symbology_properties={ 'color': '255, 0, 0, 180', 'border_color': '255, 255, 0' },