def testLoadWriteRenderingScaleVisibility(self): """Test write and load scale visibility, see GH #33840""" vl = QgsVectorLayer("LineString?crs=epsg:4326", "result", "memory") vl.setScaleBasedVisibility(True) vl.setMinimumScale(125.0) vl.setMaximumScale(1.25) style = QDomDocument() style.setContent( "<!DOCTYPE qgis PUBLIC 'http://mrcc.com/qgis.dtd' 'SYSTEM'><qgis></qgis>" ) node = style.firstChild() self.assertTrue( vl.writeStyle(node, style, "Error writing style", QgsReadWriteContext(), QgsMapLayer.Rendering)) style_content = style.toString() del (vl) # Read vl2 = QgsVectorLayer("LineString?crs=epsg:4326", "result", "memory") self.assertFalse(vl2.hasScaleBasedVisibility()) style2 = QDomDocument() style2.setContent(style_content) self.assertTrue( vl2.readStyle(style.namedItem('qgis'), "Error reading style", QgsReadWriteContext(), QgsMapLayer.Rendering)) self.assertTrue(vl2.hasScaleBasedVisibility()) self.assertEqual(vl2.minimumScale(), 125.0) self.assertEqual(vl2.maximumScale(), 1.25)
def testSingleSymbolScaleDependencies(self): layer = QgsVectorLayer("Point", "addfeat", "memory") mFilePath = QDir.toNativeSeparators('%s/symbol_layer/%s.qml' % (unitTestDataPath(), "singleSymbol")) layer.loadNamedStyle(mFilePath) layer.setMinimumScale(1000) layer.setMaximumScale(500000) layer.setScaleBasedVisibility(True) dom, root = self.layerToSld(layer) # print("Scale dep on single symbol:" + dom.toString()) self.assertScaleDenominator(root, '1000', '500000')
def testSingleSymbolScaleDependencies(self): layer = QgsVectorLayer("Point", "addfeat", "memory") mFilePath = QDir.toNativeSeparators('%s/symbol_layer/%s.qml' % (unitTestDataPath(), "singleSymbol")) layer.loadNamedStyle(mFilePath) layer.setMaximumScale(1000) layer.setMinimumScale(500000) layer.setScaleBasedVisibility(True) dom, root = self.layerToSld(layer) # print("Scale dep on single symbol:" + dom.toString()) self.assertScaleDenominator(root, '1000', '500000')
def testCategorizedWithScaleDependencies(self): layer = QgsVectorLayer("Polygon", "addfeat", "memory") mFilePath = QDir.toNativeSeparators('%s/symbol_layer/%s.qml' % (unitTestDataPath(), "categorized")) layer.loadNamedStyle(mFilePath) layer.setMinimumScale(1000) layer.setMaximumScale(500000) layer.setScaleBasedVisibility(True) dom, root = self.layerToSld(layer) # print("Categorized with scale deps:" + dom.toString()) ruleCount = root.elementsByTagName('se:Rule').size() for i in range(0, ruleCount): self.assertScaleDenominator(root, '1000', '500000', i)
def testCategorizedWithScaleDependencies(self): layer = QgsVectorLayer("Polygon", "addfeat", "memory") mFilePath = QDir.toNativeSeparators('%s/symbol_layer/%s.qml' % (unitTestDataPath(), "categorized")) layer.loadNamedStyle(mFilePath) layer.setMaximumScale(1000) layer.setMinimumScale(500000) layer.setScaleBasedVisibility(True) dom, root = self.layerToSld(layer) # print("Categorized with scale deps:" + dom.toString()) ruleCount = root.elementsByTagName('se:Rule').size() for i in range(0, ruleCount): self.assertScaleDenominator(root, '1000', '500000', i)
def testRuleBasedNoRootScaleDependencies(self): layer = QgsVectorLayer("Polygon", "addfeat", "memory") mFilePath = QDir.toNativeSeparators('%s/symbol_layer/%s.qml' % (unitTestDataPath(), "ruleBased")) status = layer.loadNamedStyle(mFilePath) # NOQA layer.setMinimumScale(5000) layer.setMaximumScale(50000000) layer.setScaleBasedVisibility(True) dom, root = self.layerToSld(layer) # print("Rule based, with root scale deps:" + dom.toString()) ruleCount = root.elementsByTagName('se:Rule').size() # NOQA self.assertScaleDenominator(root, '5000', '40000000', 0) self.assertScaleDenominator(root, '5000', '50000000', 1)
def testRuleBasedNoRootScaleDependencies(self): layer = QgsVectorLayer("Polygon", "addfeat", "memory") mFilePath = QDir.toNativeSeparators('%s/symbol_layer/%s.qml' % (unitTestDataPath(), "ruleBased")) status = layer.loadNamedStyle(mFilePath) # NOQA layer.setMaximumScale(5000) layer.setMinimumScale(50000000) layer.setScaleBasedVisibility(True) dom, root = self.layerToSld(layer) # print("Rule based, with root scale deps:" + dom.toString()) ruleCount = root.elementsByTagName('se:Rule').size() # NOQA self.assertScaleDenominator(root, '5000', '40000000', 0) self.assertScaleDenominator(root, '5000', '50000000', 1)
def layer_to_QgsVectorLayer( source_layer, # pylint: disable=too-many-locals,too-many-branches,too-many-statements input_file, context: Context, fallback_crs=QgsCoordinateReferenceSystem(), defer_layer_uri_set: bool = False): """ Converts a vector layer """ if source_layer.__class__.__name__ == 'CadFeatureLayer': layer = source_layer.layer else: layer = source_layer crs = CrsConverter.convert_crs( layer.layer_extent.crs, context) if layer.layer_extent else QgsCoordinateReferenceSystem() if not crs.isValid(): crs = fallback_crs subset_string = '' if layer.selection_set: subset_string = 'fid in ({})'.format(','.join( [str(s) for s in layer.selection_set])) elif layer.definition_query: subset_string = ExpressionConverter.convert_esri_sql( layer.definition_query) base, _ = os.path.split(input_file) uri, wkb_type, provider, encoding, file_name = VectorLayerConverter.get_uri( source_layer=source_layer, obj=layer, base=base, crs=crs, subset=subset_string, context=context) if wkb_type is None or wkb_type == QgsWkbTypes.Unknown: wkb_type = VectorLayerConverter.layer_to_wkb_type(layer) context.layer_type_hint = wkb_type if Qgis.QGIS_VERSION_INT >= 31600: # try to get the layer name so that we can remove it from field references. # e.g. if layer name is polys then qgis won't support to arcgis style "polys.field" format parts = QgsProviderRegistry.instance().decodeUri(provider, uri) context.main_layer_name = parts.get('layerName') if not context.main_layer_name and provider == 'ogr': context.main_layer_name = Path(parts['path']).stem if context.main_layer_name: subset_string = subset_string.replace( context.main_layer_name + '.', '') else: context.main_layer_name = None if provider == 'ogr' and (not file_name or not os.path.exists(file_name) ) and context.invalid_layer_resolver: res = context.invalid_layer_resolver(layer.name, uri, wkb_type) uri = res.uri provider = res.providerKey if Qgis.QGIS_VERSION_INT >= 31000: opts = QgsVectorLayer.LayerOptions() if wkb_type is not None: opts.fallbackWkbType = wkb_type if provider == 'ogr' and subset_string: uri += '|subset={}'.format(subset_string) original_uri = uri if defer_layer_uri_set: uri = 'xxxxxxxxx' + uri vl = QgsVectorLayer(uri, layer.name, provider, opts) if defer_layer_uri_set: vl.setCustomProperty('original_uri', original_uri) else: vl = QgsMemoryProviderUtils.createMemoryLayer( layer.name, QgsFields(), wkb_type, crs) # context.style_folder, _ = os.path.split(output_file) if layer.renderer: renderer = VectorRendererConverter.convert_renderer( layer.renderer, context) try: if not renderer.usingSymbolLevels(): renderer.setUsingSymbolLevels( layer.use_advanced_symbol_levels) except AttributeError: pass if layer.use_page_definition_query: filter_expression = '"{}" {} @atlas_pagename'.format( layer.page_name_field, layer.page_name_match_operator) root_rule = QgsRuleBasedRenderer.Rule(None) # special case -- convert a simple renderer if isinstance(renderer, QgsSingleSymbolRenderer): filter_rule = QgsRuleBasedRenderer.Rule( renderer.symbol().clone()) filter_rule.setFilterExpression(filter_expression) filter_rule.setLabel(layer.name) filter_rule.setDescription(layer.name) root_rule.appendChild(filter_rule) else: source_rule_renderer = QgsRuleBasedRenderer.convertFromRenderer( renderer) filter_rule = QgsRuleBasedRenderer.Rule(None) filter_rule.setFilterExpression(filter_expression) filter_rule.setLabel('Current Atlas Page') filter_rule.setDescription('Current Atlas Page') root_rule.appendChild(filter_rule) for child in source_rule_renderer.rootRule().children(): filter_rule.appendChild(child.clone()) renderer = QgsRuleBasedRenderer(root_rule) if renderer: vl.setRenderer(renderer) vl.triggerRepaint() else: vl.setRenderer(QgsNullSymbolRenderer()) vl.triggerRepaint() metadata = vl.metadata() metadata.setAbstract(layer.description) vl.setMetadata(metadata) # # layer.zoom_max = "don't show when zoomed out beyond" zoom_max = layer.zoom_max # layer.zoom_min = "don't show when zoomed in beyond" zoom_min = layer.zoom_min enabled_scale_range = bool(zoom_max or zoom_min) if zoom_max and zoom_min and zoom_min > zoom_max: # inconsistent scale range -- zoom_max should be bigger number than zoom_min zoom_min, zoom_max = zoom_max, zoom_min # qgis minimum scale = don't show when zoomed out beyond, i.e. ArcGIS zoom_max vl.setMinimumScale( zoom_max if enabled_scale_range else layer.stored_zoom_max) # qgis maximum scale = don't show when zoomed in beyond, i.e. ArcGIS zoom_min vl.setMaximumScale( zoom_min if enabled_scale_range else layer.stored_zoom_min) vl.setScaleBasedVisibility(enabled_scale_range) vl.setOpacity(1.0 - (layer.transparency or 0) / 100) if layer.display_expression_properties and layer.display_expression_properties.expression and layer.display_expression_properties.expression_parser is not None: vl.setDisplayExpression( ExpressionConverter.convert( layer.display_expression_properties.expression, layer.display_expression_properties.expression_parser, layer.display_expression_properties.advanced, context)) if Qgis.QGIS_VERSION_INT < 31000: vl.setDataSource(uri, layer.name, provider) if encoding: vl.dataProvider().setEncoding(encoding) if subset_string: vl.setSubsetString(subset_string) vl.setCrs(crs) for e in layer.extensions: if e.__class__.__name__ == 'ServerLayerExtension': if 'CopyrightText' in e.properties.properties: layer_credits = e.properties.properties['CopyrightText'] metadata = vl.metadata() rights = metadata.rights() rights.append(layer_credits) metadata.setRights(rights) vl.setMetadata(metadata) LabelConverter.convert_annotation_collection( layer.annotation_collection, dest_layer=vl, context=context) vl.setLabelsEnabled(layer.labels_enabled) DiagramConverter.convert_diagrams(layer.renderer, dest_layer=vl, context=context) # setup joins join_layer = VectorLayerConverter.add_joined_layer( source_layer=layer, input_file=input_file, base_layer=vl, context=context) context.dataset_name = '' vl.setLegend(QgsMapLayerLegend.defaultVectorLegend(vl)) if layer.hyperlinks: VectorLayerConverter.convert_hyperlinks(layer.hyperlinks, vl) vl.setDisplayExpression( QgsExpression.quotedColumnRef(layer.display_field)) res = [vl] if join_layer: res.append(join_layer) context.main_layer_name = None return res