def testSymbolColor(self):
        # Create rulebased style
        sym1 = QgsFillSymbol.createSimple({'color': '#ff0000', 'outline_color': 'black'})

        renderer = QgsSingleSymbolRenderer(sym1)
        renderer.symbols(QgsRenderContext())[0].symbolLayers()[0].setDataDefinedProperty(QgsSymbolLayer.PropertyFillColor, QgsProperty.fromExpression('set_color_part( @symbol_color, \'value\', "Value" * 4)'))
        self.layer.setRenderer(renderer)

        # Setup rendering check
        renderchecker = QgsMultiRenderChecker()
        renderchecker.setMapSettings(self.mapsettings)
        renderchecker.setControlName('expected_symbol_color_variable')
        result = renderchecker.runTest('symbol_color_variable', 50)

        self.assertTrue(result)
    def testPartCount(self):
        # Create rulebased style
        sym1 = QgsFillSymbol.createSimple({'color': '#fdbf6f', 'outline_color': 'black'})

        renderer = QgsSingleSymbolRenderer(sym1)
        renderer.symbols(QgsRenderContext())[0].symbolLayers()[0].setDataDefinedProperty(QgsSymbolLayer.PropertyFillColor, QgsProperty.fromExpression('color_rgb( (@geometry_part_count - 1) * 200, 0, 0 )'))
        self.layer.setRenderer(renderer)

        # Setup rendering check
        renderchecker = QgsMultiRenderChecker()
        renderchecker.setMapSettings(self.mapsettings)
        renderchecker.setControlName('expected_geometry_part_count')
        result = renderchecker.runTest('part_geometry_part_count')

        self.assertTrue(result)
    def testSymbolColor(self):
        # Create rulebased style
        sym1 = QgsFillSymbol.createSimple({"color": "#ff0000"})

        renderer = QgsSingleSymbolRenderer(sym1)
        renderer.symbols()[0].symbolLayers()[0].setDataDefinedProperty(
            "color", "set_color_part( @symbol_color, 'value', \"Value\" * 4)"
        )
        self.layer.setRenderer(renderer)

        # Setup rendering check
        renderchecker = QgsMultiRenderChecker()
        renderchecker.setMapSettings(self.mapsettings)
        renderchecker.setControlName("expected_symbol_color_variable")
        result = renderchecker.runTest("symbol_color_variable", 50)

        self.assertTrue(result)
    def testPartCount(self):
        # Create rulebased style
        sym1 = QgsFillSymbol.createSimple({"color": "#fdbf6f"})

        renderer = QgsSingleSymbolRenderer(sym1)
        renderer.symbols()[0].symbolLayers()[0].setDataDefinedProperty(
            "color", "color_rgb( (@geometry_part_count - 1) * 200, 0, 0 )"
        )
        self.layer.setRenderer(renderer)

        # Setup rendering check
        renderchecker = QgsMultiRenderChecker()
        renderchecker.setMapSettings(self.mapsettings)
        renderchecker.setControlName("expected_geometry_part_count")
        result = renderchecker.runTest("part_geometry_part_count")

        self.assertTrue(result)
class TestQgsSingleSymbolRenderer(unittest.TestCase):

    def setUp(self):
        self.iface = get_iface()
        myShpFile = os.path.join(TEST_DATA_DIR, 'polys_overlapping.shp')
        layer = QgsVectorLayer(myShpFile, 'Polys', 'ogr')
        QgsProject.instance().addMapLayer(layer)

        # Create rulebased style
        sym1 = QgsFillSymbol.createSimple({'color': '#fdbf6f', 'outline_color': 'black'})

        self.renderer = QgsSingleSymbolRenderer(sym1)
        layer.setRenderer(self.renderer)

        rendered_layers = [layer]
        self.mapsettings = self.iface.mapCanvas().mapSettings()
        self.mapsettings.setOutputSize(QSize(400, 400))
        self.mapsettings.setOutputDpi(96)
        self.mapsettings.setExtent(QgsRectangle(-163, 22, -70, 52))
        self.mapsettings.setLayers(rendered_layers)

    def testOrderBy(self):
        self.renderer.setOrderBy(QgsFeatureRequest.OrderBy([QgsFeatureRequest.OrderByClause('Value', False)]))
        self.renderer.setOrderByEnabled(True)

        # Setup rendering check
        renderchecker = QgsMultiRenderChecker()
        renderchecker.setMapSettings(self.mapsettings)
        renderchecker.setControlName('expected_singlesymbol_orderby')
        self.assertTrue(renderchecker.runTest('singlesymbol_orderby'))

        # disable order by and retest
        self.renderer.setOrderByEnabled(False)
        self.assertTrue(renderchecker.runTest('single'))
    def setUp(self):
        self.iface = get_iface()
        myShpFile = os.path.join(TEST_DATA_DIR, 'polys_overlapping.shp')
        layer = QgsVectorLayer(myShpFile, 'Polys', 'ogr')
        QgsProject.instance().addMapLayer(layer)

        # Create rulebased style
        sym1 = QgsFillSymbol.createSimple({'color': '#fdbf6f', 'outline_color': 'black'})

        self.renderer = QgsSingleSymbolRenderer(sym1)
        layer.setRenderer(self.renderer)

        rendered_layers = [layer]
        self.mapsettings = self.iface.mapCanvas().mapSettings()
        self.mapsettings.setOutputSize(QSize(400, 400))
        self.mapsettings.setOutputDpi(96)
        self.mapsettings.setExtent(QgsRectangle(-163, 22, -70, 52))
        self.mapsettings.setLayers(rendered_layers)
    def _setUp(self):
        myShpFile = os.path.join(TEST_DATA_DIR, 'points.shp')
        layer = QgsVectorLayer(myShpFile, 'Points', 'ogr')
        QgsProject.instance().addMapLayer(layer)

        renderer = QgsPointDisplacementRenderer()
        sym1 = QgsMarkerSymbol.createSimple({'color': '#ff00ff', 'size': '3', 'outline_style': 'no'})
        sym_renderer = QgsSingleSymbolRenderer(sym1)
        renderer.setEmbeddedRenderer(sym_renderer)
        renderer.setCircleRadiusAddition(2)
        renderer.setCircleWidth(1)
        renderer.setCircleColor(QColor(0, 0, 0))
        renderer.setCenterSymbol(QgsMarkerSymbol.createSimple({'color': '#ffff00', 'size': '3', 'outline_style': 'no'}))
        layer.setRenderer(renderer)

        rendered_layers = [layer]
        mapsettings = QgsMapSettings()
        mapsettings.setOutputSize(QSize(400, 400))
        mapsettings.setOutputDpi(96)
        mapsettings.setExtent(QgsRectangle(-123, 18, -70, 52))
        mapsettings.setLayers(rendered_layers)
        return layer, renderer, mapsettings
Пример #8
0
 def test_point_ordered_symbol_bound_offset(self):
     # Test ordered placements for point using symbol bounds offset
     self.layer = TestQgsPalLabeling.loadFeatureLayer(
         'point_ordered_placement')
     # Make a big symbol
     symbol = QgsMarkerSymbol.createSimple({
         'color': '31,120,180,255',
         'outline_color': '0,0,0,0',
         'outline_style': 'solid',
         'size': '10',
         'name': 'rectangle',
         'size_unit': 'MM'
     })
     renderer = QgsSingleSymbolRenderer(symbol)
     self.layer.setRenderer(renderer)
     self._TestMapSettings = self.cloneMapSettings(self._MapSettings)
     self.lyr.placement = QgsPalLayerSettings.OrderedPositionsAroundPoint
     self.lyr.dist = 2
     self.lyr.offsetType = QgsPalLayerSettings.FromSymbolBounds
     self.checkTest()
     self.removeMapLayer(self.layer)
     self.layer = None
Пример #9
0
    def testInitialSizeSymbolMapUnits(self):
        """Test initial size of legend with a symbol size in map units"""

        point_path = os.path.join(TEST_DATA_DIR, 'points.shp')
        point_layer = QgsVectorLayer(point_path, 'points', 'ogr')
        QgsProject.instance().addMapLayers([point_layer])

        marker_symbol = QgsMarkerSymbol.createSimple({'color': '#ff0000', 'outline_style': 'no', 'size': '5', 'size_unit': 'MapUnit'})

        point_layer.setRenderer(QgsSingleSymbolRenderer(marker_symbol))

        s = QgsMapSettings()
        s.setLayers([point_layer])
        layout = QgsLayout(QgsProject.instance())
        layout.initializeDefaults()

        map = QgsLayoutItemMap(layout)
        map.attemptSetSceneRect(QRectF(20, 20, 80, 80))
        map.setFrameEnabled(True)
        map.setLayers([point_layer])
        layout.addLayoutItem(map)
        map.setExtent(point_layer.extent())

        legend = QgsLayoutItemLegend(layout)
        legend.attemptSetSceneRect(QRectF(120, 20, 80, 80))
        legend.setFrameEnabled(True)
        legend.setFrameStrokeWidth(QgsLayoutMeasurement(2))
        legend.setBackgroundColor(QColor(200, 200, 200))
        legend.setTitle('')
        layout.addLayoutItem(legend)
        legend.setMap(map)

        checker = QgsLayoutChecker(
            'composer_legend_mapunits', layout)
        checker.setControlPathPrefix("composer_legend")
        result, message = checker.testLayout()
        self.assertTrue(result, message)

        QgsProject.instance().removeMapLayers([point_layer.id()])
Пример #10
0
    def test_multiple_masks_same_symbol_layer(self):
        """Test multiple masks that occlude the same symbol layer"""
        #
        # 1. a symbol layer mask
        #
        p = QgsMarkerSymbol.createSimple({'color': '#fdbf6f', 'size': "7"})
        self.points_layer.setRenderer(QgsSingleSymbolRenderer(p))

        circle_symbol = QgsMarkerSymbol.createSimple({'size': '10'})
        mask_layer = QgsMaskMarkerSymbolLayer()
        mask_layer.setSubSymbol(circle_symbol)
        mask_layer.setMasks([
            # the black part of roads
            QgsSymbolLayerReference(self.lines_layer.id(),
                                    QgsSymbolLayerId("", 0)),
        ])
        # add this mask layer to the point layer
        self.points_layer.renderer().symbol().appendSymbolLayer(mask_layer)

        #
        # 2. a label mask
        #

        # modify labeling settings
        label_settings = self.polys_layer.labeling().settings()
        fmt = label_settings.format()
        # enable a mask
        fmt.mask().setEnabled(True)
        fmt.mask().setSize(4.0)
        # and mask other symbol layers underneath
        fmt.mask().setMaskedSymbolLayers([
            # the black part of roads
            QgsSymbolLayerReference(self.lines_layer.id(),
                                    QgsSymbolLayerId("", 0))
        ])
        label_settings.setFormat(fmt)
        self.polys_layer.labeling().setSettings(label_settings)

        self.check_renderings(self.map_settings, "multiple_masks_same_sl")
Пример #11
0
    def testInitialSizeSymbolMapUnits(self):
        """Test initial size of legend with a symbol size in map units"""

        point_path = os.path.join(TEST_DATA_DIR, 'points.shp')
        point_layer = QgsVectorLayer(point_path, 'points', 'ogr')
        QgsProject.instance().addMapLayers([point_layer])

        marker_symbol = QgsMarkerSymbol.createSimple({'color': '#ff0000', 'outline_style': 'no', 'size': '5', 'size_unit': 'MapUnit'})

        point_layer.setRenderer(QgsSingleSymbolRenderer(marker_symbol))

        s = QgsMapSettings()
        s.setLayers([point_layer])
        composition = QgsComposition(QgsProject.instance())
        composition.setPaperSize(297, 210)

        composer_map = QgsComposerMap(composition, 20, 20, 80, 80)
        composer_map.setFrameEnabled(True)
        composer_map.setLayers([point_layer])
        composition.addComposerMap(composer_map)
        composer_map.setNewExtent(point_layer.extent())

        legend = QgsComposerLegend(composition)
        legend.setSceneRect(QRectF(120, 20, 80, 80))
        legend.setFrameEnabled(True)
        legend.setFrameStrokeWidth(2)
        legend.setBackgroundColor(QColor(200, 200, 200))
        legend.setTitle('')
        composition.addComposerLegend(legend)
        legend.setComposerMap(composer_map)

        checker = QgsCompositionChecker(
            'composer_legend_mapunits', composition)
        checker.setControlPathPrefix("composer_legend")
        result, message = checker.testComposition()
        self.assertTrue(result, message)

        QgsProject.instance().removeMapLayers([point_layer.id()])
    def testSingleLines(self):
        source = QgsVectorLayer(os.path.join(TEST_DATA_DIR, 'lines_touching.shp'))
        self.assertTrue(source.isValid())
        map_settings = QgsMapSettings()
        map_settings.setExtent(source.extent().buffered(2))
        map_settings.setDestinationCrs(source.crs())
        map_settings.setLayers([source])

        layer = QgsSimpleLineSymbolLayer()
        layer.setColor(QColor(0, 0, 0))
        layer.setWidth(1)
        symbol = QgsLineSymbol([layer])

        layer2 = QgsMarkerLineSymbolLayer()
        layer2.setPlacement(QgsTemplatedLineSymbolLayerBase.FirstVertex)
        marker = QgsMarkerSymbol.createSimple({'size': '4', 'color': '255,0,0', 'outline_style': 'no'})
        layer2.setSubSymbol(marker)
        symbol.appendSymbolLayer(layer2)

        sub_renderer = QgsSingleSymbolRenderer(symbol)
        source.setRenderer(QgsMergedFeatureRenderer(sub_renderer))

        self.assertTrue(self.imageCheck('lines_single_subrenderer', 'lines_single_subrenderer', map_settings))
Пример #13
0
        def addFlowLayerLineWidth(layerpath,
                                  fieldname,
                                  colour,
                                  transparent,
                                  layername,
                                  widthscale=1):
            vlayer = QgsVectorLayer(layerpath, layername, "ogr")
            if not vlayer.isValid():
                feedback.pushInfo("Layer failed to load: " + layerpath)
            else:
                context.temporaryLayerStore().addMapLayer(vlayer)

                maxvalue = getMaxValue(vlayer, fieldname)

                symbol = QgsLineSymbol.createSimple({
                    'color': colour,
                    'size': '1'
                })
                objTransf = QgsSizeScaleTransformer(
                    QgsSizeScaleTransformer.Flannery,
                    0,  #minvalue
                    maxvalue,  #maxvalue
                    0.1,  #minsize
                    5 * widthscale,  #maxsize
                    0,  #nullsize
                    1)  #exponent
                objProp = QgsProperty()
                objProp.setField(fieldname)
                objProp.setTransformer(objTransf)
                symbol.setDataDefinedWidth(objProp)

                renderer = QgsSingleSymbolRenderer(symbol)
                vlayer.setRenderer(renderer)
                vlayer.setOpacity(1 - transparent)

                project.addMapLayer(vlayer)
                feedback.pushInfo("Loaded " + layerpath)
Пример #14
0
def SetDefaultPointStyle(layer):
    ''' Point Symbol '''
    style = S.getDrawingPoint()
    symbol = QgsMarkerSymbol.createSimple({
        'name': style["NAME"],
        'line_color': style["LINE_COLOR"],
        'line_width': style["LINE_WIDTH"],
        'size': style["SIZE"]
    })

    renderer = QgsSingleSymbolRenderer(symbol)
    layer.setRenderer(renderer)

    layer_settings = QgsPalLayerSettings()
    text_format = QgsTextFormat()

    text_format.setFont(QFont(style["LABEL_FONT"], style["LABEL_FONT_SIZE"]))
    text_format.setColor(QColor(style["LABEL_FONT_COLOR"]))
    text_format.setSize(style["LABEL_SIZE"])

    buffer_settings = QgsTextBufferSettings()
    buffer_settings.setEnabled(True)
    buffer_settings.setSize(1)
    buffer_settings.setColor(QColor(style["LABEL_BUFFER_COLOR"]))

    text_format.setBuffer(buffer_settings)
    layer_settings.setFormat(text_format)

    layer_settings.fieldName = "number"
    layer_settings.placement = 2
    layer_settings.enabled = True

    layer_settings = QgsVectorLayerSimpleLabeling(layer_settings)
    layer.setLabelsEnabled(True)
    layer.setLabeling(layer_settings)

    return
    def style_curves(self):
        registry = QgsApplication.symbolLayerRegistry()
        symbol_props = {
            'name': 'cross2',
            'color': '0,0,0',
            'color_border': '0,0,0',
            'offset': '0,0',
            'size': '1.5',
            'angle': '0',
        }
        opacity = 0.7
        cross = registry.symbolLayerMetadata("SimpleMarker").createSymbolLayer(
            symbol_props)
        # NOTE: Cross symbols rendered for OQ-Engine disaggregation outputs are
        # opaque, wider and thicker than those used for other outputs (e.g.
        # hcurves)
        if self.output_type == 'disagg':
            cross.setSize(3)
            cross.setStrokeWidth(0.5)
            opacity = 1
        symbol = QgsSymbol.defaultSymbol(self.layer.geometryType()).clone()
        symbol.deleteSymbolLayer(0)
        symbol.appendSymbolLayer(cross)
        renderer = QgsSingleSymbolRenderer(symbol)
        effect = QgsOuterGlowEffect()
        effect.setSpread(0.5)
        effect.setOpacity(opacity)
        effect.setColor(QColor(255, 255, 255))
        effect.setBlurLevel(1)

        renderer.paintEffect().appendEffect(effect)
        renderer.paintEffect().setEnabled(True)

        self.layer.setRenderer(renderer)
        self.layer.setOpacity(opacity)
        self.layer.triggerRepaint()

        # NOTE QGIS3: probably not needed
        # self.iface.layerTreeView().refreshLayerSymbology(self.layer.id())

        self.iface.mapCanvas().refresh()
Пример #16
0
class TestQgsSingleSymbolRenderer(unittest.TestCase):
    def setUp(self):
        self.iface = get_iface()
        myShpFile = os.path.join(TEST_DATA_DIR, 'polys_overlapping.shp')
        layer = QgsVectorLayer(myShpFile, 'Polys', 'ogr')
        QgsProject.instance().addMapLayer(layer)

        # Create rulebased style
        sym1 = QgsFillSymbol.createSimple({
            'color': '#fdbf6f',
            'outline_color': 'black'
        })

        self.renderer = QgsSingleSymbolRenderer(sym1)
        layer.setRenderer(self.renderer)

        rendered_layers = [layer]
        self.mapsettings = self.iface.mapCanvas().mapSettings()
        self.mapsettings.setOutputSize(QSize(400, 400))
        self.mapsettings.setOutputDpi(96)
        self.mapsettings.setExtent(QgsRectangle(-163, 22, -70, 52))
        self.mapsettings.setLayers(rendered_layers)

    def testOrderBy(self):
        self.renderer.setOrderBy(
            QgsFeatureRequest.OrderBy(
                [QgsFeatureRequest.OrderByClause('Value', False)]))
        self.renderer.setOrderByEnabled(True)

        # Setup rendering check
        renderchecker = QgsMultiRenderChecker()
        renderchecker.setMapSettings(self.mapsettings)
        renderchecker.setControlName('expected_singlesymbol_orderby')
        self.assertTrue(renderchecker.runTest('singlesymbol_orderby'))

        # disable order by and retest
        self.renderer.setOrderByEnabled(False)
        self.assertTrue(renderchecker.runTest('single'))
Пример #17
0
def generateIsochrones(point,
                       profile,
                       costingOptions,
                       intervals,
                       colors,
                       basename,
                       overwrite=True):
    response = valhalla.isochrones(point, profile, costingOptions, intervals,
                                   colors)
    features = getFeaturesFromResponse(response)
    if costingOptions.get("shortest"):
        suffix = "km"
    else:
        suffix = "min"
    for interval, feature in zip(intervals[::-1], features):
        # FIXME: we should use the 'contour' property in the feature to be sure of the contour line that we are
        # drawing, but due to a bug in qgis json parser, this property appears to be always set to '0'
        layername = "{} {} - {}".format(interval, suffix, basename)
        try:
            # FIXME: we do not consider if there are several layers with the same name here
            existinglayer = QgsProject.instance().mapLayersByName(layername)[0]
            if overwrite:
                QgsProject.instance().removeMapLayer(existinglayer.id())
            else:
                raise OverwriteError(
                    tr("layer {layername} already exists and overwrite is {overwrite}"
                       ).format(layername=layername, overwrite=overwrite))
        except IndexError:
            LOG.debug("this layer was not found: {}".format(layername))

        layer = QgsVectorLayer(
            "Polygon?crs=epsg:4326&field=centerx:double&field=centery:double&field=interval:double",
            layername,
            "memory",
        )
        pr = layer.dataProvider()
        qgsfeature = QgsFeature()
        qgsfeature.setAttributes([point.x(), point.y(), interval])
        qgsfeature.setGeometry(feature.geometry())
        pr.addFeatures([qgsfeature])
        layer.updateExtents()
        QgsProject.instance().addMapLayer(layer)
        outlineColor = QColor(0, 0, 0)
        # Set opacity to 40% or 66 in hex (65% transparency)
        fillColor = QColor("#66" + feature["color"][1:])
        renderer = QgsSingleSymbolRenderer.defaultRenderer(
            QgsWkbTypes.PolygonGeometry)
        symbol = renderer.symbol()
        symbol.setColor(fillColor)
        symbol.symbolLayer(0).setStrokeColor(outlineColor)
        layer.setRenderer(renderer)

    # Add center of reachability
    center_point_layer_name = tr("Center of {basename}").format(
        basename=basename)
    try:
        existinglayer = QgsProject.instance().mapLayersByName(
            center_point_layer_name)[0]
        if overwrite:
            QgsProject.instance().removeMapLayer(existinglayer.id())
        else:
            raise OverwriteError(
                tr("layer {layername} already exists and overwrite is {overwrite}"
                   ).format(layername=center_point_layer_name,
                            overwrite=overwrite))
    except IndexError:
        LOG.debug(
            "this layer was not found: {}".format(center_point_layer_name))

    center_point = QgsVectorLayer(
        "Point?crs=epsg:4326",
        center_point_layer_name,
        "memory",
    )
    pr = center_point.dataProvider()
    qgsfeature = QgsFeature()
    qgsfeature.setGeometry(QgsGeometry.fromPointXY(point))
    pr.addFeatures([qgsfeature])
    # symbology
    path = ":/kadas/icons/pin_red"
    symbol = QgsSvgMarkerSymbolLayer(path)
    symbol.setSize(10)
    symbol.setVerticalAnchorPoint(QgsMarkerSymbolLayer.Bottom)
    center_point.renderer().symbol().changeSymbolLayer(0, symbol)
    QgsProject.instance().addMapLayer(center_point)
Пример #18
0
    def run(self):
        layer = self.iface.mapCanvas().currentLayer()

        layerHint = "\n\nPlease select a Vector layer of geometry type Line."

        if layer is None:
            QMessageBox.information(None, "Chinese Postman",
                                    "No layer selected." + layerHint)
            return

        if layer.type() != QgsMapLayer.VectorLayer:
            QMessageBox.information(
                None, "Chinese Postman",
                "The selected layer is not of type Vector." + layerHint)
            return

        if layer.geometryType() != QgsWkbTypes.LineGeometry:
            QMessageBox.information(
                None, "Chinese Postman",
                "The selected layer's geometry type is not Line. " +
                "Chinese Postman cannot work on Point or Polygon." + layerHint)
            return

        features = layer.selectedFeatures()
        if len(features) == 0:
            QMessageBox.information(
                None, "Chinese Postman",
                "Please select an area. The 'Select Features by Polygon' tool "
                + "works well for this.")
            return

        graph = build_graph(features)
        components = postman.graph_components(graph)
        if len(components) > 1:
            QMessageBox.information(
                None, "Chinese Postman",
                "Warning: the selected area contains multiple disconnected " +
                "components - only the largest one will be used.")

        if len(components) == 0:
            QMessageBox.information(
                None, "Chinese Postman",
                "Error: Could not find any components. Try selecting different features."
            )
            return

        component = components[0]

        eulerian_graph, nodes = postman.single_chinese_postman_path(component)

        in_length = postman.edge_sum(component) / 1000.0
        path_length = postman.edge_sum(eulerian_graph) / 1000.0
        duplicate_length = path_length - in_length

        newlayer = build_layer(eulerian_graph, nodes, layer.crs())
        symbol = build_symbol(newlayer)
        newlayer.setRenderer(QgsSingleSymbolRenderer(symbol))

        QgsProject.instance().addMapLayer(newlayer)

        info = ""
        info += "Total length of roads: %.3f km\n" % in_length
        info += "Total length of path: %.3f km\n" % path_length
        info += "Length of sections visited twice: %.3f km\n" % duplicate_length
        info += "\n"
        info += "(If the above values do not make sense, consider changing CRS.)\n"

        QMessageBox.information(None, "Chinese Postman", info)
Пример #19
0
    def testLegendRenderWithMapTheme(self):
        """Test rendering legends linked to map themes"""
        QgsProject.instance().removeAllMapLayers()

        point_path = os.path.join(TEST_DATA_DIR, 'points.shp')
        point_layer = QgsVectorLayer(point_path, 'points', 'ogr')
        line_path = os.path.join(TEST_DATA_DIR, 'lines.shp')
        line_layer = QgsVectorLayer(line_path, 'lines', 'ogr')
        QgsProject.instance().clear()
        QgsProject.instance().addMapLayers([point_layer, line_layer])

        marker_symbol = QgsMarkerSymbol.createSimple({
            'color': '#ff0000',
            'outline_style': 'no',
            'size': '5'
        })
        point_layer.setRenderer(QgsSingleSymbolRenderer(marker_symbol))
        point_layer.styleManager().addStyleFromLayer("red")

        line_symbol = QgsLineSymbol.createSimple({
            'color': '#ff0000',
            'line_width': '2'
        })
        line_layer.setRenderer(QgsSingleSymbolRenderer(line_symbol))
        line_layer.styleManager().addStyleFromLayer("red")

        red_record = QgsMapThemeCollection.MapThemeRecord()
        point_red_record = QgsMapThemeCollection.MapThemeLayerRecord(
            point_layer)
        point_red_record.usingCurrentStyle = True
        point_red_record.currentStyle = 'red'
        red_record.addLayerRecord(point_red_record)
        line_red_record = QgsMapThemeCollection.MapThemeLayerRecord(line_layer)
        line_red_record.usingCurrentStyle = True
        line_red_record.currentStyle = 'red'
        red_record.addLayerRecord(line_red_record)
        QgsProject.instance().mapThemeCollection().insert('red', red_record)

        marker_symbol1 = QgsMarkerSymbol.createSimple({
            'color': '#0000ff',
            'outline_style': 'no',
            'size': '5'
        })
        marker_symbol2 = QgsMarkerSymbol.createSimple({
            'color': '#0000ff',
            'name': 'diamond',
            'outline_style': 'no',
            'size': '5'
        })
        marker_symbol3 = QgsMarkerSymbol.createSimple({
            'color': '#0000ff',
            'name': 'rectangle',
            'outline_style': 'no',
            'size': '5'
        })

        point_layer.setRenderer(
            QgsCategorizedSymbolRenderer('Class', [
                QgsRendererCategory('B52', marker_symbol1, ''),
                QgsRendererCategory('Biplane', marker_symbol2, ''),
                QgsRendererCategory('Jet', marker_symbol3, ''),
            ]))
        point_layer.styleManager().addStyleFromLayer("blue")

        line_symbol = QgsLineSymbol.createSimple({
            'color': '#0000ff',
            'line_width': '2'
        })
        line_layer.setRenderer(QgsSingleSymbolRenderer(line_symbol))
        line_layer.styleManager().addStyleFromLayer("blue")

        blue_record = QgsMapThemeCollection.MapThemeRecord()
        point_blue_record = QgsMapThemeCollection.MapThemeLayerRecord(
            point_layer)
        point_blue_record.usingCurrentStyle = True
        point_blue_record.currentStyle = 'blue'
        blue_record.addLayerRecord(point_blue_record)
        line_blue_record = QgsMapThemeCollection.MapThemeLayerRecord(
            line_layer)
        line_blue_record.usingCurrentStyle = True
        line_blue_record.currentStyle = 'blue'
        blue_record.addLayerRecord(line_blue_record)
        QgsProject.instance().mapThemeCollection().insert('blue', blue_record)

        layout = QgsLayout(QgsProject.instance())
        layout.initializeDefaults()

        map1 = QgsLayoutItemMap(layout)
        map1.attemptSetSceneRect(QRectF(20, 20, 80, 80))
        map1.setFrameEnabled(True)
        map1.setLayers([point_layer, line_layer])
        layout.addLayoutItem(map1)
        map1.setExtent(point_layer.extent())
        map1.setFollowVisibilityPreset(True)
        map1.setFollowVisibilityPresetName('red')

        map2 = QgsLayoutItemMap(layout)
        map2.attemptSetSceneRect(QRectF(20, 120, 80, 80))
        map2.setFrameEnabled(True)
        map2.setLayers([point_layer, line_layer])
        layout.addLayoutItem(map2)
        map2.setExtent(point_layer.extent())
        map2.setFollowVisibilityPreset(True)
        map2.setFollowVisibilityPresetName('blue')

        legend = QgsLayoutItemLegend(layout)
        legend.setTitle("Legend")
        legend.attemptSetSceneRect(QRectF(120, 20, 80, 80))
        legend.setFrameEnabled(True)
        legend.setFrameStrokeWidth(QgsLayoutMeasurement(2))
        legend.setBackgroundColor(QColor(200, 200, 200))
        legend.setTitle('')
        layout.addLayoutItem(legend)
        legend.setLinkedMap(map1)

        legend2 = QgsLayoutItemLegend(layout)
        legend2.setTitle("Legend")
        legend2.attemptSetSceneRect(QRectF(120, 120, 80, 80))
        legend2.setFrameEnabled(True)
        legend2.setFrameStrokeWidth(QgsLayoutMeasurement(2))
        legend2.setBackgroundColor(QColor(200, 200, 200))
        legend2.setTitle('')
        layout.addLayoutItem(legend2)
        legend2.setLinkedMap(map2)

        checker = QgsLayoutChecker('composer_legend_theme', layout)
        checker.setControlPathPrefix("composer_legend")
        result, message = checker.testLayout()
        self.report += checker.report()
        self.assertTrue(result, message)

        QgsProject.instance().clear()
Пример #20
0
    def testRenderMultipleRenderersSelection(self):
        """
        Test that selection colors only apply to main renderer
        :return:
        """
        poly_layer = QgsVectorLayer(os.path.join(TEST_DATA_DIR, 'polys.shp'))
        self.assertTrue(poly_layer.isValid())
        poly_layer.selectAll()

        sym1 = QgsFillSymbol.createSimple({'color': '#ffaaff', 'outline_color': '#000000', 'outline_style': 'no'})
        renderer = QgsSingleSymbolRenderer(sym1)
        poly_layer.setRenderer(renderer)

        # add secondary renderer, for rendering below
        class Gen1(QgsFeatureRendererGenerator):

            def id(self):
                return 'Gen1'

            def level(self):
                return -2

            def createRenderer(self):
                renderer = QgsCategorizedSymbolRenderer()
                renderer.setClassAttribute('Name')

                sym1 = QgsFillSymbol.createSimple(
                    {'color': '#ffaaff', 'outline_color': '#33aa33', 'outline_width': '3'})
                sym2 = QgsFillSymbol.createSimple(
                    {'color': '#ffaaff', 'outline_color': '#aa33aa', 'outline_width': '3'})

                renderer.addCategory(QgsRendererCategory('Dam', sym1, 'Dam'))
                renderer.addCategory(QgsRendererCategory('Lake', sym2, 'Lake'))
                return renderer

        poly_layer.addFeatureRendererGenerator(Gen1())

        mapsettings = QgsMapSettings()
        mapsettings.setOutputSize(QSize(400, 400))
        mapsettings.setOutputDpi(96)
        mapsettings.setDestinationCrs(QgsCoordinateReferenceSystem('EPSG:3857'))
        mapsettings.setExtent(QgsRectangle(-13875783.2, 2266009.4, -8690110.7, 6673344.5))
        mapsettings.setLayers([poly_layer])

        renderchecker = QgsMultiRenderChecker()
        renderchecker.setMapSettings(mapsettings)
        renderchecker.setControlPathPrefix('vectorlayerrenderer')
        renderchecker.setControlName('expected_multiple_renderers_selection')
        result = renderchecker.runTest('expected_multiple_renderers_selection')
        self.report += renderchecker.report()
        self.assertTrue(result)

        # also try with symbol levels
        renderer.setUsingSymbolLevels(True)
        poly_layer.setRenderer(renderer)

        renderchecker = QgsMultiRenderChecker()
        renderchecker.setMapSettings(mapsettings)
        renderchecker.setControlPathPrefix('vectorlayerrenderer')
        renderchecker.setControlName('expected_multiple_renderers_selection')
        result = renderchecker.runTest('expected_multiple_renderers_selection')
        self.report += renderchecker.report()
        self.assertTrue(result)
Пример #21
0
    def testMapTheme(self):
        canvas = QgsMapCanvas()
        canvas.setDestinationCrs(QgsCoordinateReferenceSystem(4326))
        canvas.setFrameStyle(0)
        canvas.resize(600, 400)
        self.assertEqual(canvas.width(), 600)
        self.assertEqual(canvas.height(), 400)

        layer = QgsVectorLayer("Polygon?crs=epsg:4326&field=fldtxt:string",
                               "layer", "memory")
        # add a polygon to layer
        f = QgsFeature()
        f.setGeometry(QgsGeometry.fromRect(QgsRectangle(5, 25, 25, 45)))
        self.assertTrue(layer.dataProvider().addFeatures([f]))

        # create a style
        sym1 = QgsFillSymbol.createSimple({'color': '#ffb200'})
        renderer = QgsSingleSymbolRenderer(sym1)
        layer.setRenderer(renderer)

        canvas.setLayers([layer])
        canvas.setExtent(QgsRectangle(10, 30, 20, 35))
        canvas.show()

        # need to wait until first redraw can occur (note that we first need to wait till drawing starts!)
        while not canvas.isDrawing():
            app.processEvents()
        canvas.waitWhileRendering()
        self.assertTrue(self.canvasImageCheck('theme1', 'theme1', canvas))

        # add some styles
        layer.styleManager().addStyleFromLayer('style1')
        sym2 = QgsFillSymbol.createSimple({'color': '#00b2ff'})
        renderer2 = QgsSingleSymbolRenderer(sym2)
        layer.setRenderer(renderer2)
        layer.styleManager().addStyleFromLayer('style2')

        canvas.refresh()
        canvas.waitWhileRendering()
        self.assertTrue(self.canvasImageCheck('theme2', 'theme2', canvas))

        layer.styleManager().setCurrentStyle('style1')
        canvas.refresh()
        canvas.waitWhileRendering()
        self.assertTrue(self.canvasImageCheck('theme1', 'theme1', canvas))

        # ok, so all good with setting/rendering map styles
        # try setting canvas to a particular theme

        # make some themes...
        theme1 = QgsMapThemeCollection.MapThemeRecord()
        record1 = QgsMapThemeCollection.MapThemeLayerRecord(layer)
        record1.currentStyle = 'style1'
        record1.usingCurrentStyle = True
        theme1.setLayerRecords([record1])

        theme2 = QgsMapThemeCollection.MapThemeRecord()
        record2 = QgsMapThemeCollection.MapThemeLayerRecord(layer)
        record2.currentStyle = 'style2'
        record2.usingCurrentStyle = True
        theme2.setLayerRecords([record2])

        QgsProject.instance().mapThemeCollection().insert('theme1', theme1)
        QgsProject.instance().mapThemeCollection().insert('theme2', theme2)

        canvas.setTheme('theme2')
        canvas.refresh()
        canvas.waitWhileRendering()
        self.assertTrue(self.canvasImageCheck('theme2', 'theme2', canvas))

        canvas.setTheme('theme1')
        canvas.refresh()
        canvas.waitWhileRendering()
        self.assertTrue(self.canvasImageCheck('theme1', 'theme1', canvas))

        # add another layer
        layer2 = QgsVectorLayer("Polygon?crs=epsg:4326&field=fldtxt:string",
                                "layer2", "memory")
        f = QgsFeature()
        f.setGeometry(QgsGeometry.fromRect(QgsRectangle(5, 25, 25, 45)))
        self.assertTrue(layer2.dataProvider().addFeatures([f]))

        # create a style
        sym1 = QgsFillSymbol.createSimple({'color': '#b2ff00'})
        renderer = QgsSingleSymbolRenderer(sym1)
        layer2.setRenderer(renderer)

        # rerender canvas - should NOT show new layer
        canvas.refresh()
        canvas.waitWhileRendering()
        self.assertTrue(self.canvasImageCheck('theme1', 'theme1', canvas))
        # test again - this time refresh all layers
        canvas.refreshAllLayers()
        canvas.waitWhileRendering()
        self.assertTrue(self.canvasImageCheck('theme1', 'theme1', canvas))

        # add layer 2 to theme1
        record3 = QgsMapThemeCollection.MapThemeLayerRecord(layer2)
        theme1.setLayerRecords([record3])
        QgsProject.instance().mapThemeCollection().update('theme1', theme1)

        canvas.refresh()
        canvas.waitWhileRendering()
        self.assertTrue(self.canvasImageCheck('theme3', 'theme3', canvas))

        # change the appearance of an active style
        layer2.styleManager().addStyleFromLayer('original')
        layer2.styleManager().addStyleFromLayer('style4')
        record3.currentStyle = 'style4'
        record3.usingCurrentStyle = True
        theme1.setLayerRecords([record3])
        QgsProject.instance().mapThemeCollection().update('theme1', theme1)

        canvas.refresh()
        canvas.waitWhileRendering()
        self.assertTrue(self.canvasImageCheck('theme3', 'theme3', canvas))

        layer2.styleManager().setCurrentStyle('style4')
        sym3 = QgsFillSymbol.createSimple({'color': '#b200b2'})
        layer2.renderer().setSymbol(sym3)
        canvas.refresh()
        canvas.waitWhileRendering()
        self.assertTrue(self.canvasImageCheck('theme4', 'theme4', canvas))

        # try setting layers while a theme is in place
        canvas.setLayers([layer])
        canvas.refresh()

        # should be no change... setLayers should be ignored if canvas is following a theme!
        canvas.waitWhileRendering()
        self.assertTrue(self.canvasImageCheck('theme4', 'theme4', canvas))

        # setLayerStyleOverrides while theme is in place
        canvas.setLayerStyleOverrides({layer2.id(): 'original'})
        # should be no change... setLayerStyleOverrides should be ignored if canvas is following a theme!
        canvas.refresh()
        canvas.waitWhileRendering()
        self.assertTrue(self.canvasImageCheck('theme4', 'theme4', canvas))

        # clear theme
        canvas.setTheme('')
        canvas.refresh()
        canvas.waitWhileRendering()
        # should be different - we should now render project layers
        self.assertFalse(self.canvasImageCheck('theme4', 'theme4', canvas))
Пример #22
0
    def setStyle(self, layer, name):
        if name == "":
            return
        stylePath = os.path.join(os.path.dirname(os.path.dirname(__file__)),
                                 "layerStyles")

        # user style
        qmlPath = os.path.join(stylePath, name + "_user.qml")
        if os.path.exists(qmlPath):
            layer.loadNamedStyle(qmlPath)
            return

        # default style
        qmlPath = os.path.join(stylePath, name + ".qml.bak")
        if os.path.exists(qmlPath):
            layer.loadNamedStyle(qmlPath)
        svgPath = os.path.join(stylePath, name + ".svg")
        if os.path.exists(svgPath):
            if layer.geometryType() == 0:  # Point
                svg_style = dict()
                svg_style['name'] = svgPath
                svg_style['size'] = str(7)
                if name == "demands":
                    svg_style['fill'] = '#9a1313'
                symbol_layer = QgsSvgMarkerSymbolLayer.create(svg_style)
                symbol = QgsSymbol.defaultSymbol(layer.geometryType())
                symbol.changeSymbolLayer(0, symbol_layer)
                renderer = QgsSingleSymbolRenderer(symbol)
            else:  # Line
                symbol = QgsLineSymbol().createSimple({})
                symbol.deleteSymbolLayer(0)
                # Line
                lineSymbol = QgsSimpleLineSymbolLayer()
                lineSymbol.setWidthUnit(2)  # Pixels
                lineSymbol.setWidth(1.5)
                if name == "pipes":
                    lineSymbol.setColor(QColor("#0f1291"))
                symbol.appendSymbolLayer(lineSymbol)
                # Symbol
                marker = QgsMarkerSymbol.createSimple({})
                marker.deleteSymbolLayer(0)
                svg_props = dict()
                svg_props['name'] = svgPath
                size = 5
                if name == "pipes":
                    size = 0
                svg_props['size'] = str(size)
                svg_props['offset'] = '-0.5,-0.5'
                svg_props['offset_unit'] = 'Pixel'
                markerSymbol = QgsSvgMarkerSymbolLayer.create(svg_props)
                marker.appendSymbolLayer(markerSymbol)
                # Final Symbol
                finalMarker = QgsMarkerLineSymbolLayer()
                finalMarker.setSubSymbol(marker)
                finalMarker.setPlacement(QgsMarkerLineSymbolLayer.CentralPoint)
                symbol.appendSymbolLayer(finalMarker)
                if name == "pipes":
                    prop = QgsProperty()
                    prop.setExpressionString(
                        "if(IniStatus is NULL, 0,if(IniStatus !='CV', 0,5))")
                    symbol.symbolLayer(1).setDataDefinedProperty(
                        9, prop)  # 9 = PropertyWidth
                renderer = QgsSingleSymbolRenderer(symbol)

            layer.setRenderer(renderer)
    def style_maps(layer,
                   style_by,
                   iface,
                   output_type='damages-rlzs',
                   perils=None,
                   add_null_class=False,
                   render_higher_on_top=False,
                   repaint=True,
                   use_sgc_style=False):
        symbol = QgsSymbol.defaultSymbol(layer.geometryType())
        # see properties at:
        # https://qgis.org/api/qgsmarkersymbollayerv2_8cpp_source.html#l01073
        symbol.setOpacity(1)
        if isinstance(symbol, QgsMarkerSymbol):
            # do it only for the layer with points
            symbol.symbolLayer(0).setStrokeStyle(Qt.PenStyle(Qt.NoPen))

        style = get_style(layer, iface.messageBar())

        # this is the default, as specified in the user settings
        ramp = QgsGradientColorRamp(style['color_from'], style['color_to'])
        style_mode = style['style_mode']

        # in most cases, we override the user-specified setting, and use
        # instead a setting that was required by scientists
        if output_type in OQ_TO_LAYER_TYPES:
            default_qgs_style = QgsStyle().defaultStyle()
            default_color_ramp_names = default_qgs_style.colorRampNames()
            if output_type in (
                    'damages-rlzs',
                    'avg_losses-rlzs',
                    'avg_losses-stats',
            ):
                # options are EqualInterval, Quantile, Jenks, StdDev, Pretty
                # jenks = natural breaks
                if Qgis.QGIS_VERSION_INT < 31000:
                    style_mode = QgsGraduatedSymbolRenderer.Jenks
                else:
                    style_mode = 'Jenks'
                ramp_type_idx = default_color_ramp_names.index('Reds')
                symbol.setColor(QColor(RAMP_EXTREME_COLORS['Reds']['top']))
                inverted = False
            elif (output_type in ('gmf_data', 'ruptures')
                  or (output_type == 'hmaps' and not use_sgc_style)):
                # options are EqualInterval, Quantile, Jenks, StdDev, Pretty
                # jenks = natural breaks
                if output_type == 'ruptures':
                    if Qgis.QGIS_VERSION_INT < 31000:
                        style_mode = QgsGraduatedSymbolRenderer.Pretty
                    else:
                        style_mode = 'PrettyBreaks'
                else:
                    if Qgis.QGIS_VERSION_INT < 31000:
                        style_mode = QgsGraduatedSymbolRenderer.EqualInterval
                    else:
                        style_mode = 'EqualInterval'
                ramp_type_idx = default_color_ramp_names.index('Spectral')
                inverted = True
                symbol.setColor(QColor(RAMP_EXTREME_COLORS['Reds']['top']))
            elif output_type == 'hmaps' and use_sgc_style:
                # FIXME: for SGC they were using size 10000 map units

                # options are EqualInterval, Quantile, Jenks, StdDev, Pretty
                # jenks = natural breaks
                if Qgis.QGIS_VERSION_INT < 31000:
                    style_mode = QgsGraduatedSymbolRenderer.Pretty
                else:
                    style_mode = 'PrettyBreaks'
                try:
                    ramp_type_idx = default_color_ramp_names.index(
                        'SGC_Green2Red_Hmap_Color_Ramp')
                except ValueError:
                    raise ValueError(
                        'Color ramp SGC_Green2Red_Hmap_Color_Ramp was '
                        'not found. Please import it from '
                        'Settings -> Style Manager, loading '
                        'svir/resources/sgc_green2red_hmap_color_ramp.xml')
                inverted = False
                registry = QgsApplication.symbolLayerRegistry()
                symbol_props = {
                    'name': 'square',
                    'color': '0,0,0',
                    'color_border': '0,0,0',
                    'offset': '0,0',
                    'size': '1.5',  # FIXME
                    'angle': '0',
                }
                square = registry.symbolLayerMetadata(
                    "SimpleMarker").createSymbolLayer(symbol_props)
                symbol = QgsSymbol.defaultSymbol(layer.geometryType()).clone()
                symbol.deleteSymbolLayer(0)
                symbol.appendSymbolLayer(square)
                symbol.symbolLayer(0).setStrokeStyle(Qt.PenStyle(Qt.NoPen))
            elif output_type in ['asset_risk', 'input']:
                # options are EqualInterval, Quantile, Jenks, StdDev, Pretty
                # jenks = natural breaks
                if Qgis.QGIS_VERSION_INT < 31000:
                    style_mode = QgsGraduatedSymbolRenderer.EqualInterval
                else:
                    style_mode = 'EqualInterval'
                # exposure_strings = ['number', 'occupants', 'value']
                # setting exposure colors by default
                colors = {
                    'single': RAMP_EXTREME_COLORS['Blues']['top'],
                    'ramp_name': 'Blues'
                }
                inverted = False
                if output_type == 'asset_risk':
                    damage_strings = perils
                    for damage_string in damage_strings:
                        if damage_string in style_by:
                            colors = {
                                'single':
                                RAMP_EXTREME_COLORS['Spectral']['top'],
                                'ramp_name': 'Spectral'
                            }
                            inverted = True
                            break
                else:  # 'input'
                    colors = {
                        'single': RAMP_EXTREME_COLORS['Greens']['top'],
                        'ramp_name': 'Greens'
                    }
                    symbol.symbolLayer(0).setShape(
                        QgsSimpleMarkerSymbolLayerBase.Square)
                single_color = colors['single']
                ramp_name = colors['ramp_name']
                ramp_type_idx = default_color_ramp_names.index(ramp_name)
                symbol.setColor(QColor(single_color))
            else:
                raise NotImplementedError(
                    'Undefined color ramp for output type %s' % output_type)
            ramp = default_qgs_style.colorRamp(
                default_color_ramp_names[ramp_type_idx])
            if inverted:
                ramp.invert()
        # get unique values
        fni = layer.fields().indexOf(style_by)
        unique_values = layer.dataProvider().uniqueValues(fni)
        num_unique_values = len(unique_values - {NULL})
        if num_unique_values > 2:
            if Qgis.QGIS_VERSION_INT < 31000:
                renderer = QgsGraduatedSymbolRenderer.createRenderer(
                    layer, style_by, min(num_unique_values, style['classes']),
                    style_mode, symbol.clone(), ramp)
            else:
                renderer = QgsGraduatedSymbolRenderer(style_by, [])
                # NOTE: the following returns an instance of one of the
                #       subclasses of QgsClassificationMethod
                classification_method = \
                    QgsApplication.classificationMethodRegistry().method(
                        style_mode)
                renderer.setClassificationMethod(classification_method)
                renderer.updateColorRamp(ramp)
                renderer.updateSymbols(symbol.clone())
                renderer.updateClasses(
                    layer, min(num_unique_values, style['classes']))
            if not use_sgc_style:
                if Qgis.QGIS_VERSION_INT < 31000:
                    label_format = renderer.labelFormat()
                    # NOTE: the following line might be useful
                    # label_format.setTrimTrailingZeroes(True)
                    label_format.setPrecision(2)
                    renderer.setLabelFormat(label_format, updateRanges=True)
                else:
                    renderer.classificationMethod().setLabelPrecision(2)
                    renderer.calculateLabelPrecision()
        elif num_unique_values == 2:
            categories = []
            for unique_value in unique_values:
                symbol = symbol.clone()
                try:
                    symbol.setColor(
                        QColor(RAMP_EXTREME_COLORS[ramp_name]
                               ['bottom' if unique_value ==
                                min(unique_values) else 'top']))
                except Exception:
                    symbol.setColor(
                        QColor(style['color_from'] if unique_value ==
                               min(unique_values) else style['color_to']))
                category = QgsRendererCategory(unique_value, symbol,
                                               str(unique_value))
                # entry for the list of category items
                categories.append(category)
            renderer = QgsCategorizedSymbolRenderer(style_by, categories)
        else:
            renderer = QgsSingleSymbolRenderer(symbol.clone())
        if add_null_class and NULL in unique_values:
            # add a class for NULL values
            rule_renderer = QgsRuleBasedRenderer(symbol.clone())
            root_rule = rule_renderer.rootRule()
            not_null_rule = root_rule.children()[0].clone()
            # strip parentheses from stringified color HSL
            not_null_rule.setFilterExpression(
                '%s IS NOT NULL' % QgsExpression.quotedColumnRef(style_by))
            not_null_rule.setLabel('%s:' % style_by)
            root_rule.appendChild(not_null_rule)
            null_rule = root_rule.children()[0].clone()
            null_rule.setSymbol(
                QgsFillSymbol.createSimple({
                    'color': '160,160,160',
                    'style': 'diagonal_x'
                }))
            null_rule.setFilterExpression(
                '%s IS NULL' % QgsExpression.quotedColumnRef(style_by))
            null_rule.setLabel(tr('No points'))
            root_rule.appendChild(null_rule)
            if isinstance(renderer, QgsGraduatedSymbolRenderer):
                # create value ranges
                rule_renderer.refineRuleRanges(not_null_rule, renderer)
                # remove default rule
            elif isinstance(renderer, QgsCategorizedSymbolRenderer):
                rule_renderer.refineRuleCategoris(not_null_rule, renderer)
            for rule in rule_renderer.rootRule().children()[1].children():
                label = rule.label()
                # by default, labels are like:
                # ('"collapse-structural-ASH_DRY_sum" >= 0.0000 AND
                # "collapse-structural-ASH_DRY_sum" <= 2.3949')
                first, second = label.split(" AND ")
                bottom = first.rsplit(" ", 1)[1]
                top = second.rsplit(" ", 1)[1]
                simplified = "%s - %s" % (bottom, top)
                rule.setLabel(simplified)
            root_rule.removeChildAt(0)
            renderer = rule_renderer
        if render_higher_on_top:
            renderer.setUsingSymbolLevels(True)
            symbol_items = [item for item in renderer.legendSymbolItems()]
            for i in range(len(symbol_items)):
                sym = symbol_items[i].symbol().clone()
                key = symbol_items[i].ruleKey()
                for lay in range(sym.symbolLayerCount()):
                    sym.symbolLayer(lay).setRenderingPass(i)
                renderer.setLegendSymbolItem(key, sym)
        layer.setRenderer(renderer)
        if not use_sgc_style:
            layer.setOpacity(0.7)
        if repaint:
            layer.triggerRepaint()
            iface.setActiveLayer(layer)
            iface.zoomToActiveLayer()
            # NOTE QGIS3: probably not needed
            # iface.layerTreeView().refreshLayerSymbology(layer.id())
            iface.mapCanvas().refresh()
Пример #24
0
    def testLegendRenderLinkedMapScale(self):
        """Test rendering legends linked to maps follow scale correctly"""
        QgsProject.instance().removeAllMapLayers()

        line_path = os.path.join(TEST_DATA_DIR, 'lines.shp')
        line_layer = QgsVectorLayer(line_path, 'lines', 'ogr')
        QgsProject.instance().clear()
        QgsProject.instance().addMapLayers([line_layer])

        line_symbol = QgsLineSymbol.createSimple({
            'color': '#ff0000',
            'width_unit': 'mapunits',
            'width': '0.0001'
        })
        line_layer.setRenderer(QgsSingleSymbolRenderer(line_symbol))

        layout = QgsLayout(QgsProject.instance())
        layout.initializeDefaults()

        map1 = QgsLayoutItemMap(layout)
        map1.attemptSetSceneRect(QRectF(20, 20, 80, 80))
        map1.setFrameEnabled(True)
        map1.setLayers([line_layer])
        layout.addLayoutItem(map1)
        map1.setExtent(line_layer.extent())
        map1.setScale(2000)

        map2 = QgsLayoutItemMap(layout)
        map2.attemptSetSceneRect(QRectF(20, 120, 80, 80))
        map2.setFrameEnabled(True)
        map2.setLayers([line_layer])
        layout.addLayoutItem(map2)
        map2.setExtent(line_layer.extent())
        map2.setScale(5000)

        legend = QgsLayoutItemLegend(layout)
        legend.setTitle("Legend")
        legend.attemptSetSceneRect(QRectF(120, 20, 80, 80))
        legend.setFrameEnabled(True)
        legend.setFrameStrokeWidth(QgsLayoutMeasurement(2))
        legend.setBackgroundColor(QColor(200, 200, 200))
        legend.setTitle('')
        layout.addLayoutItem(legend)
        legend.setLinkedMap(map1)

        legend2 = QgsLayoutItemLegend(layout)
        legend2.setTitle("Legend")
        legend2.attemptSetSceneRect(QRectF(120, 120, 80, 80))
        legend2.setFrameEnabled(True)
        legend2.setFrameStrokeWidth(QgsLayoutMeasurement(2))
        legend2.setBackgroundColor(QColor(200, 200, 200))
        legend2.setTitle('')
        layout.addLayoutItem(legend2)
        legend2.setLinkedMap(map2)

        checker = QgsLayoutChecker('composer_legend_scale_map', layout)
        checker.setControlPathPrefix("composer_legend")
        result, message = checker.testLayout()
        TestQgsLayoutItemLegend.report += checker.report()
        self.assertTrue(result, message)

        QgsProject.instance().clear()
Пример #25
0
    def testCase(self):
        self.TEST_DATA_DIR = unitTestDataPath()
        tmppath = tempfile.mkdtemp()
        for file in glob.glob(
                os.path.join(self.TEST_DATA_DIR, 'france_parts.*')):
            shutil.copy(os.path.join(self.TEST_DATA_DIR, file), tmppath)
        vectorFileInfo = QFileInfo(tmppath + "/france_parts.shp")
        mVectorLayer = QgsVectorLayer(vectorFileInfo.filePath(),
                                      vectorFileInfo.completeBaseName(), "ogr")

        QgsMapLayerRegistry.instance().addMapLayers([mVectorLayer])

        # create composition with composer map
        self.mapSettings = QgsMapSettings()
        layerStringList = []
        layerStringList.append(mVectorLayer.id())
        self.mapSettings.setLayers(layerStringList)
        self.mapSettings.setCrsTransformEnabled(True)
        self.mapSettings.setMapUnits(QgsUnitTypes.DistanceMeters)

        # select epsg:2154
        crs = QgsCoordinateReferenceSystem()
        crs.createFromSrid(2154)
        self.mapSettings.setDestinationCrs(crs)

        self.mComposition = QgsComposition(self.mapSettings)
        self.mComposition.setPaperSize(297, 210)

        # fix the renderer, fill with green
        props = {"color": "0,127,0"}
        fillSymbol = QgsFillSymbol.createSimple(props)
        renderer = QgsSingleSymbolRenderer(fillSymbol)
        mVectorLayer.setRenderer(renderer)

        # the atlas map
        self.mAtlasMap = QgsComposerMap(self.mComposition, 20, 20, 130, 130)
        self.mAtlasMap.setFrameEnabled(True)
        self.mComposition.addComposerMap(self.mAtlasMap)

        # the atlas
        self.mAtlas = self.mComposition.atlasComposition()
        self.mAtlas.setCoverageLayer(mVectorLayer)
        self.mAtlas.setEnabled(True)
        self.mComposition.setAtlasMode(QgsComposition.ExportAtlas)

        # an overview
        mOverview = QgsComposerMap(self.mComposition, 180, 20, 50, 50)
        mOverview.setFrameEnabled(True)
        mOverview.overview().setFrameMap(self.mAtlasMap.id())
        self.mComposition.addComposerMap(mOverview)
        nextent = QgsRectangle(49670.718, 6415139.086, 699672.519, 7065140.887)
        mOverview.setNewExtent(nextent)

        # set the fill symbol of the overview map
        props2 = {"color": "127,0,0,127"}
        fillSymbol2 = QgsFillSymbol.createSimple(props2)
        mOverview.overview().setFrameSymbol(fillSymbol2)

        # header label
        self.mLabel1 = QgsComposerLabel(self.mComposition)
        self.mComposition.addComposerLabel(self.mLabel1)
        self.mLabel1.setText("[% \"NAME_1\" %] area")
        self.mLabel1.setFont(QgsFontUtils.getStandardTestFont())
        self.mLabel1.adjustSizeToText()
        self.mLabel1.setSceneRect(QRectF(150, 5, 60, 15))

        qWarning(
            "header label font: %s exactMatch:%s" %
            (self.mLabel1.font().toString(), self.mLabel1.font().exactMatch()))

        # feature number label
        self.mLabel2 = QgsComposerLabel(self.mComposition)
        self.mComposition.addComposerLabel(self.mLabel2)
        self.mLabel2.setText(
            "# [%@atlas_featurenumber || ' / ' || @atlas_totalfeatures%]")
        self.mLabel2.setFont(QgsFontUtils.getStandardTestFont())
        self.mLabel2.adjustSizeToText()
        self.mLabel2.setSceneRect(QRectF(150, 200, 60, 15))

        qWarning(
            "feature number label font: %s exactMatch:%s" %
            (self.mLabel2.font().toString(), self.mLabel2.font().exactMatch()))

        self.filename_test()
        self.autoscale_render_test()
        self.fixedscale_render_test()
        self.predefinedscales_render_test()
        self.hidden_render_test()
        self.legend_test()

        shutil.rmtree(tmppath, True)
Пример #26
0
    def download(self, url):

        # Test if permalink is valid
        pattern = r"^(https?:\/\/(\w+[\w\-\.\:\/])+)\?((\&+)?(\w+)\=?([\w\-\.\:\,]+?)?)+(\&+)?$"
        if not re.match(pattern, self.url):
            raise Exception("Le permalien n'est pas valide.")

        # Extract params from url
        params = parse_qs(urlparse(self.url).query)

        # Check mandatory parameters
        try:
            context = str(params[r"context"][0])
            center = params[r"centre"][0]
        except:
            raise Exception(
                "Les paramètres \'Context\' et \'Centre\' sont obligatoires.")

        auth_contexts = [
            r"metropole", r"guadeloupe", r"stmartin", r"stbarthelemy",
            r"guyane", r"reunion", r"mayotte", r"martinique"
        ]

        # Check scale parameter
        try:
            scale = int(params[r"echelle"][0])
        except:
            raise Exception("Le paramètre \'Echelle\' est obligatoire.")
        else:
            if scale > scale_limit:
                raise Exception(wrong_scale_txt.format(str(scale_limit)))

        # Check if context is valid
        if context not in auth_contexts:
            raise Exception(
                "La valeur \'%s\' est incorrecte.\n\n"
                "\'Context\' doit prentre une des %s valeurs suivantes: "
                "%s" % (context, len(auth_contexts), ", ".join(auth_contexts)))

        self.zone = context
        if self.zone in [
                r"guadeloupe", r"stmartin", r"stbarthelemy", r"martinique"
        ]:
            self.zone = r"antilles"

        # Check if XY are valid
        if not re.match(r"^\-?\d+,\-?\d+$", center):
            raise Exception("Les coordonnées XY du centre sont incorrectes.")

        # Extract XY (&centre)
        xcenter = int(center.split(r",")[0])
        ycenter = int(center.split(r",")[1])

        # Compute the bbox
        xmin = xcenter - self.conn.extract_lim / 2
        xmax = xcenter + self.conn.extract_lim / 2
        ymin = ycenter - self.conn.extract_lim / 2
        ymax = ycenter + self.conn.extract_lim / 2

        # Transform coordinates in WGS84
        bbox = tools.reproj(QgsRectangle(xmin, ymin, xmax, ymax), 3857, 4326,
                            self.project)

        # Extract RFU (Send the request)
        resp = self.conn.extraction(bbox.xMinimum(), bbox.yMinimum(),
                                    bbox.xMaximum(), bbox.yMaximum())

        resp_read = resp.read()

        # DEBUG: Export response as a text file
        # urlresp_to_file(resp_read)

        if resp.code != 200:
            raise Exception(resp_read)
        tree = EltTree.fromstring(resp_read)
        # Check if error
        err = tree.find(r"./erreur")
        if err:
            raise Exception(err.text)

        # Create the layer: "Masque d'extraction"
        self.l_bbox = QgsVectorLayer(r"Polygon?crs=epsg:4326&index=yes",
                                     "Zone de travail", r"memory")

        p_bbox = self.l_bbox.dataProvider()

        simple_symbol = QgsFillSymbol.createSimple({
            r"color": r"116,97,87,255",
            r"style": r"b_diagonal",
            r"outline_style": r"no"
        })

        renderer_bbox = QgsInvertedPolygonRenderer(
            QgsSingleSymbolRenderer(simple_symbol))

        self.l_bbox.setRenderer(renderer_bbox)

        self.ft_bbox = QgsFeature()
        self.limit_area = QgsRectangle(bbox.xMinimum(), bbox.yMinimum(),
                                       bbox.xMaximum(), bbox.yMaximum())
        self.ft_bbox.setGeometry(QgsGeometry.fromRect(self.limit_area))
        p_bbox.addFeatures([self.ft_bbox])

        self.l_bbox.updateFields()
        self.l_bbox.updateExtents()

        # Create layers..
        self.layers = self.extract_layers(tree)
        self.l_vertex = self.layers[0]
        self.l_edge = self.layers[1]

        # Add layer to the registry
        self.project.addMapLayers([self.l_vertex, self.l_edge, self.l_bbox])

        # Set extent
        # self.canvas.setExtent(QgsRectangle(bbox.xMinimum(), bbox.yMinimum(),
        # bbox.xMaximum(), bbox.yMaximum()))

        self.features_vertex_backed_up = \
            dict((ft[r"fid"], ft) for ft in self.get_features(self.l_vertex))
        self.features_edge_backed_up = \
            dict((ft[r"fid"], ft) for ft in self.get_features(self.l_edge))

        # Get Capabitilies
        resp = self.conn.get_capabilities(self.zone)
        resp_read = resp.read()

        # DEBUG
        # urlresp_to_file(resp_read)

        if resp.code != 200:
            raise Exception(resp_read)

        tree = EltTree.fromstring(resp_read)

        # Find tolerance to determine if 2 points are equals
        for entry in tree.findall(r"./tolerance"):
            self.tol_same_pt = float(entry.text)

        err = tree.find(r"./erreur")
        if err:
            raise Exception(err.text)

        for entry in tree.findall(r"./classe_rattachement/classe"):
            t = (entry.attrib[r"som_precision_rattachement"], entry.text)
            self.precision_class.append(t)

        for entry in tree.findall(
                r"./representation_plane_sommet_autorise/representation_plane_sommet"
        ):
            t = (entry.attrib[r"som_representation_plane"],
                 entry.attrib[r"epsg_crs_id"], entry.text)
            self.ellips_acronym.append(t)

        # Added v2.1 <<
        for entry in tree.findall(r"./typologie_nature_sommet/nature"):
            self.typo_nature_som.append(entry.text)

        for entry in tree.findall(r"./nature_sommet_conseille/nature"):
            self.nature.append(entry.text)

        for entry in tree.findall(r"./typologie_nature_limite/nature"):
            self.typo_nature_lim.append(entry.text)
        # >>

        for entry in tree.findall(
                r"./som_ge_createur_autorise/som_ge_createur"):
            t = (entry.attrib[r"num_ge"], entry.text)
            self.auth_creator.append(t)

        try:
            ft = next(ft for ft in self.l_vertex.getFeatures())
            ft_attrib = tools.attrib_as_kv(ft.fields(), ft.attributes())
            self.dflt_ellips_acronym = ft_attrib[r"som_representation_plane"]
        except:
            self.dflt_ellips_acronym = None

        for i, e in enumerate(self.ellips_acronym):

            self.projComboBox.addItem(e[2])

            if not self.dflt_ellips_acronym and i == 0:
                self.project_crs = int(e[1])

            if self.dflt_ellips_acronym == e[0]:

                # Check projection in combobox
                self.projComboBox.setCurrentIndex(i)

                # Then change the CRS in canvas
                epsg_str = "EPSG:" + str(int(e[1]))
                crs = QgsCoordinateReferenceSystem(epsg_str)
                self.project.setCrs(crs)
                self.project_crs = int(e[1])

        # Calculate bbox in the project CRS (used for the scale limitation of the canvas)
        self.bbox_crsproject = tools.reproj(
            QgsRectangle(xmin, ymin, xmax, ymax), 3857, self.project_crs,
            self.project)

        # Zoom to bbox extents
        self.zoom_bbox()
        self.canvas.refresh()

        # Modified in v2.1 <<
        # Add the list of possible values to the field som_nature
        map_predefined_vals_to_fld(self.l_vertex, "som_typologie_nature",
                                   self.typo_nature_som)
        # Add the list of possible values to the field som_precision_rattachement
        map_predefined_vals_to_fld(self.l_vertex, "som_precision_rattachement",
                                   self.precision_class, 0, 1)
        # Add the list of possible values to the field som_precision_rattachement
        map_predefined_vals_to_fld(self.l_vertex, "som_representation_plane",
                                   self.ellips_acronym, 0, 2)
        # Add the list of possible values to the field lim_typologie_nature
        map_predefined_vals_to_fld(self.l_edge, "lim_typologie_nature",
                                   self.typo_nature_lim)
        # Add the list of possible values to the field som_delimitation_publique
        false_true_lst = [('False', 'Faux'), ('True', 'Vrai')]
        map_predefined_vals_to_fld(self.l_vertex, "som_delimitation_publique",
                                   false_true_lst, 0, 1)
        # Add the list of possible values to the field lim_delimitation_publique
        map_predefined_vals_to_fld(self.l_edge, "lim_delimitation_publique",
                                   false_true_lst, 0, 1)
        # >>

        # Then, start editing mode..
        for idx, layer in enumerate(self.layers):
            if not layer.isEditable():
                layer.startEditing()
            if idx == 0:
                self.iface.setActiveLayer(layer)

        self.projComboBox.setDisabled(False)

        self.permalinkCmb.setDisabled(True)
        self.downloadPushButton.setDisabled(True)
        self.resetPushButton.setDisabled(False)
        self.uploadPushButton.setDisabled(False)

        self.downloadPushButton.clicked.disconnect(self.on_downloaded)
        # self.permalinkLineEdit.returnPressed.disconnect(self.on_downloaded)
        self.resetPushButton.clicked.connect(self.on_reset)
        self.uploadPushButton.clicked.connect(self.on_uploaded)

        # Activate the scale limitation for the canvas
        self.canvas.scaleChanged.connect(self.limit_cvs_scale)

        self.downloaded.emit()

        return True
Пример #27
0
    def testRenderMultipleRenderersAboveAndBelow(self):
        poly_layer = QgsVectorLayer(os.path.join(TEST_DATA_DIR, 'polys.shp'))
        self.assertTrue(poly_layer.isValid())

        sym1 = QgsFillSymbol.createSimple({'color': '#ffaaff', 'outline_color': '#000000', 'outline_width': '1'})
        renderer = QgsSingleSymbolRenderer(sym1)
        poly_layer.setRenderer(renderer)

        # add secondary renderer, for rendering below
        class Gen1(QgsFeatureRendererGenerator):

            def id(self):
                return 'Gen1'

            def level(self):
                return 3

            def createRenderer(self):
                renderer = QgsCategorizedSymbolRenderer()
                renderer.setClassAttribute('Name')

                cf1 = QgsCentroidFillSymbolLayer()
                cf1.setSubSymbol(QgsMarkerSymbol.createSimple(
                    {'color': '#33aa33', 'outline_style': 'no', 'size': '5'}))
                sym1 = QgsFillSymbol([cf1])

                cf2 = QgsCentroidFillSymbolLayer()
                cf2.setSubSymbol(QgsMarkerSymbol.createSimple(
                    {'color': '#aa33aa', 'outline_style': 'no', 'size': '5'}))
                sym2 = QgsFillSymbol([cf2])

                renderer.addCategory(QgsRendererCategory('Dam', sym1, 'Dam'))
                renderer.addCategory(QgsRendererCategory('Lake', sym2, 'Lake'))
                return renderer

        # add secondary renderer, for rendering below
        class Gen2(QgsFeatureRendererGenerator):

            def id(self):
                return 'Gen2'

            def level(self):
                return 2

            def createRenderer(self):
                renderer = QgsCategorizedSymbolRenderer()
                renderer.setClassAttribute('Value < 12')

                cf1 = QgsCentroidFillSymbolLayer()
                cf1.setSubSymbol(QgsMarkerSymbol.createSimple(
                    {'color': '#aa1111', 'outline_style': 'no', 'size': '8'}))
                sym1 = QgsFillSymbol([cf1])

                cf2 = QgsCentroidFillSymbolLayer()
                cf2.setSubSymbol(QgsMarkerSymbol.createSimple(
                    {'color': '#1111dd', 'outline_style': 'no', 'size': '8'}))
                sym2 = QgsFillSymbol([cf2])

                renderer.addCategory(QgsRendererCategory('1', sym1, '1'))
                renderer.addCategory(QgsRendererCategory('0', sym2, '0'))
                return renderer

        # add secondary renderer, for rendering below

        class Gen1b(QgsFeatureRendererGenerator):

            def id(self):
                return 'Gen1b'

            def level(self):
                return -2

            def createRenderer(self):
                renderer = QgsCategorizedSymbolRenderer()
                renderer.setClassAttribute('Name')

                sym1 = QgsFillSymbol.createSimple(
                    {'color': '#ffaaff', 'outline_color': '#33aa33', 'outline_width': '3'})
                sym2 = QgsFillSymbol.createSimple(
                    {'color': '#ffaaff', 'outline_color': '#aa33aa', 'outline_width': '3'})

                renderer.addCategory(QgsRendererCategory('Dam', sym1, 'Dam'))
                renderer.addCategory(QgsRendererCategory('Lake', sym2, 'Lake'))
                return renderer

        # add secondary renderer, for rendering below
        class Gen2b(QgsFeatureRendererGenerator):

            def id(self):
                return 'Gen2b'

            def level(self):
                return -3

            def createRenderer(self):
                renderer = QgsCategorizedSymbolRenderer()
                renderer.setClassAttribute('Value < 12')

                sym1 = QgsFillSymbol.createSimple(
                    {'color': '#ffaaff', 'outline_color': '#aa1111', 'outline_width': '5'})
                sym2 = QgsFillSymbol.createSimple(
                    {'color': '#ffaaff', 'outline_color': '#1111dd', 'outline_width': '5'})

                renderer.addCategory(QgsRendererCategory('1', sym1, '1'))
                renderer.addCategory(QgsRendererCategory('0', sym2, '0'))
                return renderer

        poly_layer.addFeatureRendererGenerator(Gen1())
        poly_layer.addFeatureRendererGenerator(Gen2())
        poly_layer.addFeatureRendererGenerator(Gen1b())
        poly_layer.addFeatureRendererGenerator(Gen2b())

        mapsettings = QgsMapSettings()
        mapsettings.setOutputSize(QSize(400, 400))
        mapsettings.setOutputDpi(96)
        mapsettings.setDestinationCrs(QgsCoordinateReferenceSystem('EPSG:3857'))
        mapsettings.setExtent(QgsRectangle(-13875783.2, 2266009.4, -8690110.7, 6673344.5))
        mapsettings.setLayers([poly_layer])

        renderchecker = QgsMultiRenderChecker()
        renderchecker.setMapSettings(mapsettings)
        renderchecker.setControlPathPrefix('vectorlayerrenderer')
        renderchecker.setControlName('expected_multiple_renderers_both_above_below')
        result = renderchecker.runTest('expected_multiple_renderers_both_above_below')
        self.report += renderchecker.report()
        self.assertTrue(result)

        # also try with symbol levels
        renderer.setUsingSymbolLevels(True)
        poly_layer.setRenderer(renderer)

        renderchecker = QgsMultiRenderChecker()
        renderchecker.setMapSettings(mapsettings)
        renderchecker.setControlPathPrefix('vectorlayerrenderer')
        renderchecker.setControlName('expected_multiple_renderers_both_above_below')
        result = renderchecker.runTest('expected_multiple_renderers_both_above_below')
        self.report += renderchecker.report()
        self.assertTrue(result)
Пример #28
0
    def testInitialSizeSymbolMapUnits(self):
        """Test initial size of legend with a symbol size in map units"""

        point_path = os.path.join(TEST_DATA_DIR, 'points.shp')
        point_layer = QgsVectorLayer(point_path, 'points', 'ogr')
        QgsProject.instance().addMapLayers([point_layer])

        marker_symbol = QgsMarkerSymbol.createSimple({
            'color': '#ff0000',
            'outline_style': 'no',
            'size': '5',
            'size_unit': 'MapUnit'
        })

        point_layer.setRenderer(QgsSingleSymbolRenderer(marker_symbol))

        s = QgsMapSettings()
        s.setLayers([point_layer])
        layout = QgsLayout(QgsProject.instance())
        layout.initializeDefaults()

        map = QgsLayoutItemMap(layout)
        map.attemptSetSceneRect(QRectF(20, 20, 80, 80))
        map.setFrameEnabled(True)
        map.setLayers([point_layer])
        layout.addLayoutItem(map)
        map.setExtent(point_layer.extent())

        legend = QgsLayoutItemLegend(layout)
        legend.attemptSetSceneRect(QRectF(120, 20, 80, 80))
        legend.setFrameEnabled(True)
        legend.setFrameStrokeWidth(QgsLayoutMeasurement(2))
        legend.setBackgroundColor(QColor(200, 200, 200))
        legend.setTitle('')
        layout.addLayoutItem(legend)
        legend.setLinkedMap(map)

        checker = QgsLayoutChecker('composer_legend_mapunits', layout)
        checker.setControlPathPrefix("composer_legend")
        result, message = checker.testLayout()
        self.assertTrue(result, message)

        # resize with non-top-left reference point
        legend.setResizeToContents(False)
        legend.setReferencePoint(QgsLayoutItem.LowerRight)
        legend.attemptMove(QgsLayoutPoint(120, 90))
        legend.attemptResize(QgsLayoutSize(50, 60))

        self.assertEqual(legend.positionWithUnits().x(), 120.0)
        self.assertEqual(legend.positionWithUnits().y(), 90.0)
        self.assertAlmostEqual(legend.pos().x(), 70, -1)
        self.assertAlmostEqual(legend.pos().y(), 30, -1)

        legend.setResizeToContents(True)
        legend.updateLegend()
        self.assertEqual(legend.positionWithUnits().x(), 120.0)
        self.assertEqual(legend.positionWithUnits().y(), 90.0)
        self.assertAlmostEqual(legend.pos().x(), 91, -1)
        self.assertAlmostEqual(legend.pos().y(), 71, -1)

        QgsProject.instance().removeMapLayers([point_layer.id()])
Пример #29
0
    def testClippingHideClipSource(self):
        """
        When an item is set to be the clip source, it shouldn't render anything itself
        """
        format = QgsTextFormat()
        format.setFont(QgsFontUtils.getStandardTestFont("Bold"))
        format.setSize(30)
        format.setNamedStyle("Bold")
        format.setColor(QColor(0, 0, 0))
        settings = QgsPalLayerSettings()
        settings.setFormat(format)
        settings.fieldName = "'XXXX'"
        settings.isExpression = True
        settings.placement = QgsPalLayerSettings.OverPoint

        vl = QgsVectorLayer("Polygon?crs=epsg:4326&field=id:integer", "vl",
                            "memory")

        props = {
            "color": "127,255,127",
            'outline_style': 'solid',
            'outline_width': '1',
            'outline_color': '0,0,255'
        }
        fillSymbol = QgsFillSymbol.createSimple(props)
        renderer = QgsSingleSymbolRenderer(fillSymbol)
        vl.setRenderer(renderer)

        f = QgsFeature(vl.fields(), 1)
        for x in range(0, 15, 3):
            for y in range(0, 15, 3):
                f.setGeometry(QgsGeometry(QgsPoint(x, y)).buffer(1, 3))
                vl.dataProvider().addFeature(f)

        vl.setLabeling(QgsVectorLayerSimpleLabeling(settings))
        vl.setLabelsEnabled(True)

        p = QgsProject()

        p.addMapLayer(vl)
        layout = QgsLayout(p)
        layout.initializeDefaults()
        p.setCrs(QgsCoordinateReferenceSystem('EPSG:4326'))
        map = QgsLayoutItemMap(layout)
        map.attemptSetSceneRect(QRectF(10, 10, 180, 180))
        map.setFrameEnabled(False)
        map.zoomToExtent(vl.extent())
        map.setLayers([vl])
        layout.addLayoutItem(map)

        shape = QgsLayoutItemShape(layout)
        layout.addLayoutItem(shape)
        shape.setShapeType(QgsLayoutItemShape.Ellipse)
        shape.attemptSetSceneRect(QRectF(10, 10, 180, 180))

        map.itemClippingSettings().setEnabled(True)
        map.itemClippingSettings().setSourceItem(shape)
        map.itemClippingSettings().setForceLabelsInsideClipPath(False)
        map.itemClippingSettings().setFeatureClippingType(
            QgsMapClippingRegion.FeatureClippingType.ClipToIntersection)

        checker = QgsLayoutChecker('composermap_itemclip_nodrawsource', layout)
        checker.setControlPathPrefix("composer_map")
        result, message = checker.testLayout()
        TestQgsLayoutMap.report += checker.report()
        self.assertTrue(result, message)
Пример #30
0
    def testCase(self):
        self.TEST_DATA_DIR = unitTestDataPath()
        tmppath = tempfile.mkdtemp()
        for file in glob.glob(os.path.join(self.TEST_DATA_DIR, 'france_parts.*')):
            shutil.copy(os.path.join(self.TEST_DATA_DIR, file), tmppath)
        vectorFileInfo = QFileInfo(tmppath + "/france_parts.shp")
        mVectorLayer = QgsVectorLayer(vectorFileInfo.filePath(), vectorFileInfo.completeBaseName(), "ogr")

        QgsProject.instance().addMapLayers([mVectorLayer])
        self.layers = [mVectorLayer]

        # create layout with layout map

        # select epsg:2154
        crs = QgsCoordinateReferenceSystem()
        crs.createFromSrid(2154)
        QgsProject.instance().setCrs(crs)

        self.layout = QgsPrintLayout(QgsProject.instance())
        self.layout.initializeDefaults()

        # fix the renderer, fill with green
        props = {"color": "0,127,0", 'outline_color': 'black'}
        fillSymbol = QgsFillSymbol.createSimple(props)
        renderer = QgsSingleSymbolRenderer(fillSymbol)
        mVectorLayer.setRenderer(renderer)

        # the atlas map
        self.atlas_map = QgsLayoutItemMap(self.layout)
        self.atlas_map.attemptSetSceneRect(QRectF(20, 20, 130, 130))
        self.atlas_map.setFrameEnabled(True)
        self.atlas_map.setLayers([mVectorLayer])
        self.layout.addLayoutItem(self.atlas_map)

        # the atlas
        self.atlas = self.layout.atlas()
        self.atlas.setCoverageLayer(mVectorLayer)
        self.atlas.setEnabled(True)

        # an overview
        self.overview = QgsLayoutItemMap(self.layout)
        self.overview.attemptSetSceneRect(QRectF(180, 20, 50, 50))
        self.overview.setFrameEnabled(True)
        self.overview.overview().setLinkedMap(self.atlas_map)
        self.overview.setLayers([mVectorLayer])
        self.layout.addLayoutItem(self.overview)
        nextent = QgsRectangle(49670.718, 6415139.086, 699672.519, 7065140.887)
        self.overview.setExtent(nextent)

        # set the fill symbol of the overview map
        props2 = {"color": "127,0,0,127", 'outline_color': 'black'}
        fillSymbol2 = QgsFillSymbol.createSimple(props2)
        self.overview.overview().setFrameSymbol(fillSymbol2)

        # header label
        self.mLabel1 = QgsLayoutItemLabel(self.layout)
        self.layout.addLayoutItem(self.mLabel1)
        self.mLabel1.setText("[% \"NAME_1\" %] area")
        self.mLabel1.setFont(QgsFontUtils.getStandardTestFont())
        self.mLabel1.adjustSizeToText()
        self.mLabel1.attemptSetSceneRect(QRectF(150, 5, 60, 15))
        self.mLabel1.setMarginX(1)
        self.mLabel1.setMarginY(1)

        # feature number label
        self.mLabel2 = QgsLayoutItemLabel(self.layout)
        self.layout.addLayoutItem(self.mLabel2)
        self.mLabel2.setText("# [%@atlas_featurenumber || ' / ' || @atlas_totalfeatures%]")
        self.mLabel2.setFont(QgsFontUtils.getStandardTestFont())
        self.mLabel2.adjustSizeToText()
        self.mLabel2.attemptSetSceneRect(QRectF(150, 200, 60, 15))
        self.mLabel2.setMarginX(1)
        self.mLabel2.setMarginY(1)

        self.filename_test()
        self.autoscale_render_test()
        self.fixedscale_render_test()
        self.predefinedscales_render_test()
        self.hidden_render_test()
        self.legend_test()
        self.rotation_test()

        shutil.rmtree(tmppath, True)
Пример #31
0
    def run(self):
        print ("paso por el run")
       
        #coloco el puntero arriba del todo
        QgsProject.instance().layerTreeRegistryBridge().setLayerInsertionPoint( QgsProject.instance().layerTreeRoot(), 0 )
   
             
        
        """Run method that performs all the real work"""

        
        #genero una lista con las columnas de la capa de puntos
        vl2=iface.activeLayer()
        if vl2 is None:
            iface.messageBar().pushMessage("ATENCION", "Selecciona una capa de puntos", duration=10)
        #if vl2.wkbType()< 1 or vl2.wkbType() > 1:
            #iface.messageBar().pushMessage("ATENCION", "Selecciona una capa de puntos", duration=10)
        #else:
        if vl2.wkbType()== 1 or vl2.wkbType()==1001:
            misdatos=[]
            misdatos = [f.name() for f in vl2.fields()]
            
            #trato de rellenar el desplegable con las columnas
            #anado un elemneto en blanco en el desplegable
            self.dlg.cb1.clear()
            self.dlg.cb1.addItem( "")
            for element in misdatos:
                self.dlg.cb1.addItem( element)
                
            # Create the dialog with elements (after translation) and keep reference
            # Only create GUI ONCE in callback, so that it will only load when the plugin is started
            if self.first_start == True:
                self.first_start = False

            # show the dialog
            self.dlg.show()
            
            # Run the dialog event loop
            result = self.dlg.exec_()
            # See if OK was pressed
            if result:
                column = self.dlg.cb1.currentIndex()
                columna=misdatos[int(column)-1]                

                #parece que lo mejor sera la seleccion de una capa y dentro de ella de los elementos en ella seleccionados solo. Para ello habria que crear una capa temporal con solo los seleccioandos      
                #if vl2.wkbType()== 1 or vl2.wkbType()==1001:
                selection = vl2.selectedFeatures()
                elementosseleccionados=len(selection)

                if elementosseleccionados ==0:
                    vl2.selectAll()
                if elementosseleccionados ==1 or elementosseleccionados ==2:
                    iface.messageBar().pushMessage("ATENCION", "Tienes algun elemento seleccionado pero no los suficientes para crear un poligono", duration=10)
                    
                #onlySelectedFeatures
                results0=processing.run("native:saveselectedfeatures", {'INPUT':vl2,'OUTPUT':'memory:puntos_seleccionados_ptos2pol'})
                result_layer0 = results0['OUTPUT']
                entrada=result_layer0
                QgsProject.instance().addMapLayer(result_layer0)
            
                #hay que hacer que cree una columna con el orden el solo por si por defecto no se pone ninguna
                params={'INPUT':entrada,'GROUP_FIELD':None,'ORDER_FIELD':columna,'DATE_FORMAT':'', 'OUTPUT':'memory:lineas_ptos2pol'}
                results=processing.run("qgis:pointstopath", params)
                result_layer = results['OUTPUT']
                QgsProject.instance().addMapLayer(result_layer)
                params={'INPUT':result_layer,'OUTPUT':'memory:poligono_ptos2pol '}
                results2=processing.run("qgis:linestopolygons", params )
                result_layer2 = results2['OUTPUT']
               
                #por el mismo precio calculo la superficie
                #ADDING NEW FIELD
                layer_provider=result_layer2.dataProvider()
                layer_provider.addAttributes([QgsField("hectarea",QVariant.Double, "double", 10, 4)])
                result_layer2.updateFields()
                #UPDATING/ADD ATTRIBUTE VALUE
                result_layer2.startEditing()
                features = result_layer2.getFeatures()
                for f in features:
                    id=f.id()
                    area=f.geometry().area()/10000
                    fieldindex = result_layer2.dataProvider().fieldNameIndex("hectarea")
                    attr_value={fieldindex:area}#fieldindex, antes era 2
                    layer_provider.changeAttributeValues({id:attr_value})
                result_layer2.commitChanges()
                
                #tendra que etiquetar la superficie con dos decimales y cambiar la simbologia, ya que estamos.
                sym1 = QgsFillSymbol.createSimple({'style': 'vertical','color': '0,0,0,0', 'outline_color': 'red'})
                renderer=QgsSingleSymbolRenderer(sym1)
                #etiqueto
                layer_settings  = QgsPalLayerSettings()
                text_format = QgsTextFormat()
                text_format.setFont(QFont("Arial", 12))
                text_format.setSize(12)
                text_format.setColor(QColor("Red"))
                layer_settings.setFormat(text_format)
                layer_settings.fieldName = '''concat(round("hectarea",2),' ha.')'''            
                layer_settings.isExpression = True
                layer_settings.enabled = True
                layer_settings = QgsVectorLayerSimpleLabeling(layer_settings)
                result_layer2.setLabelsEnabled(True)
                result_layer2.setLabeling(layer_settings)
                result_layer2.triggerRepaint()
                result_layer2.setRenderer(renderer)

                QgsProject.instance().addMapLayer(result_layer2)
        else:
            print(vl2.wkbType())
            iface.messageBar().pushMessage("ATENCION", "Selecciona una capa de puntos", duration=10)