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.º 2
0
    def run(self):

        #coloco el puntero arriba del todo
        #QgsProject.instance().layerTreeRegistryBridge().setLayerInsertionPoint( QgsProject.instance().layerTreeRoot(), 0 )
        #genero una lista con los campos de la capa selecionada
        layer = iface.activeLayer()
        if layer is None:
            iface.messageBar().pushMessage("ATENCION",
                                           "Selecciona una capa de puntos",
                                           duration=10)
        if layer.wkbType() == 1 or layer.wkbType() == 1001:
            prov = layer.dataProvider()
            field_names = [field.name() for field in prov.fields()]
            self.dlg.mycomboBox.clear()
            for element in field_names:
                self.dlg.mycomboBox.addItem(element)
            """Run method that performs all the real work"""

            # 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:
                global index_campo_seleccionado
                distanciaminima = int(self.dlg.lineEdit_distancia.text())
                # "layer" is a QgsVectorLayer instance
                layer = iface.activeLayer()
                idx = layer.fields().indexFromName("distanc")
                if idx == -1:
                    print("ya existe")
                    res = layer.dataProvider().addAttributes(
                        [QgsField("distanc", QVariant.String)])
                #layer.addAttribute(QgsField("valido", QVariant.String))
                layer.updateFields()
                features = layer.getFeatures()

                for feature in features:
                    # retrieve every feature with its geometry and attributes
                    #print("Feature ID: ", feature.id())
                    # fetch geometry
                    # show some information about the feature geometry
                    geom = feature.geometry()
                    geomSingleType = QgsWkbTypes.isSingleType(geom.wkbType())
                    if geom.type() == QgsWkbTypes.PointGeometry:
                        punto = geom.asPoint()
                        x = punto.x()
                        y = punto.y()
                        #print("analizo los puntos",x,y)
                        features2 = layer.getFeatures()
                        for feature2 in features2:
                            geom2 = feature2.geometry()
                            punto2 = geom2.asPoint()
                            x3 = punto2.x()
                            y3 = punto2.y()
                            d = ((x3 - x)**2 + (y3 - y)**2)**0.5
                            if d < distanciaminima:
                                if feature2.id() == feature.id():
                                    pass
                                else:
                                    layer.startEditing()
                                    feature.setAttribute("distanc", 'no')
                                    print(feature2.id())
                                    layer.updateFeature(feature)
                                    #Call commit to save the changes
                                    layer.commitChanges()

                categorias = []
                sym = QgsMarkerSymbol.createSimple({
                    'name': 'circle',
                    'color': 'red',
                    'size': '3'
                })
                categoria = QgsRendererCategory("no", sym, "No cumple")
                categorias.append(categoria)
                sym = QgsMarkerSymbol.createSimple({
                    'name': 'circle',
                    'color': 'blue',
                    'size': '2'
                })
                categoria = QgsRendererCategory("", sym, "Cumple")
                categorias.append(categoria)
                renderer = QgsCategorizedSymbolRenderer("distanc", categorias)
                layer.setRenderer(renderer)
                # update layer's extent when new features have been added
                # because change of extent in provider is not propagated to the layer

                #Configure label settings
                settings = QgsPalLayerSettings()
                settings.fieldName = field_names[
                    index_campo_seleccionado]  #'name'
                textFormat = QgsTextFormat()
                textFormat.setSize(10)
                settings.setFormat(textFormat)
                #create and append a new rule
                root = QgsRuleBasedLabeling.Rule(QgsPalLayerSettings())
                rule = QgsRuleBasedLabeling.Rule(settings)
                #rule.setDescription(fieldName)
                rule.setFilterExpression(''' "distanc" = 'no' ''')
                root.appendChild(rule)
                #Apply label configuration
                rules = QgsRuleBasedLabeling(root)
                layer.setLabeling(rules)
                layer.setLabelsEnabled(True)
                layer.triggerRepaint()

        else:
            iface.messageBar().pushMessage("ATENCION",
                                           "Selecciona una capa de puntos",
                                           duration=10)
Ejemplo n.º 3
0
    def testMultiPoint(self):
        """
        Test multipoint handling
        """
        layer = QgsVectorLayer('Multipoint?field=cat:string', '', 'memory')
        self.assertTrue(layer.isValid())

        f = QgsFeature(layer.fields())
        f.setAttributes(['a'])
        f.setGeometry(QgsGeometry.fromWkt('MultiPoint(5 5, 5 6, 9 9)'))
        layer.dataProvider().addFeature(f)
        f.setAttributes(['b'])
        f.setGeometry(QgsGeometry.fromWkt('MultiPoint(2 1, 2 2, 5 5)'))
        layer.dataProvider().addFeature(f)
        f.setAttributes(['c'])
        f.setGeometry(QgsGeometry.fromWkt('MultiPoint(9 1)'))
        layer.dataProvider().addFeature(f)

        renderer = QgsPointDisplacementRenderer()
        sym1 = QgsMarkerSymbol.createSimple({
            'color': '#ff00ff',
            'size': '3',
            'outline_style': 'no'
        })
        sym_renderer = QgsCategorizedSymbolRenderer()
        sym_renderer.setClassAttribute('cat')
        sym1.setColor(QColor(255, 0, 0))
        sym_renderer.addCategory(QgsRendererCategory('a', sym1.clone(), 'a'))
        sym1.setColor(QColor(0, 255, 0))
        sym_renderer.addCategory(QgsRendererCategory('b', sym1.clone(), 'b'))
        sym1.setColor(QColor(0, 0, 255))
        sym_renderer.addCategory(QgsRendererCategory('c', sym1.clone(), 'c'))
        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'
            }))
        renderer.setToleranceUnit(QgsUnitTypes.RenderMapUnits)
        renderer.setTolerance(2)
        layer.setRenderer(renderer)

        rendered_layers = [layer]
        mapsettings = QgsMapSettings()
        mapsettings.setOutputSize(QSize(400, 400))
        mapsettings.setOutputDpi(96)
        mapsettings.setExtent(QgsRectangle(0, 0, 10, 10))
        mapsettings.setLayers(rendered_layers)

        renderchecker = QgsMultiRenderChecker()
        renderchecker.setMapSettings(mapsettings)
        renderchecker.setControlPathPrefix('displacement_renderer')
        renderchecker.setControlName('expected_displacement_multipoint')
        result = renderchecker.runTest('expected_displacement_multipoint')
        self.report += renderchecker.report()
        self.assertTrue(result)
Ejemplo n.º 4
0
    def testConvertFromCategorisedRendererNoLayer(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)')

        # Next try with a complex name -- in this case since we don't have a layer or
        # actual field names available, we must assume the complex field name is actually an expression
        cats = []
        cats.append(QgsRendererCategory(1, QgsMarkerSymbol(),
                                        "fa_cy-fie+ld 1"))
        cats.append(QgsRendererCategory(2, QgsMarkerSymbol(),
                                        "fa_cy-fie+ld 2"))
        c = QgsCategorizedSymbolRenderer("fa_cy-fie+ld", cats)

        r = QgsRuleBasedRenderer.convertFromRenderer(c)
        self.assertEqual(r.rootRule().children()[0].filterExpression(),
                         'fa_cy-fie+ld = 1')
        self.assertEqual(r.rootRule().children()[1].filterExpression(),
                         'fa_cy-fie+ld = 2')
Ejemplo n.º 5
0
    def test_legend_key_to_expression(self):
        renderer = QgsCategorizedSymbolRenderer()
        renderer.setClassAttribute('field_name')

        exp, ok = renderer.legendKeyToExpression('xxxx', None)
        self.assertFalse(ok)

        # no categories
        exp, ok = renderer.legendKeyToExpression('0', None)
        self.assertFalse(ok)

        symbol_a = createMarkerSymbol()
        renderer.addCategory(QgsRendererCategory('a', symbol_a, 'a'))
        symbol_b = createMarkerSymbol()
        renderer.addCategory(QgsRendererCategory(5, symbol_b, 'b'))
        symbol_c = createMarkerSymbol()
        renderer.addCategory(QgsRendererCategory(5.5, symbol_c, 'c', False))
        symbol_d = createMarkerSymbol()
        renderer.addCategory(QgsRendererCategory(['d', 'e'], symbol_d, 'de'))

        exp, ok = renderer.legendKeyToExpression('0', None)
        self.assertTrue(ok)
        self.assertEqual(exp, "field_name = 'a'")

        exp, ok = renderer.legendKeyToExpression('1', None)
        self.assertTrue(ok)
        self.assertEqual(exp, "field_name = 5")

        exp, ok = renderer.legendKeyToExpression('2', None)
        self.assertTrue(ok)
        self.assertEqual(exp, "field_name = 5.5")

        exp, ok = renderer.legendKeyToExpression('3', None)
        self.assertTrue(ok)
        self.assertEqual(exp, "field_name IN ('d', 'e')")

        layer = QgsVectorLayer(
            "Point?field=field_name:double&field=fldint:integer", "addfeat",
            "memory")
        # with layer
        exp, ok = renderer.legendKeyToExpression('3', layer)
        self.assertTrue(ok)
        self.assertEqual(exp, "\"field_name\" IN ('d', 'e')")

        # with expression as attribute
        renderer.setClassAttribute('upper("field_name")')

        exp, ok = renderer.legendKeyToExpression('0', None)
        self.assertTrue(ok)
        self.assertEqual(exp, """upper("field_name") = 'a'""")

        exp, ok = renderer.legendKeyToExpression('1', None)
        self.assertTrue(ok)
        self.assertEqual(exp, """upper("field_name") = 5""")

        exp, ok = renderer.legendKeyToExpression('2', None)
        self.assertTrue(ok)
        self.assertEqual(exp, """upper("field_name") = 5.5""")

        exp, ok = renderer.legendKeyToExpression('3', None)
        self.assertTrue(ok)
        self.assertEqual(exp, """upper("field_name") IN ('d', 'e')""")

        exp, ok = renderer.legendKeyToExpression('3', layer)
        self.assertTrue(ok)
        self.assertEqual(exp, """upper("field_name") IN ('d', 'e')""")
    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.º 7
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
Ejemplo n.º 8
0
def stylize_map(layer: QgsVectorLayer) -> [List[str], List[str]]:
    """Stylize the layer with unique colors per timezone

    Args:
        layer (QgsVectorLayer): The layer to stylize

    Returns:
        [List[str], List[str]]: A list with all timezone ids and one with the respective color
    """

    print("Reading timezones from file")
    timezones = layer.uniqueValues(layer.fields().indexOf("tzid"))
    timezones = list(timezones)
    timezones.sort()

    categorized_renderer = QgsCategorizedSymbolRenderer()

    print("Stylizing map")

    timezone_ids = []
    timezone_colors = []
    features = layer.getFeatures()
    categories = []
    currentColor = 0

    for tz in timezones:
        # Modify the Etc timezones to match the Qt format

        qt_tz = tz

        # There are a few exceptions where the Qt timezone ids differ from the dataset ids:
        match = re.match(r"Etc/GMT([+-])(\d+)", tz)
        if match:
            qt_tz = f"UTC{match.group(1)}{match.group(2):0>2}:00"
        elif tz == "Etc/UTC":
            qt_tz = "UTC"
        elif tz == "Etc/GMT":
            qt_tz = "UTC+00:00"

        # Generate a consecutive color for each timezone
        currentColor += 25000
        r = (currentColor >> 16) & 255
        g = (currentColor >> 8 ) & 255
        b = (currentColor      ) & 255

        # Add it to the mapping
        rh = hex(r)[2:]
        gh = hex(g)[2:]
        bh = hex(b)[2:]
        timezone_ids.append(qt_tz)
        timezone_colors.append(f"#{rh:0>2}{gh:0>2}{bh:0>2}")

        symbol = QgsSymbol.defaultSymbol(layer.geometryType())
        symbol_layer = QgsSimpleFillSymbolLayer.create({"color": f"{r}, {g}, {b}"})
        symbol_layer.setStrokeWidth(0.0)
        symbol_layer.setStrokeStyle(Qt.PenStyle.NoPen)
        symbol.changeSymbolLayer(0, symbol_layer)

        category = QgsRendererCategory(tz, symbol, tz)
        categories.append(category)

    renderer = QgsCategorizedSymbolRenderer("tzid", categories)
    layer.setRenderer(renderer)
    layer.triggerRepaint()

    return timezone_ids, timezone_colors
Ejemplo n.º 9
0
    def _apply_symbology_fixed_divisions(self, layer, field, tbl_name, schema,
                                         min_v, max_v, steps):
        """Finds the amount of levels that is necessary to describe the layer,
        a maximum of 20 different levels is set.

        Parameters
        ----------
        layer: QgsVectorLayer
        field: str
        tbl_name: str
        schema: str
        min_v: float
        max_v: float
        steps: int
        """
        str_values = False
        if min_v is not None and max_v is not None:
            distinct_values = list(np.arange(min_v, max_v, steps))
        elif not str_values:
            distinct = self.db.get_distinct(tbl_name, field, schema)
            if len(distinct) == 1:
                return
            distinct_values = []
            distinct_count = []
            for value, count in distinct:
                if value is None:
                    continue
                distinct_values.append(value)
                distinct_count.append(count)
            if len(distinct_values) > 20:
                distinct_values.sort()
                temp_list = []
                for val in range(0, len(distinct_values), int(np.floor(len(distinct_values)/20))):
                    temp_list.append(distinct_values[val])
                if temp_list[-1] != distinct_values[-1]:
                    temp_list.append(distinct_values[-1])
                distinct_values = temp_list
        if isinstance(distinct_values[0], str):
            str_values = True
        colors = self._create_colors(len(distinct_values))
        if len(distinct_values) > 19 and not str_values:
            range_list = []
            for i in range(len(distinct_values) - 1):
                red, green, blue = colors[i]
                range_list.append(self._make_symbology(layer, distinct_values[i],
                                                     distinct_values[i + 1],
                                                     str(distinct_values[i]) + ' - ' + str(distinct_values[i + 1]),
                                                     QColor(int(red*255),int(green*255), int(blue*255), 128) ) )
            renderer = QgsGraduatedSymbolRenderer(field, range_list)
            renderer.setMode(QgsGraduatedSymbolRenderer.Custom )
        else:
            categories = []
            for i in range(len(distinct_values)):
                symbol = QgsSymbol.defaultSymbol(layer.geometryType())
                red, green, blue = colors[i]
                symbol.setColor(QColor(int(red*255),int(green*255), int(blue*255), 128))
                symbol.symbolLayer(0).setStrokeColor(QColor(int(red*255),int(green*255), int(blue*255), 128))
                category = QgsRendererCategory(str(distinct_values[i]), symbol, str(distinct_values[i]))
                categories.append(category)
            renderer = QgsCategorizedSymbolRenderer(field, categories)
            #renderer.setMode(QgsCategorizedSymbolRenderer.Custom)
        layer.setRenderer(renderer)
Ejemplo n.º 10
0
    def __build_lines(self) -> None:
        """
        Save the current self.__tmp_units in an in-memory layer called 'Parallel Unit Lines'
        Create a layer with the given name if it is not existing
        :return: Nothing
        """
        unit_list = list()
        for unit in self.__tmp_units:
            unit_list.append([unit[0], unit[1].asGeometry()])

        layers = [
            lyr for lyr in self.__iface.mapCanvas().layers()
            if lyr.name() == "Parallel Unit Lines"
        ]
        if len(layers) == 0:
            current_layer = self.__iface.mapCanvas().currentLayer()
            # noinspection PyArgumentList
            crs = QgsProject.instance().crs().toWkt()
            uri = "linestring?crs=wkt:{}&field=name:string(255)".format(crs)
            vector_layer = QgsVectorLayer(uri, "Parallel Unit Lines", "memory")
            # noinspection PyArgumentList
            QgsProject.instance().addMapLayer(vector_layer)
            self.__iface.mapCanvas().setCurrentLayer(current_layer)
        else:
            vector_layer = layers[0]

        if (not vector_layer.isValid()) or (vector_layer.type() !=
                                            QgsMapLayer.VectorLayer):
            self.__iface.messageBar(). \
                pushCritical("Wrong Layer Type",
                             "The layer \"Parallel Unit Lines\" cannot be created or has the wrong format")
            return

        vpr = vector_layer.dataProvider()
        fields = [f.name() for f in vpr.fields().toList()]
        if "name" not in fields:
            # noinspection PyArgumentList
            vpr.addAttributes([QgsField("name", QVariant.String, len=255)])

        name_field_index = vpr.fields().indexOf("name")
        if vpr.fields()[name_field_index].typeName().lower() != "string":
            self.__iface.messageBar(). \
                pushCritical("Wrong Attribute Type",
                             "The name attribute of the layer \"Parallel Unit Lines\" is not of type \"String\"!")
            return

        try:
            # adding the features to the layer
            for unit in unit_list:
                f = QgsFeature()
                f.setGeometry(unit[1])
                attr = list()
                for _ in vpr.fields().toList():
                    attr.append(None)
                attr[name_field_index] = unit[0]
                f.setAttributes(attr)
                vpr.addFeatures([f])

            vector_layer.updateExtents()

            # at least: try to set symbology
            symbology = list()
            for index in range(self.model.rowCount()):
                row = self.model.row(index)
                # noinspection PyArgumentList
                sym = QgsSymbol.defaultSymbol(vector_layer.geometryType())
                sym.setColor(row.color)
                sym.setWidth(0.4)
                category = QgsRendererCategory(row.name, sym, row.name)
                symbology.append(category)

            renderer = QgsCategorizedSymbolRenderer("name", symbology)
            vector_layer.setRenderer(renderer)
            vector_layer.triggerRepaint()

        except Exception as e:
            _, _, exc_traceback = sys.exc_info()
            text = "Error Message:\n{}\nTraceback:\n{}".format(
                str(e), '\n'.join(traceback.format_tb(exc_traceback)))
            # noinspection PyTypeChecker,PyCallByClass
            QgsMessageLog.logMessage(text, level=2)
        finally:
            self.reset()
Ejemplo n.º 11
0
def add_design_to_map(qris_project, item, node):
    """adds designs to the map"""
    # Establish paths to layers
    design_id = item.data(item_code['feature_id'])
    subset_string = ("design_id = " + str(design_id))
    design_name = item.text()
    geopackage_path = qris_project.project_designs.geopackage_path(
        qris_project.project_path)
    designs_layer = QgsVectorLayer(geopackage_path + "|layername=designs",
                                   "Designs", "ogr")
    structure_types_layer = QgsVectorLayer(
        geopackage_path + "|layername=structure_types", "Structure Types",
        "ogr")
    phases_layer = QgsVectorLayer(geopackage_path + "|layername=phases",
                                  "Implementation Phases", "ogr")
    zoi_layer = QgsVectorLayer(geopackage_path + "|layername=zoi", "ZOI",
                               "ogr")
    zoi_types_layer = QgsVectorLayer(geopackage_path + "|layername=zoi_types",
                                     "ZOI", "ogr")
    complexes_layer = QgsVectorLayer(geopackage_path + "|layername=complexes",
                                     "Complexes", "ogr")
    structure_points_layer = QgsVectorLayer(
        geopackage_path + "|layername=structure_points", "Structures", "ogr")
    structure_lines_layer = QgsVectorLayer(
        geopackage_path + "|layername=structure_lines", "Structures", "ogr")

    # Get the structure geometry type
    # Could also do this with SQL
    design_iterator = designs_layer.getFeatures(
        QgsFeatureRequest().setFilterFid(design_id))
    design_feature = next(design_iterator)
    structure_geometry = design_feature['structure_geometry']

    def add_design_table(display_name, table_name, qml_name, read_only,
                         group_node):
        """A handy way to add design layers and tables to the map"""
        if not any([c.name() == display_name for c in group_node.children()]):
            layer = QgsProject.instance().addMapLayer(
                QgsVectorLayer(geopackage_path + "|layername=" + table_name,
                               display_name, "ogr"), False)
            if qml_name:
                layer_qml = os.path.join(symbology_path, 'symbology', qml_name)
                layer.loadNamedStyle(layer_qml)
            if read_only:
                layer.setReadOnly()
            group_node.addLayer(layer)

    # Summary tables (views)
    if any([c.name() == "Low-Tech Tables" for c in node.children()]):
        # if is there set it to the design node
        table_node = next(n for n in node.children()
                          if n.name() == "Low-Tech Tables")
    else:
        # if not add the node as a group
        table_node = node.addGroup("Low-Tech Tables")
        table_node.setExpanded(False)

    # Summary tables (views)
    if any([c.name() == "Summary Tables" for c in table_node.children()]):
        # if is there set it to the design node
        summary_node = next(n for n in table_node.children()
                            if n.name() == "Summary Tables")
    else:
        # if not add the node as a group
        summary_node = table_node.addGroup("Summary Tables")
        summary_node.setExpanded(False)

    add_design_table('Structure Totals - Points',
                     'qry_total_structures_points', None, True, summary_node)
    add_design_table('Structure Totals - Lines', 'qry_total_structures_lines',
                     None, True, summary_node)
    add_design_table('Structure Summary - Points',
                     'qry_structure_summary_points', None, True, summary_node)
    add_design_table('Structure Summary - Lines',
                     'qry_structure_summary_lines', None, True, summary_node)
    add_design_table('Complexes Summary - Points',
                     'qry_complexes_by_type_points', None, True, summary_node)
    add_design_table('Complexes Summary - Lines',
                     'qry_complexes_by_type_lines', None, True, summary_node)
    add_design_table('ZOI Summary', 'qry_zoi_summary', None, True,
                     summary_node)

    # Lookup Tables
    if any([c.name() == "Lookup Tables" for c in table_node.children()]):
        # if is there set it to the design node
        lookup_node = next(n for n in table_node.children()
                           if n.name() == "Lookup Tables")
    else:
        # if not add the node as a group
        lookup_node = table_node.addGroup("Lookup Tables")
        lookup_node.setExpanded(False)

    add_design_table('Design Status', 'lkp_design_status',
                     'lkp_design_status.qml', True, lookup_node)
    add_design_table('Phase Action', 'lkp_phase_action',
                     'lkp_phase_action.qml', True, lookup_node)
    add_design_table('ZOI Influence', 'lkp_zoi_influence',
                     'lkp_zoi_influence.qml', True, lookup_node)
    add_design_table('ZOI Stage', 'lkp_zoi_stage', 'lkp_zoi_stage.qml', True,
                     lookup_node)
    add_design_table('Structure Mimics', 'lkp_structure_mimics',
                     'lkp_structure_mimics.qml', True, lookup_node)

    # Add Design Tables
    if any([c.name() == "Design Tables" for c in table_node.children()]):
        # if is there set it to the design node
        design_tables_node = next(n for n in table_node.children()
                                  if n.name() == "Design Tables")
    else:
        # if not add the node as a group
        design_tables_node = table_node.addGroup("Design Tables")
        design_tables_node.setExpanded(False)

    # Check if the designs table has been added and if not add it.
    add_design_table('Designs', 'designs', 'designs.qml', False,
                     design_tables_node)
    add_design_table('Structure Types', 'structure_types',
                     'structure_types.qml', False, design_tables_node)
    add_design_table('ZOI Types', 'zoi_types', 'zoi_types.qml', False,
                     design_tables_node)
    add_design_table('Phases', 'phases', 'phases.qml', False,
                     design_tables_node)

    # Check if the design node is already added
    design_group_name = str(design_id) + "-" + item.text()
    if any([c.name() == design_group_name for c in node.children()]):
        # if is there set it to the design node
        design_node = next(n for n in node.children()
                           if n.name() == design_group_name)
    else:
        # if not add the node as a group
        design_node = node.addGroup(design_group_name)

    # Add structures
    structure_layer_name = str(design_id) + "-Structures"
    if structure_geometry == 'Point':
        # Start setting custom symbology
        # TODO Refactor into a functio
        unique_values = []
        for feature in structure_types_layer.getFeatures():
            values = (feature["fid"], feature["name"])
            unique_values.append(values)
        categories = []
        for value in unique_values:
            layer_style = {}
            layer_style["color"] = '%d, %d, %d' % (randrange(
                0, 256), randrange(0, 256), randrange(0, 256))
            layer_style['size'] = '3'
            layer_style['outline_color'] = 'black'
            symbol_layer = QgsMarkerSymbol.createSimple(layer_style)
            category = QgsRendererCategory(str(value[0]), symbol_layer,
                                           value[1])
            categories.append(category)
        renderer = QgsCategorizedSymbolRenderer('structure_type_id',
                                                categories)

        if not any(
            [c.name() == structure_layer_name
             for c in design_node.children()]):
            # Adding the type suffix as I could see adding qml that symbolizes on other attributes
            structure_points_qml = os.path.join(symbology_path, 'symbology',
                                                'structure_points.qml')
            structure_points_layer.loadNamedStyle(structure_points_qml)
            QgsExpressionContextUtils.setLayerVariable(structure_points_layer,
                                                       'parent_id', design_id)
            structure_points_layer.setSubsetString(subset_string)
            QgsProject.instance().addMapLayer(structure_points_layer, False)
            structure_points_layer.setName(structure_layer_name)
            design_node.addLayer(structure_points_layer)
            layer_node = design_node.findLayer(structure_points_layer.id())
            layer_node.setExpanded(False)
        else:
            structure_points_layer = QgsProject.instance().mapLayersByName(
                structure_layer_name)[0]
        if renderer is not None:
            structure_points_layer.setRenderer(renderer)
            structure_points_layer.triggerRepaint()

    else:
        # Add line structures
        # Start setting custom symbology
        # TODO Refactor into a function
        unique_values = []
        for feature in structure_types_layer.getFeatures():
            values = (feature["fid"], feature["name"])
            unique_values.append(values)

        categories = []
        for value in unique_values:
            layer_style = {}
            layer_style["color"] = '%d, %d, %d' % (randrange(
                0, 256), randrange(0, 256), randrange(0, 256))
            layer_style['width'] = '1'
            layer_style['capstyle'] = 'round'
            symbol_layer = QgsLineSymbol.createSimple(layer_style)
            category = QgsRendererCategory(str(value[0]), symbol_layer,
                                           value[1])
            categories.append(category)
        renderer = QgsCategorizedSymbolRenderer('structure_type_id',
                                                categories)
        # end custom symbology

        if not any(
            [c.name() == structure_layer_name
             for c in design_node.children()]):
            structures_lines_qml = os.path.join(symbology_path, 'symbology',
                                                'structure_lines.qml')
            structure_lines_layer.loadNamedStyle(structures_lines_qml)
            QgsExpressionContextUtils.setLayerVariable(structure_lines_layer,
                                                       'parent_id', design_id)
            structure_lines_layer.setSubsetString(subset_string)
            QgsProject.instance().addMapLayer(structure_lines_layer, False)
            structure_lines_layer.setName(structure_layer_name)
            design_node.addLayer(structure_lines_layer)
            layer_node = design_node.findLayer(structure_lines_layer.id())
            layer_node.setExpanded(False)
        else:
            structure_lines_layer = QgsProject.instance().mapLayersByName(
                structure_layer_name)[0]
        if renderer is not None:
            structure_lines_layer.setRenderer(renderer)
            structure_lines_layer.triggerRepaint()

    # Add zoi
    zoi_layer_name = str(design_id) + "-ZOI"
    # TODO Refactor into a function
    # TODO Refactor into sql query
    unique_values = []
    for feature in zoi_types_layer.getFeatures():
        values = (feature["fid"], feature["name"])
        unique_values.append(values)
    categories = []
    for value in unique_values:
        layer_style = {}
        alpha = 60
        layer_style["color"] = "{}, {}, {}, {}".format(randrange(0, 256),
                                                       randrange(0, 256),
                                                       randrange(0, 256),
                                                       alpha)
        layer_style["outline_width"] = '0.50'
        layer_style["outline_style"] = 'dash'
        symbol_layer = QgsFillSymbol.createSimple(layer_style)
        category = QgsRendererCategory(str(value[0]), symbol_layer, value[1])
        categories.append(category)
    renderer = QgsCategorizedSymbolRenderer('influence_type_id', categories)
    # End custom symbology

    # check for the zoi layer, and if it is not there symbolize and add it
    if not any([c.name() == zoi_layer_name for c in design_node.children()]):
        zoi_qml = os.path.join(symbology_path, 'symbology', 'zoi.qml')
        zoi_layer.loadNamedStyle(zoi_qml)
        QgsExpressionContextUtils.setLayerVariable(zoi_layer, 'parent_id',
                                                   design_id)
        zoi_layer.setSubsetString(subset_string)
        QgsProject.instance().addMapLayer(zoi_layer, False)
        zoi_layer.setName(zoi_layer_name)
        design_node.addLayer(zoi_layer)
        layer_node = design_node.findLayer(zoi_layer.id())
        layer_node.setExpanded(False)
    else:
        zoi_layer = QgsProject.instance().mapLayersByName(zoi_layer_name)[0]
    if renderer is not None:
        zoi_layer.setRenderer(renderer)
    zoi_layer.triggerRepaint()

    # Add complexes
    complex_layer_name = str(design_id) + "-Complexes"
    if not any(
        [c.name() == complex_layer_name for c in design_node.children()]):
        complex_qml = os.path.join(symbology_path, 'symbology',
                                   'complexes.qml')
        complexes_layer.loadNamedStyle(complex_qml)
        QgsExpressionContextUtils.setLayerVariable(complexes_layer,
                                                   'parent_id', design_id)
        complexes_layer.setSubsetString(subset_string)
        QgsProject.instance().addMapLayer(complexes_layer, False)
        complexes_layer.setName(complex_layer_name)
        design_node.addLayer(complexes_layer)
    def run(self):
        """Run method that performs all the real work"""
        
        layers = self.iface.mapCanvas().layers()
        layer_list = []
        self.dlg.layerComboBox.clear()
        for layer in layers:
            layer_list.append(layer.name())
        self.dlg.layerComboBox.addItems(layer_list)
        # TODO: Make the active layer the selected item in combo box  aLayer = qgis.utils.iface.activeLayer()
        
        # TODO: Add signal to update toleranceSpinBox.suffix (Degrees) from layerComboBox.crs.mapUnits when layer is selected:
        #my_UnitType = { 0: 'Meters', 1: 'Feet', 2: 'Degrees', 7: 'NauticalMiles', 8: 'Kilometers', 9: 'Yards', 10: 'Miles', 3: 'UnknownUnit'}
        #suffix = my_UnitType[aLayer.crs().mapUnits()]
        
        # show the dialog
        self.dlg.show()
        # Run the dialog event loop
        result = self.dlg.exec_()
        # See if OK was pressed
        if result:
            if self.checkNetworkXModule() < 0:
                return -4
            import networkx as nx
            
            layerName = self.dlg.layerComboBox.currentText()
            try:
                aLayer = QgsProject.instance().mapLayersByName(layerName)[0]
            except:
                self.iface.messageBar().pushMessage("Error", "Failed to load layer!", level=Qgis.Critical)
                return -1

            try:

                previousEditingMode = True
                if not aLayer.isEditable():
                    aLayer.startEditing()
                    #self.iface.messageBar().pushMessage("Info", "Layer " + aLayer.name() + " needs to be in edit mode", level=Qgis.Info)
                    #self.iface.messageBar().pushMessage("Error", "Layer " + aLayer.name() + " needs to be in edit mode", level=Qgis.Critical)
                    #return -2
                    previousEditingMode = False
                     
                attrIdx = self.getAttributeIndex(aLayer)
                if attrIdx < 0:
                    return -3  

                progressMessageBar = self.iface.messageBar().createMessage("Creating network graph...")
                progress = QProgressBar()
                progress.setMaximum(aLayer.featureCount())
                progress.setAlignment(Qt.AlignLeft|Qt.AlignVCenter)
                progressMessageBar.layout().addWidget(progress)
                self.iface.messageBar().pushWidget(progressMessageBar, Qgis.Info)          
                
                G = nx.Graph()

                aLayer.beginEditCommand("Clear group attribute, create graph")
                # construct undirected graph
                tolerance = self.dlg.toleranceSpinBox.value()
                if tolerance == 0:
                    tolerance = 0.000001
                count = 0
                for feat in aLayer.getFeatures():
                    count += 1
                    progress.setValue(count)
                    done = aLayer.changeAttributeValue(feat.id(), attrIdx, -1)
                    geom = feat.geometry()
                    QgsGeometry.convertToSingleType(geom)       # QGIS 3.x seems to load single LineString as MultiLineString??
                    line = geom.asPolyline()
                    
                    for i in range(len(line)-1):
                        G.add_edges_from([((int(line[i][0]/tolerance), int(line[i][1]/tolerance)), (int(line[i+1][0]/tolerance), int(line[i+1][1]/tolerance)), 
                                          {'fid': feat.id()})])     # first scale by tolerance, then convert to int.  Before doing this, there were problems (in NetworkX v1) with floats not equating, thus creating disconnects that weren't there.
                    if count % 100 == 0:
                        QApplication.processEvents()      # keep the UI responsive, every 100 features
                        #TODO: check to see if Esc pressed

                aLayer.endEditCommand()
                
                self.iface.messageBar().pushMessage("Finding connected subgraphs, please wait...",  level=Qgis.Warning)     # WARNING - to highlight the next stage, where we cannot show progress
                QApplication.processEvents()
                connected_components = list(G.subgraph(c) for c in nx.connected_components(G)) # this takes a long time.  TODO: how to show progress?
                self.iface.messageBar().pushMessage("Updating group attribute...",  level=Qgis.Info)
                QApplication.processEvents()
                          
                # gather edges and components to which they belong
                fid_comp = {}
                for i, graph in enumerate(connected_components):
                   for edge in graph.edges(data=True):
                       fid_comp[edge[2].get('fid', None)] = i
                
                # write output to csv file
                #with open('C:/Tmp/Components.csv', 'wb') as f:
                #    w = csv.DictWriter(f, fieldnames=['fid', 'group'])
                #    w.writeheader()
                #    for (fid, group) in fid_comp.items():
                #        w.writerow({'fid': fid, 'group': group})
                
                aLayer.beginEditCommand("Update group attribute")
                for (fid, group) in fid_comp.items():
                    done = aLayer.changeAttributeValue(fid, attrIdx, group)
                aLayer.endEditCommand()
                
                groups = list(set(fid_comp.values()))            
                if self.dlg.stylingCheckBox.isChecked():
                    aLayer.beginEditCommand("Update layer styling")
                    categories = []
                    firstCat = True
                    for cat in groups:
                        symbol = QgsSymbol.defaultSymbol(aLayer.geometryType())
                        symbol.setColor(QColor(randint(0,255), randint(0,255), randint(0,255)))
                        if firstCat:
                            firstCat = False
                        else:
                            symbol.setWidth(symbol.width()*5)
                        category = QgsRendererCategory(cat, symbol, "%d" % cat)
                        categories.append(category)

                    field = self.dlg.attributeNameEditBox.text()
                    renderer = QgsCategorizedSymbolRenderer(field, categories)
                    aLayer.setRenderer(renderer)

#                    if self.iface.mapCanvas().isCachingEnabled():
#                        aLayer.setCacheImage(None)
#                    else:
#                        self.iface.mapCanvas().refresh()
                    aLayer.triggerRepaint()
                    aLayer.endEditCommand()            
                   
                self.iface.messageBar().clearWidgets()   
                self.iface.messageBar().pushMessage("Found main network and %d disconnected islands in layer %s" % (len(groups)-1, aLayer.name()),  level=Qgis.Success)

                aLayer.commitChanges()
#                if not previousEditingMode: 
    
            except Exception as e:
                self.iface.messageBar().pushMessage("Error", "Exception caught: %s.  Please report an issue to the author of the plugin." % repr(e), level=Qgis.Critical)
                
Ejemplo n.º 13
0
    def on_classifyPushButton_clicked(self):

        input_raster_layer_name = self.rasterLayerComboBox.currentText()
        input_vector_layer_name = self.vectorLayerComboBox.currentText()

        # 调用QGIS区域统计工具

        processing.run(
            'qgis:zonalstatistics', {
                'INPUT_RASTER': input_raster_layer_name,
                'RASTER_BAND': 1,
                'INPUT_VECTOR': input_vector_layer_name,
                'COLUMN_PREFIX': 'Band1_',
                'STATS': 2
            })
        processing.run(
            'qgis:zonalstatistics', {
                'INPUT_RASTER': input_raster_layer_name,
                'RASTER_BAND': 2,
                'INPUT_VECTOR': input_vector_layer_name,
                'COLUMN_PREFIX': 'Band2_',
                'STATS': 2
            })
        processing.run(
            'qgis:zonalstatistics', {
                'INPUT_RASTER': input_raster_layer_name,
                'RASTER_BAND': 3,
                'INPUT_VECTOR': input_vector_layer_name,
                'COLUMN_PREFIX': 'Band3_',
                'STATS': 2
            })
        # QgsProject.instance().addMapLayer(vector_layer)

        # 获取计算结果

        input_vector_layer = QgsProject.instance().mapLayersByName(
            input_vector_layer_name)[0]

        features = input_vector_layer.getFeatures()
        feature_id_list = []
        feature_band_list = []
        for feature in features:
            feature_id_list.append(feature.id())
            feature_band_list.append([
                feature['Band1_mean'], feature['Band2_mean'],
                feature['Band3_mean']
            ])

        # 聚类

        cluster_num = self.spinBox.value()
        cluster_result = cluster(np.array(feature_band_list))

        # 添加聚类结果到字段,字段存在则删除。只要涉及字段操作,每次操作都要更新字段

        field_name_list = [
            field.name() for field in input_vector_layer.fields()
        ]
        if 'cluster_id' in field_name_list:
            input_vector_layer.dataProvider().deleteAttributes(
                [field_name_list.index('cluster_id')])
            input_vector_layer.updateFields()

        input_vector_layer.dataProvider().addAttributes(
            [QgsField("cluster_id", QVariant.Int)])
        input_vector_layer.updateFields()
        field_name_list = [
            field.name() for field in input_vector_layer.fields()
        ]
        print(field_name_list)
        cluster_id_field_index = field_name_list.index('cluster_id')

        for index, fid in enumerate(feature_id_list):
            attrs = {cluster_id_field_index: int(cluster_result[index])}
            change_result = input_vector_layer.dataProvider(
            ).changeAttributeValues({fid: attrs})
            print(fid)
            print(attrs)
            print(change_result)
        input_vector_layer.updateFields()

        # 符号化

        categorized_renderer = QgsCategorizedSymbolRenderer()
        categorized_renderer.setClassAttribute('cluster_id')

        for cluster_id in range(cluster_num):
            fill_symbol = QgsFillSymbol.createSimple({})
            fill_symbol.setColor(
                QtGui.QColor(*np.random.randint(0, 256, 3), 200))
            categorized_renderer.addCategory(
                QgsRendererCategory(cluster_id, fill_symbol,
                                    f'cluster {cluster_id}'))
        input_vector_layer.setRenderer(categorized_renderer)
Ejemplo n.º 14
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()
Ejemplo n.º 15
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)')
Ejemplo n.º 16
0
    def run(self):
        """Run method that performs all the real work"""

        # 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
            self.dlg = HealthSIGDialog()

        # Clear the contents of the comboBox from previous runs
        self.dlg.comboBox.clear()
        # Populate the comboBox
        self.dlg.comboBox.addItems(["Hospitais", "ACES", "Farmácias"])
        # show the dialog
        self.dlg.show()
        # Run the dialog event loop
        result = self.dlg.exec_()

        # See if OK was pressed and check index
        index = self.dlg.comboBox.currentIndex()

        # file directory for relative paths
        dirn = os.path.dirname(__file__)

        # escolheu unidades de saude
        if result and index == 1:
            # create layer
            vl = QgsVectorLayer("Point?crs=epsg:3763&index=yes", "aces",
                                "memory")
            pr = vl.dataProvider()

            # Enter editing mode
            vl.startEditing()

            # add fields
            pr.addAttributes([
                QgsField("ACES", QVariant.String),
                QgsField("ARS", QVariant.String),
                QgsField("Coord_X", QVariant.Double),
                QgsField("Coord_Y", QVariant.Double),
                QgsField("Num_USF", QVariant.Int)
            ])
            vl.updateFields(
            )  # tell the vector layer to fetch changes from the provider

            # add features ---> IR BUSCAR AO JSON....
            filename = os.path.join(dirn, 'unidades_saude.json')
            #with open("/home/skywalker/.local/share/QGIS/QGIS3/profiles/default/python/plugins/health_sig/unidades_saude.json",
            #          "r") as read_file:
            with open(filename, "r") as read_file:
                json_file = json.load(read_file)

            # transformar coordenadas gps para as pretendidas
            crsSrc = QgsCoordinateReferenceSystem(4326)  # gps
            crsDest = QgsCoordinateReferenceSystem(3763)  # pt
            xform = QgsCoordinateTransform(crsSrc, crsDest,
                                           QgsProject.instance())

            # addfeatures
            for entry in json_file:
                if entry["fields"]["tempo"] == "2019-01":  # valores recentes
                    x_coord = float(entry["geometry"]["coordinates"][0])
                    y_coord = float(entry["geometry"]["coordinates"][1])
                    num_usf = int(
                        entry["fields"]
                        ["total_usf"])  #numero de unidades de saude familiares
                    entidade = entry["fields"]["entidade"]
                    ars = entry["fields"]["ars"]
                    fet = QgsFeature()
                    fet.setGeometry(QgsGeometry().buffer(
                        distance=num_usf * 10, segments=100).fromPointXY(
                            xform.transform(QgsPointXY(x_coord, y_coord))))
                    fet.setAttributes([
                        QVariant(entidade),
                        QVariant(ars),
                        QVariant(x_coord),
                        QVariant(y_coord),
                        QVariant(num_usf)
                    ])
                    pr.addFeatures([fet])

            vl.updateExtents()
            vl.commitChanges()

            # fazer render categorizado
            features = vl.getFeatures()

            categories = []

            for feat in features:

                f = feat.attributes()[4]  # num_usf
                entidade = feat.attributes()[0]  # entidade
                symbol = QgsSymbol.defaultSymbol(vl.geometryType())
                svgStyle = {}
                path_uni = os.path.join(dirn, 'medicine.svg')
                svgStyle['name'] = path_uni
                svgStyle['size'] = str((f / 10) + 1)

                symbol_layer = QgsSvgMarkerSymbolLayer.create(svgStyle)

                if symbol_layer is not None:
                    symbol.changeSymbolLayer(0, symbol_layer)

                # create renderer object
                category = QgsRendererCategory(f, symbol, str(entidade))
                # entry for the list of category items
                categories.append(category)

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

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

            vl.triggerRepaint()

            QgsProject.instance().addMapLayer(vl)

        # hospitais
        elif result and index == 0:
            vl = QgsVectorLayer("Point?crs=epsg:3763&index=yes", "hospitais",
                                "memory")
            pr = vl.dataProvider()

            # Enter editing mode
            vl.startEditing()

            # add fields
            pr.addAttributes([
                QgsField("Hospital", QVariant.String),
                QgsField("Morada", QVariant.String),
                QgsField("Coord_X", QVariant.Double),
                QgsField("Coord_Y", QVariant.Double)
            ])
            vl.updateFields(
            )  # tell the vector layer to fetch changes from the provider

            # add features ---> IR BUSCAR AO JSON....
            filename = os.path.join(dirn, 'hospitais.json')

            with open(filename, "r") as read_file:
                json_file = json.load(read_file)

            # transformar coordenadas gps para as pretendidas
            crsSrc = QgsCoordinateReferenceSystem(4326)  # gps
            crsDest = QgsCoordinateReferenceSystem(3763)  # pt
            xform = QgsCoordinateTransform(crsSrc, crsDest,
                                           QgsProject.instance())

            # addfeatures
            for entry in json_file.keys():

                x_coord = float(json_file[entry][1][1])
                y_coord = float(json_file[entry][1][0])
                morada = json_file[entry][0]
                fet = QgsFeature()
                fet.setGeometry(QgsGeometry().fromPointXY(
                    xform.transform(QgsPointXY(x_coord, y_coord))))
                fet.setAttributes([
                    QVariant(entry),
                    QVariant(morada),
                    QVariant(x_coord),
                    QVariant(y_coord)
                ])
                pr.addFeatures([fet])

            vl.updateExtents()
            vl.commitChanges()

            #symbol = QgsMarkerSymbol.createSimple({'name': 'square', 'color': 'red'})
            svgStyle = {}
            path_hosp = os.path.join(dirn, 'hospital.svg')
            svgStyle['name'] = path_hosp
            svgStyle['size'] = '6'

            symbol_layer = QgsSvgMarkerSymbolLayer.create(svgStyle)
            symbol = QgsSymbol.defaultSymbol(vl.geometryType())
            #vl.renderer().setSymbol(symbol)
            symbol.changeSymbolLayer(0, symbol_layer)
            vl.renderer().setSymbol(symbol)

            # show the change
            vl.triggerRepaint()

            QgsProject.instance().addMapLayer(vl)

        # farmacias
        elif result and index == 2:
            vl = QgsVectorLayer("Point?crs=epsg:3763&index=yes", "farmacias",
                                "memory")
            pr = vl.dataProvider()

            # Enter editing mode
            vl.startEditing()

            # add fields
            pr.addAttributes([
                QgsField("Farmácia", QVariant.String),
                QgsField("Morada", QVariant.String),
                QgsField("Coord_X", QVariant.Double),
                QgsField("Coord_Y", QVariant.Double)
            ])
            vl.updateFields(
            )  # tell the vector layer to fetch changes from the provider

            # add features ---> IR BUSCAR AO JSON....
            filename = os.path.join(dirn, 'farmacias.json')

            with open(filename, "r") as read_file:
                json_file = json.load(read_file)

            # transformar coordenadas gps para as pretendidas
            crsSrc = QgsCoordinateReferenceSystem(4326)  # gps
            crsDest = QgsCoordinateReferenceSystem(3763)  # pt
            xform = QgsCoordinateTransform(crsSrc, crsDest,
                                           QgsProject.instance())

            # addfeatures
            for entry in json_file.keys():
                x_coord = float(json_file[entry][1][1])
                y_coord = float(json_file[entry][1][0])
                morada = json_file[entry][0]
                fet = QgsFeature()
                fet.setGeometry(QgsGeometry().fromPointXY(
                    xform.transform(QgsPointXY(x_coord, y_coord))))
                fet.setAttributes([
                    QVariant(entry),
                    QVariant(morada),
                    QVariant(x_coord),
                    QVariant(y_coord)
                ])
                pr.addFeatures([fet])

            vl.updateExtents()
            vl.commitChanges()

            #symbol = QgsMarkerSymbol.createSimple({'name': 'square', 'color': 'purplet'})
            #vl.renderer().setSymbol(symbol)
            svgStyle = {}
            path_farm = os.path.join(dirn, 'pharmacy.svg')
            svgStyle['name'] = path_farm
            svgStyle['size'] = '4'
            symbol_layer = QgsSvgMarkerSymbolLayer.create(svgStyle)
            symbol = QgsSymbol.defaultSymbol(vl.geometryType())
            # vl.renderer().setSymbol(symbol)
            symbol.changeSymbolLayer(0, symbol_layer)
            vl.renderer().setSymbol(symbol)

            # show the change
            vl.triggerRepaint()

            QgsProject.instance().addMapLayer(vl)
Ejemplo n.º 17
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()
        TestQgsLayoutItemLegend.report += checker.report()
        self.assertTrue(result, message)

        QgsProject.instance().clear()
Ejemplo n.º 18
0
    def legend_test(self):
        self.mAtlasMap.setAtlasDriven(True)
        self.mAtlasMap.setAtlasScalingMode(QgsComposerMap.Auto)
        self.mAtlasMap.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.fromPoint(QgsPoint(-0.638, 48.954)))
        f2 = QgsFeature(2)
        f2.initAttributes(2)
        f2.setAttribute(0, 2)
        f2.setAttribute(1, "Test label 2")
        f2.setGeometry(QgsGeometry.fromPoint(QgsPoint(-1.682, 48.550)))
        pr.addFeatures([f1, f2])

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

        QgsProject.instance().addMapLayer(ptLayer)

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

        # add a legend
        legend = QgsComposerLegend(self.mComposition)
        legend.moveBy(200, 100)
        # sets the legend filter parameter
        legend.setComposerMap(self.mAtlasMap)
        legend.setLegendFilterOutAtlas(True)
        self.mComposition.addComposerLegend(legend)

        self.mAtlas.beginRender()

        self.mAtlas.prepareForFeature(0)
        self.mLabel1.adjustSizeToText()

        checker = QgsCompositionChecker('atlas_legend', self.mComposition)
        myTestResult, myMessage = checker.testComposition()
        assert myTestResult

        self.mAtlas.endRender()

        # restore state
        self.mAtlasMap.setLayers([layers[1]])
        self.mComposition.removeComposerItem(legend)
        QgsProject.instance().removeMapLayer(ptLayer.id())
Ejemplo n.º 19
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.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())
Ejemplo n.º 20
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}