def testFilterNeedsGeometry(self):
        renderer = QgsCategorizedSymbolRenderer()

        renderer.setClassAttribute("value")
        self.assertFalse(renderer.filterNeedsGeometry())
        renderer.setClassAttribute("$area")
        self.assertTrue(renderer.filterNeedsGeometry())
        renderer.setClassAttribute("value - $area")
        self.assertTrue(renderer.filterNeedsGeometry())
 def _create_categorized_renderer(self):
     cat_renderer = QgsCategorizedSymbolRenderer(attrName='Class')
     sym1 = QgsMarkerSymbol.createSimple({'color': '#ff00ff', 'size': '6', 'outline_style': 'no'})
     cat1 = QgsRendererCategory('Biplane', sym1, 'Big')
     cat_renderer.addCategory(cat1)
     sym2 = QgsMarkerSymbol.createSimple({'color': '#ff00ff', 'size': '3', 'outline_style': 'no'})
     cat2 = QgsRendererCategory(['B52', 'Jet'], sym2, 'Smaller')
     cat_renderer.addCategory(cat2)
     return cat_renderer
    def testUsedAttributes(self):
        renderer = QgsCategorizedSymbolRenderer()
        ctx = QgsRenderContext()

        # attribute can contain either attribute name or an expression.
        # Sometimes it is not possible to distinguish between those two,
        # e.g. "a - b" can be both a valid attribute name or expression.
        # Since we do not have access to fields here, the method should return both options.
        renderer.setClassAttribute("value")
        self.assertEqual(renderer.usedAttributes(ctx), {"value"})
        renderer.setClassAttribute("value - 1")
        self.assertEqual(renderer.usedAttributes(ctx), {"value", "value - 1"})
        renderer.setClassAttribute("valuea - valueb")
        self.assertEqual(renderer.usedAttributes(ctx), {"valuea", "valuea - valueb", "valueb"})
    def testCategories(self):
        layer = QgsVectorLayer("Point?field=fldtxt:string&field=fldint:integer", "addfeat", "memory")
        layer.setEditorWidgetSetup(1, QgsEditorWidgetSetup("ValueMap", {'map': [{'One': '1'}, {'Two': '2'}]}))

        result = QgsCategorizedSymbolRenderer.createCategories([1, 2, 3], QgsMarkerSymbol(), layer, 'fldint')

        self.assertEqual(result[0].label(), 'One')
        self.assertEqual(result[1].label(), 'Two')
        self.assertEqual(result[2].label(), '(3)')
    def testFilterNeedsGeometry(self):
        renderer = QgsCategorizedSymbolRenderer()

        renderer.setClassAttribute("value")
        self.assertFalse(renderer.filterNeedsGeometry())
        renderer.setClassAttribute("$area")
        self.assertTrue(renderer.filterNeedsGeometry())
        renderer.setClassAttribute("value - $area")
        self.assertTrue(renderer.filterNeedsGeometry())
Ejemplo n.º 6
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()
    def testMatchToSymbols(self):
        """
        Test QgsCategorizedSymbolRender.matchToSymbols
        """
        renderer = QgsCategorizedSymbolRenderer()
        renderer.setClassAttribute('x')

        symbol_a = createMarkerSymbol()
        symbol_a.setColor(QColor(255, 0, 0))
        renderer.addCategory(QgsRendererCategory('a', symbol_a, 'a'))
        symbol_b = createMarkerSymbol()
        symbol_b.setColor(QColor(0, 255, 0))
        renderer.addCategory(QgsRendererCategory('b', symbol_b, 'b'))
        symbol_c = createMarkerSymbol()
        symbol_c.setColor(QColor(0, 0, 255))
        renderer.addCategory(QgsRendererCategory('c ', symbol_c, 'c'))

        matched, unmatched_cats, unmatched_symbols = renderer.matchToSymbols(None, QgsSymbol.Marker)
        self.assertEqual(matched, 0)

        style = QgsStyle()
        symbol_a = createMarkerSymbol()
        symbol_a.setColor(QColor(255, 10, 10))
        self.assertTrue(style.addSymbol('a', symbol_a))
        symbol_B = createMarkerSymbol()
        symbol_B.setColor(QColor(10, 255, 10))
        self.assertTrue(style.addSymbol('B ', symbol_B))
        symbol_b = createFillSymbol()
        symbol_b.setColor(QColor(10, 255, 10))
        self.assertTrue(style.addSymbol('b', symbol_b))
        symbol_C = createLineSymbol()
        symbol_C.setColor(QColor(10, 255, 10))
        self.assertTrue(style.addSymbol('C', symbol_C))
        symbol_C = createMarkerSymbol()
        symbol_C.setColor(QColor(10, 255, 10))
        self.assertTrue(style.addSymbol(' ----c/- ', symbol_C))

        # non-matching symbol type
        matched, unmatched_cats, unmatched_symbols = renderer.matchToSymbols(style, QgsSymbol.Line)
        self.assertEqual(matched, 0)
        self.assertEqual(unmatched_cats, ['a', 'b', 'c '])
        self.assertEqual(unmatched_symbols, [' ----c/- ', 'B ', 'C', 'a', 'b'])

        # exact match
        matched, unmatched_cats, unmatched_symbols = renderer.matchToSymbols(style, QgsSymbol.Marker)
        self.assertEqual(matched, 1)
        self.assertEqual(unmatched_cats, ['b', 'c '])
        self.assertEqual(unmatched_symbols, [' ----c/- ', 'B ', 'C', 'b'])

        # make sure symbol was applied
        context = QgsRenderContext()
        renderer.startRender(context, QgsFields())
        symbol, ok = renderer.symbolForValue2('a')
        self.assertTrue(ok)
        self.assertEqual(symbol.color().name(), '#ff0a0a')
        renderer.stopRender(context)

        # case insensitive match
        matched, unmatched_cats, unmatched_symbols = renderer.matchToSymbols(style, QgsSymbol.Marker, False)
        self.assertEqual(matched, 2)
        self.assertEqual(unmatched_cats, ['c '])
        self.assertEqual(unmatched_symbols, [' ----c/- ', 'C', 'b'])

        # make sure symbols were applied
        context = QgsRenderContext()
        renderer.startRender(context, QgsFields())
        symbol, ok = renderer.symbolForValue2('a')
        self.assertTrue(ok)
        self.assertEqual(symbol.color().name(), '#ff0a0a')
        symbol, ok = renderer.symbolForValue2('b')
        self.assertTrue(ok)
        self.assertEqual(symbol.color().name(), '#0aff0a')
        renderer.stopRender(context)

        # case insensitive match
        matched, unmatched_cats, unmatched_symbols = renderer.matchToSymbols(style, QgsSymbol.Marker, False)
        self.assertEqual(matched, 2)
        self.assertEqual(unmatched_cats, ['c '])
        self.assertEqual(unmatched_symbols, [' ----c/- ', 'C', 'b'])

        # make sure symbols were applied
        context = QgsRenderContext()
        renderer.startRender(context, QgsFields())
        symbol, ok = renderer.symbolForValue2('a')
        self.assertTrue(ok)
        self.assertEqual(symbol.color().name(), '#ff0a0a')
        symbol, ok = renderer.symbolForValue2('b')
        self.assertTrue(ok)
        self.assertEqual(symbol.color().name(), '#0aff0a')
        renderer.stopRender(context)

        # tolerant match
        matched, unmatched_cats, unmatched_symbols = renderer.matchToSymbols(style, QgsSymbol.Marker, True, True)
        self.assertEqual(matched, 2)
        self.assertEqual(unmatched_cats, ['b'])
        self.assertEqual(unmatched_symbols, ['B ', 'C', 'b'])

        # make sure symbols were applied
        context = QgsRenderContext()
        renderer.startRender(context, QgsFields())
        symbol, ok = renderer.symbolForValue2('a')
        self.assertTrue(ok)
        self.assertEqual(symbol.color().name(), '#ff0a0a')
        symbol, ok = renderer.symbolForValue2('c ')
        self.assertTrue(ok)
        self.assertEqual(symbol.color().name(), '#0aff0a')
        renderer.stopRender(context)

        # tolerant match, case insensitive
        matched, unmatched_cats, unmatched_symbols = renderer.matchToSymbols(style, QgsSymbol.Marker, False, True)
        self.assertEqual(matched, 3)
        self.assertFalse(unmatched_cats)
        self.assertEqual(unmatched_symbols, ['C', 'b'])

        # make sure symbols were applied
        context = QgsRenderContext()
        renderer.startRender(context, QgsFields())
        symbol, ok = renderer.symbolForValue2('a')
        self.assertTrue(ok)
        self.assertEqual(symbol.color().name(), '#ff0a0a')
        symbol, ok = renderer.symbolForValue2('b')
        self.assertTrue(ok)
        self.assertEqual(symbol.color().name(), '#0aff0a')
        symbol, ok = renderer.symbolForValue2('c ')
        self.assertTrue(ok)
        self.assertEqual(symbol.color().name(), '#0aff0a')
        renderer.stopRender(context)
Ejemplo n.º 8
0
    def test_displayString(self):
        """Test the displayString method"""

        # Default locale for tests is EN
        original_locale = QLocale()
        locale = QLocale(QLocale.English)
        locale.setNumberOptions(QLocale.DefaultNumberOptions)
        QLocale().setDefault(locale)

        self.assertEqual(QgsCategorizedSymbolRenderer.displayString(1234.56), "1,234.56")
        self.assertEqual(QgsCategorizedSymbolRenderer.displayString(1234.56, 4), "1,234.5600")
        self.assertEqual(QgsCategorizedSymbolRenderer.displayString(1234567), "1,234,567")
        self.assertEqual(QgsCategorizedSymbolRenderer.displayString(1234567.0, 4), "1,234,567.0000")
        # Precision is ignored for integers
        self.assertEqual(QgsCategorizedSymbolRenderer.displayString(1234567, 4), "1,234,567")

        # Test list
        self.assertEqual(QgsCategorizedSymbolRenderer.displayString([1234567, 891234], 4), "1,234,567;891,234")
        self.assertEqual(QgsCategorizedSymbolRenderer.displayString([1234567.123, 891234.123], 4), "1,234,567.1230;891,234.1230")

        locale.setNumberOptions(QLocale.OmitGroupSeparator)
        QLocale().setDefault(locale)
        self.assertTrue(QLocale().numberOptions() & QLocale.OmitGroupSeparator)
        self.assertEqual(QgsCategorizedSymbolRenderer.displayString([1234567, 891234], 4), "1234567;891234")
        self.assertEqual(QgsCategorizedSymbolRenderer.displayString([1234567.123, 891234.123], 4), "1234567.1230;891234.1230")

        # Test a non-dot locale
        locale = QLocale(QLocale.Italian)
        locale.setNumberOptions(QLocale.DefaultNumberOptions)
        QLocale().setDefault(locale)
        self.assertEqual(QgsCategorizedSymbolRenderer.displayString(1234.56), "1.234,56")
        self.assertEqual(QgsCategorizedSymbolRenderer.displayString(1234.56, 4), "1.234,5600")
        self.assertEqual(QgsCategorizedSymbolRenderer.displayString(1234567), "1.234.567")
        self.assertEqual(QgsCategorizedSymbolRenderer.displayString(1234567.0, 4), "1.234.567,0000")
        # Precision is ignored for integers
        self.assertEqual(QgsCategorizedSymbolRenderer.displayString(1234567, 4), "1.234.567")

        # Test list
        self.assertEqual(QgsCategorizedSymbolRenderer.displayString([1234567, 891234], 4), "1.234.567;891.234")
        self.assertEqual(QgsCategorizedSymbolRenderer.displayString([1234567.123, 891234.123], 4), "1.234.567,1230;891.234,1230")

        locale.setNumberOptions(QLocale.OmitGroupSeparator)
        QLocale().setDefault(locale)
        self.assertEqual(QgsCategorizedSymbolRenderer.displayString([1234567, 891234], 4), "1234567;891234")
        self.assertEqual(QgsCategorizedSymbolRenderer.displayString([1234567.123, 891234.123], 4), "1234567,1230;891234,1230")

        QLocale().setDefault(original_locale)
    def testSymbolForValue(self):
        """Test symbolForValue"""
        renderer = QgsCategorizedSymbolRenderer()
        renderer.setClassAttribute('field')

        symbol_a = createMarkerSymbol()
        symbol_a.setColor(QColor(255, 0, 0))
        renderer.addCategory(QgsRendererCategory('a', symbol_a, 'a'))
        symbol_b = createMarkerSymbol()
        symbol_b.setColor(QColor(0, 255, 0))
        renderer.addCategory(QgsRendererCategory('b', symbol_b, 'b'))
        symbol_c = createMarkerSymbol()
        symbol_c.setColor(QColor(0, 0, 255))
        renderer.addCategory(QgsRendererCategory('c', symbol_c, 'c', False))
        # add default category
        default_symbol = createMarkerSymbol()
        default_symbol.setColor(QColor(255, 255, 255))
        renderer.addCategory(QgsRendererCategory('', default_symbol, 'default'))

        context = QgsRenderContext()
        renderer.startRender(context, QgsFields())

        symbol, ok = renderer.symbolForValue2('a')
        self.assertEqual(symbol.color(), QColor(255, 0, 0))
        self.assertTrue(ok)
        symbol, ok = renderer.symbolForValue2('b')
        self.assertEqual(symbol.color(), QColor(0, 255, 0))
        self.assertTrue(ok)

        # hidden category
        symbol, ok = renderer.symbolForValue2('c')
        self.assertIsNone(symbol)
        self.assertTrue(ok)

        # no matching category
        symbol, ok = renderer.symbolForValue2('xxxx')
        self.assertIsNone(symbol)
        self.assertFalse(ok)

        renderer.stopRender(context)
    def testSymbolForValue(self):
        """Test symbolForValue"""
        renderer = QgsCategorizedSymbolRenderer()
        renderer.setClassAttribute('field')

        symbol_a = createMarkerSymbol()
        symbol_a.setColor(QColor(255, 0, 0))
        renderer.addCategory(QgsRendererCategory('a', symbol_a, 'a'))
        symbol_b = createMarkerSymbol()
        symbol_b.setColor(QColor(0, 255, 0))
        renderer.addCategory(QgsRendererCategory('b', symbol_b, 'b'))
        symbol_c = createMarkerSymbol()
        symbol_c.setColor(QColor(0, 0, 255))
        renderer.addCategory(QgsRendererCategory('c', symbol_c, 'c', False))
        # add default category
        default_symbol = createMarkerSymbol()
        default_symbol.setColor(QColor(255, 255, 255))
        renderer.addCategory(QgsRendererCategory('', default_symbol, 'default'))

        context = QgsRenderContext()
        renderer.startRender(context, QgsFields())

        symbol, ok = renderer.symbolForValue2('a')
        self.assertEqual(symbol.color(), QColor(255, 0, 0))
        self.assertTrue(ok)
        symbol, ok = renderer.symbolForValue2('b')
        self.assertEqual(symbol.color(), QColor(0, 255, 0))
        self.assertTrue(ok)

        # hidden category
        symbol, ok = renderer.symbolForValue2('c')
        self.assertIsNone(symbol)
        self.assertTrue(ok)

        # no matching category
        symbol, ok = renderer.symbolForValue2('xxxx')
        self.assertIsNone(symbol)
        self.assertFalse(ok)

        renderer.stopRender(context)
    def testLegendKeysWhileCounting(self):
        # test determining legend keys for features, while counting features
        fields = QgsFields()
        fields.append(QgsField('x'))

        # setup renderer
        renderer = QgsCategorizedSymbolRenderer()
        renderer.setClassAttribute('x')

        symbol_a = createMarkerSymbol()
        symbol_a.setColor(QColor(255, 0, 0))
        renderer.addCategory(QgsRendererCategory('a', symbol_a, 'a'))
        symbol_b = createMarkerSymbol()
        symbol_b.setColor(QColor(0, 255, 0))
        renderer.addCategory(QgsRendererCategory('b', symbol_b, 'b'))
        symbol_c = createMarkerSymbol()
        symbol_c.setColor(QColor(0, 0, 255))
        renderer.addCategory(QgsRendererCategory('c', symbol_c, 'c', False))
        # add default category
        default_symbol = createMarkerSymbol()
        default_symbol.setColor(QColor(255, 255, 255))
        renderer.addCategory(QgsRendererCategory('', default_symbol, 'default'))

        context = QgsRenderContext()
        context.setRendererScale(0) # simulate counting
        renderer.startRender(context, fields)

        f = QgsFeature(fields)
        f.setAttributes(['a'])

        keys = renderer.legendKeysForFeature(f, context)
        self.assertEqual(keys, {'0'})

        f.setAttributes(['b'])
        keys = renderer.legendKeysForFeature(f, context)
        self.assertEqual(keys, {'1'})

        # hidden category, should still return keys
        f.setAttributes(['c'])
        keys = renderer.legendKeysForFeature(f, context)
        self.assertEqual(keys, {'2'})

        # no matching category
        f.setAttributes(['xxx'])
        keys = renderer.legendKeysForFeature(f, context)
        self.assertFalse(keys)

        renderer.stopRender(context)
Ejemplo n.º 12
0
def open_file(dialog: QDialog = None,
              osm_file: str = None,
              output_geom_types: list = None,
              white_list_column: dict = None,
              key: Union[str, List[str]] = None,
              layer_name: str = "OsmFile",
              config_outputs: dict = None,
              output_dir: str = None,
              output_format: Format = None,
              final_query: str = None,
              prefix_file: str = None,
              subset: bool = False,
              subset_query: str = None,
              feedback: QgsFeedback = None) -> int:
    """
    Open an osm file.

    Memory layer if no output directory is set, or Geojson in the output
    directory.

    :param final_query: The query where the file comes from. Might be empty if
    it's a local OSM file.
    :type final_query: basestring
    """

    if output_geom_types is None:
        output_geom_types = OSM_LAYERS
    # Legacy, waiting to remove the OsmParser for QGIS >= 3.6
    # Change in osm_file_dialog.py L131 too
    output_geom_legacy = [geom.value.lower() for geom in output_geom_types]
    if not white_list_column:
        white_list_column = None

    LOGGER.info('The OSM file is: {}'.format(osm_file))
    if feedback:
        if feedback.isCanceled():
            return None

    # Parsing the file
    osm_parser = OsmParser(osm_file=osm_file,
                           layers=output_geom_legacy,
                           output_format=output_format,
                           output_dir=output_dir,
                           prefix_file=prefix_file,
                           layer_name=layer_name,
                           key=key,
                           white_list_column=white_list_column,
                           subset=subset,
                           subset_query=subset_query,
                           feedback=feedback)

    if dialog:
        osm_parser.signalText.connect(dialog.set_progress_text)
        osm_parser.signalPercentage.connect(dialog.set_progress_percentage)

    start_time = time.time()
    layers = osm_parser.processing_parse()
    elapsed_time = time.time() - start_time
    parser_time = time.strftime("%Hh %Mm %Ss", time.gmtime(elapsed_time))
    LOGGER.info('The OSM parser took: {}'.format(parser_time))

    if feedback:
        if feedback.isCanceled():
            return None

    # Finishing the process with an output format or memory layer
    num_layers = 0

    for i, (layer, item) in enumerate(layers.items()):
        if dialog:
            dialog.set_progress_percentage(i / len(layers) * 100)
        QApplication.processEvents()
        if item['featureCount'] and (LayerType(layer.capitalize())
                                     in output_geom_types):

            final_layer_name = layer_name
            # If configOutputs is not None (from My Queries)
            if config_outputs:
                if config_outputs[layer]['namelayer']:
                    final_layer_name = config_outputs[layer]['namelayer']

            new_layer = item['vector_layer']
            new_layer.setName(final_layer_name)

            # Try to set styling if defined
            if config_outputs and config_outputs[layer]['style']:
                new_layer.loadNamedStyle(config_outputs[layer]['style'])
            else:
                if "colour" in item['tags']:
                    index = item['tags'].index('colour')
                    colors = new_layer.uniqueValues(index)
                    categories = []
                    for value in colors:
                        if str(value) == 'None':
                            value = ''
                        if layer in ['lines', 'multilinestrings']:
                            symbol = QgsSymbol.defaultSymbol(
                                QgsWkbTypes.LineGeometry)
                        elif layer == "points":
                            symbol = QgsSymbol.defaultSymbol(
                                QgsWkbTypes.PointGeometry)
                        elif layer == "multipolygons":
                            symbol = QgsSymbol.defaultSymbol(
                                QgsWkbTypes.PolygonGeometry)
                        symbol.setColor(QColor(value))
                        category = QgsRendererCategory(str(value), symbol,
                                                       str(value))
                        categories.append(category)

                    renderer = QgsCategorizedSymbolRenderer(
                        "colour", categories)
                    new_layer.setRenderer(renderer)

            # Add action about OpenStreetMap
            actions.add_actions(new_layer, item['tags'])

            QgsProject.instance().addMapLayer(new_layer)

            if final_query:
                QgsExpressionContextUtils.setLayerVariable(
                    new_layer, 'quickosm_query', final_query)
                actions.add_relaunch_action(new_layer, final_layer_name)
                if dialog:
                    dialog.iface.addCustomActionForLayer(
                        dialog.reload_action, new_layer)

            metadata = QgsLayerMetadata()
            metadata.setRights([tr("© OpenStreetMap contributors")])
            metadata.setLicenses(['https://openstreetmap.org/copyright'])
            new_layer.setMetadata(metadata)
            num_layers += 1

    return num_layers
    def testWriteReadXml(self):
        # test writing renderer to xml and restoring

        renderer = QgsCategorizedSymbolRenderer()
        renderer.setClassAttribute('x')

        symbol_a = createMarkerSymbol()
        symbol_a.setColor(QColor(255, 0, 0))
        renderer.addCategory(QgsRendererCategory('a', symbol_a, 'a'))
        symbol_b = createMarkerSymbol()
        symbol_b.setColor(QColor(0, 255, 0))
        renderer.addCategory(QgsRendererCategory('b', symbol_b, 'b'))
        symbol_c = createMarkerSymbol()
        symbol_c.setColor(QColor(0, 0, 255))
        renderer.addCategory(QgsRendererCategory('c', symbol_c, 'c', False))
        symbol_d = createMarkerSymbol()
        symbol_d.setColor(QColor(255, 0, 255))
        renderer.addCategory(QgsRendererCategory(['d', 'e'], symbol_d, 'de'))
        # add default category
        default_symbol = createMarkerSymbol()
        default_symbol.setColor(QColor(255, 255, 255))
        renderer.addCategory(QgsRendererCategory('', default_symbol, 'default'))

        doc = QDomDocument("testdoc")
        elem = renderer.save(doc, QgsReadWriteContext())

        renderer2 = QgsCategorizedSymbolRenderer.create(elem, QgsReadWriteContext())
        self.assertEqual(renderer2.classAttribute(), 'x')
        self.assertEqual([l.label() for l in renderer2.categories()], ['a', 'b', 'c', 'de', 'default'])
        self.assertEqual([l.value() for l in renderer2.categories()], ['a', 'b', 'c', ['d', 'e'], ''])
        self.assertEqual([l.symbol().color().name() for l in renderer2.categories()], ['#ff0000', '#00ff00', '#0000ff', '#ff00ff', '#ffffff'])
    def testUsedAttributes(self):
        renderer = QgsCategorizedSymbolRenderer()
        ctx = QgsRenderContext()

        # attribute can contain either attribute name or an expression.
        # Sometimes it is not possible to distinguish between those two,
        # e.g. "a - b" can be both a valid attribute name or expression.
        # Since we do not have access to fields here, the method should return both options.
        renderer.setClassAttribute("value")
        self.assertEqual(renderer.usedAttributes(ctx), {"value"})
        renderer.setClassAttribute("value - 1")
        self.assertEqual(renderer.usedAttributes(ctx), {"value", "value - 1"})
        renderer.setClassAttribute("valuea - valueb")
        self.assertEqual(renderer.usedAttributes(ctx), {"valuea", "valuea - valueb", "valueb"})
    def testMatchToSymbols(self):
        """
        Test QgsCategorizedSymbolRender.matchToSymbols
        """
        renderer = QgsCategorizedSymbolRenderer()
        renderer.setClassAttribute('x')

        symbol_a = createMarkerSymbol()
        symbol_a.setColor(QColor(255, 0, 0))
        renderer.addCategory(QgsRendererCategory('a', symbol_a, 'a'))
        symbol_b = createMarkerSymbol()
        symbol_b.setColor(QColor(0, 255, 0))
        renderer.addCategory(QgsRendererCategory('b', symbol_b, 'b'))
        symbol_c = createMarkerSymbol()
        symbol_c.setColor(QColor(0, 0, 255))
        renderer.addCategory(QgsRendererCategory('c ', symbol_c, 'c'))

        matched, unmatched_cats, unmatched_symbols = renderer.matchToSymbols(None, QgsSymbol.Marker)
        self.assertEqual(matched, 0)

        style = QgsStyle()
        symbol_a = createMarkerSymbol()
        symbol_a.setColor(QColor(255, 10, 10))
        self.assertTrue(style.addSymbol('a', symbol_a))
        symbol_B = createMarkerSymbol()
        symbol_B.setColor(QColor(10, 255, 10))
        self.assertTrue(style.addSymbol('B ', symbol_B))
        symbol_b = createFillSymbol()
        symbol_b.setColor(QColor(10, 255, 10))
        self.assertTrue(style.addSymbol('b', symbol_b))
        symbol_C = createLineSymbol()
        symbol_C.setColor(QColor(10, 255, 10))
        self.assertTrue(style.addSymbol('C', symbol_C))
        symbol_C = createMarkerSymbol()
        symbol_C.setColor(QColor(10, 255, 10))
        self.assertTrue(style.addSymbol(' ----c/- ', symbol_C))

        # non-matching symbol type
        matched, unmatched_cats, unmatched_symbols = renderer.matchToSymbols(style, QgsSymbol.Line)
        self.assertEqual(matched, 0)
        self.assertEqual(unmatched_cats, ['a', 'b', 'c '])
        self.assertEqual(unmatched_symbols, [' ----c/- ', 'B ', 'C', 'a', 'b'])

        # exact match
        matched, unmatched_cats, unmatched_symbols = renderer.matchToSymbols(style, QgsSymbol.Marker)
        self.assertEqual(matched, 1)
        self.assertEqual(unmatched_cats, ['b', 'c '])
        self.assertEqual(unmatched_symbols, [' ----c/- ', 'B ', 'C', 'b'])

        # make sure symbol was applied
        context = QgsRenderContext()
        renderer.startRender(context, QgsFields())
        symbol, ok = renderer.symbolForValue2('a')
        self.assertTrue(ok)
        self.assertEqual(symbol.color().name(), '#ff0a0a')
        renderer.stopRender(context)

        # case insensitive match
        matched, unmatched_cats, unmatched_symbols = renderer.matchToSymbols(style, QgsSymbol.Marker, False)
        self.assertEqual(matched, 2)
        self.assertEqual(unmatched_cats, ['c '])
        self.assertEqual(unmatched_symbols, [' ----c/- ', 'C', 'b'])

        # make sure symbols were applied
        context = QgsRenderContext()
        renderer.startRender(context, QgsFields())
        symbol, ok = renderer.symbolForValue2('a')
        self.assertTrue(ok)
        self.assertEqual(symbol.color().name(), '#ff0a0a')
        symbol, ok = renderer.symbolForValue2('b')
        self.assertTrue(ok)
        self.assertEqual(symbol.color().name(), '#0aff0a')
        renderer.stopRender(context)

        # case insensitive match
        matched, unmatched_cats, unmatched_symbols = renderer.matchToSymbols(style, QgsSymbol.Marker, False)
        self.assertEqual(matched, 2)
        self.assertEqual(unmatched_cats, ['c '])
        self.assertEqual(unmatched_symbols, [' ----c/- ', 'C', 'b'])

        # make sure symbols were applied
        context = QgsRenderContext()
        renderer.startRender(context, QgsFields())
        symbol, ok = renderer.symbolForValue2('a')
        self.assertTrue(ok)
        self.assertEqual(symbol.color().name(), '#ff0a0a')
        symbol, ok = renderer.symbolForValue2('b')
        self.assertTrue(ok)
        self.assertEqual(symbol.color().name(), '#0aff0a')
        renderer.stopRender(context)

        # tolerant match
        matched, unmatched_cats, unmatched_symbols = renderer.matchToSymbols(style, QgsSymbol.Marker, True, True)
        self.assertEqual(matched, 2)
        self.assertEqual(unmatched_cats, ['b'])
        self.assertEqual(unmatched_symbols, ['B ', 'C', 'b'])

        # make sure symbols were applied
        context = QgsRenderContext()
        renderer.startRender(context, QgsFields())
        symbol, ok = renderer.symbolForValue2('a')
        self.assertTrue(ok)
        self.assertEqual(symbol.color().name(), '#ff0a0a')
        symbol, ok = renderer.symbolForValue2('c ')
        self.assertTrue(ok)
        self.assertEqual(symbol.color().name(), '#0aff0a')
        renderer.stopRender(context)

        # tolerant match, case insensitive
        matched, unmatched_cats, unmatched_symbols = renderer.matchToSymbols(style, QgsSymbol.Marker, False, True)
        self.assertEqual(matched, 3)
        self.assertFalse(unmatched_cats)
        self.assertEqual(unmatched_symbols, ['C', 'b'])

        # make sure symbols were applied
        context = QgsRenderContext()
        renderer.startRender(context, QgsFields())
        symbol, ok = renderer.symbolForValue2('a')
        self.assertTrue(ok)
        self.assertEqual(symbol.color().name(), '#ff0a0a')
        symbol, ok = renderer.symbolForValue2('b')
        self.assertTrue(ok)
        self.assertEqual(symbol.color().name(), '#0aff0a')
        symbol, ok = renderer.symbolForValue2('c ')
        self.assertTrue(ok)
        self.assertEqual(symbol.color().name(), '#0aff0a')
        renderer.stopRender(context)
    def testLegendKeysWhileCounting(self):
        # test determining legend keys for features, while counting features
        fields = QgsFields()
        fields.append(QgsField('x'))

        # setup renderer
        renderer = QgsCategorizedSymbolRenderer()
        renderer.setClassAttribute('x')

        symbol_a = createMarkerSymbol()
        symbol_a.setColor(QColor(255, 0, 0))
        renderer.addCategory(QgsRendererCategory('a', symbol_a, 'a'))
        symbol_b = createMarkerSymbol()
        symbol_b.setColor(QColor(0, 255, 0))
        renderer.addCategory(QgsRendererCategory('b', symbol_b, 'b'))
        symbol_c = createMarkerSymbol()
        symbol_c.setColor(QColor(0, 0, 255))
        renderer.addCategory(QgsRendererCategory('c', symbol_c, 'c', False))
        symbol_d = createMarkerSymbol()
        symbol_d.setColor(QColor(255, 0, 255))
        renderer.addCategory(QgsRendererCategory(['d', 'e'], symbol_d, 'de'))
        # add default category
        default_symbol = createMarkerSymbol()
        default_symbol.setColor(QColor(255, 255, 255))
        renderer.addCategory(QgsRendererCategory('', default_symbol, 'default'))

        context = QgsRenderContext()
        context.setRendererScale(0) # simulate counting
        renderer.startRender(context, fields)

        f = QgsFeature(fields)
        f.setAttributes(['a'])

        keys = renderer.legendKeysForFeature(f, context)
        self.assertEqual(keys, {'0'})

        f.setAttributes(['b'])
        keys = renderer.legendKeysForFeature(f, context)
        self.assertEqual(keys, {'1'})

        # hidden category, should still return keys
        f.setAttributes(['c'])
        keys = renderer.legendKeysForFeature(f, context)
        self.assertEqual(keys, {'2'})

        # list
        f.setAttributes(['d'])
        keys = renderer.legendKeysForFeature(f, context)
        self.assertEqual(keys, {'3'})
        f.setAttributes(['e'])
        keys = renderer.legendKeysForFeature(f, context)
        self.assertEqual(keys, {'3'})

        # no matching category
        f.setAttributes(['xxx'])
        keys = renderer.legendKeysForFeature(f, context)
        self.assertFalse(keys)

        renderer.stopRender(context)
    def testOriginalSymbolForFeature(self):
        # test renderer with features
        fields = QgsFields()
        fields.append(QgsField('x'))

        # setup renderer
        renderer = QgsCategorizedSymbolRenderer()
        renderer.setClassAttribute('x')

        symbol_a = createMarkerSymbol()
        symbol_a.setColor(QColor(255, 0, 0))
        renderer.addCategory(QgsRendererCategory('a', symbol_a, 'a'))
        symbol_b = createMarkerSymbol()
        symbol_b.setColor(QColor(0, 255, 0))
        renderer.addCategory(QgsRendererCategory('b', symbol_b, 'b'))
        symbol_c = createMarkerSymbol()
        symbol_c.setColor(QColor(0, 0, 255))
        renderer.addCategory(QgsRendererCategory('c', symbol_c, 'c', False))
        symbol_d = createMarkerSymbol()
        symbol_d.setColor(QColor(255, 0, 255))
        renderer.addCategory(QgsRendererCategory(['d', 'e'], symbol_d, 'de'))
        # add default category
        default_symbol = createMarkerSymbol()
        default_symbol.setColor(QColor(255, 255, 255))
        renderer.addCategory(QgsRendererCategory('', default_symbol, 'default'))

        context = QgsRenderContext()
        renderer.startRender(context, fields)

        f = QgsFeature(fields)
        f.setAttributes(['a'])

        symbol = renderer.originalSymbolForFeature(f, context)
        self.assertEqual(symbol.color(), QColor(255, 0, 0))

        f.setAttributes(['b'])
        symbol = renderer.originalSymbolForFeature(f, context)
        self.assertEqual(symbol.color(), QColor(0, 255, 0))

        # list
        f.setAttributes(['d'])
        symbol = renderer.originalSymbolForFeature(f, context)
        self.assertEqual(symbol.color(), QColor(255, 0, 255))
        f.setAttributes(['e'])
        symbol = renderer.originalSymbolForFeature(f, context)
        self.assertEqual(symbol.color(), QColor(255, 0, 255))

        # hidden category
        f.setAttributes(['c'])
        symbol = renderer.originalSymbolForFeature(f, context)
        self.assertIsNone(symbol)

        # no matching category
        f.setAttributes(['xxx'])
        symbol = renderer.originalSymbolForFeature(f, context)
        self.assertEqual(symbol.color(), QColor(255, 255, 255)) # default symbol

        renderer.stopRender(context)
Ejemplo n.º 18
0
    def stylePoly(self, layer, metric: str):
        """
        Style isochrone polygon layer.

        :param QgsVectorLayer layer: Polygon layer to be styled.
        :param str metric: distance or time.
        """
        field = layer.fields().lookupField('contour')
        unique_values = sorted(layer.uniqueValues(field))

        colors = {
            "distance": {
                0: QColor('#FCF0EE'),
                1: QColor('#F9E1DC'),
                2: QColor('#F6D2CB'),
                3: QColor('#F3C3BA'),
                4: QColor('#F0B3A8'),
                5: QColor('#EDA396'),
                6: QColor('#EA9485'),
                7: QColor('#E78573'),
                8: QColor('#E47662'),
                9: QColor('#E16651')
            },
            "time": {
                0: QColor('#2b83ba'),
                1: QColor('#64abb0'),
                2: QColor('#9dd3a7'),
                3: QColor('#c7e9ad'),
                4: QColor('#edf8b9'),
                5: QColor('#ffedaa'),
                6: QColor('#fec980'),
                7: QColor('#f99e59'),
                8: QColor('#e85b3a'),
                9: QColor('#d7191c')
            }
        }

        categories = []

        for cid, unique_value in enumerate(unique_values):
            # initialize the default symbol for this geometry type
            symbol = QgsSymbol.defaultSymbol(layer.geometryType())

            # configure a symbol layer
            symbol_layer = QgsSimpleFillSymbolLayer(
                color=colors[metric][cid], strokeColor=QColor('#000000'))

            # replace default symbol layer with the configured one
            if symbol_layer is not None:
                symbol.changeSymbolLayer(0, symbol_layer)

            # create renderer object
            category = QgsRendererCategory(unique_value, symbol,
                                           str(unique_value) + ' mins')
            # entry for the list of category items
            categories.append(category)

        # create renderer object
        renderer = QgsCategorizedSymbolRenderer('contour', categories)

        # assign the created renderer to the layer
        if renderer is not None:
            layer.setRenderer(renderer)
        layer.setOpacity(0.5)

        layer.triggerRepaint()
    def testWriteReadXml(self):
        # test writing renderer to xml and restoring

        renderer = QgsCategorizedSymbolRenderer()
        renderer.setClassAttribute('x')

        symbol_a = createMarkerSymbol()
        symbol_a.setColor(QColor(255, 0, 0))
        renderer.addCategory(QgsRendererCategory('a', symbol_a, 'a'))
        symbol_b = createMarkerSymbol()
        symbol_b.setColor(QColor(0, 255, 0))
        renderer.addCategory(QgsRendererCategory('b', symbol_b, 'b'))
        symbol_c = createMarkerSymbol()
        symbol_c.setColor(QColor(0, 0, 255))
        renderer.addCategory(QgsRendererCategory('c', symbol_c, 'c', False))
        symbol_d = createMarkerSymbol()
        symbol_d.setColor(QColor(255, 0, 255))
        renderer.addCategory(QgsRendererCategory(['d', 'e'], symbol_d, 'de'))
        # add default category
        default_symbol = createMarkerSymbol()
        default_symbol.setColor(QColor(255, 255, 255))
        renderer.addCategory(QgsRendererCategory('', default_symbol, 'default'))

        doc = QDomDocument("testdoc")
        elem = renderer.save(doc, QgsReadWriteContext())

        renderer2 = QgsCategorizedSymbolRenderer.create(elem, QgsReadWriteContext())
        self.assertEqual(renderer2.classAttribute(), 'x')
        self.assertEqual([l.label() for l in renderer2.categories()], ['a', 'b', 'c', 'de', 'default'])
        self.assertEqual([l.value() for l in renderer2.categories()], ['a', 'b', 'c', ['d', 'e'], ''])
        self.assertEqual([l.symbol().color().name() for l in renderer2.categories()], ['#ff0000', '#00ff00', '#0000ff', '#ff00ff', '#ffffff'])
Ejemplo n.º 20
0
    def legend_test(self):
        self.atlas_map.setAtlasDriven(True)
        self.atlas_map.setAtlasScalingMode(QgsLayoutItemMap.Auto)
        self.atlas_map.setAtlasMargin(0.10)

        # add a point layer
        ptLayer = QgsVectorLayer(
            "Point?crs=epsg:4326&field=attr:int(1)&field=label:string(20)",
            "points", "memory")

        pr = ptLayer.dataProvider()
        f1 = QgsFeature(1)
        f1.initAttributes(2)
        f1.setAttribute(0, 1)
        f1.setAttribute(1, "Test label 1")
        f1.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(-0.638, 48.954)))
        f2 = QgsFeature(2)
        f2.initAttributes(2)
        f2.setAttribute(0, 2)
        f2.setAttribute(1, "Test label 2")
        f2.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(-1.682, 48.550)))
        pr.addFeatures([f1, f2])

        # categorized symbology
        r = QgsCategorizedSymbolRenderer("attr", [
            QgsRendererCategory(
                1,
                QgsMarkerSymbol.createSimple({
                    "color": "255,0,0",
                    'outline_color': 'black'
                }), "red"),
            QgsRendererCategory(
                2,
                QgsMarkerSymbol.createSimple({
                    "color": "0,0,255",
                    'outline_color': 'black'
                }), "blue")
        ])
        ptLayer.setRenderer(r)

        QgsProject.instance().addMapLayer(ptLayer)

        # add the point layer to the map settings
        layers = self.layers
        layers = [ptLayer] + layers
        self.atlas_map.setLayers(layers)
        self.overview.setLayers(layers)

        # add a legend
        legend = QgsLayoutItemLegend(self.layout)
        legend.rstyle(QgsLegendStyle.Title).setFont(
            QgsFontUtils.getStandardTestFont('Bold', 20))
        legend.rstyle(QgsLegendStyle.Group).setFont(
            QgsFontUtils.getStandardTestFont('Bold', 18))
        legend.rstyle(QgsLegendStyle.Subgroup).setFont(
            QgsFontUtils.getStandardTestFont('Bold', 18))
        legend.rstyle(QgsLegendStyle.SymbolLabel).setFont(
            QgsFontUtils.getStandardTestFont('Bold', 14))

        legend.setTitle("Legend")
        legend.attemptMove(QgsLayoutPoint(200, 100))
        # sets the legend filter parameter
        legend.setLinkedMap(self.atlas_map)
        legend.setLegendFilterOutAtlas(True)
        self.layout.addLayoutItem(legend)

        self.atlas.beginRender()

        self.atlas.seekTo(0)
        self.mLabel1.adjustSizeToText()

        checker = QgsLayoutChecker('atlas_legend', self.layout)
        myTestResult, myMessage = checker.testLayout()
        self.report += checker.report()
        self.assertTrue(myTestResult, myMessage)

        self.atlas.endRender()

        # restore state
        self.atlas_map.setLayers([layers[1]])
        self.layout.removeLayoutItem(legend)
        QgsProject.instance().removeMapLayer(ptLayer.id())
    def testFilterExpression(self):
        """Test filter creation with expression"""
        renderer = QgsCategorizedSymbolRenderer()
        renderer.setClassAttribute("field + field2")

        renderer.addCategory(QgsRendererCategory("a", createMarkerSymbol(), "a"))
        renderer.addCategory(QgsRendererCategory("b", createMarkerSymbol(), "b"))
        renderer.addCategory(QgsRendererCategory("c", createMarkerSymbol(), "c"))
        # add default category
        renderer.addCategory(QgsRendererCategory("", createMarkerSymbol(), "default"))

        fields = QgsFields()
        fields.append(QgsField("field", QVariant.String))

        self.assertEqual(renderer.filter(fields), "")
        # remove categories, leaving default
        assert renderer.updateCategoryRenderState(0, False)
        self.assertEqual(renderer.filter(fields), "(field + field2) NOT IN ('a') OR (field + field2) IS NULL")
        assert renderer.updateCategoryRenderState(1, False)
        self.assertEqual(renderer.filter(fields), "(field + field2) NOT IN ('a','b') OR (field + field2) IS NULL")
        assert renderer.updateCategoryRenderState(2, False)
        self.assertEqual(renderer.filter(fields), "(field + field2) NOT IN ('a','b','c') OR (field + field2) IS NULL")
        # remove default category
        assert renderer.updateCategoryRenderState(3, False)
        self.assertEqual(renderer.filter(fields), "FALSE")
        # add back other categories, leaving default disabled
        assert renderer.updateCategoryRenderState(0, True)
        self.assertEqual(renderer.filter(fields), "(field + field2) IN ('a')")
        assert renderer.updateCategoryRenderState(1, True)
        self.assertEqual(renderer.filter(fields), "(field + field2) IN ('a','b')")
        assert renderer.updateCategoryRenderState(2, True)
        self.assertEqual(renderer.filter(fields), "(field + field2) IN ('a','b','c')")

        renderer.deleteAllCategories()
        # just default category
        renderer.addCategory(QgsRendererCategory("", createMarkerSymbol(), "default"))
        self.assertEqual(renderer.filter(fields), "")
        assert renderer.updateCategoryRenderState(0, False)
        self.assertEqual(renderer.filter(fields), "FALSE")

        renderer.deleteAllCategories()
        # no default category
        renderer.addCategory(QgsRendererCategory("a", createMarkerSymbol(), "a"))
        renderer.addCategory(QgsRendererCategory("b", createMarkerSymbol(), "b"))
        renderer.addCategory(QgsRendererCategory("c", createMarkerSymbol(), "c"))
        self.assertEqual(renderer.filter(fields), "(field + field2) IN ('a','b','c')")
        assert renderer.updateCategoryRenderState(0, False)
        self.assertEqual(renderer.filter(fields), "(field + field2) IN ('b','c')")
        assert renderer.updateCategoryRenderState(2, False)
        self.assertEqual(renderer.filter(fields), "(field + field2) IN ('b')")
        assert renderer.updateCategoryRenderState(1, False)
        self.assertEqual(renderer.filter(fields), "FALSE")

        renderer.deleteAllCategories()
        # numeric categories
        renderer.addCategory(QgsRendererCategory(1, createMarkerSymbol(), "a"))
        renderer.addCategory(QgsRendererCategory(2, createMarkerSymbol(), "b"))
        renderer.addCategory(QgsRendererCategory(3, createMarkerSymbol(), "c"))
        self.assertEqual(renderer.filter(fields), "(field + field2) IN (1,2,3)")
        assert renderer.updateCategoryRenderState(0, False)
        self.assertEqual(renderer.filter(fields), "(field + field2) IN (2,3)")
        assert renderer.updateCategoryRenderState(2, False)
        self.assertEqual(renderer.filter(fields), "(field + field2) IN (2)")
        assert renderer.updateCategoryRenderState(1, False)
        self.assertEqual(renderer.filter(fields), "FALSE")
Ejemplo n.º 22
0
    def testConvertFromCategorisedRenderer(self):
        # Test converting categorised renderer to rule based

        # First, try with a field based category (id)
        cats = []
        cats.append(QgsRendererCategory(1, QgsMarkerSymbol(), "id 1"))
        cats.append(QgsRendererCategory(2, QgsMarkerSymbol(), "id 2"))
        cats.append(QgsRendererCategory('a\'b', QgsMarkerSymbol(), "id a'b"))
        cats.append(QgsRendererCategory('a\nb', QgsMarkerSymbol(), "id a\\nb"))
        cats.append(QgsRendererCategory('a\\b', QgsMarkerSymbol(),
                                        "id a\\\\b"))
        cats.append(QgsRendererCategory('a\tb', QgsMarkerSymbol(), "id a\\tb"))
        cats.append(QgsRendererCategory(['c', 'd'], QgsMarkerSymbol(), "c/d"))
        c = QgsCategorizedSymbolRenderer("id", cats)

        r = QgsRuleBasedRenderer.convertFromRenderer(c)
        self.assertEqual(len(r.rootRule().children()), 7)
        self.assertEqual(r.rootRule().children()[0].filterExpression(),
                         '"id" = 1')
        self.assertEqual(r.rootRule().children()[1].filterExpression(),
                         '"id" = 2')
        self.assertEqual(r.rootRule().children()[2].filterExpression(),
                         '"id" = \'a\'\'b\'')
        self.assertEqual(r.rootRule().children()[3].filterExpression(),
                         '"id" = \'a\\nb\'')
        self.assertEqual(r.rootRule().children()[4].filterExpression(),
                         '"id" = \'a\\\\b\'')
        self.assertEqual(r.rootRule().children()[5].filterExpression(),
                         '"id" = \'a\\tb\'')
        self.assertEqual(r.rootRule().children()[6].filterExpression(),
                         '"id" IN (\'c\',\'d\')')

        # Next try with an expression based category
        cats = []
        cats.append(QgsRendererCategory(1, QgsMarkerSymbol(), "result 1"))
        cats.append(QgsRendererCategory(2, QgsMarkerSymbol(), "result 2"))
        cats.append(
            QgsRendererCategory([3, 4], QgsMarkerSymbol(), "result 3/4"))
        c = QgsCategorizedSymbolRenderer("id + 1", cats)

        r = QgsRuleBasedRenderer.convertFromRenderer(c)
        self.assertEqual(len(r.rootRule().children()), 3)
        self.assertEqual(r.rootRule().children()[0].filterExpression(),
                         'id + 1 = 1')
        self.assertEqual(r.rootRule().children()[1].filterExpression(),
                         'id + 1 = 2')
        self.assertEqual(r.rootRule().children()[2].filterExpression(),
                         'id + 1 IN (3,4)')

        # Last try with an expression which is just a quoted field name
        cats = []
        cats.append(QgsRendererCategory(1, QgsMarkerSymbol(), "result 1"))
        cats.append(QgsRendererCategory(2, QgsMarkerSymbol(), "result 2"))
        cats.append(
            QgsRendererCategory([3, 4], QgsMarkerSymbol(), "result 3/4"))
        c = QgsCategorizedSymbolRenderer('"id"', cats)

        r = QgsRuleBasedRenderer.convertFromRenderer(c)
        self.assertEqual(len(r.rootRule().children()), 3)
        self.assertEqual(r.rootRule().children()[0].filterExpression(),
                         '"id" = 1')
        self.assertEqual(r.rootRule().children()[1].filterExpression(),
                         '"id" = 2')
        self.assertEqual(r.rootRule().children()[2].filterExpression(),
                         '"id" IN (3,4)')
    def testOriginalSymbolForFeature(self):
        # test renderer with features
        fields = QgsFields()
        fields.append(QgsField('x'))

        # setup renderer
        renderer = QgsCategorizedSymbolRenderer()
        renderer.setClassAttribute('x')

        symbol_a = createMarkerSymbol()
        symbol_a.setColor(QColor(255, 0, 0))
        renderer.addCategory(QgsRendererCategory('a', symbol_a, 'a'))
        symbol_b = createMarkerSymbol()
        symbol_b.setColor(QColor(0, 255, 0))
        renderer.addCategory(QgsRendererCategory('b', symbol_b, 'b'))
        symbol_c = createMarkerSymbol()
        symbol_c.setColor(QColor(0, 0, 255))
        renderer.addCategory(QgsRendererCategory('c', symbol_c, 'c', False))
        # add default category
        default_symbol = createMarkerSymbol()
        default_symbol.setColor(QColor(255, 255, 255))
        renderer.addCategory(QgsRendererCategory('', default_symbol, 'default'))

        context = QgsRenderContext()
        renderer.startRender(context, fields)

        f = QgsFeature(fields)
        f.setAttributes(['a'])

        symbol = renderer.originalSymbolForFeature(f, context)
        self.assertEqual(symbol.color(), QColor(255, 0, 0))

        f.setAttributes(['b'])
        symbol = renderer.originalSymbolForFeature(f, context)
        self.assertEqual(symbol.color(), QColor(0, 255, 0))

        # hidden category
        f.setAttributes(['c'])
        symbol = renderer.originalSymbolForFeature(f, context)
        self.assertIsNone(symbol)

        # no matching category
        f.setAttributes(['xxx'])
        symbol = renderer.originalSymbolForFeature(f, context)
        self.assertEqual(symbol.color(), QColor(255, 255, 255)) # default symbol

        renderer.stopRender(context)
    def testFilterExpression(self):
        """Test filter creation with expression"""
        renderer = QgsCategorizedSymbolRenderer()
        renderer.setClassAttribute('field + field2')

        renderer.addCategory(QgsRendererCategory('a', createMarkerSymbol(), 'a'))
        renderer.addCategory(QgsRendererCategory('b', createMarkerSymbol(), 'b'))
        renderer.addCategory(QgsRendererCategory('c', createMarkerSymbol(), 'c'))
        # add default category
        renderer.addCategory(QgsRendererCategory('', createMarkerSymbol(), 'default'))

        fields = QgsFields()
        fields.append(QgsField('field', QVariant.String))

        self.assertEqual(renderer.filter(fields), '')
        # remove categories, leaving default
        assert renderer.updateCategoryRenderState(0, False)
        self.assertEqual(renderer.filter(fields), "(field + field2) NOT IN ('a') OR (field + field2) IS NULL")
        assert renderer.updateCategoryRenderState(1, False)
        self.assertEqual(renderer.filter(fields), "(field + field2) NOT IN ('a','b') OR (field + field2) IS NULL")
        assert renderer.updateCategoryRenderState(2, False)
        self.assertEqual(renderer.filter(fields), "(field + field2) NOT IN ('a','b','c') OR (field + field2) IS NULL")
        # remove default category
        assert renderer.updateCategoryRenderState(3, False)
        self.assertEqual(renderer.filter(fields), "FALSE")
        # add back other categories, leaving default disabled
        assert renderer.updateCategoryRenderState(0, True)
        self.assertEqual(renderer.filter(fields), "(field + field2) IN ('a')")
        assert renderer.updateCategoryRenderState(1, True)
        self.assertEqual(renderer.filter(fields), "(field + field2) IN ('a','b')")
        assert renderer.updateCategoryRenderState(2, True)
        self.assertEqual(renderer.filter(fields), "(field + field2) IN ('a','b','c')")

        renderer.deleteAllCategories()
        # just default category
        renderer.addCategory(QgsRendererCategory('', createMarkerSymbol(), 'default'))
        self.assertEqual(renderer.filter(fields), '')
        assert renderer.updateCategoryRenderState(0, False)
        self.assertEqual(renderer.filter(fields), 'FALSE')

        renderer.deleteAllCategories()
        # no default category
        renderer.addCategory(QgsRendererCategory('a', createMarkerSymbol(), 'a'))
        renderer.addCategory(QgsRendererCategory('b', createMarkerSymbol(), 'b'))
        renderer.addCategory(QgsRendererCategory('c', createMarkerSymbol(), 'c'))
        self.assertEqual(renderer.filter(fields), "(field + field2) IN ('a','b','c')")
        assert renderer.updateCategoryRenderState(0, False)
        self.assertEqual(renderer.filter(fields), "(field + field2) IN ('b','c')")
        assert renderer.updateCategoryRenderState(2, False)
        self.assertEqual(renderer.filter(fields), "(field + field2) IN ('b')")
        assert renderer.updateCategoryRenderState(1, False)
        self.assertEqual(renderer.filter(fields), "FALSE")

        renderer.deleteAllCategories()
        # numeric categories
        renderer.addCategory(QgsRendererCategory(1, createMarkerSymbol(), 'a'))
        renderer.addCategory(QgsRendererCategory(2, createMarkerSymbol(), 'b'))
        renderer.addCategory(QgsRendererCategory(3, createMarkerSymbol(), 'c'))
        self.assertEqual(renderer.filter(fields), '(field + field2) IN (1,2,3)')
        assert renderer.updateCategoryRenderState(0, False)
        self.assertEqual(renderer.filter(fields), "(field + field2) IN (2,3)")
        assert renderer.updateCategoryRenderState(2, False)
        self.assertEqual(renderer.filter(fields), "(field + field2) IN (2)")
        assert renderer.updateCategoryRenderState(1, False)
        self.assertEqual(renderer.filter(fields), "FALSE")
    def testFilter(self):
        """Test filter creation"""
        renderer = QgsCategorizedSymbolRenderer()
        renderer.setClassAttribute('field')

        renderer.addCategory(QgsRendererCategory('a', createMarkerSymbol(), 'a'))
        renderer.addCategory(QgsRendererCategory('b', createMarkerSymbol(), 'b'))
        renderer.addCategory(QgsRendererCategory('c', createMarkerSymbol(), 'c'))
        # add default category
        renderer.addCategory(QgsRendererCategory('', createMarkerSymbol(), 'default'))

        fields = QgsFields()
        fields.append(QgsField('field', QVariant.String))
        fields.append(QgsField('num', QVariant.Double))

        self.assertEqual(renderer.filter(fields), '')
        # remove categories, leaving default
        assert renderer.updateCategoryRenderState(0, False)
        self.assertEqual(renderer.filter(fields), "(\"field\") NOT IN ('a') OR (\"field\") IS NULL")
        assert renderer.updateCategoryRenderState(1, False)
        self.assertEqual(renderer.filter(fields), "(\"field\") NOT IN ('a','b') OR (\"field\") IS NULL")
        assert renderer.updateCategoryRenderState(2, False)
        self.assertEqual(renderer.filter(fields), "(\"field\") NOT IN ('a','b','c') OR (\"field\") IS NULL")
        # remove default category
        assert renderer.updateCategoryRenderState(3, False)
        self.assertEqual(renderer.filter(fields), "FALSE")
        # add back other categories, leaving default disabled
        assert renderer.updateCategoryRenderState(0, True)
        self.assertEqual(renderer.filter(fields), "(\"field\") IN ('a')")
        assert renderer.updateCategoryRenderState(1, True)
        self.assertEqual(renderer.filter(fields), "(\"field\") IN ('a','b')")
        assert renderer.updateCategoryRenderState(2, True)
        self.assertEqual(renderer.filter(fields), "(\"field\") IN ('a','b','c')")

        renderer.deleteAllCategories()
        # just default category
        renderer.addCategory(QgsRendererCategory('', createMarkerSymbol(), 'default'))
        self.assertEqual(renderer.filter(fields), '')
        assert renderer.updateCategoryRenderState(0, False)
        self.assertEqual(renderer.filter(fields), 'FALSE')

        renderer.deleteAllCategories()
        # no default category
        renderer.addCategory(QgsRendererCategory('a', createMarkerSymbol(), 'a'))
        renderer.addCategory(QgsRendererCategory('b', createMarkerSymbol(), 'b'))
        renderer.addCategory(QgsRendererCategory('c', createMarkerSymbol(), 'c'))
        self.assertEqual(renderer.filter(fields), "(\"field\") IN ('a','b','c')")
        assert renderer.updateCategoryRenderState(0, False)
        self.assertEqual(renderer.filter(fields), "(\"field\") IN ('b','c')")
        assert renderer.updateCategoryRenderState(2, False)
        self.assertEqual(renderer.filter(fields), "(\"field\") IN ('b')")
        assert renderer.updateCategoryRenderState(1, False)
        self.assertEqual(renderer.filter(fields), "FALSE")

        renderer.deleteAllCategories()
        renderer.setClassAttribute('num')
        # numeric categories
        renderer.addCategory(QgsRendererCategory(1, createMarkerSymbol(), 'a'))
        renderer.addCategory(QgsRendererCategory(2, createMarkerSymbol(), 'b'))
        renderer.addCategory(QgsRendererCategory(3, createMarkerSymbol(), 'c'))
        self.assertEqual(renderer.filter(fields), '(\"num\") IN (1,2,3)')
        assert renderer.updateCategoryRenderState(0, False)
        self.assertEqual(renderer.filter(fields), "(\"num\") IN (2,3)")
        assert renderer.updateCategoryRenderState(2, False)
        self.assertEqual(renderer.filter(fields), "(\"num\") IN (2)")
        assert renderer.updateCategoryRenderState(1, False)
        self.assertEqual(renderer.filter(fields), "FALSE")
Ejemplo n.º 26
0
    def processAlgorithm(self, parameters, context, feedback):
        project = QgsProject()
        project.setFileName(
            os.path.join(parameters[self.FOLDER], "all-outputs-qgis.qgs"))
        project.setCrs(QgsCoordinateReferenceSystem('EPSG:27700'))

        def getMaxValue(layer, fieldname):
            maxfound = float("-inf")
            for f in layer.getFeatures():
                attr = f.attribute(fieldname)
                assert attr >= 0
                if attr > maxfound:
                    maxfound = attr
            return maxfound

        with open(
                os.path.join(parameters[self.FOLDER],
                             "all-town-metadata.json")) as f:
            metadata = json.load(f)

        classmethods = {
            'quantile': QgsClassificationQuantile,
            'jenks': QgsClassificationJenks,
            'equal': QgsClassificationEqualInterval
        }

        html = ""
        output = []
        views_sorted_by_mode = sorted(metadata["views"],
                                      key=lambda v: v["mode"])
        for view in views_sorted_by_mode:
            keysymbol = u'🔑'
            viewname = view["label"]
            keysign = ""
            if viewname.find(keysymbol) != -1:
                viewname = viewname.replace(keysymbol, '', 1)
                keysign = "*** "
            viewname = keysign + view["mode"] + " " + viewname

            html += f"""
                    <h2>{viewname}</h2>
                    {view["description"]}
                    <ul>
                    """
            for layer in view["layers"]:
                layername = viewname + " - " + layer["scalar_field_units"]

                layerpath = os.path.join(parameters[self.FOLDER],
                                         layer["file"])
                vlayer = QgsVectorLayer(layerpath, layername, "ogr")
                if not vlayer.isValid():
                    feedback.pushInfo("Layer failed to load: " + layerpath)
                else:
                    context.temporaryLayerStore().addMapLayer(vlayer)
                    html += f"""<li><b>file:</b> {layer["file"]}"""
                    if "symbol_field" in layer:
                        html += f"""<ul>
                                    <li><b>symbol field:</b> {layer["symbol_field"]}
                                  </ul>
                                """
                        categories = []
                        scalar_fieldname = layer["scalar_field"]
                        maxvalue = getMaxValue(vlayer, scalar_fieldname)
                        feedback.pushInfo("Max value for %s is %f" %
                                          (scalar_fieldname, maxvalue))
                        for formality in ["I", "F"]:
                            for severity, colour in [(3, 'red'), (2, 'yellow'),
                                                     (1, 'green')]:
                                colour = {
                                    ("I", "red"): "#FF0000",
                                    ("I", "yellow"): "#FFFF00",
                                    ("I", "green"): "#00FF00",
                                    ("F", "red"): "#FF9999",
                                    ("F", "yellow"): "#FFFF66",
                                    ("F", "green"): "#99FF99",
                                }[(formality, colour)]
                                symbol_code = "%s%d" % (formality, severity)
                                if formality == "F":
                                    symbol = QgsMarkerSymbol.createSimple({
                                        'color':
                                        colour,
                                        'size':
                                        '3',
                                        'outline_color':
                                        '#888888'
                                    })
                                else:
                                    assert (formality == "I")
                                    symbol = QgsMarkerSymbol.createSimple({
                                        'color':
                                        colour,
                                        'size':
                                        '3',
                                        'outline_color':
                                        '#000000',
                                        'name':
                                        'star'
                                    })

                                objTransf = QgsSizeScaleTransformer(
                                    QgsSizeScaleTransformer.Flannery,
                                    0,  #minvalue
                                    maxvalue,  #maxvalue
                                    3,  #minsize
                                    10,  #maxsize
                                    0,  #nullsize
                                    1)  #exponent
                                objProp = QgsProperty()
                                objProp.setField(scalar_fieldname)
                                objProp.setTransformer(objTransf)
                                symbol.setDataDefinedSize(objProp)
                                label = {
                                    "F": "Formal",
                                    "I": "Informal"
                                }[formality] + " " + {
                                    3: "Major",
                                    2: "Secondary",
                                    1: "Tertiary"
                                }[severity]
                                cat = QgsRendererCategory(
                                    symbol_code, symbol, label, True)
                                categories.append(cat)
                        renderer = QgsCategorizedSymbolRenderer(
                            "Crossings", categories)
                        renderer.setClassAttribute(layer["symbol_field"])
                        vlayer.setRenderer(renderer)
                    else:
                        html += f"""<ul>
                                    <li><b>field:</b> {layer["scalar_field"]}
                                    <li><b>units:</b> {layer["scalar_field_units"]}
                                    <li><b>recommended classification:</b> {layer["classes"]}
                                  </ul>
                                """
                        default_style = QgsStyle().defaultStyle()
                        color_ramp = default_style.colorRamp('bt')
                        renderer = QgsGraduatedSymbolRenderer()
                        renderer.setClassAttribute(layer["scalar_field"])
                        classmethod = classmethods[layer["classes"]]()
                        renderer.setClassificationMethod(classmethod)
                        renderer.updateClasses(vlayer, 5)
                        renderer.updateColorRamp(color_ramp)
                        vlayer.setRenderer(renderer)

                    project.addMapLayer(vlayer)
                    feedback.pushInfo("Loaded " + layerpath)
            html += "</ul>"

        project.write()
        town = views_sorted_by_mode[0]["town"]
        with open(os.path.join(parameters[self.FOLDER], "metadata.html"),
                  "w") as htmlfile:
            htmlfile.write(
                f"<html><head><title>{town} metadata</title></head><body><h1>{town}</h1>{html}</body></html>"
            )
        return {self.OUTPUT: output}