Пример #1
0
    def setUp(self):
        myShpFile = os.path.join(TEST_DATA_DIR, 'rectangles.shp')
        layer = QgsVectorLayer(myShpFile, 'Points', 'ogr')
        QgsMapLayerRegistry.instance().addMapLayer(layer)

        # Create rulebased style
        sym1 = QgsFillSymbolV2.createSimple({'color': '#fdbf6f'})
        sym2 = QgsFillSymbolV2.createSimple({'color': '#71bd6c'})
        sym3 = QgsFillSymbolV2.createSimple({'color': '#1f78b4'})

        self.r1 = QgsRuleBasedRendererV2.Rule(sym1, 0, 0, '"id" = 1')
        self.r2 = QgsRuleBasedRendererV2.Rule(sym2, 0, 0, '"id" = 2')
        self.r3 = QgsRuleBasedRendererV2.Rule(sym3, 0, 0, 'ELSE')

        self.rootrule = QgsRuleBasedRendererV2.Rule(None)
        self.rootrule.appendChild(self.r1)
        self.rootrule.appendChild(self.r2)
        self.rootrule.appendChild(self.r3)

        self.renderer = QgsRuleBasedRendererV2(self.rootrule)
        layer.setRendererV2(self.renderer)
        self.mapsettings = CANVAS.mapSettings()
        self.mapsettings.setOutputSize(QSize(400, 400))
        self.mapsettings.setOutputDpi(96)
        self.mapsettings.setExtent(QgsRectangle(-163, 22, -70, 52))

        rendered_layers = [layer.id()]
        self.mapsettings.setLayers(rendered_layers)
Пример #2
0
    def setUp(self):
        self.iface = get_iface()
        myShpFile = os.path.join(TEST_DATA_DIR, 'rectangles.shp')
        layer = QgsVectorLayer(myShpFile, 'Points', 'ogr')
        QgsMapLayerRegistry.instance().addMapLayer(layer)

        # Create rulebased style
        sym1 = QgsFillSymbolV2.createSimple({'color': '#fdbf6f'})
        sym2 = QgsFillSymbolV2.createSimple({'color': '#71bd6c'})
        sym3 = QgsFillSymbolV2.createSimple({'color': '#1f78b4'})

        self.r1 = QgsRuleBasedRendererV2.Rule(sym1, 0, 0, '"id" = 1')
        self.r2 = QgsRuleBasedRendererV2.Rule(sym2, 0, 0, '"id" = 2')
        self.r3 = QgsRuleBasedRendererV2.Rule(sym3, 0, 0, 'ELSE')

        self.rootrule = QgsRuleBasedRendererV2.Rule(None)
        self.rootrule.appendChild(self.r1)
        self.rootrule.appendChild(self.r2)
        self.rootrule.appendChild(self.r3)

        self.renderer = QgsRuleBasedRendererV2(self.rootrule)
        layer.setRendererV2(self.renderer)
        self.mapsettings = self.iface.mapCanvas().mapSettings()
        self.mapsettings.setOutputSize(QSize(400, 400))
        self.mapsettings.setOutputDpi(96)
        self.mapsettings.setExtent(QgsRectangle(-163, 22, -70, 52))

        rendered_layers = [layer.id()]
        self.mapsettings.setLayers(rendered_layers)
    def render_and_save_pointwise_output_layer(
            self,
            pointwise_output_csv_filepath,
            output_layer_name,
            on_values_of_attribute,
            graduated_rendering_interval_points,
            shapefile_path=''):

        uri = 'file:///' + pointwise_output_csv_filepath + \
         '?delimiter=%s&crs=epsg:32643&xField=%s&yField=%s' % (',', 'X', 'Y')
        output_layer = QgsVectorLayer(uri, output_layer_name, 'delimitedtext')

        if 'Crop' in on_values_of_attribute:
            ET_D_max = max([
                point.budget.PET_minus_AET_crop_end
                for point in model_calculator.output_grid_points
            ])
        elif 'Monsoon' in on_values_of_attribute:
            ET_D_max = max([
                point.budget.PET_minus_AET_monsoon_end
                for point in model_calculator.output_grid_points
            ])

        graduated_symbol_renderer_range_list = []
        opacity = 1
        intervals_count = len(graduated_rendering_interval_points)
        for i in range(intervals_count):
            interval_min = 0 if graduated_rendering_interval_points[
                i] == 0 else (
                    graduated_rendering_interval_points[i] * ET_D_max / 100.0 +
                    0.01)
            interval_max = (graduated_rendering_interval_points * ET_D_max /
                            100.0)
            label = "{0:.2f} - {1:.2f}".format(interval_min, interval_max)
            colour = QColor(
                int(255 * (1 - (i + 1.0) / (intervals_count + 1.0))), 0,
                0)  # +1 done to tackle boundary cases
            symbol = QgsSymbolV2.defaultSymbol(output_layer.geometryType())
            symbol.setColor(colour)
            symbol.setAlpha(opacity)
            interval_range = QgsRendererRangeV2(interval_min, interval_max,
                                                symbol, label)
            graduated_symbol_renderer_range_list.append(interval_range)
        renderer = QgsGraduatedSymbolRendererV2(
            '', graduated_symbol_renderer_range_list)
        renderer.setMode(QgsGraduatedSymbolRendererV2.EqualInterval)
        renderer.setClassAttribute(on_values_of_attribute)
        output_layer.setRendererV2(renderer)
        QgsMapLayerRegistry.instance().addMapLayer(output_layer)

        if shapefile_path != '':
            QgsVectorFileWriter.writeAsVectorFormat(output_layer,
                                                    shapefile_path, "utf-8",
                                                    None, "ESRI Shapefile")

        return output_layer
Пример #4
0
class TestQgsArrowSymbolLayer(unittest.TestCase):

    def setUp(self):
        self.iface = get_iface()

        lines_shp = os.path.join(TEST_DATA_DIR, 'lines.shp')
        self.lines_layer = QgsVectorLayer(lines_shp, 'Lines', 'ogr')
        QgsMapLayerRegistry.instance().addMapLayer(self.lines_layer)

        # Create style
        sym2 = QgsLineSymbolV2.createSimple({'color': '#fdbf6f'})
        self.lines_layer.setRendererV2(QgsSingleSymbolRendererV2(sym2))

        self.mapsettings = self.iface.mapCanvas().mapSettings()
        self.mapsettings.setOutputSize(QSize(400, 400))
        self.mapsettings.setOutputDpi(96)
        self.mapsettings.setExtent(QgsRectangle(-113, 28, -91, 40))
        self.mapsettings.setBackgroundColor(QColor("white"))

    def tearDown(self):
        QgsMapLayerRegistry.instance().removeAllMapLayers()

    def test_1(self):
        sym = self.lines_layer.rendererV2().symbol()
        sym_layer = QgsArrowSymbolLayer.create({'head_size': '6.5'})
        dd = QgsDataDefined("(@geometry_point_num % 4) * 2")
        sym_layer.setDataDefinedProperty("arrow_width", dd)
        dd2 = QgsDataDefined("(@geometry_point_num % 4) * 2")
        sym_layer.setDataDefinedProperty("head_size", dd2)
        fill_sym = QgsFillSymbolV2.createSimple({'color': '#8bcfff', 'outline_color': '#000000', 'outline_style': 'solid', 'outline_width': '1'})
        sym_layer.setSubSymbol(fill_sym)
        sym.changeSymbolLayer(0, sym_layer)

        rendered_layers = [self.lines_layer.id()]
        self.mapsettings.setLayers(rendered_layers)

        renderchecker = QgsMultiRenderChecker()
        renderchecker.setMapSettings(self.mapsettings)
        renderchecker.setControlName('expected_arrowsymbollayer_1')
        self.assertTrue(renderchecker.runTest('arrowsymbollayer_1'))

    def test_2(self):
        sym = self.lines_layer.rendererV2().symbol()
        # double headed
        sym_layer = QgsArrowSymbolLayer.create({'arrow_width': '5', 'head_size': '6.5', 'head_type': '2'})
        fill_sym = QgsFillSymbolV2.createSimple({'color': '#8bcfff', 'outline_color': '#000000', 'outline_style': 'solid', 'outline_width': '1'})
        sym_layer.setSubSymbol(fill_sym)
        sym.changeSymbolLayer(0, sym_layer)

        rendered_layers = [self.lines_layer.id()]
        self.mapsettings.setLayers(rendered_layers)

        renderchecker = QgsMultiRenderChecker()
        renderchecker.setMapSettings(self.mapsettings)
        renderchecker.setControlName('expected_arrowsymbollayer_2')
        self.assertTrue(renderchecker.runTest('arrowsymbollayer_2'))
Пример #5
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 = QgsCategorizedSymbolRendererV2("attr", [QgsRendererCategoryV2(1, QgsMarkerSymbolV2.createSimple({"color": "255,0,0"}), "red"),
                                                    QgsRendererCategoryV2(2, QgsMarkerSymbolV2.createSimple({"color": "0,0,255"}), "blue")])
        ptLayer.setRendererV2(r)

        QgsMapLayerRegistry.instance().addMapLayer(ptLayer)

        # add the point layer to the map settings
        layers = self.mapSettings.layers()
        layers = [ptLayer.id()] + layers
        self.mapSettings.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.mapSettings.setLayers([layers[1]])
        self.mComposition.removeComposerItem(legend)
        QgsMapLayerRegistry.instance().removeMapLayer(ptLayer.id())
Пример #6
0
class TestQgsArrowSymbolLayer(unittest.TestCase):

    def setUp(self):
        self.iface = get_iface()

        lines_shp = os.path.join(TEST_DATA_DIR, 'lines.shp')
        self.lines_layer = QgsVectorLayer(lines_shp, 'Lines', 'ogr')
        QgsMapLayerRegistry.instance().addMapLayer(self.lines_layer)

        # Create style
        sym2 = QgsLineSymbolV2.createSimple({'color': '#fdbf6f'})
        self.lines_layer.setRendererV2(QgsSingleSymbolRendererV2(sym2))

        self.mapsettings = self.iface.mapCanvas().mapSettings()
        self.mapsettings.setOutputSize(QSize(400, 400))
        self.mapsettings.setOutputDpi(96)
        self.mapsettings.setExtent(QgsRectangle(-113, 28, -91, 40))
        self.mapsettings.setBackgroundColor(QColor("white"))

    def tearDown(self):
        QgsMapLayerRegistry.instance().removeAllMapLayers()

    def test_1(self):
        sym = self.lines_layer.rendererV2().symbol()
        sym_layer = QgsArrowSymbolLayer.create({'head_size': '6.5'})
        dd = QgsDataDefined("(@geometry_point_num % 4) * 2")
        sym_layer.setDataDefinedProperty("arrow_width", dd)
        dd2 = QgsDataDefined("(@geometry_point_num % 4) * 2")
        sym_layer.setDataDefinedProperty("head_size", dd2)
        fill_sym = QgsFillSymbolV2.createSimple({'color': '#8bcfff', 'outline_color': '#000000', 'outline_style': 'solid', 'outline_width': '1'})
        sym_layer.setSubSymbol(fill_sym)
        sym.changeSymbolLayer(0, sym_layer)

        rendered_layers = [self.lines_layer.id()]
        self.mapsettings.setLayers(rendered_layers)

        renderchecker = QgsMultiRenderChecker()
        renderchecker.setMapSettings(self.mapsettings)
        renderchecker.setControlName('expected_arrowsymbollayer_1')
        self.assertTrue(renderchecker.runTest('arrowsymbollayer_1'))

    def test_2(self):
        sym = self.lines_layer.rendererV2().symbol()
        # double headed
        sym_layer = QgsArrowSymbolLayer.create({'arrow_width': '5', 'head_size': '6.5', 'head_type': '2'})
        fill_sym = QgsFillSymbolV2.createSimple({'color': '#8bcfff', 'outline_color': '#000000', 'outline_style': 'solid', 'outline_width': '1'})
        sym_layer.setSubSymbol(fill_sym)
        sym.changeSymbolLayer(0, sym_layer)

        rendered_layers = [self.lines_layer.id()]
        self.mapsettings.setLayers(rendered_layers)

        renderchecker = QgsMultiRenderChecker()
        renderchecker.setMapSettings(self.mapsettings)
        renderchecker.setControlName('expected_arrowsymbollayer_2')
        self.assertTrue(renderchecker.runTest('arrowsymbollayer_2'))
Пример #7
0
class TestQgsSymbolExpressionVariables(TestCase):
    def setUp(self):
        myShpFile = os.path.join(TEST_DATA_DIR, 'polys.shp')
        self.layer = QgsVectorLayer(myShpFile, 'Polys', 'ogr')
        QgsMapLayerRegistry.instance().addMapLayer(self.layer)

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

    def tearDown(self):
        QgsMapLayerRegistry.instance().removeAllMapLayers()

    def testPartNum(self):
        # Create rulebased style
        sym1 = QgsFillSymbolV2.createSimple({'color': '#fdbf6f'})

        renderer = QgsSingleSymbolRendererV2(sym1)
        renderer.symbols()[0].symbolLayers()[0].setDataDefinedProperty(
            'color', 'color_rgb( (@geometry_part_num - 1) * 200, 0, 0 )')
        self.layer.setRendererV2(renderer)

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

        self.assertTrue(result)

    def testPartCount(self):
        # Create rulebased style
        sym1 = QgsFillSymbolV2.createSimple({'color': '#fdbf6f'})

        renderer = QgsSingleSymbolRendererV2(sym1)
        renderer.symbols()[0].symbolLayers()[0].setDataDefinedProperty(
            'color', 'color_rgb( (@geometry_part_count - 1) * 200, 0, 0 )')
        self.layer.setRendererV2(renderer)

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

        self.assertTrue(result)
class TestQgsSymbolExpressionVariables(TestCase):

    def setUp(self):
        myShpFile = os.path.join(TEST_DATA_DIR, 'polys.shp')
        self.layer = QgsVectorLayer(myShpFile, 'Polys', 'ogr')
        QgsMapLayerRegistry.instance().addMapLayer(self.layer)

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

    def tearDown(self):
        QgsMapLayerRegistry.instance().removeAllMapLayers()

    def testPartNum(self):
        # Create rulebased style
        sym1 = QgsFillSymbolV2.createSimple({'color': '#fdbf6f'})

        renderer = QgsSingleSymbolRendererV2(sym1)
        renderer.symbols()[0].symbolLayers()[0].setDataDefinedProperty('color', 'color_rgb( (@geometry_part_num - 1) * 200, 0, 0 )')
        self.layer.setRendererV2(renderer)

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

        self.assertTrue(result)

    def testPartCount(self):
        # Create rulebased style
        sym1 = QgsFillSymbolV2.createSimple({'color': '#fdbf6f'})

        renderer = QgsSingleSymbolRendererV2(sym1)
        renderer.symbols()[0].symbolLayers()[0].setDataDefinedProperty('color', 'color_rgb( (@geometry_part_count - 1) * 200, 0, 0 )')
        self.layer.setRendererV2(renderer)

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

        self.assertTrue(result)
Пример #9
0
    def make_OD_markers(nb, xo, yo, xd, yd, list_coords=None):
        """
        Prepare the Origin (green), Destination (red) and Intalternative_geometriesermediates (grey)
        markers.
        """
        OD_layer = QgsVectorLayer(
            "Point?crs=epsg:4326&field=id_route:integer&field=role:string(80)",
            "markers_osrm{}".format(nb), "memory")
        features = []
        fet = QgsFeature()
        fet.setGeometry(QgsGeometry.fromPoint(QgsPoint(float(xo), float(yo))))
        fet.setAttributes([nb, 'Origin'])
        features.append(fet)
        fet = QgsFeature()
        fet.setGeometry(QgsGeometry.fromPoint(QgsPoint(float(xd), float(yd))))
        fet.setAttributes([nb, 'Destination'])
        features.append(fet)
        marker_rules = [
            ('Origin', '"role" LIKE \'Origin\'', '#50b56d', 4),
            ('Destination', '"role" LIKE \'Destination\'', '#d31115', 4),
        ]
        if list_coords:
            for i, pt in enumerate(list_coords):
                fet = QgsFeature()
                fet.setGeometry(
                    QgsGeometry.fromPoint(QgsPoint(float(pt[0]), float(pt[1])))
                    )
                fet.setAttributes([nb, 'Via point n°{}'.format(i)])
                features.append(fet)
            marker_rules.insert(
                1, ('Intermediate', '"role" LIKE \'Via point%\'', 'grey', 2))
        OD_layer.dataProvider().addFeatures(features)

        symbol = QgsSymbolV2.defaultSymbol(OD_layer.geometryType())
        renderer = QgsRuleBasedRendererV2(symbol)
        root_rule = renderer.rootRule()
        for label, expression, color_name, size in marker_rules:
            rule = root_rule.children()[0].clone()
            rule.setLabel(label)
            rule.setFilterExpression(expression)
            rule.symbol().setColor(QtGui.QColor(color_name))
            rule.symbol().setSize(size)
            root_rule.appendChild(rule)

        root_rule.removeChildAt(0)
        OD_layer.setRendererV2(renderer)
        return OD_layer
Пример #10
0
    def make_OD_markers(nb, xo, yo, xd, yd, list_coords=None):
        """
        Prepare the Origin (green), Destination (red) and Intermediates (grey)
        markers.
        """
        OD_layer = QgsVectorLayer(
            "Point?crs=epsg:4326&field=id_route:integer&field=role:string(80)",
            "markers_osrm{}".format(nb), "memory")
        features = []
        fet = QgsFeature()
        fet.setGeometry(QgsGeometry.fromPoint(QgsPoint(float(xo), float(yo))))
        fet.setAttributes([nb, 'Origin'])
        features.append(fet)
        fet = QgsFeature()
        fet.setGeometry(QgsGeometry.fromPoint(QgsPoint(float(xd), float(yd))))
        fet.setAttributes([nb, 'Destination'])
        features.append(fet)
        marker_rules = [
            ('Origin', '"role" LIKE \'Origin\'', '#50b56d', 4),
            ('Destination', '"role" LIKE \'Destination\'', '#d31115', 4),
        ]
        if list_coords:
            for i, pt in enumerate(list_coords):
                fet = QgsFeature()
                fet.setGeometry(
                    QgsGeometry.fromPoint(QgsPoint(float(pt[0]),
                                                   float(pt[1]))))
                fet.setAttributes([nb, 'Via point n°{}'.format(i)])
                features.append(fet)
            marker_rules.insert(
                1, ('Intermediate', '"role" LIKE \'Via point%\'', 'grey', 2))
        OD_layer.dataProvider().addFeatures(features)

        symbol = QgsSymbolV2.defaultSymbol(OD_layer.geometryType())
        renderer = QgsRuleBasedRendererV2(symbol)
        root_rule = renderer.rootRule()
        for label, expression, color_name, size in marker_rules:
            rule = root_rule.children()[0].clone()
            rule.setLabel(label)
            rule.setFilterExpression(expression)
            rule.symbol().setColor(QtGui.QColor(color_name))
            rule.symbol().setSize(size)
            root_rule.appendChild(rule)

        root_rule.removeChildAt(0)
        OD_layer.setRendererV2(renderer)
        return OD_layer
    def setUp(self):
        myShpFile = os.path.join(TEST_DATA_DIR, 'polys_overlapping.shp')
        layer = QgsVectorLayer(myShpFile, 'Polygons', 'ogr')
        QgsMapLayerRegistry.instance().addMapLayer(layer)

        # Create style
        sym1 = QgsFillSymbolV2.createSimple({'color': '#fdbf6f'})

        self.renderer = QgsSingleSymbolRendererV2(sym1)
        layer.setRendererV2(self.renderer)
        self.mapsettings = CANVAS.mapSettings()
        self.mapsettings.setOutputSize(QSize(400, 400))
        self.mapsettings.setOutputDpi(96)
        self.mapsettings.setExtent(QgsRectangle(-133, 22, -70, 52))

        rendered_layers = [layer.id()]
        self.mapsettings.setLayers(rendered_layers)
Пример #12
0
 def add_final_pts(self, pts):
     center_pt_layer = QgsVectorLayer(
         "Point?crs=epsg:4326&field=id_center:integer&field=role:string(80)",
         "center_{}".format(self.nb_isocr), "memory")
     my_symb = QgsSymbolV2.defaultSymbol(0)
     my_symb.setColor(QtGui.QColor("#e31a1c"))
     my_symb.setSize(1.2)
     center_pt_layer.setRendererV2(QgsSingleSymbolRendererV2(my_symb))
     features = []
     for nb, pt in enumerate(pts):
         xo, yo = pt["point"]
         fet = QgsFeature()
         fet.setGeometry(QgsGeometry.fromPoint(QgsPoint(float(xo), float(yo))))
         fet.setAttributes([nb, 'Origin'])
         features.append(fet)
     center_pt_layer.dataProvider().addFeatures(features)
     QgsMapLayerRegistry.instance().addMapLayer(center_pt_layer)
    def setUp(self):
        myShpFile = os.path.join(TEST_DATA_DIR, 'polys_overlapping.shp')
        layer = QgsVectorLayer(myShpFile, 'Polys', 'ogr')
        QgsMapLayerRegistry.instance().addMapLayer(layer)

        # Create rulebased style
        sym1 = QgsFillSymbolV2.createSimple({'color': '#fdbf6f'})

        self.renderer = QgsSingleSymbolRendererV2(sym1)
        layer.setRendererV2(self.renderer)

        rendered_layers = [layer.id()]
        self.mapsettings = CANVAS.mapSettings()
        self.mapsettings.setOutputSize(QSize(400, 400))
        self.mapsettings.setOutputDpi(96)
        self.mapsettings.setExtent(QgsRectangle(-163, 22, -70, 52))
        self.mapsettings.setLayers(rendered_layers)
Пример #14
0
def createLayerGrille(uriGrille):

    layerGrille = QgsVectorLayer(uriGrille, CONST_NOM_LAYER_GRILLE, "ogr")

    fieldIndex = getFieldIndex(layerGrille)
    if fieldIndex < 0:
        caps = layerGrille.dataProvider().capabilities()
        if caps & QgsVectorDataProvider.AddAttributes:
            layerGrille.dataProvider().addAttributes(
                [QgsField(CONST_ATTRIBUT_ID, QVariant.Int)])
        layerGrille.updateFields()

    # Style
    props = {'color': '241,241,241,0', 'size': '1', 'color_border': '255,0,0'}
    s = QgsFillSymbolV2.createSimple(props)
    layerGrille.setRendererV2(QgsSingleSymbolRendererV2(s))

    return layerGrille
Пример #15
0
 def add_final_pts(self, pts):
     center_pt_layer = QgsVectorLayer(
         "Point?crs=epsg:4326&field=id_center:integer&field=role:string(80)",
         "isochrone_center_{}".format(self.nb_isocr), "memory")
     my_symb = QgsSymbolV2.defaultSymbol(0)
     my_symb.setColor(QtGui.QColor("#e31a1c"))
     my_symb.setSize(1.2)
     center_pt_layer.setRendererV2(QgsSingleSymbolRendererV2(my_symb))
     features = []
     for nb, pt in enumerate(pts):
         xo, yo = pt["point"]
         fet = QgsFeature()
         fet.setGeometry(
             QgsGeometry.fromPoint(QgsPoint(float(xo), float(yo))))
         fet.setAttributes([nb, 'Origin'])
         features.append(fet)
     center_pt_layer.dataProvider().addFeatures(features)
     QgsMapLayerRegistry.instance().addMapLayer(center_pt_layer)
Пример #16
0
    def testInitialSizeSymbolMapUnits(self):
        """Test initial size of legend with a symbol size in map units"""

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

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

        point_layer.setRendererV2(QgsSingleSymbolRendererV2(marker_symbol))

        s = QgsMapSettings()
        s.setLayers([point_layer.id()])
        s.setCrsTransformEnabled(False)
        composition = QgsComposition(s)
        composition.setPaperSize(297, 210)

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

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

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

        QgsMapLayerRegistry.instance().removeMapLayers([point_layer.id()])
Пример #17
0
 def create_virtual_layer(self, virtual_layer_name):
 
     sql = ("SELECT value FROM " + self.controller.schema_name + ".config_param_user"
            " WHERE cur_user = current_user AND parameter = 'virtual_layer_polygon'")
     row = self.controller.get_row(sql)
     if not row:
         sql = ("INSERT INTO "+self.schema_name + ".config_param_user (parameter, value, cur_user) "
                " VALUES ('virtual_layer_polygon', '"+virtual_layer_name+"', current_user)")
         self.controller.execute_sql(sql)
     srid = self.controller.plugin_settings_value('srid')
     uri = "Polygon?crs=epsg:" + str(srid)
     virtual_layer = QgsVectorLayer(uri, virtual_layer_name, "memory")
     props = {'color': '0, 0, 0', 'style': 'no', 'style_border': 'solid', 'color_border': '255, 0, 0'}
     s = QgsFillSymbolV2.createSimple(props)
     virtual_layer.setRendererV2(QgsSingleSymbolRendererV2(s))
     virtual_layer.updateExtents()
     QgsProject.instance().setSnapSettingsForLayer(virtual_layer.id(), True, 2, 0, 1.0, False)
     QgsMapLayerRegistry.instance().addMapLayer(virtual_layer)
     self.iface.mapCanvas().refresh()
Пример #18
0
class TestQgsNullSymbolRenderer(unittest.TestCase):

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

        self.renderer = QgsNullSymbolRenderer()
        self.layer.setRendererV2(self.renderer)

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

    def tearDown(self):
        QgsMapLayerRegistry.instance().removeAllMapLayers()

    def testRender(self):
        # test no features are rendered
        renderchecker = QgsMultiRenderChecker()
        renderchecker.setMapSettings(self.mapsettings)
        renderchecker.setControlPathPrefix('null_renderer')
        renderchecker.setControlName('expected_nullrenderer_render')
        result = renderchecker.runTest('nullrenderer_render')
        assert result

    def testSelected(self):
        # select a feature and render
        self.layer.select([1, 2, 3])
        renderchecker = QgsMultiRenderChecker()
        renderchecker.setMapSettings(self.mapsettings)
        renderchecker.setControlPathPrefix('null_renderer')
        renderchecker.setControlName('expected_nullrenderer_selected')
        result = renderchecker.runTest('nullrenderer_selected')
        assert result
Пример #19
0
    def testInitialSizeSymbolMapUnits(self):
        """Test initial size of legend with a symbol size in map units"""

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

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

        point_layer.setRendererV2(QgsSingleSymbolRendererV2(marker_symbol))

        s = QgsMapSettings()
        s.setLayers([point_layer.id()])
        s.setCrsTransformEnabled(False)
        composition = QgsComposition(s)
        composition.setPaperSize(297, 210)

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

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

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

        QgsMapLayerRegistry.instance().removeMapLayers([point_layer.id()])
Пример #20
0
class RFUDockWidget(QDockWidget, gui_dckwdgt_rfu_connector):

    closed = pyqtSignal()
    downloaded = pyqtSignal()
    uploaded = pyqtSignal()

    def __init__(self, iface, canvas, map_layer_registry, conn=None, parent=None):

        super(RFUDockWidget, self).__init__(parent)
        self.setupUi(self)

        self.iface = iface
        self.canvas = canvas
        self.map_layer_registry = map_layer_registry
        self.conn = conn
        self.zone = None
        self.precision_class = []
        self.ellips_acronym = []
        self.dflt_ellips_acronym = None
        self.selected_ellips_acronym = None
        self.nature = []
        self.auth_creator = []

        self.url = None

        self.l_vertex = None
        self.l_edge = None
        self.layers = [self.l_vertex, self.l_edge]

        # Initialize dicts which contains changed datasets
        self.edges_added = {}
        self.vertices_added = {}
        self.edges_removed = {}
        self.vertices_removed = {}
        self.edges_modified = {}
        self.vertices_modified = {}

        self.downloadPushButton.clicked.connect(self.on_downloaded)
        self.permalinkLineEdit.returnPressed.connect(self.on_downloaded)
        self.projComboBox.currentIndexChanged.connect(self.set_destination_crs)

    def closeEvent(self, event):

        self.closed.emit()

    def on_downloaded(self):

        widget = self.iface.messageBar().createMessage(u"Géofoncier", u"Téléchargement du RFU.")

        progress_bar = QProgressBar()
        progress_bar.setMinimum(0)
        progress_bar.setMaximum(2)
        widget.layout().addWidget(progress_bar)

        self.iface.messageBar().pushWidget(widget, QgsMessageBar.WARNING)
        progress_bar.setValue(1)

        # https://pro.geofoncier.fr/index.php?&centre=-196406,5983255&context=metropole
        url = self.permalinkLineEdit.text()
        if not url:
            return self.abort_action(msg=u"Veuillez renseigner le permalien.")
        self.url = url

        try:
            self.download(self.url)
        except Exception as e:
            return self.abort_action(msg=e.message)

        progress_bar.setValue(2)
        self.iface.messageBar().clearWidgets()

        return

    def on_reset(self):

        # Ensure that the action is intentional
        msg = (u"Cette action est irreversible. "
               u"Toute modification sera perdue. "
               u"Êtes-vous sûr de vouloir réinitialiser l'outil ?")
        resp = QMessageBox.question(self, r"Question", msg,
                                    QMessageBox.Yes, QMessageBox.No)
        if resp == QMessageBox.Yes:
            self.reset()

        return

    def on_uploaded(self):

        self.uploaded.emit()

        # Create message
        widget = self.iface.messageBar().createMessage(u"Géofoncier", u"Envoi des modifications.")
        progress_bar = QProgressBar()
        progress_bar.setMinimum(0)
        progress_bar.setMaximum(3)
        widget.layout().addWidget(progress_bar)
        self.iface.messageBar().pushWidget(widget, QgsMessageBar.WARNING)
        progress_bar.setValue(1)

        enr_ref_dossier, ok = QInputDialog.getText(
                                self, u"Référence de dossier",
                                u"Vous êtes sur le point de soumettre\n"
                                u"les modifications au serveur Géofoncier.\n"
                                u"Veuillez renseigner la référence du dossier.")
        if not ok:
            return self.abort_action()

        if not enr_ref_dossier:
            return self.abort_action(msg=u"Merci de renseigner une référence de dossier.")

        commentaire = u"Dossier %s" % enr_ref_dossier

        dossiers = self.conn.dossiersoge_dossiers(self.zone, enr_ref_dossier)
        if dossiers.code != 200:
            return self.abort_action(msg=dossiers.read())

        tree = EltTree.fromstring(dossiers.read())

        # Check if exception
        err = tree.find(r"./erreur")
        if err:
            return self.abort_action(msg=err.text)

        nb_dossiers = int(tree.find(r"./dossiers").attrib[r"total"])

        if nb_dossiers == 0:
            return self.abort_action(msg=u"Le dossier \'%s\' n'existe pas." % enr_ref_dossier)

        if nb_dossiers >= 1:
            # Prendre par défaut le dernier dossier dans la liste
            dossier_uri = tree.getiterator(tag=r"dossier")[nb_dossiers-1].find(
                                    r"{http://www.w3.org/2005/Atom}link")
            enr_api_dossier = dossier_uri.attrib[r"href"].split(r"/")[-1][1:]

        progress_bar.setValue(2)

        # Stop editing mode
        for layer in self.layers:
            if layer.isEditable():
                layer.commitChanges()

        # Check if dataset changes
        if (self.edges_added
                or self.vertices_added
                or self.edges_removed
                or self.vertices_removed
                or self.edges_modified
                or self.vertices_modified):
            pass
        else:
            return self.abort_action(msg=u"Aucune modification des données n'est détecté.")

        # Upload, reset and re-download datasets
        try:
            log = self.upload(enr_api_dossier=enr_api_dossier, commentaire=commentaire)
            self.reset()
            self.download(self.url)
        except Exception as e:
            return self.abort_action(msg=e.message)

        self.canvas.zoomToFullExtent()
        self.iface.messageBar().clearWidgets()

        return QMessageBox.information(self, r"Information", u"\r".join(log))

    def download(self, url):

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

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

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

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

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

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

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

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

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

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

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

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

        tree = EltTree.fromstring(resp.read())

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

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

        p_bbox = self.l_bbox.dataProvider()

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

        renderer_bbox = QgsInvertedPolygonRenderer(QgsSingleSymbolRendererV2(simple_symbol))

        self.l_bbox.setRendererV2(renderer_bbox)

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

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

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

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

        # Set the map canvas layer set
        self.canvas.setLayerSet([QgsMapCanvasLayer(self.l_vertex),
                                 QgsMapCanvasLayer(self.l_edge),
                                 QgsMapCanvasLayer(self.l_bbox)])

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

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

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

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

        tree = EltTree.fromstring(resp.read())

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

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

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

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

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

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

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

            self.projComboBox.addItem(e[2])

            if not self.dflt_ellips_acronym:
                continue

            if self.dflt_ellips_acronym == e[0]:

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

                # Activate 'On The Fly'
                self.canvas.setCrsTransformEnabled(True)

                # Then change the CRS in canvas
                crs = QgsCoordinateReferenceSystem(int(e[1]), QgsCoordinateReferenceSystem.EpsgCrsId)
                self.canvas.setDestinationCrs(crs)

        # Then, start editing mode..
        for layer in self.layers:
            if not layer.isEditable():
                layer.startEditing()

        self.projComboBox.setDisabled(False)

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

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

        self.downloaded.emit()

        return True

    def reset(self):
        """Remove RFU layers."""

        # Remove RFU layers
        try:
            self.map_layer_registry.removeMapLayers([
                    self.l_vertex.id(), self.l_edge.id(), self.l_bbox.id()])
        except:
            return

        # Reset variable
        self.precision_class = []
        self.ellips_acronym = []
        self.dflt_ellips_acronym = None
        self.nature = []
        self.auth_creator = []
        self.l_vertex = None
        self.l_edge = None
        self.layers = [self.l_vertex, self.l_edge]
        self.edges_added = {}
        self.vertices_added = {}
        self.edges_removed = {}
        self.vertices_removed = {}
        self.edges_modified = {}
        self.vertices_modified = {}

        # Reset ComboBox which contains projections authorized
        self.projComboBox.clear()
        self.projComboBox.setDisabled(True)

        self.permalinkLineEdit.clear()
        self.permalinkLineEdit.setDisabled(False)
        self.permalinkLineEdit.returnPressed.connect(self.on_downloaded)

        self.downloadPushButton.setDisabled(False)
        self.downloadPushButton.clicked.connect(self.on_downloaded)

        self.resetPushButton.setDisabled(True)
        self.resetPushButton.clicked.disconnect(self.on_reset)

        self.uploadPushButton.setDisabled(True)
        self.uploadPushButton.clicked.disconnect(self.on_uploaded)

        return True

    def upload(self, enr_api_dossier=None, commentaire=None):
        """Upload data to Géofoncier REST API.
        On success returns the log messages (Array).

        """

        # Set XML document
        root = EltTree.Element(r"rfu")

        # Add to our XML document datasets which have been changed
        if self.vertices_added:
            for fid in self.vertices_added:
                tools.xml_subelt_creator(root, u"sommet",
                                         data=self.vertices_added[fid],
                                         action=r"create")

        if self.edges_added:
            for fid in self.edges_added:
                tools.xml_subelt_creator(root, u"limite",
                                         data=self.edges_added[fid],
                                         action=r"create")

        if self.vertices_removed:
            for fid in self.vertices_removed:
                tools.xml_subelt_creator(root, u"sommet",
                                         data=self.vertices_removed[fid],
                                         action=r"delete")

        if self.edges_removed:
            for fid in self.edges_removed:
                tools.xml_subelt_creator(root, u"limite",
                                         data=self.edges_removed[fid],
                                         action=r"delete")

        if self.vertices_modified:
            for fid in self.vertices_modified:
                tools.xml_subelt_creator(root, u"sommet",
                                         data=self.vertices_modified[fid],
                                         action=r"update")

        if self.edges_modified:
            for fid in self.edges_modified:
                tools.xml_subelt_creator(root, u"limite",
                                         data=self.edges_modified[fid],
                                         action=r"update")

        # Create a new changeset Id
        changeset_id = self.create_changeset(enr_api_dossier=enr_api_dossier, commentaire=commentaire)

        # Add changeset value in our XML document
        root.attrib[r"changeset"] = changeset_id

        # Send data
        edit = self.conn.edit(self.zone, EltTree.tostring(root))
        if edit.code != 200:
            raise Exception(edit.read())

        tree = EltTree.fromstring(edit.read())

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

        # Returns log info
        msgs_log = []
        for log in tree.iter(r"log"):
            msgs_log.append(u"%s: %s" % (log.attrib[u"type"], log.text))

        # Close the changeset
        self.destroy_changeset(changeset_id)

        # Reset all
        self.edges_added = {}
        self.vertices_added = {}
        self.edges_removed = {}
        self.vertices_removed = {}
        self.edges_modified = {}
        self.vertices_modified = {}

        return msgs_log

    def create_changeset(self, enr_api_dossier=None, commentaire=None):
        """Open a new changeset from Géofoncier API.
        On success, returns the new changeset id.

        """

        opencs = self.conn.open_changeset(self.zone, enr_api_dossier=enr_api_dossier, commentaire=commentaire)
        if opencs.code != 200:
            raise Exception(opencs.read())

        tree = EltTree.fromstring(opencs.read())

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

        treeterator = tree.getiterator(tag=r"changeset")

        # We should get only one changeset
        if len(treeterator) != 1:
            raise Exception(u"Le nombre de \'changeset\' est incohérent.\n"
                            u"Merci de contacter l'administrateur Géofoncier.")

        return treeterator[0].attrib[r"id"]

    def destroy_changeset(self, id):
        """Close a changeset."""

        closecs = self.conn.close_changeset(self.zone, id)

        if closecs.code != 200:
            raise Exception(closecs.read())

        tree = EltTree.fromstring(closecs.read())

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

        return True

    def abort_action(self, msg=None):

        for layer in self.layers:
            if layer and not layer.isEditable():
                layer.startEditing()

        # Clear message bar
        self.iface.messageBar().clearWidgets()

        if msg:
            return QMessageBox.warning(self, r"Warning", msg)

        return

    def extract_layers(self, tree):
        """Return a list of RFU layers."""

        # Create vector layers..
        l_vertex = QgsVectorLayer(r"Point?crs=epsg:4326&index=yes",
                                  u"Sommet RFU", r"memory")
        l_edge = QgsVectorLayer(r"LineString?crs=epsg:4326&index=yes",
                                u"Limite RFU", r"memory")

        p_vertex = l_vertex.dataProvider()
        p_edge = l_edge.dataProvider()

        # Define default style renderer..

        renderer_vertex = QgsRuleBasedRendererV2(QgsMarkerSymbolV2())
        vertex_root_rule = renderer_vertex.rootRule()
        vertex_rules = (
            (
                 (u"Borne, borne à puce, pierre, piquet, clou ou broche"),
                 (u"$id >= 0 AND \"som_nature\" IN ('Borne',"
                  u"'Borne à puce', 'Pierre', 'Piquet', 'Clou ou broche')"),
                 r"#EC0000", 2.2
            ), (
                 (u"Axe cours d'eau, axe fossé, haut de talus, pied de talus"),
                 (u"$id >= 0 AND \"som_nature\" IN ('Axe cours d\'\'eau',"
                  u"'Axe fossé', 'Haut de talus', 'Pied de talus')"),
                 r"#EE8012", 2.2
            ), (
                 (u"Angle de bâtiment, axe de mur, angle de mur, "
                  u"angle de clôture, pylône et toute autre valeur"),
                 (u"$id >= 0 AND \"som_nature\" NOT IN ('Borne',"
                  u"'Borne à puce', 'Pierre', 'Piquet', 'Clou ou broche',"
                  u"'Axe cours d\'\'eau', 'Axe fossé', 'Haut de talus',"
                  u"'Pied de talus')"),
                 r"#9784EC", 2.2
            ), (
                u"Temporaire", r"$id < 0", "cyan", 2.4
            ))

        for label, expression, color, size in vertex_rules:
            rule = vertex_root_rule.children()[0].clone()
            rule.setLabel(label)
            rule.setFilterExpression(expression)
            rule.symbol().setColor(QColor(color))
            rule.symbol().setSize(size)
            vertex_root_rule.appendChild(rule)

        vertex_root_rule.removeChildAt(0)
        l_vertex.setRendererV2(renderer_vertex)

        renderer_edge = QgsRuleBasedRendererV2(QgsLineSymbolV2())
        edge_root_rule = renderer_edge.rootRule()
        edge_rules = ((r"Limite", r"$id >= 0", "#0A0AFF", 0.5),
                      (r"Temporaire", r"$id < 0", "cyan", 1))

        for label, expression, color, width in edge_rules:
            rule = edge_root_rule.children()[0].clone()
            rule.setLabel(label)
            rule.setFilterExpression(expression)
            rule.symbol().setColor(QColor(color))
            rule.symbol().setWidth(width)
            edge_root_rule.appendChild(rule)

        edge_root_rule.removeChildAt(0)
        l_edge.setRendererV2(renderer_edge)

        # Add fields..
        p_vertex.addAttributes([
                    QgsField(r"@id_noeud", QVariant.Int),
                    # QgsField(r"@changeset", QVariant.Int),
                    # QgsField(r"@timestamp", QVariant.Date),
                    QgsField(r"@version", QVariant.Int),
                    QgsField(r"som_ge_createur", QVariant.String),
                    QgsField(r"som_nature", QVariant.String),
                    QgsField(r"som_precision_rattachement", QVariant.Int),
                    QgsField(r"som_coord_est", QVariant.Double),
                    QgsField(r"som_coord_nord", QVariant.Double),
                    QgsField(r"som_representation_plane", QVariant.String),
                    # QgsField(r"date_creation", QVariant.Date)
                    ])

        p_edge.addAttributes([
                    QgsField(r"@id_arc", QVariant.Int),
                    # QgsField(r"@id_noeud_debut", QVariant.Int),
                    # QgsField(r"@id_noeud_fin", QVariant.Int),
                    # QgsField(r"@changeset", QVariant.Int),
                    # QgsField(r"@timestamp", QVariant.Date),
                    QgsField(r"@version", QVariant.Int),
                    QgsField(r"lim_ge_createur", QVariant.String),
                    # QgsField(r"lim_date_creation", QVariant.Date)
                    ])

        # Add features from xml tree..
        # ..to vertex layer..
        fts_vertex = []
        for e in tree.findall(r"sommet"):

            ft_vertex = QgsFeature()
            ft_vertex.setGeometry(QgsGeometry.fromWkt(e.attrib[r"geometrie"]))

            _id_noeud = int(e.attrib[r"id_noeud"])
            # _changeset = int(e.attrib[r"changeset"])
            # _timestamp = QDateTime(datetime.strptime(
            #                 e.attrib[r"timestamp"], r"%Y-%m-%d %H:%M:%S.%f"))
            _version = int(e.attrib[r"version"])
            som_ge_createur = unicode(e.find(r"./som_ge_createur").text)
            som_nature = unicode(e.find(r"./som_nature").text)
            som_prec_rattcht = int(e.find(r"./som_precision_rattachement").text)
            som_coord_est = float(e.find(r"./som_coord_est").text)
            som_coord_nord = float(e.find(r"./som_coord_nord").text)
            som_repres_plane = unicode(e.find(r"./som_representation_plane").text)
            # som_date_creation = QDate(datetime.strptime(
            #                         e.find(r"./som_date_creation").text, r"%Y-%m-%d").date())

            ft_vertex.setAttributes([
                        _id_noeud,
                        # _changeset,
                        # _timestamp,
                        _version,
                        som_ge_createur,
                        som_nature,
                        som_prec_rattcht,
                        som_coord_est,
                        som_coord_nord,
                        som_repres_plane,
                        # som_date_creation
                        ])

            fts_vertex.append(ft_vertex)

        # ..to edge layer..
        fts_edge = []
        for e in tree.findall(r"limite"):

            ft_edge = QgsFeature()
            ft_edge.setGeometry(QgsGeometry.fromWkt(e.attrib[r"geometrie"]))

            _id_arc = int(e.attrib[r"id_arc"])
            # _id_noeud_debut = int(e.attrib[r"id_noeud_debut"])
            # _id_noeud_fin = int(e.attrib[r"id_noeud_fin"])
            # _changeset = int(e.attrib[r"changeset"])
            # _timestamp = QDateTime(datetime.strptime(
            #                 e.attrib[r"timestamp"], r"%Y-%m-%d %H:%M:%S.%f"))
            _version = int(e.attrib[r"version"])
            lim_ge_createur = unicode(e.find(r"./lim_ge_createur").text)
            # lim_date_creation = QDate(datetime.strptime(
            #                        e.find(r"./lim_date_creation").text, r"%Y-%m-%d").date())

            ft_edge.setAttributes([
                        _id_arc,
                        # _id_noeud_debut,
                        # _id_noeud_fin,
                        # _changeset,
                        # _timestamp,
                        _version,
                        lim_ge_createur,
                        # lim_date_creation
                        ])

            fts_edge.append(ft_edge)

        # Add features to layers..
        p_vertex.addFeatures(fts_vertex)
        p_edge.addFeatures(fts_edge)

        # Update fields..
        l_vertex.updateFields()
        l_edge.updateFields()

        # Update layer's extent..
        l_vertex.updateExtents()
        l_edge.updateExtents()

        # Check if valid..
        if not l_vertex.isValid() or not l_edge.isValid():
            raise Exception(u"Une erreur est survenue lors du chargement de la couche.")

        # Set labelling...
        palyr = QgsPalLayerSettings()
        palyr.enabled = True
        # palyr.readFromLayer(l_vertex)
        palyr.fieldName = r"$id"  # Expression $id
        palyr.placement = 1  # ::OverPoint
        palyr.quadOffset = 2  # ::QuadrantAboveRight
        palyr.setDataDefinedProperty(80, True, True, r"1", "")  # ::OffsetUnits -> ::MM
        palyr.xOffset = 2.0
        palyr.yOffset = -1.0
        palyr.writeToLayer(l_vertex)

        # Then return layers..
        return [l_vertex, l_edge]

    def get_features(self, layer):

        features = []
        for ft in layer.getFeatures():
            attributes = tools.attrib_as_kv(ft.fields(), ft.attributes())
            attributes[r"fid"] = ft.id()
            features.append(attributes)

        return features

    def remove_features(self, layer_id, fids):

        for fid in fids:

            if layer_id == self.l_edge.id() and fid in self.features_edge_backed_up:
                self.edges_removed[fid] = self.features_edge_backed_up[fid]

            if layer_id == self.l_vertex.id() and fid in self.features_vertex_backed_up:
                self.vertices_removed[fid] = self.features_vertex_backed_up[fid]

    def add_features(self, layer_id, features):

        for ft in features:

            attrib = tools.attrib_as_kv(
                        ft.fields(), ft.attributes(), qgsgeom=ft.geometry())

            if layer_id == self.l_vertex.id():
                self.vertices_added[ft.id()] = attrib

            if layer_id == self.l_edge.id():
                self.edges_added[ft.id()] = attrib

    def modify_feature(self, layer_id, feature, qgsgeom=None):

        if qgsgeom:
            f = tools.attrib_as_kv(
                        feature.fields(), feature.attributes(), qgsgeom=qgsgeom)
        else:
            f = tools.attrib_as_kv(feature.fields(), feature.attributes())

        if self.l_edge.id() == layer_id:
            if feature.id() not in self.features_edge_backed_up:
                return
            self.edges_modified[feature.id()] = f

        if self.l_vertex.id() == layer_id:
            if feature.id() not in self.features_vertex_backed_up:
                return
            self.vertices_modified[feature.id()] = f

    def set_destination_crs(self, j):

        epsg = 4326 # by default
        for i, e in enumerate(self.ellips_acronym):
            if i == j:
                self.selected_ellips_acronym = e[0]
                epsg = int(e[1])
                continue

        crs = QgsCoordinateReferenceSystem(epsg, QgsCoordinateReferenceSystem.EpsgCrsId)
        self.canvas.setDestinationCrs(crs)
        self.canvas.zoomToFullExtent()
Пример #21
0
 def run(self):
     """Run method that performs all the real work"""
     self.dlg.layerComboBox.clear()
     self.dlg.sheetTypeComboBox.clear()
     self.dlg.scaleComboBox.clear()  
     #self.dlg.label_2.setText('')        
     Alllayers = self.iface.legendInterface().layers()
     #layer_list = []
     lcount=0
     for layer in Alllayers:
         xyCrs = layer.crs()
         if xyCrs.projectionAcronym()=='longlat':
             lcount=lcount+1
             self.dlg.layerComboBox.addItem(layer.name(),layer)
             
     self.dlg.sheetTypeComboBox.addItem('Indian and Adjoining Countries Series Maps')    
     self.dlg.sheetTypeComboBox.addItem('Open Series Maps')    
     
     scale_list=['1:1M','1:250,000','1:125,000','1:50,000','1:25,000']
     self.dlg.scaleComboBox.addItems(scale_list)
     # show the dialog
     self.dlg.show()
     # Run the dialog event loop
     result = self.dlg.exec_()
     # See if OK was pressed
     if result:
         global scaleID
         global sheetw
         global sheeth
         if lcount>0:
             scaleID=self.dlg.scaleComboBox.currentIndex()+1
             maptype= self.dlg.sheetTypeComboBox.currentIndex()+1
             if maptype==1:                
                 sheetw,sheeth=setFactor1(scaleID)
             if maptype==2:
                 sheetw,sheeth=setFactor2(scaleID)               
             index = self.dlg.layerComboBox.currentIndex()
             clayer = self.dlg.layerComboBox.itemData(index)
             e=clayer.extent()
             a,b,c=degDec2dms(e.xMinimum())
             slongs=dmstosec(a,b,c)
             a,b,c=degDec2dms(e.xMaximum())
             elongs=dmstosec(a,b,c)
             a,b,c=degDec2dms(e.yMinimum())
             slats=dmstosec(a,b,c)
             a,b,c=degDec2dms(e.yMaximum())
             elats=dmstosec(a,b,c)
             slongs,elongs,slats,elats=CalculateExtentInTermsOfSheet(slongs,elongs,slats,elats)
             Xgrids=int(elongs-slongs)//sheetw # // is used for modular division
             Ygrids=int(elats-slats)//sheeth
             layer = QgsVectorLayer("Polygon?crs=EPSG:4326", "TopoSheets", "memory")
             global poly
             global pr
             pr = layer.dataProvider() 
             pr.addAttributes([QgsField("id",QVariant.Int),QgsField("SheetNo",QVariant.String),QgsField("Inside",QVariant.String)])
             layer.updateFields()
            
             poly = QgsFeature()
             CalculateSheet(maptype,slats,slongs,Xgrids,Ygrids)
             n=0
             # check intersection of selected layer feature with sheets
             fieldIdx = pr.fields().indexFromName('Inside' )
             updateMap = {}
             for f in clayer.getFeatures():
                 for a in layer.getFeatures():
                     if a.geometry().intersects(f.geometry()):
                         n=n+1
                         updateMap[a.id()] = { fieldIdx:1 }
             pr.changeAttributeValues(updateMap)
             
             # set the layer symbology
             values = (
             ('In', True,True,QColor.fromRgb(95,254,99)),
             ('Out', False,False,'yellow'),
             )
             # create a category for each item in values
             ranges=[]
             for label, lower, upper, color in values:
                 symbol = QgsSymbolV2.defaultSymbol(layer.geometryType())
                 symbol.setColor(QColor(color))
                 rng = QgsRendererRangeV2(lower, upper, symbol, label)
                 ranges.append(rng)
             expression = 'Inside' # field name
             renderer = QgsGraduatedSymbolRendererV2(expression, ranges)
             layer.setRendererV2(renderer)
             
             # set layer transparence and dolabelling
             layer.setLayerTransparency(65)              
             layer.updateExtents()
             QgsMapLayerRegistry.instance().addMapLayers([layer])
             layer.setCustomProperty("labeling", "pal")
             layer.setCustomProperty("labeling/enabled", "true")
             layer.setCustomProperty("labeling/fontFamily", "Arial")
             layer.setCustomProperty("labeling/fontSize", "10")
             layer.setCustomProperty("labeling/fieldName", "SheetNo")
             layer.setCustomProperty("labeling/placement", "1")
             iface.mapCanvas().refresh()
         else:
             iface.messageBar().pushMessage("Error", "No layers loaded, Load layer with Geographic Corrdinates", level=QgsMessageBar.CRITICAL)
         pass
Пример #22
0
    def WPT2Layer(self):
        mapUnits = define._canvas.mapUnits()
        if define._mapCrs == None:
            if mapUnits == QGis.Meters:
                resultLayer = QgsVectorLayer(
                    "Point?crs=EPSG:32633", "WPT_" +
                    self.surfaceType.replace(" ", "_").replace("-", "_"),
                    "memory")
            else:
                resultLayer = QgsVectorLayer(
                    "Point?crs=EPSG:4326", "WPT_" +
                    self.surfaceType.replace(" ", "_").replace("-", "_"),
                    "memory")
        else:
            resultLayer = QgsVectorLayer(
                "Point?crs=%s" % define._mapCrs.authid(),
                "WPT_" + self.surfaceType.replace(" ", "_").replace("-", "_"),
                "memory")
        shpPath = ""
        if define.obstaclePath != None:
            shpPath = define.obstaclePath
        elif define.xmlPath != None:
            shpPath = define.xmlPath
        else:
            shpPath = define.appPath
        er = QgsVectorFileWriter.writeAsVectorFormat(
            resultLayer,
            shpPath + "/" + "RnavTurningSegmentAnalyserWpt" + ".shp", "utf-8",
            resultLayer.crs())
        resultLayer = QgsVectorLayer(
            shpPath + "/" + "RnavTurningSegmentAnalyserWpt" + ".shp",
            "WPT_RnavTurningSegmentAnalyser", "ogr")

        fieldName = "CATEGORY"
        resultLayer.dataProvider().addAttributes(
            [QgsField(fieldName, QVariant.String)])
        resultLayer.startEditing()
        fields = resultLayer.pendingFields()
        i = 1
        feature = QgsFeature()
        feature.setFields(fields)

        feature.setGeometry(
            QgsGeometry.fromPoint(self.parametersPanel.pnlWaypoint1.Point3d))
        feature.setAttribute(fieldName, "Waypoint1")
        pr = resultLayer.dataProvider()
        pr.addFeatures([feature])
        # resultLayer.addFeature(feature)
        feature.setGeometry(
            QgsGeometry.fromPoint(self.parametersPanel.pnlWaypoint2.Point3d))
        feature.setAttribute(fieldName, "Waypoint2")
        pr = resultLayer.dataProvider()
        pr.addFeatures([feature])
        # resultLayer.addFeature(feature)
        resultLayer.commitChanges()

        renderCatFly = None
        if self.parametersPanel.cmbType1.SelectedIndex == 1:
            '''FlyOver'''

            symbolFlyOver = QgsSymbolV2.defaultSymbol(
                resultLayer.geometryType())
            symbolFlyOver.deleteSymbolLayer(0)
            svgSymLayer = QgsSvgMarkerSymbolLayerV2("Resource/flyover.svg",
                                                    10.0, 0.0)
            symbolFlyOver.appendSymbolLayer(svgSymLayer)
            renderCatFly = QgsRendererCategoryV2(0, symbolFlyOver, "Fly Over")
        elif self.parametersPanel.cmbType1.SelectedIndex == 0:
            '''FlyBy'''
            symbolFlyBy = QgsSymbolV2.defaultSymbol(resultLayer.geometryType())
            symbolFlyBy.deleteSymbolLayer(0)
            svgSymLayer = QgsSvgMarkerSymbolLayerV2("Resource/flyby.svg", 10.0,
                                                    0.0)
            symbolFlyBy.appendSymbolLayer(svgSymLayer)
            renderCatFly = QgsRendererCategoryV2(0, symbolFlyBy, "Fly By")
        else:
            return None
        WPT_EXPRESION = "CASE WHEN  \"CATEGORY\" = 'Waypoint1'  THEN 0 " + \
                                        "END"
        symRenderer = QgsCategorizedSymbolRendererV2(WPT_EXPRESION,
                                                     [renderCatFly])

        resultLayer.setRendererV2(symRenderer)
        return resultLayer
Пример #23
0
    def testCase(self):
        self.TEST_DATA_DIR = unitTestDataPath()
        vectorFileInfo = QFileInfo( self.TEST_DATA_DIR + "/france_parts.shp")
        mVectorLayer = QgsVectorLayer( vectorFileInfo.filePath(), vectorFileInfo.completeBaseName(), "ogr" )

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

        # create composition with composer map
        mMapRenderer = QgsMapRenderer()
        layerStringList = []
        layerStringList.append( mVectorLayer.id() )
        mMapRenderer.setLayerSet( layerStringList )
        mMapRenderer.setProjectionsEnabled( True )
        mMapRenderer.setMapUnits( QGis.Meters )

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

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

        # fix the renderer, fill with green
        props = { "color": "0,127,0" }
        fillSymbol = QgsFillSymbolV2.createSimple( props )
        renderer = QgsSingleSymbolRendererV2( fillSymbol )
        mVectorLayer.setRendererV2( renderer )

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

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

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

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

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

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

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

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

        self.filename_test()
        self.autoscale_render_test()
        self.autoscale_render_test_old_api()
        self.fixedscale_render_test()
        self.predefinedscales_render_test()
        self.hidden_render_test()
Пример #24
0
    def get_access_isochrones(self):
        """
        Making the accessibility isochrones in few steps:
        - make a grid of points aroung the origin point,
        - snap each point (using OSRM locate function) on the road network,
        - get the time-distance between the origin point and each of these pts
            (using OSRM table function),
        - make an interpolation grid to extract polygons corresponding to the
            desired time intervals (using matplotlib library),
        - render the polygon.
        """
        try:
            self.host = check_host(self.lineEdit_host.text())
            self.profile = check_profile_name(self.lineEdit_profileName.text())
        except (ValueError, AssertionError) as err:
            self.iface.messageBar().pushMessage(
                "Error", "Please provide a valid non-empty URL", duration=10)
            return

        if 'clicking' in self.comboBox_method.currentText():
            pts = self.get_points_from_canvas()
        elif 'selecting' in self.comboBox_method.currentText():
            layer = self.comboBox_pointlayer.currentLayer()
            pts, _ = get_coords_ids(
                layer, '', on_selected=self.checkBox_selectedFt.isChecked())
            pts = tuple(pts)

        if not pts:
            return

        max_time = self.spinBox_max.value()
        interval_time = self.spinBox_intervall.value()
        nb_inter = int(round(max_time / interval_time)) + 1
        levels = tuple([nb for nb in xrange(0, int(
            max_time + 1) + interval_time, interval_time)][:nb_inter])

        self.make_prog_bar()
        self.max_points = 750 if len(pts) == 1 else 250
        self.polygons = []

        pts = [{"point": pt, "max": max_time, "levels": levels,
                "host": self.host, "profile": self.profile, "max_points": self.max_points}
                for pt in pts]

        pool = ThreadPool(processes=4 if len(pts) >= 4 else len(pts))

        try:
            self.polygons = [i for i in pool.map(prep_access, pts)]
        except Exception as err:
            self.display_error(err, 1)
            return

        if len(self.polygons) == 1:
            self.polygons = self.polygons[0]
        else:
            self.polygons = np.array(self.polygons).transpose().tolist()
            self.polygons = [QgsGeometry.unaryUnion(polys) for polys in self.polygons]

        isochrone_layer = QgsVectorLayer(
            "MultiPolygon?crs=epsg:4326&field=id:integer"
            "&field=min:integer(10)"
            "&field=max:integer(10)",
            "isochrone_osrm_{}".format(self.nb_isocr), "memory")
        data_provider = isochrone_layer.dataProvider()
        # Add the features to the layer to display :
        features = []
        levels = levels[1:]
        self.progress.setValue(8.5)
        for i, poly in enumerate(self.polygons):
            if not poly: continue
            ft = QgsFeature()
            ft.setGeometry(poly)
            ft.setAttributes(
                [i, levels[i] - interval_time, levels[i]])
            features.append(ft)
        data_provider.addFeatures(features[::-1])
        self.nb_isocr += 1
        self.progress.setValue(9.5)

        # Render the value :
        renderer = self.prepare_renderer(
            levels, interval_time, len(self.polygons))
        isochrone_layer.setRendererV2(renderer)
        isochrone_layer.setLayerTransparency(25)
        self.iface.messageBar().clearWidgets()
        QgsMapLayerRegistry.instance().addMapLayer(isochrone_layer)

        self.add_final_pts(pts)
        self.iface.setActiveLayer(isochrone_layer)
class TestQgsGeometryGeneratorSymbolLayerV2(TestCase):

    def setUp(self):
        polys_shp = os.path.join(TEST_DATA_DIR, 'polys.shp')
        points_shp = os.path.join(TEST_DATA_DIR, 'points.shp')
        lines_shp = os.path.join(TEST_DATA_DIR, 'lines.shp')
        self.polys_layer = QgsVectorLayer(polys_shp, 'Polygons', 'ogr')
        self.points_layer = QgsVectorLayer(points_shp, 'Points', 'ogr')
        self.lines_layer = QgsVectorLayer(lines_shp, 'Lines', 'ogr')
        QgsMapLayerRegistry.instance().addMapLayer(self.polys_layer)
        QgsMapLayerRegistry.instance().addMapLayer(self.lines_layer)
        QgsMapLayerRegistry.instance().addMapLayer(self.points_layer)

        # Create style
        sym1 = QgsFillSymbolV2.createSimple({'color': '#fdbf6f'})
        sym2 = QgsLineSymbolV2.createSimple({'color': '#fdbf6f'})
        sym3 = QgsMarkerSymbolV2.createSimple({'color': '#fdbf6f'})

        self.polys_layer.setRendererV2(QgsSingleSymbolRendererV2(sym1))
        self.lines_layer.setRendererV2(QgsSingleSymbolRendererV2(sym2))
        self.points_layer.setRendererV2(QgsSingleSymbolRendererV2(sym3))

        self.mapsettings = CANVAS.mapSettings()
        self.mapsettings.setOutputSize(QSize(400, 400))
        self.mapsettings.setOutputDpi(96)
        self.mapsettings.setExtent(QgsRectangle(-133, 22, -70, 52))

    def tearDown(self):
        QgsMapLayerRegistry.instance().removeAllMapLayers()

    def test_marker(self):
        sym = self.polys_layer.rendererV2().symbol()
        sym_layer = QgsGeometryGeneratorSymbolLayerV2.create({'geometryModifier': 'centroid($geometry)'})
        sym_layer.setSymbolType(QgsSymbolV2.Marker)
        sym.changeSymbolLayer(0, sym_layer)

        rendered_layers = [self.polys_layer.id()]
        self.mapsettings.setLayers(rendered_layers)

        renderchecker = QgsMultiRenderChecker()
        renderchecker.setMapSettings(self.mapsettings)
        renderchecker.setControlName('expected_geometrygenerator_marker')
        self.assertTrue(renderchecker.runTest('geometrygenerator_marker'))

    def test_mixed(self):
        sym = self.polys_layer.rendererV2().symbol()

        buffer_layer = QgsGeometryGeneratorSymbolLayerV2.create({'geometryModifier': 'buffer($geometry, "value"/15)'})
        buffer_layer.setSymbolType(QgsSymbolV2.Fill)
        self.assertIsNotNone(buffer_layer.subSymbol())
        sym.appendSymbolLayer(buffer_layer)
        marker_layer = QgsGeometryGeneratorSymbolLayerV2.create({'geometryModifier': 'centroid($geometry)'})
        marker_layer.setSymbolType(QgsSymbolV2.Marker)
        sym.appendSymbolLayer(marker_layer)

        rendered_layers = [self.polys_layer.id()]
        self.mapsettings.setLayers(rendered_layers)

        renderchecker = QgsMultiRenderChecker()
        renderchecker.setMapSettings(self.mapsettings)
        renderchecker.setControlName('expected_geometrygenerator_mixed')
        self.assertTrue(renderchecker.runTest('geometrygenerator_mixed'))

    def test_buffer_lines(self):
        sym = self.lines_layer.rendererV2().symbol()

        buffer_layer = QgsGeometryGeneratorSymbolLayerV2.create({'geometryModifier': 'buffer($geometry, "value"/15)'})
        buffer_layer.setSymbolType(QgsSymbolV2.Fill)
        self.assertIsNotNone(buffer_layer.subSymbol())
        sym.appendSymbolLayer(buffer_layer)

        rendered_layers = [self.lines_layer.id()]
        self.mapsettings.setLayers(rendered_layers)

        renderchecker = QgsMultiRenderChecker()
        renderchecker.setMapSettings(self.mapsettings)
        renderchecker.setControlName('expected_geometrygenerator_buffer_lines')
        self.assertTrue(renderchecker.runTest('geometrygenerator_buffer_lines'))

    def test_buffer_points(self):
        sym = self.points_layer.rendererV2().symbol()

        buffer_layer = QgsGeometryGeneratorSymbolLayerV2.create({'geometryModifier': 'buffer($geometry, "staff"/15)'})
        buffer_layer.setSymbolType(QgsSymbolV2.Fill)
        self.assertIsNotNone(buffer_layer.subSymbol())
        sym.appendSymbolLayer(buffer_layer)

        rendered_layers = [self.points_layer.id()]
        self.mapsettings.setLayers(rendered_layers)

        renderchecker = QgsMultiRenderChecker()
        renderchecker.setMapSettings(self.mapsettings)
        renderchecker.setControlName('expected_geometrygenerator_buffer_points')
        self.assertTrue(renderchecker.runTest('geometrygenerator_buffer_points'))
Пример #26
0
class CartoTools:
    def __init__(self, iface, dlg):
        self.iface = iface
        self.canvas = iface.mapCanvas()
        self.layerRegistry = QgsMapLayerRegistry.instance()
        self.dlg = dlg
        self.messageBar = iface.messageBar()

    def showNodes(self):
        """
        Parse the geometry of a selected layer and show its vertices (nodes)
        """

        mr = self.layerRegistry
        # Get the selected layer for which to show nodes
        selectedIndex = self.dlg.comboLayers.currentIndex()
        selectedLayer = self.dlg.comboLayers.itemData(selectedIndex)
        registeredLayers = self.layerRegistry.mapLayersByName('Noeuds')
        featuresCount = int(selectedLayer.featureCount())

        # Remove the node layer if already existing
        if mr.mapLayersByName('Noeuds'):
            mr.removeMapLayer(mr.mapLayersByName('Noeuds')[0].id())

        # Create memory layer to display nodes
        self.nodeLayer = QgsVectorLayer("Point?crs=EPSG:2056", "Noeuds",
                                        "memory")

        self.nodeLayerProvider = self.nodeLayer.dataProvider()

        # Create rendering style
        nodeSymbol = QgsMarkerSymbolV2.defaultSymbol(
            self.nodeLayer.geometryType())

        nodeSymbol.setColor(QColor('#CC3300'))
        nodeSymbol.setSize(2.0)
        nodeRenderer = QgsSingleSymbolRendererV2(nodeSymbol)
        self.nodeLayer.setRendererV2(nodeRenderer)

        # Select features visible in current map canvas extent
        if self.dlg.chkSelectByCanvasExtent.checkState():
            extent = self.canvas.extent()

            rect = QgsRectangle(extent.xMinimum(), extent.yMinimum(),
                                extent.xMaximum(), extent.yMaximum())

            request = QgsFeatureRequest()
            request.setFilterRect(rect)
            featureIterator = selectedLayer.getFeatures(request)

        # Select all features
        else:
            featureIterator = selectedLayer.getFeatures()

        # Create progress bar
        progressMessageBar = self.messageBar.createMessage(
            unicode("Création des noeuds...", "utf-8"))
        progress = QProgressBar()
        progress.setMinimum(0)
        progress.setMaximum(featuresCount)
        progress.setAlignment(Qt.AlignLeft | Qt.AlignVCenter)
        progressMessageBar.layout().addWidget(progress)
        self.messageBar.pushWidget(progressMessageBar,
                                   self.iface.messageBar().INFO)

        # Iterate over feature
        k = 0
        for feature in featureIterator:
            k += 1
            progress.setValue(k)
            geom = feature.geometry()
            feat = QgsFeature()

            # Adapt procedure for each geometry type
            if (geom):
                type = geom.wkbType()
            # LineString
            if type == QGis.WKBLineString:
                for point in geom.asPolyline():
                    feat.setGeometry(QgsGeometry.fromPoint(point))
                    self.nodeLayerProvider.addFeatures([feat])
            # MultiLineString
            elif type == QGis.WKBMultiLineString:
                for line in geom.asMultiPolyline():
                    for vertex in line:
                        feat.setGeometry(
                            QgsGeometry.fromPoint(
                                QgsPoint(vertex[0], vertex[1])))
                        self.nodeLayerProvider.addFeatures([feat])
            # Polygon
            elif type == QGis.WKBPolygon:
                polygons = geom.asPolygon()
                for polygon in polygons:
                    for vertex in polygon:
                        feat.setGeometry(
                            QgsGeometry.fromPoint(
                                QgsPoint(vertex[0], vertex[1])))
                        self.nodeLayerProvider.addFeatures([feat])
            # MultiPolygon
            elif type == QGis.WKBMultiPolygon:
                multiPoly = geom.asMultiPolygon()
                for polygons in multiPoly:
                    for polygon in polygons:
                        for vertex in polygon:
                            feat.setGeometry(
                                QgsGeometry.fromPoint(
                                    QgsPoint(vertex[0], vertex[1])))
                            self.nodeLayerProvider.addFeatures([feat])
            else:
                self.messageBar.pushMessage(
                    "Cartotools : ",
                    unicode("Type de géométrie non" + "supporté: " + str(type),
                            "utf-8"),
                    level=QgsMessageBar.CRITICAL)

        self.messageBar.clearWidgets()

        self.layerRegistry.addMapLayer(self.nodeLayer)

    def clearNodeLayer(self):

        if self.layerRegistry.mapLayersByName('Noeuds'):
            self.layerRegistry.removeMapLayer(
                self.layerRegistry.mapLayersByName('Noeuds')[0].id())
Пример #27
0
class OSRM_DialogTSP(QtGui.QDialog, FORM_CLASS_tsp, TemplateOsrm):
    def __init__(self, iface, parent=None):
        """ Constructor"""
        super(OSRM_DialogTSP, self).__init__(parent)
        self.setupUi(self)
        self.iface = iface
        self.pushButton_display.clicked.connect(self.run_tsp)
        self.pushButton_clear.clicked.connect(self.clear_results)
        self.comboBox_layer.setFilters(QgsMapLayerProxyModel.PointLayer)
        self.nb_route = 0

    def clear_results(self):
        """
        Clear previous result and set back counter to 0.
        """
        for layer in QgsMapLayerRegistry.instance().mapLayers():
            if 'tsp_solution_osrm' in layer:
                QgsMapLayerRegistry.instance().removeMapLayer(layer)
        self.nb_route = 0

    def run_tsp(self):
        """
        Main method, preparing the query and displaying the result on
        the canvas.
        """
        layer = self.comboBox_layer.currentLayer()
        coords, _ = get_coords_ids(
            layer, '', on_selected=self.checkBox_selec_features.isChecked())

        if len(coords) < 2:
            return -1

        try:
            self.host = check_host(self.lineEdit_host.text())
            profile = check_profile_name(self.lineEdit_profileName.text())
        except (ValueError, AssertionError) as err:
            print(err)
            self.iface.messageBar().pushMessage(
                "Error", "Please provide a valid non-empty URL and profile name", duration=10)
            return

        query = ''.join(
            ["http://", self.host,
            "/trip/", profile, "/",
            ";".join(["{},{}".format(coord[0], coord[1]) for coord in coords])])

        try:
            self.parsed = self.query_url(query)
        except Exception as err:
            self.iface.messageBar().pushMessage(
                "Error", "An error occured when trying to contact the OSRM "
                "instance (see QGis log for error traceback)",
                duration=10)
            QgsMessageLog.logMessage(
                'OSRM-plugin error report :\n {}'.format(err),
                level=QgsMessageLog.WARNING)
            return

        try:
            line_geoms = \
                [decode_geom(self.parsed['trips'][i]['geometry'])
                 for i in range(len(self.parsed['trips']))]
        except KeyError:
            self.iface.messageBar().pushMessage(
                "Error",
                "?...",
                duration=5)
            return

        tsp_route_layer = QgsVectorLayer(
            "Linestring?crs=epsg:4326&field=id:integer"
            "&field=total_time:integer(20)&field=distance:integer(20)",
            "tsp_solution_osrm{}".format(self.nb_route), "memory")
        my_symb = prepare_route_symbol(self.nb_route)
        tsp_route_layer.setRendererV2(QgsSingleSymbolRendererV2(my_symb))
        features = []
        for idx, feature in enumerate(self.parsed['trips']):
            ft = QgsFeature()
            ft.setGeometry(line_geoms[idx])
            ft.setAttributes([idx,
                              feature['distance'],
                              feature['duration']])
            features.append(ft)
            self.prepare_ordered_marker(coords, idx)
        tsp_route_layer.dataProvider().addFeatures(features)
        tsp_route_layer.updateExtents()
        QgsMapLayerRegistry.instance().addMapLayer(tsp_route_layer)
        self.iface.setActiveLayer(tsp_route_layer)
        self.iface.zoomToActiveLayer()
        put_on_top(self.tsp_marker_lr.id(), tsp_route_layer.id())
        self.nb_route += 1

#        if self.checkBox_instructions.isChecked():
#            pr_instruct, instruct_layer = self.prep_instruction()
#            QgsMapLayerRegistry.instance().addMapLayer(instruct_layer)
#            self.iface.setActiveLayer(instruct_layer)


    def prepare_ordered_marker(self, coords, idx):
        """
        Try to display nice marker on a point layer, showing the order of
        the path computed by OSRM.
        """
        self.tsp_marker_lr = QgsVectorLayer(
            "Point?crs=epsg:4326&field=id:integer"
            "&field=TSP_nb:integer(20)&field=Origin_nb:integer(20)",
            "tsp_markers_osrm{}".format(self.nb_route), "memory")
        symbol = QgsSymbolV2.defaultSymbol(self.tsp_marker_lr.geometryType())
        symbol.setSize(4.5)
        symbol.setColor(QtGui.QColor("yellow"))

        ordered_pts = \
            [coords[i["waypoint_index"]] for i in self.parsed['waypoints']]
        print("ordered_pts : ", ordered_pts)

        features = []
        for nb, pt in enumerate(ordered_pts):
            ft = QgsFeature()
            ft.setGeometry(QgsGeometry.fromPoint(QgsPoint(pt)))
            ft.setAttributes([nb, nb + 1, coords.index(pt)])
            features.append(ft)
        self.tsp_marker_lr.dataProvider().addFeatures(features)

        pal_lyr = QgsPalLayerSettings()
        pal_lyr.readFromLayer(self.tsp_marker_lr)
        pal_lyr.enabled = True
        pal_lyr.fieldName = 'TSP_nb'
        pal_lyr.placement= QgsPalLayerSettings.OverPoint
        pal_lyr.setDataDefinedProperty(QgsPalLayerSettings.Size,True,True,'12','')
        pal_lyr.writeToLayer(self.tsp_marker_lr)

        self.tsp_marker_lr.setRendererV2(QgsSingleSymbolRendererV2(symbol))
        QgsMapLayerRegistry.instance().addMapLayer(self.tsp_marker_lr)
Пример #28
0
class RFUDockWidget(QDockWidget, gui_dckwdgt_rfu_connector):

    closed = pyqtSignal()
    downloaded = pyqtSignal()
    uploaded = pyqtSignal()

    def __init__(self,
                 iface,
                 canvas,
                 map_layer_registry,
                 conn=None,
                 parent=None):

        super(RFUDockWidget, self).__init__(parent)
        self.setupUi(self)

        self.iface = iface
        self.canvas = canvas
        self.map_layer_registry = map_layer_registry
        self.conn = conn
        self.zone = None
        self.precision_class = []
        self.ellips_acronym = []
        self.dflt_ellips_acronym = None
        self.selected_ellips_acronym = None
        self.nature = []
        self.auth_creator = []

        self.url = None

        self.l_vertex = None
        self.l_edge = None
        self.layers = [self.l_vertex, self.l_edge]

        # Initialize dicts which contains changed datasets
        self.edges_added = {}
        self.vertices_added = {}
        self.edges_removed = {}
        self.vertices_removed = {}
        self.edges_modified = {}
        self.vertices_modified = {}

        self.downloadPushButton.clicked.connect(self.on_downloaded)
        self.permalinkLineEdit.returnPressed.connect(self.on_downloaded)
        self.projComboBox.currentIndexChanged.connect(self.set_destination_crs)

    def closeEvent(self, event):

        self.closed.emit()

    def on_downloaded(self):

        widget = self.iface.messageBar().createMessage(
            u"Géofoncier", u"Téléchargement du RFU.")

        progress_bar = QProgressBar()
        progress_bar.setMinimum(0)
        progress_bar.setMaximum(2)
        widget.layout().addWidget(progress_bar)

        self.iface.messageBar().pushWidget(widget, QgsMessageBar.WARNING)
        progress_bar.setValue(1)

        # https://pro.geofoncier.fr/index.php?&centre=-196406,5983255&context=metropole
        url = self.permalinkLineEdit.text()
        if not url:
            return self.abort_action(msg=u"Veuillez renseigner le permalien.")
        self.url = url

        try:
            self.download(self.url)
        except Exception as e:
            return self.abort_action(msg=e.message)

        progress_bar.setValue(2)
        self.iface.messageBar().clearWidgets()

        return

    def on_reset(self):

        # Ensure that the action is intentional
        msg = (u"Cette action est irreversible. "
               u"Toute modification sera perdue. "
               u"Êtes-vous sûr de vouloir réinitialiser l'outil ?")
        resp = QMessageBox.question(self, r"Question", msg, QMessageBox.Yes,
                                    QMessageBox.No)
        if resp == QMessageBox.Yes:
            self.reset()

        return

    def on_uploaded(self):

        self.uploaded.emit()

        # Create message
        widget = self.iface.messageBar().createMessage(
            u"Géofoncier", u"Envoi des modifications.")
        progress_bar = QProgressBar()
        progress_bar.setMinimum(0)
        progress_bar.setMaximum(3)
        widget.layout().addWidget(progress_bar)
        self.iface.messageBar().pushWidget(widget, QgsMessageBar.WARNING)
        progress_bar.setValue(1)

        enr_ref_dossier, ok = QInputDialog.getText(
            self, u"Référence de dossier",
            u"Vous êtes sur le point de soumettre\n"
            u"les modifications au serveur Géofoncier.\n"
            u"Veuillez renseigner la référence du dossier.")
        if not ok:
            return self.abort_action()

        if not enr_ref_dossier:
            return self.abort_action(
                msg=u"Merci de renseigner une référence de dossier.")

        commentaire = u"Dossier %s" % enr_ref_dossier

        dossiers = self.conn.dossiersoge_dossiers(self.zone, enr_ref_dossier)
        if dossiers.code != 200:
            return self.abort_action(msg=dossiers.read())

        tree = EltTree.fromstring(dossiers.read())

        # Check if exception
        err = tree.find(r"./erreur")
        if err:
            return self.abort_action(msg=err.text)

        nb_dossiers = int(tree.find(r"./dossiers").attrib[r"total"])

        if nb_dossiers == 0:
            return self.abort_action(msg=u"Le dossier \'%s\' n'existe pas." %
                                     enr_ref_dossier)

        if nb_dossiers >= 1:
            # Prendre par défaut le dernier dossier dans la liste
            dossier_uri = tree.getiterator(
                tag=r"dossier")[nb_dossiers -
                                1].find(r"{http://www.w3.org/2005/Atom}link")
            enr_api_dossier = dossier_uri.attrib[r"href"].split(r"/")[-1][1:]

        progress_bar.setValue(2)

        # Stop editing mode
        for layer in self.layers:
            if layer.isEditable():
                layer.commitChanges()

        # Check if dataset changes
        if (self.edges_added or self.vertices_added or self.edges_removed
                or self.vertices_removed or self.edges_modified
                or self.vertices_modified):
            pass
        else:
            return self.abort_action(
                msg=u"Aucune modification des données n'est détecté.")

        # Upload, reset and re-download datasets
        try:
            log = self.upload(enr_api_dossier=enr_api_dossier,
                              commentaire=commentaire)
            self.reset()
            self.download(self.url)
        except Exception as e:
            return self.abort_action(msg=e.message)

        self.canvas.zoomToFullExtent()
        self.iface.messageBar().clearWidgets()

        return QMessageBox.information(self, r"Information", u"\r".join(log))

    def download(self, url):

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

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

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

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

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

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

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

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

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

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

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

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

        tree = EltTree.fromstring(resp.read())

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

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

        p_bbox = self.l_bbox.dataProvider()

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

        renderer_bbox = QgsInvertedPolygonRenderer(
            QgsSingleSymbolRendererV2(simple_symbol))

        self.l_bbox.setRendererV2(renderer_bbox)

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

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

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

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

        # Set the map canvas layer set
        self.canvas.setLayerSet([
            QgsMapCanvasLayer(self.l_vertex),
            QgsMapCanvasLayer(self.l_edge),
            QgsMapCanvasLayer(self.l_bbox)
        ])

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

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

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

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

        tree = EltTree.fromstring(resp.read())

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

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

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

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

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

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

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

            self.projComboBox.addItem(e[2])

            if not self.dflt_ellips_acronym:
                continue

            if self.dflt_ellips_acronym == e[0]:

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

                # Activate 'On The Fly'
                self.canvas.setCrsTransformEnabled(True)

                # Then change the CRS in canvas
                crs = QgsCoordinateReferenceSystem(
                    int(e[1]), QgsCoordinateReferenceSystem.EpsgCrsId)
                self.canvas.setDestinationCrs(crs)

        # Then, start editing mode..
        for layer in self.layers:
            if not layer.isEditable():
                layer.startEditing()

        self.projComboBox.setDisabled(False)

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

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

        self.downloaded.emit()

        return True

    def reset(self):
        """Remove RFU layers."""

        # Remove RFU layers
        try:
            self.map_layer_registry.removeMapLayers(
                [self.l_vertex.id(),
                 self.l_edge.id(),
                 self.l_bbox.id()])
        except:
            return

        # Reset variable
        self.precision_class = []
        self.ellips_acronym = []
        self.dflt_ellips_acronym = None
        self.nature = []
        self.auth_creator = []
        self.l_vertex = None
        self.l_edge = None
        self.layers = [self.l_vertex, self.l_edge]
        self.edges_added = {}
        self.vertices_added = {}
        self.edges_removed = {}
        self.vertices_removed = {}
        self.edges_modified = {}
        self.vertices_modified = {}

        # Reset ComboBox which contains projections authorized
        self.projComboBox.clear()
        self.projComboBox.setDisabled(True)

        self.permalinkLineEdit.clear()
        self.permalinkLineEdit.setDisabled(False)
        self.permalinkLineEdit.returnPressed.connect(self.on_downloaded)

        self.downloadPushButton.setDisabled(False)
        self.downloadPushButton.clicked.connect(self.on_downloaded)

        self.resetPushButton.setDisabled(True)
        self.resetPushButton.clicked.disconnect(self.on_reset)

        self.uploadPushButton.setDisabled(True)
        self.uploadPushButton.clicked.disconnect(self.on_uploaded)

        return True

    def upload(self, enr_api_dossier=None, commentaire=None):
        """Upload data to Géofoncier REST API.
        On success returns the log messages (Array).

        """

        # Set XML document
        root = EltTree.Element(r"rfu")

        # Add to our XML document datasets which have been changed
        if self.vertices_added:
            for fid in self.vertices_added:
                tools.xml_subelt_creator(root,
                                         u"sommet",
                                         data=self.vertices_added[fid],
                                         action=r"create")

        if self.edges_added:
            for fid in self.edges_added:
                tools.xml_subelt_creator(root,
                                         u"limite",
                                         data=self.edges_added[fid],
                                         action=r"create")

        if self.vertices_removed:
            for fid in self.vertices_removed:
                tools.xml_subelt_creator(root,
                                         u"sommet",
                                         data=self.vertices_removed[fid],
                                         action=r"delete")

        if self.edges_removed:
            for fid in self.edges_removed:
                tools.xml_subelt_creator(root,
                                         u"limite",
                                         data=self.edges_removed[fid],
                                         action=r"delete")

        if self.vertices_modified:
            for fid in self.vertices_modified:
                tools.xml_subelt_creator(root,
                                         u"sommet",
                                         data=self.vertices_modified[fid],
                                         action=r"update")

        if self.edges_modified:
            for fid in self.edges_modified:
                tools.xml_subelt_creator(root,
                                         u"limite",
                                         data=self.edges_modified[fid],
                                         action=r"update")

        # Create a new changeset Id
        changeset_id = self.create_changeset(enr_api_dossier=enr_api_dossier,
                                             commentaire=commentaire)

        # Add changeset value in our XML document
        root.attrib[r"changeset"] = changeset_id

        # Send data
        edit = self.conn.edit(self.zone, EltTree.tostring(root))
        if edit.code != 200:
            raise Exception(edit.read())

        tree = EltTree.fromstring(edit.read())

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

        # Returns log info
        msgs_log = []
        for log in tree.iter(r"log"):
            msgs_log.append(u"%s: %s" % (log.attrib[u"type"], log.text))

        # Close the changeset
        self.destroy_changeset(changeset_id)

        # Reset all
        self.edges_added = {}
        self.vertices_added = {}
        self.edges_removed = {}
        self.vertices_removed = {}
        self.edges_modified = {}
        self.vertices_modified = {}

        return msgs_log

    def create_changeset(self, enr_api_dossier=None, commentaire=None):
        """Open a new changeset from Géofoncier API.
        On success, returns the new changeset id.

        """

        opencs = self.conn.open_changeset(self.zone,
                                          enr_api_dossier=enr_api_dossier,
                                          commentaire=commentaire)
        if opencs.code != 200:
            raise Exception(opencs.read())

        tree = EltTree.fromstring(opencs.read())

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

        treeterator = tree.getiterator(tag=r"changeset")

        # We should get only one changeset
        if len(treeterator) != 1:
            raise Exception(u"Le nombre de \'changeset\' est incohérent.\n"
                            u"Merci de contacter l'administrateur Géofoncier.")

        return treeterator[0].attrib[r"id"]

    def destroy_changeset(self, id):
        """Close a changeset."""

        closecs = self.conn.close_changeset(self.zone, id)

        if closecs.code != 200:
            raise Exception(closecs.read())

        tree = EltTree.fromstring(closecs.read())

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

        return True

    def abort_action(self, msg=None):

        for layer in self.layers:
            if layer and not layer.isEditable():
                layer.startEditing()

        # Clear message bar
        self.iface.messageBar().clearWidgets()

        if msg:
            return QMessageBox.warning(self, r"Warning", msg)

        return

    def extract_layers(self, tree):
        """Return a list of RFU layers."""

        # Create vector layers..
        l_vertex = QgsVectorLayer(r"Point?crs=epsg:4326&index=yes",
                                  u"Sommet RFU", r"memory")
        l_edge = QgsVectorLayer(r"LineString?crs=epsg:4326&index=yes",
                                u"Limite RFU", r"memory")

        p_vertex = l_vertex.dataProvider()
        p_edge = l_edge.dataProvider()

        # Define default style renderer..

        renderer_vertex = QgsRuleBasedRendererV2(QgsMarkerSymbolV2())
        vertex_root_rule = renderer_vertex.rootRule()
        vertex_rules = (
            ((u"Borne, borne à puce, pierre, piquet, clou ou broche"),
             (u"$id >= 0 AND \"som_nature\" IN ('Borne',"
              u"'Borne à puce', 'Pierre', 'Piquet', 'Clou ou broche')"),
             r"#EC0000", 2.2),
            ((u"Axe cours d'eau, axe fossé, haut de talus, pied de talus"),
             (u"$id >= 0 AND \"som_nature\" IN ('Axe cours d\'\'eau',"
              u"'Axe fossé', 'Haut de talus', 'Pied de talus')"), r"#EE8012",
             2.2), ((u"Angle de bâtiment, axe de mur, angle de mur, "
                     u"angle de clôture, pylône et toute autre valeur"),
                    (u"$id >= 0 AND \"som_nature\" NOT IN ('Borne',"
                     u"'Borne à puce', 'Pierre', 'Piquet', 'Clou ou broche',"
                     u"'Axe cours d\'\'eau', 'Axe fossé', 'Haut de talus',"
                     u"'Pied de talus')"), r"#9784EC",
                    2.2), (u"Temporaire", r"$id < 0", "cyan", 2.4))

        for label, expression, color, size in vertex_rules:
            rule = vertex_root_rule.children()[0].clone()
            rule.setLabel(label)
            rule.setFilterExpression(expression)
            rule.symbol().setColor(QColor(color))
            rule.symbol().setSize(size)
            vertex_root_rule.appendChild(rule)

        vertex_root_rule.removeChildAt(0)
        l_vertex.setRendererV2(renderer_vertex)

        renderer_edge = QgsRuleBasedRendererV2(QgsLineSymbolV2())
        edge_root_rule = renderer_edge.rootRule()
        edge_rules = ((r"Limite", r"$id >= 0", "#0A0AFF", 0.5),
                      (r"Temporaire", r"$id < 0", "cyan", 1))

        for label, expression, color, width in edge_rules:
            rule = edge_root_rule.children()[0].clone()
            rule.setLabel(label)
            rule.setFilterExpression(expression)
            rule.symbol().setColor(QColor(color))
            rule.symbol().setWidth(width)
            edge_root_rule.appendChild(rule)

        edge_root_rule.removeChildAt(0)
        l_edge.setRendererV2(renderer_edge)

        # Add fields..
        p_vertex.addAttributes([
            QgsField(r"@id_noeud", QVariant.Int),
            # QgsField(r"@changeset", QVariant.Int),
            # QgsField(r"@timestamp", QVariant.Date),
            QgsField(r"@version", QVariant.Int),
            QgsField(r"som_ge_createur", QVariant.String),
            QgsField(r"som_nature", QVariant.String),
            QgsField(r"som_precision_rattachement", QVariant.Int),
            QgsField(r"som_coord_est", QVariant.Double),
            QgsField(r"som_coord_nord", QVariant.Double),
            QgsField(r"som_representation_plane", QVariant.String),
            # QgsField(r"date_creation", QVariant.Date)
        ])

        p_edge.addAttributes([
            QgsField(r"@id_arc", QVariant.Int),
            # QgsField(r"@id_noeud_debut", QVariant.Int),
            # QgsField(r"@id_noeud_fin", QVariant.Int),
            # QgsField(r"@changeset", QVariant.Int),
            # QgsField(r"@timestamp", QVariant.Date),
            QgsField(r"@version", QVariant.Int),
            QgsField(r"lim_ge_createur", QVariant.String),
            # QgsField(r"lim_date_creation", QVariant.Date)
        ])

        # Add features from xml tree..
        # ..to vertex layer..
        fts_vertex = []
        for e in tree.findall(r"sommet"):

            ft_vertex = QgsFeature()
            ft_vertex.setGeometry(QgsGeometry.fromWkt(e.attrib[r"geometrie"]))

            _id_noeud = int(e.attrib[r"id_noeud"])
            # _changeset = int(e.attrib[r"changeset"])
            # _timestamp = QDateTime(datetime.strptime(
            #                 e.attrib[r"timestamp"], r"%Y-%m-%d %H:%M:%S.%f"))
            _version = int(e.attrib[r"version"])
            som_ge_createur = unicode(e.find(r"./som_ge_createur").text)
            som_nature = unicode(e.find(r"./som_nature").text)
            som_prec_rattcht = int(
                e.find(r"./som_precision_rattachement").text)
            som_coord_est = float(e.find(r"./som_coord_est").text)
            som_coord_nord = float(e.find(r"./som_coord_nord").text)
            som_repres_plane = unicode(
                e.find(r"./som_representation_plane").text)
            # som_date_creation = QDate(datetime.strptime(
            #                         e.find(r"./som_date_creation").text, r"%Y-%m-%d").date())

            ft_vertex.setAttributes([
                _id_noeud,
                # _changeset,
                # _timestamp,
                _version,
                som_ge_createur,
                som_nature,
                som_prec_rattcht,
                som_coord_est,
                som_coord_nord,
                som_repres_plane,
                # som_date_creation
            ])

            fts_vertex.append(ft_vertex)

        # ..to edge layer..
        fts_edge = []
        for e in tree.findall(r"limite"):

            ft_edge = QgsFeature()
            ft_edge.setGeometry(QgsGeometry.fromWkt(e.attrib[r"geometrie"]))

            _id_arc = int(e.attrib[r"id_arc"])
            # _id_noeud_debut = int(e.attrib[r"id_noeud_debut"])
            # _id_noeud_fin = int(e.attrib[r"id_noeud_fin"])
            # _changeset = int(e.attrib[r"changeset"])
            # _timestamp = QDateTime(datetime.strptime(
            #                 e.attrib[r"timestamp"], r"%Y-%m-%d %H:%M:%S.%f"))
            _version = int(e.attrib[r"version"])
            lim_ge_createur = unicode(e.find(r"./lim_ge_createur").text)
            # lim_date_creation = QDate(datetime.strptime(
            #                        e.find(r"./lim_date_creation").text, r"%Y-%m-%d").date())

            ft_edge.setAttributes([
                _id_arc,
                # _id_noeud_debut,
                # _id_noeud_fin,
                # _changeset,
                # _timestamp,
                _version,
                lim_ge_createur,
                # lim_date_creation
            ])

            fts_edge.append(ft_edge)

        # Add features to layers..
        p_vertex.addFeatures(fts_vertex)
        p_edge.addFeatures(fts_edge)

        # Update fields..
        l_vertex.updateFields()
        l_edge.updateFields()

        # Update layer's extent..
        l_vertex.updateExtents()
        l_edge.updateExtents()

        # Check if valid..
        if not l_vertex.isValid() or not l_edge.isValid():
            raise Exception(
                u"Une erreur est survenue lors du chargement de la couche.")

        # Set labelling...
        palyr = QgsPalLayerSettings()
        palyr.enabled = True
        # palyr.readFromLayer(l_vertex)
        palyr.fieldName = r"$id"  # Expression $id
        palyr.placement = 1  # ::OverPoint
        palyr.quadOffset = 2  # ::QuadrantAboveRight
        palyr.setDataDefinedProperty(80, True, True, r"1",
                                     "")  # ::OffsetUnits -> ::MM
        palyr.xOffset = 2.0
        palyr.yOffset = -1.0
        palyr.writeToLayer(l_vertex)

        # Then return layers..
        return [l_vertex, l_edge]

    def get_features(self, layer):

        features = []
        for ft in layer.getFeatures():
            attributes = tools.attrib_as_kv(ft.fields(), ft.attributes())
            attributes[r"fid"] = ft.id()
            features.append(attributes)

        return features

    def remove_features(self, layer_id, fids):

        for fid in fids:

            if layer_id == self.l_edge.id(
            ) and fid in self.features_edge_backed_up:
                self.edges_removed[fid] = self.features_edge_backed_up[fid]

            if layer_id == self.l_vertex.id(
            ) and fid in self.features_vertex_backed_up:
                self.vertices_removed[fid] = self.features_vertex_backed_up[
                    fid]

    def add_features(self, layer_id, features):

        for ft in features:

            attrib = tools.attrib_as_kv(ft.fields(),
                                        ft.attributes(),
                                        qgsgeom=ft.geometry())

            if layer_id == self.l_vertex.id():
                self.vertices_added[ft.id()] = attrib

            if layer_id == self.l_edge.id():
                self.edges_added[ft.id()] = attrib

    def modify_feature(self, layer_id, feature, qgsgeom=None):

        if qgsgeom:
            f = tools.attrib_as_kv(feature.fields(),
                                   feature.attributes(),
                                   qgsgeom=qgsgeom)
        else:
            f = tools.attrib_as_kv(feature.fields(), feature.attributes())

        if self.l_edge.id() == layer_id:
            if feature.id() not in self.features_edge_backed_up:
                return
            self.edges_modified[feature.id()] = f

        if self.l_vertex.id() == layer_id:
            if feature.id() not in self.features_vertex_backed_up:
                return
            self.vertices_modified[feature.id()] = f

    def set_destination_crs(self, j):

        epsg = 4326  # by default
        for i, e in enumerate(self.ellips_acronym):
            if i == j:
                self.selected_ellips_acronym = e[0]
                epsg = int(e[1])
                continue

        crs = QgsCoordinateReferenceSystem(
            epsg, QgsCoordinateReferenceSystem.EpsgCrsId)
        self.canvas.setDestinationCrs(crs)
        self.canvas.zoomToFullExtent()
    def process_layers(self):

        download_path = self.dlg.download_path.text()

        if self.dlg.download_path.text() is None or len(self.dlg.download_path.text()) == 0:
            QMessageBox.critical(None, self.tr('Error'), self.tr('Please insert the download folder'))

        elif (int(self.dlg.cbToYear.currentText())) - int(self.dlg.cbFromYear.currentText()) < 0:
            QMessageBox.critical(None, self.tr('Error'), self.tr('Year selection is not valid'))

        else:
            processed_layers = 0
            self.dlg.progressBar.setValue(processed_layers)
            self.dlg.progressText.setText('Fetching Data from the World Bank')

            indicator_name = self.dlg.cbIndicator.currentText()
            indicator = self.indicators[indicator_name]

            from_year = int(self.dlg.cbFromYear.currentText())
            to_year = int(self.dlg.cbToYear.currentText()) + 1
            total_years = to_year - from_year

            layers = []
            layers_not_available = []

            # create tmp layer
            tmp_layer = QgsVectorLayer("Polygon?crs=EPSG:4326", "tmp", "memory")
            tmp_data_provider = tmp_layer.dataProvider()

            # add fields
            tmp_data_provider.addAttributes([QgsField("value", QVariant.Double)])

            data = get_world_bank_data(indicator, str(from_year), str(to_year-1))

            # copy layer
            output_file = copy_layer(download_path, indicator_name)

            layer = QgsVectorLayer(output_file, "layer_name", "ogr")

            # create layer by year
            for index, year in enumerate(range(from_year, to_year)):
                self.dlg.progressText.setText('Processing ' + str(year))

                data_yearly = get_data_by_year(data, year)
                if len(data_yearly) > 0:
                    added = create_layer(layer, tmp_layer, data_yearly, year, index)
                    layers.append(str(year))
                else:
                    layers_not_available.append(str(year))


                # update procgress bar
                processed_layers += 1
                self.dlg.progressBar.setValue(int((float(processed_layers) / float(total_years)) * 100))

            # commit changed on tmp layer
            tmp_layer.commitChanges()
            layer.commitChanges()

            renderer = create_join_renderer(tmp_layer, 'value', 5,  QgsGraduatedSymbolRendererV2.Jenks)

            if self.dlg.open_in_qgis.isChecked():
                for index, year in enumerate(reversed(layers)):
                    l = QgsVectorLayer(output_file, indicator_name + ' (' + str(year) + ')', "ogr")
                    r = renderer.clone()
                    r.setClassAttribute(str(year))
                    l.setRendererV2(r)
                    QgsMapLayerRegistry.instance().addMapLayer(l)
                    self.iface.legendInterface().setLayerVisible(l, (index == 0))

                    # for index, year in enumerate(range(from_year, to_year)):
                    #     if str(year) not in layers_not_available:
                    #         l = QgsVectorLayer(output_file, indicator_name + ' (' + str(year) + ')', "ogr")
                    #         r = renderer.clone()
                    #         r.setClassAttribute(str(year))
                    #         l.setRendererV2(r)
                    #         QgsMapLayerRegistry.instance().addMapLayer(l)
                    #         self.iface.legendInterface().setLayerVisible(l, (index == (to_year - from_year-1)))

            self.iface.mapCanvas().refresh()

            self.dlg.progressText.setText('Process Finished')

            if len(layers_not_available) > 0:
                self.iface.messageBar().pushMessage(indicator_name, 'Data are not available for ' + ', '.join(layers_not_available) + '', level=QgsMessageBar.WARNING)
    def process_layers(self):

        download_path = self.dlg.download_path.text()

        if self.dlg.download_path.text() is None or len(
                self.dlg.download_path.text()) == 0:
            QMessageBox.critical(None, self.tr('Error'),
                                 self.tr('Please insert the download folder'))

        elif (int(self.dlg.cbToYear.currentText())) - int(
                self.dlg.cbFromYear.currentText()) < 0:
            QMessageBox.critical(None, self.tr('Error'),
                                 self.tr('Year selection is not valid'))

        else:
            processed_layers = 0
            self.dlg.progressBar.setValue(processed_layers)
            self.dlg.progressText.setText('Fetching Data from the World Bank')

            indicator_name = self.dlg.cbIndicator.currentText()
            indicator = self.indicators[indicator_name]

            from_year = int(self.dlg.cbFromYear.currentText())
            to_year = int(self.dlg.cbToYear.currentText()) + 1
            total_years = to_year - from_year

            layers = []
            layers_not_available = []

            # create tmp layer
            tmp_layer = QgsVectorLayer("Polygon?crs=EPSG:4326", "tmp",
                                       "memory")
            tmp_data_provider = tmp_layer.dataProvider()

            # add fields
            tmp_data_provider.addAttributes(
                [QgsField("value", QVariant.Double)])

            data = get_world_bank_data(indicator, str(from_year),
                                       str(to_year - 1))

            # copy layer
            output_file = copy_layer(download_path, indicator_name)

            layer = QgsVectorLayer(output_file, "layer_name", "ogr")

            # create layer by year
            for index, year in enumerate(range(from_year, to_year)):
                self.dlg.progressText.setText('Processing ' + str(year))

                data_yearly = get_data_by_year(data, year)
                if len(data_yearly) > 0:
                    added = create_layer(layer, tmp_layer, data_yearly, year,
                                         index)
                    layers.append(str(year))
                else:
                    layers_not_available.append(str(year))

                # update procgress bar
                processed_layers += 1
                self.dlg.progressBar.setValue(
                    int((float(processed_layers) / float(total_years)) * 100))

            # commit changed on tmp layer
            tmp_layer.commitChanges()
            layer.commitChanges()

            renderer = create_join_renderer(tmp_layer, 'value', 5,
                                            QgsGraduatedSymbolRendererV2.Jenks)

            if self.dlg.open_in_qgis.isChecked():
                for index, year in enumerate(reversed(layers)):
                    l = QgsVectorLayer(output_file,
                                       indicator_name + ' (' + str(year) + ')',
                                       "ogr")
                    r = renderer.clone()
                    r.setClassAttribute(str(year))
                    l.setRendererV2(r)
                    QgsMapLayerRegistry.instance().addMapLayer(l)
                    self.iface.legendInterface().setLayerVisible(
                        l, (index == 0))

                    # for index, year in enumerate(range(from_year, to_year)):
                    #     if str(year) not in layers_not_available:
                    #         l = QgsVectorLayer(output_file, indicator_name + ' (' + str(year) + ')', "ogr")
                    #         r = renderer.clone()
                    #         r.setClassAttribute(str(year))
                    #         l.setRendererV2(r)
                    #         QgsMapLayerRegistry.instance().addMapLayer(l)
                    #         self.iface.legendInterface().setLayerVisible(l, (index == (to_year - from_year-1)))

            self.iface.mapCanvas().refresh()

            self.dlg.progressText.setText('Process Finished')

            if len(layers_not_available) > 0:
                self.iface.messageBar().pushMessage(
                    indicator_name,
                    'Data are not available for ' +
                    ', '.join(layers_not_available) + '',
                    level=QgsMessageBar.WARNING)
Пример #31
0
    def run(self):
        """Run method that performs all the real work"""

        #~path = 'C:/Users/Sudhanshu/Downloads/Hivre_Bajar'
        #~ path = 'C:/Users/Rahul/Desktop/Gondala1'
        #~ path = 'C:/Users/Rahul/Desktop/BW_new'
        path = ''
        debugging = path != ''
        if debugging:
            zones_layer = self.iface.addVectorLayer(path + '/Zones.shp',
                                                    'Zones', 'ogr')
            soil_layer = self.iface.addVectorLayer(path + '/Soil.shp',
                                                   'Soil Cover', 'ogr')
            lulc_layer = self.iface.addVectorLayer(path + '/LULC.shp',
                                                   'Land-Use-Land-Cover',
                                                   'ogr')
            cadastral_layer = self.iface.addVectorLayer(
                path + '/Cadastral.shp', 'Cadastral Map', 'ogr')
            slope_layer = self.iface.addRasterLayer(path + '/Slope.tif',
                                                    'Slope')
            #~ drainage_layer = self.iface.addRasterLayer(path + '/Drainage.shp', 'Drainage', 'ogr')

            rainfall_csv = path + '/Rainfall.csv'
            sowing_threshold = 30
            crop = 'soyabean'
            interval_points = [50, 100]
            monsoon_end_date_index = MONSOON_END_DATE_INDEX

        else:
            self.dlg.show()
            if self.dlg.exec_() == QFileDialog.Rejected: return

            path = self.dlg.folder_path.text()
            zones_layer = self.iface.addVectorLayer(
                self.dlg.zones_layer_filename.text(), 'Zones', 'ogr')
            soil_layer = self.iface.addVectorLayer(
                self.dlg.soil_layer_filename.text(), 'Soil Cover', 'ogr')
            lulc_layer = self.iface.addVectorLayer(
                self.dlg.lulc_layer_filename.text(), 'Land-Use-Land-Cover',
                'ogr')
            cadastral_layer = self.iface.addVectorLayer(
                self.dlg.cadastral_layer_filename.text(), 'Cadastral Map',
                'ogr')
            slope_layer = self.iface.addRasterLayer(
                self.dlg.slope_layer_filename.text(), 'Slope')
            if self.dlg.drainage_layer_filename.text() != '':
                drainage_layer = self.iface.addRasterLayer(
                    self.dlg.drainage_layer_filename.text(), 'Drainage', 'ogr')

            rainfall_csv = self.dlg.rainfall_csv_filename.text()
            sowing_threshold = self.dlg.sowing_threshold.value()
            monsoon_end_date_index = self.dlg.monsoon_end.value() + 123
            crop = self.dlg.crop_combo_box.currentText()
            interval_points = [
                int(
                    self.dlg.colour_code_intervals_list_widget.item(
                        i).text().split('-')[0])
                for i in range(
                    1, self.dlg.colour_code_intervals_list_widget.count())
            ]

            #~ print path, zones_layer, soil_layer, lulc_layer, cadastral_layer, slope_layer, drainage_layer, rainfall_csv

        #~ start_qdate = self.dlg.from_date_edit.date()
        #~ date_with_index_0 = QDate(start_qdate.year(), 6, 1).dayOfYear()
        #~ start_date_index = start_qdate.dayOfYear() - date_with_index_0
        #~ end_qdate = self.dlg.to_date_edit.date()
        #~ end_date_index = end_qdate.dayOfYear() - date_with_index_0

        pointwise_output_csv_filename = '/kharif_model_pointwise_output.csv'
        zonewise_budget_csv_filename = '/kharif_model_zonewise_budget.csv'
        zonewise_budget_csv_filename_LU = '/kharif_model_zonewise_LU_budget.csv'
        zonewise_budget_areawise_csv_filename = '/kharif_model_zonewise_budget_area.csv'
        cadastral_vulnerability_csv_filename = '/kharif_model_cadastral_vulnerability.csv'
        model_calculator = KharifModelCalculator(path, zones_layer, soil_layer,
                                                 lulc_layer, cadastral_layer,
                                                 slope_layer, rainfall_csv)

        model_calculator.calculate(crop, pointwise_output_csv_filename,
                                   zonewise_budget_csv_filename,
                                   zonewise_budget_csv_filename_LU,
                                   zonewise_budget_areawise_csv_filename,
                                   cadastral_vulnerability_csv_filename,
                                   sowing_threshold, monsoon_end_date_index)
        uri = 'file:///' + path + pointwise_output_csv_filename + '?delimiter=%s&crs=epsg:32643&xField=%s&yField=%s' % (
            ',', 'X', 'Y')
        kharif_model_output_layer = QgsVectorLayer(uri, 'Kharif Model Output',
                                                   'delimitedtext')
        graduated_symbol_renderer_range_list = []
        ET_D_max = max([
            point.budget.PET_minus_AET_crop_end
            for point in model_calculator.output_grid_points
        ])
        opacity = 1
        intervals_count = self.dlg.colour_code_intervals_list_widget.count()
        for i in range(intervals_count):
            percent_interval_start_text, percent_interval_end_text = self.dlg.colour_code_intervals_list_widget.item(
                i).text().split('-')
            interval_min = 0 if percent_interval_start_text == '0' else (
                int(percent_interval_start_text) * ET_D_max / 100.0 + 0.01)
            interval_max = (int(percent_interval_end_text) * ET_D_max / 100.0)
            label = "{0:.2f} - {1:.2f}".format(interval_min, interval_max)
            colour = QColor(
                int(255 * (1 - (i + 1.0) / (intervals_count + 1.0))), 0,
                0)  # +1 done to tackle boundary cases
            symbol = QgsSymbolV2.defaultSymbol(
                kharif_model_output_layer.geometryType())
            symbol.setColor(colour)
            symbol.setAlpha(opacity)
            interval_range = QgsRendererRangeV2(interval_min, interval_max,
                                                symbol, label)
            graduated_symbol_renderer_range_list.append(interval_range)
        renderer = QgsGraduatedSymbolRendererV2(
            '', graduated_symbol_renderer_range_list)
        renderer.setMode(QgsGraduatedSymbolRendererV2.EqualInterval)
        renderer.setClassAttribute('Crop duration PET-AET')
        kharif_model_output_layer.setRendererV2(renderer)
        QgsMapLayerRegistry.instance().addMapLayer(kharif_model_output_layer)

        QgsVectorFileWriter.writeAsVectorFormat(
            kharif_model_output_layer, path + '/kharif_et_deficit.shp',
            "utf-8", None, "ESRI Shapefile")

        #Dislpaying for long kharif crops
        if (crop in long_kharif_crops):
            kharif_model_monsoon_end_output_layer = QgsVectorLayer(
                uri, 'Kharif Model Monsoon End Output', 'delimitedtext')
            graduated_symbol_renderer_range_list = []
            ET_D_max = max([
                point.budget.PET_minus_AET_monsoon_end
                for point in model_calculator.output_grid_points
            ])
            opacity = 1
            intervals_count = self.dlg.colour_code_intervals_list_widget.count(
            )
            geometry_type = kharif_model_monsoon_end_output_layer.geometryType(
            )
            for i in range(intervals_count):
                percent_interval_start_text, percent_interval_end_text = self.dlg.colour_code_intervals_list_widget.item(
                    i).text().split('-')
                interval_min = 0 if percent_interval_start_text == '0' else (
                    int(percent_interval_start_text) * ET_D_max / 100.0 + 0.01)
                interval_max = (int(percent_interval_end_text) * ET_D_max /
                                100.0)
                label = "{0:.2f} - {1:.2f}".format(interval_min, interval_max)
                colour = QColor(
                    int(255 * (1 - (i + 1.0) / (intervals_count + 1.0))), 0,
                    0)  # +1 done to tackle boundary cases
                symbol = QgsSymbolV2.defaultSymbol(geometry_type)
                symbol.setColor(colour)
                symbol.setAlpha(opacity)
                interval_range = QgsRendererRangeV2(interval_min, interval_max,
                                                    symbol, label)
                graduated_symbol_renderer_range_list.append(interval_range)
            renderer = QgsGraduatedSymbolRendererV2(
                '', graduated_symbol_renderer_range_list)
            renderer.setMode(QgsGraduatedSymbolRendererV2.EqualInterval)
            renderer.setClassAttribute('Monsoon PET-AET')
            kharif_model_monsoon_end_output_layer.setRendererV2(renderer)
            QgsMapLayerRegistry.instance().addMapLayer(
                kharif_model_monsoon_end_output_layer)
            QgsVectorFileWriter.writeAsVectorFormat(
                kharif_model_monsoon_end_output_layer,
                path + '/kharif_post_monsoon_et_deficit.shp', "utf-8", None,
                "ESRI Shapefile")

        self.iface.actionHideAllLayers().trigger()
        self.iface.legendInterface().setLayerVisible(zones_layer, True)
        if 'drainage_layer' in locals():
            self.iface.legendInterface().setLayerVisible(drainage_layer, True)
        if (crop in long_kharif_crops):
            self.iface.legendInterface().setLayerVisible(
                kharif_model_monsoon_end_output_layer, True)
        self.iface.legendInterface().setLayerVisible(kharif_model_output_layer,
                                                     True)
        self.iface.mapCanvas().setExtent(zones_layer.extent())
        self.iface.mapCanvas().mapRenderer().setDestinationCrs(
            zones_layer.crs())

        self.iface.mapCanvas().refresh()

        if self.dlg.save_image_group_box.isChecked():
            QTimer.singleShot(
                1000, lambda: self.iface.mapCanvas().saveAsImage(
                    self.dlg.save_image_filename.text()))
    def download_data(self):

        # Get user selection
        group_code = self.cbGroups.itemData(self.cbGroups.currentIndex())
        domain_code = self.cbDomains.itemData(self.cbDomains.currentIndex())
        element_code = self.cbElements.itemData(self.cbElements.currentIndex())
        item_code = self.cbItems.itemData(self.cbItems.currentIndex())
        download_folder = self.download_folder.text()

        # Check selection
        if group_code is None:
            self.bar.pushMessage(None, self.tr('Please select a group'), level=QgsMessageBar.CRITICAL)
        elif domain_code is None:
            self.bar.pushMessage(None, self.tr('Please select a domain'), level=QgsMessageBar.CRITICAL)
        elif element_code is None:
            self.bar.pushMessage(None, self.tr('Please select an element'), level=QgsMessageBar.CRITICAL)
        elif item_code is None:
            self.bar.pushMessage(None, self.tr('Please select an item'), level=QgsMessageBar.CRITICAL)
        elif download_folder is None or len(download_folder) == 0:
            self.bar.pushMessage(None, self.tr('Please select a download folder'), level=QgsMessageBar.CRITICAL)
        else:
            # Get data
            data = get_data(domain_code, element_code, item_code)
            # Notify the user
            self.bar.pushMessage(None, self.tr('Downloaded rows: ') + str(len(data)), level=QgsMessageBar.INFO)
            # Layer name
            layer_name = self.cbItems.currentText().replace(' ', '_') + '_' + self.cbElements.currentText().replace(' ', '_')
            folder_name = os.path.join(download_folder, group_code, domain_code)
            if not os.path.exists(folder_name):
                os.makedirs(folder_name)
            # Copy template layer
            output_file = copy_layer(folder_name, layer_name)
            layer = QgsVectorLayer(output_file, 'layer_name', 'ogr')
            # Add all the years to the layer
            feature_idx = 64
            year_to_be_shown = 2014
            number_of_nulls = 0
            for year in range(2014, 1960, -1):
                progress = (1 + (feature_idx - 64)) * 1.86
                self.progress.setValue(progress)
                self.progress_label.setText('<b>' + self.tr('Progress') + ': ' + '</b> ' + self.tr('Adding Year ') + str(year))
                year_data = self.get_year_data(data, year)
                layer.dataProvider().addAttributes([QgsField(str(year), QVariant.Double)])
                if len(year_data) > 0:
                    layer.startEditing()
                    for feature in layer.getFeatures():
                        if feature['FAOSTAT'] is not None:
                            feature_code = str(feature['FAOSTAT'])
                            for d in year_data:
                                data_code = str(d['code'])
                                if data_code == feature_code:
                                    value = d['value']
                                    layer.changeAttributeValue(feature.id(), (feature_idx), float(value))
                                    tmp_feature = QgsFeature()
                                    tmp_feature.setAttributes([float(value)])
                                    layer.dataProvider().addFeatures([tmp_feature])
                                    if value is None:
                                        number_of_nulls += 1
                    layer.commitChanges()
                else:
                    year_to_be_shown -= 1
                feature_idx += 1
            # Add layer to canvas
            if self.add_to_canvas.isChecked():
                renderer = self.create_join_renderer(layer, str(year_to_be_shown), 11, QgsGraduatedSymbolRendererV2.Pretty)
                l = QgsVectorLayer(output_file, layer_name + '(' + str(year_to_be_shown) + ')', 'ogr')
                r = renderer.clone()
                r.setClassAttribute(str(year_to_be_shown))
                l.setRendererV2(r)
                QgsMapLayerRegistry.instance().addMapLayer(l)
                self.iface.legendInterface().setLayerVisible(l, True)
            # Close pop-up
            self.dlg.close()
Пример #33
0
class OSRM_DialogTSP(QtGui.QDialog, FORM_CLASS_tsp, TemplateOsrm):
    def __init__(self, iface, parent=None):
        """ Constructor"""
        super(OSRM_DialogTSP, self).__init__(parent)
        self.setupUi(self)
        self.iface = iface
        self.pushButton_display.clicked.connect(self.run_tsp)
        self.pushButton_clear.clicked.connect(self.clear_results)
        self.comboBox_layer.setFilters(QgsMapLayerProxyModel.PointLayer)
        self.nb_route = 0

    def clear_results(self):
        """
        Clear previous result and set back counter to 0.
        """
        for layer in QgsMapLayerRegistry.instance().mapLayers():
            if 'tsp_solution_osrm' in layer:
                QgsMapLayerRegistry.instance().removeMapLayer(layer)
        self.nb_route = 0

    def run_tsp(self):
        """
        Main method, preparing the query and displaying the result on
        the canvas.
        """
        layer = self.comboBox_layer.currentLayer()
        coords, _ = get_coords_ids(
            layer, '', on_selected=self.checkBox_selec_features.isChecked())

        if len(coords) < 2:
            return -1

        try:
            self.host = check_host(self.lineEdit_host.text())
            profile = check_profile_name(self.lineEdit_profileName.text())
        except (ValueError, AssertionError) as err:
            print(err)
            self.iface.messageBar().pushMessage(
                "Error",
                "Please provide a valid non-empty URL and profile name",
                duration=10)
            return

        query = ''.join([
            "http://", self.host, "/trip/", profile, "/",
            ";".join(["{},{}".format(c[0], c[1]) for c in coords])
        ])

        try:
            self.parsed = self.query_url(query)
        except Exception as err:
            self.iface.messageBar().pushMessage(
                "Error", "An error occured when trying to contact the OSRM "
                "instance (see QGis log for error traceback)",
                duration=10)
            QgsMessageLog.logMessage(
                'OSRM-plugin error report :\n {}'.format(err),
                level=QgsMessageLog.WARNING)
            return

        try:
            line_geoms = \
                [decode_geom(self.parsed['trips'][i]['geometry'])
                 for i in range(len(self.parsed['trips']))]
        except KeyError:
            self.iface.messageBar().pushMessage("Error", "?...", duration=5)
            return

        tsp_route_layer = QgsVectorLayer(
            "Linestring?crs=epsg:4326&field=id:integer"
            "&field=total_time:integer(20)&field=distance:integer(20)",
            "tsp_solution_osrm{}".format(self.nb_route), "memory")
        my_symb = prepare_route_symbol(self.nb_route)
        tsp_route_layer.setRendererV2(QgsSingleSymbolRendererV2(my_symb))
        features = []
        for idx, feature in enumerate(self.parsed['trips']):
            ft = QgsFeature()
            ft.setGeometry(line_geoms[idx])
            ft.setAttributes([idx, feature['distance'], feature['duration']])
            features.append(ft)
            self.prepare_ordered_marker(coords, idx)
        tsp_route_layer.dataProvider().addFeatures(features)
        tsp_route_layer.updateExtents()
        QgsMapLayerRegistry.instance().addMapLayer(tsp_route_layer)
        self.iface.setActiveLayer(tsp_route_layer)
        self.iface.zoomToActiveLayer()
        put_on_top(self.tsp_marker_lr.id(), tsp_route_layer.id())
        self.nb_route += 1


#        if self.checkBox_instructions.isChecked():
#            pr_instruct, instruct_layer = self.prep_instruction()
#            QgsMapLayerRegistry.instance().addMapLayer(instruct_layer)
#            self.iface.setActiveLayer(instruct_layer)

    def prepare_ordered_marker(self, coords, idx):
        """
        Try to display nice marker on a point layer, showing the order of
        the path computed by OSRM.
        """
        self.tsp_marker_lr = QgsVectorLayer(
            "Point?crs=epsg:4326&field=id:integer"
            "&field=TSP_nb:integer(20)&field=Origin_nb:integer(20)",
            "tsp_markers_osrm{}".format(self.nb_route), "memory")
        symbol = QgsSymbolV2.defaultSymbol(self.tsp_marker_lr.geometryType())
        symbol.setSize(4.5)
        symbol.setColor(QtGui.QColor("yellow"))

        ordered_pts = \
            [coords[i["waypoint_index"]] for i in self.parsed['waypoints']]
        print("ordered_pts : ", ordered_pts)

        features = []
        for nb, pt in enumerate(ordered_pts):
            ft = QgsFeature()
            ft.setGeometry(QgsGeometry.fromPoint(QgsPoint(pt)))
            ft.setAttributes([nb, nb + 1, coords.index(pt)])
            features.append(ft)
        self.tsp_marker_lr.dataProvider().addFeatures(features)

        pal_lyr = QgsPalLayerSettings()
        pal_lyr.readFromLayer(self.tsp_marker_lr)
        pal_lyr.enabled = True
        pal_lyr.fieldName = 'TSP_nb'
        pal_lyr.placement = QgsPalLayerSettings.OverPoint
        pal_lyr.setDataDefinedProperty(QgsPalLayerSettings.Size, True, True,
                                       '12', '')
        pal_lyr.writeToLayer(self.tsp_marker_lr)

        self.tsp_marker_lr.setRendererV2(QgsSingleSymbolRendererV2(symbol))
        QgsMapLayerRegistry.instance().addMapLayer(self.tsp_marker_lr)
    def testCase(self):
        self.TEST_DATA_DIR = unitTestDataPath()
        tmppath = tempfile.mkdtemp()
        for file in glob.glob(
                os.path.join(self.TEST_DATA_DIR, 'france_parts.*')):
            shutil.copy(os.path.join(self.TEST_DATA_DIR, file), tmppath)
        vectorFileInfo = QFileInfo(tmppath + "/france_parts.shp")
        mVectorLayer = QgsVectorLayer(vectorFileInfo.filePath(),
                                      vectorFileInfo.completeBaseName(), "ogr")

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

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

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

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

        # fix the renderer, fill with green
        props = {"color": "0,127,0"}
        fillSymbol = QgsFillSymbolV2.createSimple(props)
        renderer = QgsSingleSymbolRendererV2(fillSymbol)
        mVectorLayer.setRendererV2(renderer)

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

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

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

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

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

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

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

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

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

        shutil.rmtree(tmppath, True)
Пример #35
0
    def get_route(self):
        """
        Main method to prepare the request and display the result on the
        QGIS canvas.
        """
        try:
            self.host = check_host(self.lineEdit_host.text())
            profile = check_profile_name(self.lineEdit_profileName.text())
        except (ValueError, AssertionError) as err:
            print(err)
            self.iface.messageBar().pushMessage(
                "Error", "Please provide a valid non-empty URL and profile name", duration=10)
            return

        origin = self.lineEdit_xyO.text()
        interm = self.lineEdit_xyI.text()
        destination = self.lineEdit_xyD.text()

        try:
            assert match('^[^a-zA-Z]+$', origin) \
                and 46 > len(origin) > 4
            assert match('^[^a-zA-Z]+$', destination) \
                and 46 > len(destination) > 4
            xo, yo = eval(origin)
            xd, yd = eval(destination)
        except:
            self.iface.messageBar().pushMessage(
                "Error", "Invalid coordinates !", duration=10)
            return -1

        if interm:
            try:
                assert match('^[^a-zA-Z]+$', interm) \
                    and 150 > len(interm) > 4
                interm = eval(''.join(['[', interm, ']']))
                tmp = ';'.join(
                    ['{},{}'.format(xi, yi) for xi, yi in interm])
                url = ''.join(["http://", self.host, "/route/", profile, "/",
                               "{},{};".format(xo, yo), tmp, ";{},{}".format(xd, yd),
                               "?overview=full&steps={}&alternatives={}".format(
                        str(self.checkBox_instruction.isChecked()).lower(),
                        str(self.checkBox_alternative.isChecked()).lower())])
            except:
                self.iface.messageBar().pushMessage(
                    "Error", "Invalid intemediates coordinates", duration=10)
        else:
            url = ''.join([
                "http://", self.host, "/route/", profile, "/",
                "polyline(", encode_to_polyline([(yo, xo), (yd, xd)]), ")",
#                "{},{};{},{}".format(xo, yo, xd, yd),
                "?overview=full&steps={}&alternatives={}"
                .format(str(self.checkBox_instruction.isChecked()).lower(),
                       str(self.checkBox_alternative.isChecked()).lower())])

        try:
            self.parsed = self.query_url(url)
            assert "code" in self.parsed
        except Exception as err:
            self.display_error(err, 1)
            return

        if not 'Ok' in self.parsed['code']:
            self.display_error(self.parsed['code'], 1)
            return

        try:
            enc_line = self.parsed['routes'][0]["geometry"]
            line_geom = decode_geom(enc_line)
        except KeyError:
            self.iface.messageBar().pushMessage(
                "Error",
                "No route found between {} and {}".format(origin, destination),
                duration=5)
            return

        self.nb_route += 1
        osrm_route_layer = QgsVectorLayer(
            "Linestring?crs=epsg:4326&field=id:integer"
            "&field=total_time:integer(20)&field=distance:integer(20)",
            "route_osrm{}".format(self.nb_route), "memory")
        my_symb = prepare_route_symbol(self.nb_route)
        osrm_route_layer.setRendererV2(QgsSingleSymbolRendererV2(my_symb))
        provider = osrm_route_layer.dataProvider()
        fet = QgsFeature()
        fet.setGeometry(line_geom)
        fet.setAttributes([0, self.parsed['routes'][0]['duration'],
                           self.parsed['routes'][0]['distance']])
        provider.addFeatures([fet])
        OD_layer = self.make_OD_markers(self.nb_route, xo, yo, xd, yd, interm)
        QgsMapLayerRegistry.instance().addMapLayer(OD_layer)

        osrm_route_layer.updateExtents()
        QgsMapLayerRegistry.instance().addMapLayer(osrm_route_layer)
        self.iface.setActiveLayer(osrm_route_layer)
        self.iface.zoomToActiveLayer()
        put_on_top(OD_layer.id(), osrm_route_layer.id())
#        if self.checkBox_instruction.isChecked():
#            pr_instruct, instruct_layer = self.prep_instruction()
#            QgsMapLayerRegistry.instance().addMapLayer(instruct_layer)
#            self.iface.setActiveLayer(instruct_layer)

        if self.checkBox_alternative.isChecked() \
                and 'alternative_geometries' in self.parsed:
            self.nb_alternative = len(self.parsed['routes'] - 1)
            self.get_alternatives(provider)
#            if self.dlg.checkBox_instruction.isChecked():
#                for i in range(self.nb_alternative):
#                    pr_instruct, instruct_layer = \
#                       self.prep_instruction(
#                           i + 1, pr_instruct, instruct_layer)
        return
class TestQgsArrowSymbolLayer(unittest.TestCase):
    def setUp(self):
        self.iface = get_iface()

        lines_shp = os.path.join(TEST_DATA_DIR, 'lines.shp')
        self.lines_layer = QgsVectorLayer(lines_shp, 'Lines', 'ogr')
        QgsMapLayerRegistry.instance().addMapLayer(self.lines_layer)

        # Create style
        sym2 = QgsLineSymbolV2.createSimple({'color': '#fdbf6f'})
        self.lines_layer.setRendererV2(QgsSingleSymbolRendererV2(sym2))

        self.mapsettings = self.iface.mapCanvas().mapSettings()
        self.mapsettings.setOutputSize(QSize(400, 400))
        self.mapsettings.setOutputDpi(96)
        self.mapsettings.setExtent(QgsRectangle(-113, 28, -91, 40))
        self.mapsettings.setBackgroundColor(QColor("white"))

    def tearDown(self):
        QgsMapLayerRegistry.instance().removeAllMapLayers()

    def test_1(self):
        sym = self.lines_layer.rendererV2().symbol()
        sym_layer = QgsArrowSymbolLayer.create({
            'head_length': '6.5',
            'head_thickness': '6.5'
        })
        dd = QgsDataDefined("(@geometry_point_num % 4) * 2")
        sym_layer.setDataDefinedProperty("arrow_width", dd)
        dd2 = QgsDataDefined("(@geometry_point_num % 4) * 2")
        sym_layer.setDataDefinedProperty("head_length", dd2)
        dd3 = QgsDataDefined("(@geometry_point_num % 4) * 2")
        sym_layer.setDataDefinedProperty("head_thickness", dd3)
        fill_sym = QgsFillSymbolV2.createSimple({
            'color': '#8bcfff',
            'outline_color': '#000000',
            'outline_style': 'solid',
            'outline_width': '1'
        })
        sym_layer.setSubSymbol(fill_sym)
        sym.changeSymbolLayer(0, sym_layer)

        rendered_layers = [self.lines_layer.id()]
        self.mapsettings.setLayers(rendered_layers)

        renderchecker = QgsMultiRenderChecker()
        renderchecker.setMapSettings(self.mapsettings)
        renderchecker.setControlName('expected_arrowsymbollayer_1')
        self.assertTrue(renderchecker.runTest('arrowsymbollayer_1'))

    def test_2(self):
        sym = self.lines_layer.rendererV2().symbol()
        # double headed
        sym_layer = QgsArrowSymbolLayer.create({
            'arrow_width': '5',
            'head_length': '4',
            'head_thickness': '6',
            'head_type': '2'
        })
        fill_sym = QgsFillSymbolV2.createSimple({
            'color': '#8bcfff',
            'outline_color': '#000000',
            'outline_style': 'solid',
            'outline_width': '1'
        })
        sym_layer.setSubSymbol(fill_sym)
        sym.changeSymbolLayer(0, sym_layer)

        rendered_layers = [self.lines_layer.id()]
        self.mapsettings.setLayers(rendered_layers)

        renderchecker = QgsMultiRenderChecker()
        renderchecker.setMapSettings(self.mapsettings)
        renderchecker.setControlName('expected_arrowsymbollayer_2')
        self.assertTrue(renderchecker.runTest('arrowsymbollayer_2'))

    def test_3(self):
        sym = self.lines_layer.rendererV2().symbol()
        # double headed
        sym_layer = QgsArrowSymbolLayer.create({
            'arrow_width': '7',
            'head_length': '6',
            'head_thickness': '8',
            'head_type': '0',
            'arrow_type': '1',
            'is_curved': '0'
        })
        fill_sym = QgsFillSymbolV2.createSimple({
            'color': '#8bcfff',
            'outline_color': '#000000',
            'outline_style': 'solid',
            'outline_width': '1'
        })
        sym_layer.setSubSymbol(fill_sym)
        sym.changeSymbolLayer(0, sym_layer)

        rendered_layers = [self.lines_layer.id()]
        self.mapsettings.setLayers(rendered_layers)

        renderchecker = QgsMultiRenderChecker()
        ms = self.mapsettings
        ms.setExtent(QgsRectangle(-101, 35, -99, 37))
        renderchecker.setMapSettings(ms)
        renderchecker.setControlName('expected_arrowsymbollayer_3')
        self.assertTrue(renderchecker.runTest('arrowsymbollayer_3'))

    def test_unrepeated(self):
        sym = self.lines_layer.rendererV2().symbol()
        # double headed
        sym_layer = QgsArrowSymbolLayer.create({
            'arrow_width': '7',
            'head_length': '6',
            'head_thickness': '8',
            'head_type': '0',
            'arrow_type': '0'
        })
        # no repetition
        sym_layer.setIsRepeated(False)
        fill_sym = QgsFillSymbolV2.createSimple({
            'color': '#8bcfff',
            'outline_color': '#000000',
            'outline_style': 'solid',
            'outline_width': '1'
        })
        sym_layer.setSubSymbol(fill_sym)
        sym.changeSymbolLayer(0, sym_layer)

        rendered_layers = [self.lines_layer.id()]
        self.mapsettings.setLayers(rendered_layers)

        renderchecker = QgsMultiRenderChecker()
        ms = self.mapsettings
        ms.setExtent(QgsRectangle(-119, 17, -82, 50))
        renderchecker.setMapSettings(ms)
        renderchecker.setControlName('expected_arrowsymbollayer_4')
        self.assertTrue(renderchecker.runTest('arrowsymbollayer_4'))

    def testColors(self):
        """
        Test colors, need to make sure colors are passed/retrieved from subsymbol
        """
        sym_layer = QgsArrowSymbolLayer.create()
        sym_layer.setColor(QColor(150, 50, 100))
        self.assertEqual(sym_layer.color(), QColor(150, 50, 100))
        self.assertEqual(sym_layer.subSymbol().color(), QColor(150, 50, 100))
        sym_layer.subSymbol().setColor(QColor(250, 150, 200))
        self.assertEqual(sym_layer.subSymbol().color(), QColor(250, 150, 200))
        self.assertEqual(sym_layer.color(), QColor(250, 150, 200))
Пример #37
0
    def get_route(self):
        """
        Main method to prepare the request and display the result on the
        QGIS canvas.
        """
        try:
            self.host = check_host(self.lineEdit_host.text())
            profile = check_profile_name(self.lineEdit_profileName.text())
        except (ValueError, AssertionError) as err:
            print(err)
            self.iface.messageBar().pushMessage(
                "Error",
                "Please provide a valid non-empty URL and profile name",
                duration=10)
            return

        origin = self.lineEdit_xyO.text()
        interm = self.lineEdit_xyI.text()
        destination = self.lineEdit_xyD.text()

        try:
            assert match('^[^a-zA-Z]+$', origin) \
                and 46 > len(origin) > 4
            assert match('^[^a-zA-Z]+$', destination) \
                and 46 > len(destination) > 4
            xo, yo = eval(origin)
            xd, yd = eval(destination)
        except:
            self.iface.messageBar().pushMessage("Error",
                                                "Invalid coordinates !",
                                                duration=10)
            return -1

        if interm:
            try:
                assert match('^[^a-zA-Z]+$', interm) \
                    and 150 > len(interm) > 4
                interm = eval(''.join(['[', interm, ']']))
                tmp = ';'.join(['{},{}'.format(xi, yi) for xi, yi in interm])
                url = ''.join([
                    "http://", self.host, "/route/", profile, "/",
                    "{},{};".format(xo, yo), tmp, ";{},{}".format(xd, yd),
                    "?overview=full&alternatives={}".format(
                        str(self.checkBox_alternative.isChecked()).lower())
                ])
            except:
                self.iface.messageBar().pushMessage(
                    "Error", "Invalid intemediates coordinates", duration=10)
        else:
            url = ''.join([
                "http://", self.host, "/route/", profile, "/", "polyline(",
                encode_to_polyline([(yo, xo), (yd, xd)]), ")",
                "?overview=full&alternatives={}".format(
                    str(self.checkBox_alternative.isChecked()).lower())
            ])

        try:
            self.parsed = self.query_url(url)
            assert "code" in self.parsed
        except Exception as err:
            self.display_error(err, 1)
            return

        if 'Ok' not in self.parsed['code']:
            self.display_error(self.parsed['code'], 1)
            return

        try:
            enc_line = self.parsed['routes'][0]["geometry"]
            line_geom = decode_geom(enc_line)
        except KeyError:
            self.iface.messageBar().pushMessage(
                "Error",
                "No route found between {} and {}".format(origin, destination),
                duration=5)
            return

        self.nb_route += 1
        osrm_route_layer = QgsVectorLayer(
            "Linestring?crs=epsg:4326&field=id:integer"
            "&field=total_time:integer(20)&field=distance:integer(20)",
            "route_osrm{}".format(self.nb_route), "memory")
        my_symb = prepare_route_symbol(self.nb_route)
        osrm_route_layer.setRendererV2(QgsSingleSymbolRendererV2(my_symb))
        provider = osrm_route_layer.dataProvider()
        fet = QgsFeature()
        fet.setGeometry(line_geom)
        fet.setAttributes([
            0, self.parsed['routes'][0]['duration'],
            self.parsed['routes'][0]['distance']
        ])
        provider.addFeatures([fet])
        OD_layer = self.make_OD_markers(self.nb_route, xo, yo, xd, yd, interm)
        QgsMapLayerRegistry.instance().addMapLayer(OD_layer)

        osrm_route_layer.updateExtents()
        QgsMapLayerRegistry.instance().addMapLayer(osrm_route_layer)
        self.iface.setActiveLayer(osrm_route_layer)
        self.iface.zoomToActiveLayer()
        put_on_top(OD_layer.id(), osrm_route_layer.id())
        #        if self.checkBox_instruction.isChecked():
        #            pr_instruct, instruct_layer = self.prep_instruction()
        #            QgsMapLayerRegistry.instance().addMapLayer(instruct_layer)
        #            self.iface.setActiveLayer(instruct_layer)

        if self.checkBox_alternative.isChecked() \
                and 'alternative_geometries' in self.parsed:
            self.nb_alternative = len(self.parsed['routes'] - 1)
            self.get_alternatives(provider)


#            if self.dlg.checkBox_instruction.isChecked():
#                for i in range(self.nb_alternative):
#                    pr_instruct, instruct_layer = \
#                       self.prep_instruction(
#                           i + 1, pr_instruct, instruct_layer)
        return
Пример #38
0
    def add_source_layers(self, sources):
        """
        :param list sources:
            a list of nrmllib Source Models (e.g. SimpleFaultSource)
        """
        source_type = collections.namedtuple(
            'SourceType', 'layer_type transform color')

        geometries = {
            'PointSource': source_type(
                'Point', lambda x: x.geometry.wkt, "255,255,255,185"),
            'AreaSource': source_type(
                'Polygon', lambda x: x.geometry.wkt, '0,255,255,185'),
            'SimpleFaultSource': source_type(
                'Polygon',
                lambda x: simple_surface_from_source(x).wkt,
                '0,50,255,185'),
            'ComplexFaultSource': source_type(
                'MultiPolygon', lambda _: NotImplementedError, '50,50,50,185')}

        source_dict = collections.defaultdict(list)

        for s in sources:
            source_dict[s.__class__.__name__].append(s)

        for stype, sources in source_dict.items():
            layer = QgsVectorLayer(
                '%s?crs=epsg:4326' % (
                    geometries[stype].layer_type),
                stype, 'memory')
            QgsMapLayerRegistry.instance().addMapLayer(layer)
            pr = layer.dataProvider()
            layer.startEditing()

            fields = [QgsField("source_id", QVariant.String)]
            pr.addAttributes(fields)

            qgs_fields = QgsFields()
            for field in fields:
                qgs_fields.append(field)

            features = []
            for src in sources:
                fet = QgsFeature()
                fet.setFields(qgs_fields)
                fet['source_id'] = src.id
                if stype == 'SimpleFaultSource':
                    self.sources[src.id] = _nrml_to_hazardlib(src, 1.)
                fet.setGeometry(QgsGeometry.fromWkt(
                    geometries[stype].transform(src)))
                features.append(fet)
            pr.addFeatures(features)
            layer.commitChanges()
            layer.updateExtents()

            symbol = QgsFillSymbolV2.createSimple(
                {'style': 'diagonal_x',
                 'color': geometries[stype].color,
                 'style_border': 'solid'})
            layer.setRendererV2(QgsSingleSymbolRendererV2(symbol))

            self.source_layers[stype] = layer

        self.reset_map()
Пример #39
0
    def run_tsp(self):
        """
        Main method, preparing the query and displaying the result on
        the canvas.
        """
        layer = self.comboBox_layer.currentLayer()
        coords, _ = get_coords_ids(
            layer, '', on_selected=self.checkBox_selec_features.isChecked())

        if len(coords) < 2:
            return -1

        try:
            self.host = check_host(self.lineEdit_host.text())
            profile = check_profile_name(self.lineEdit_profileName.text())
        except (ValueError, AssertionError) as err:
            print(err)
            self.iface.messageBar().pushMessage(
                "Error", "Please provide a valid non-empty URL and profile name", duration=10)
            return

        query = ''.join(
            ["http://", self.host,
            "/trip/", profile, "/",
            ";".join(["{},{}".format(coord[0], coord[1]) for coord in coords])])

        try:
            self.parsed = self.query_url(query)
        except Exception as err:
            self.iface.messageBar().pushMessage(
                "Error", "An error occured when trying to contact the OSRM "
                "instance (see QGis log for error traceback)",
                duration=10)
            QgsMessageLog.logMessage(
                'OSRM-plugin error report :\n {}'.format(err),
                level=QgsMessageLog.WARNING)
            return

        try:
            line_geoms = \
                [decode_geom(self.parsed['trips'][i]['geometry'])
                 for i in range(len(self.parsed['trips']))]
        except KeyError:
            self.iface.messageBar().pushMessage(
                "Error",
                "?...",
                duration=5)
            return

        tsp_route_layer = QgsVectorLayer(
            "Linestring?crs=epsg:4326&field=id:integer"
            "&field=total_time:integer(20)&field=distance:integer(20)",
            "tsp_solution_osrm{}".format(self.nb_route), "memory")
        my_symb = prepare_route_symbol(self.nb_route)
        tsp_route_layer.setRendererV2(QgsSingleSymbolRendererV2(my_symb))
        features = []
        for idx, feature in enumerate(self.parsed['trips']):
            ft = QgsFeature()
            ft.setGeometry(line_geoms[idx])
            ft.setAttributes([idx,
                              feature['distance'],
                              feature['duration']])
            features.append(ft)
            self.prepare_ordered_marker(coords, idx)
        tsp_route_layer.dataProvider().addFeatures(features)
        tsp_route_layer.updateExtents()
        QgsMapLayerRegistry.instance().addMapLayer(tsp_route_layer)
        self.iface.setActiveLayer(tsp_route_layer)
        self.iface.zoomToActiveLayer()
        put_on_top(self.tsp_marker_lr.id(), tsp_route_layer.id())
        self.nb_route += 1
class LoadOutputAsLayerDialog(QDialog, FORM_CLASS):
    """
    Modal dialog to load an oq-engine output as layer
    """
    def __init__(self,
                 iface,
                 viewer_dock,
                 session,
                 hostname,
                 calc_id,
                 output_type=None,
                 path=None,
                 mode=None,
                 zonal_layer_path=None,
                 engine_version=None):
        # sanity check
        if output_type not in OQ_TO_LAYER_TYPES:
            raise NotImplementedError(output_type)
        self.iface = iface
        self.viewer_dock = viewer_dock
        self.path = path
        self.session = session
        self.hostname = hostname
        self.calc_id = calc_id
        self.output_type = output_type
        self.mode = mode  # if 'testing' it will avoid some user interaction
        self.zonal_layer_path = zonal_layer_path
        self.engine_version = engine_version
        QDialog.__init__(self)
        # Set up the user interface from Designer.
        self.setupUi(self)
        # Disable ok_button until all user options are set
        self.ok_button = self.buttonBox.button(QDialogButtonBox.Ok)
        self.ok_button.setDisabled(True)

    def create_file_hlayout(self):
        self.file_hlayout = QHBoxLayout()
        self.file_lbl = QLabel('File to load')
        self.file_browser_tbn = QToolButton()
        self.file_browser_tbn.setText('...')
        self.file_browser_tbn.clicked.connect(self.on_file_browser_tbn_clicked)
        self.path_le = QLineEdit()
        self.path_le.setEnabled(False)
        self.file_hlayout.addWidget(self.file_lbl)
        self.file_hlayout.addWidget(self.file_browser_tbn)
        self.file_hlayout.addWidget(self.path_le)
        self.vlayout.addLayout(self.file_hlayout)

    def create_num_sites_indicator(self):
        self.num_sites_msg = 'Number of sites: %s'
        self.num_sites_lbl = QLabel(self.num_sites_msg % '')
        self.vlayout.addWidget(self.num_sites_lbl)

    def create_file_size_indicator(self):
        self.file_size_msg = 'File size: %s'
        self.file_size_lbl = QLabel(self.file_size_msg % '')
        self.vlayout.addWidget(self.file_size_lbl)

    def create_rlz_or_stat_selector(self, label='Realization'):
        self.rlz_or_stat_lbl = QLabel(label)
        self.rlz_or_stat_cbx = QComboBox()
        self.rlz_or_stat_cbx.setEnabled(False)
        self.rlz_or_stat_cbx.currentIndexChanged['QString'].connect(
            self.on_rlz_or_stat_changed)
        self.vlayout.addWidget(self.rlz_or_stat_lbl)
        self.vlayout.addWidget(self.rlz_or_stat_cbx)

    def create_imt_selector(self):
        self.imt_lbl = QLabel('Intensity Measure Type')
        self.imt_cbx = QComboBox()
        self.imt_cbx.setEnabled(False)
        self.imt_cbx.currentIndexChanged['QString'].connect(
            self.on_imt_changed)
        self.vlayout.addWidget(self.imt_lbl)
        self.vlayout.addWidget(self.imt_cbx)

    def create_poe_selector(self):
        self.poe_lbl = QLabel('Probability of Exceedance')
        self.poe_cbx = QComboBox()
        self.poe_cbx.setEnabled(False)
        self.poe_cbx.currentIndexChanged['QString'].connect(
            self.on_poe_changed)
        self.vlayout.addWidget(self.poe_lbl)
        self.vlayout.addWidget(self.poe_cbx)

    def create_loss_type_selector(self):
        self.loss_type_lbl = QLabel('Loss Type')
        self.loss_type_cbx = QComboBox()
        self.loss_type_cbx.setEnabled(False)
        self.loss_type_cbx.currentIndexChanged['QString'].connect(
            self.on_loss_type_changed)
        self.vlayout.addWidget(self.loss_type_lbl)
        self.vlayout.addWidget(self.loss_type_cbx)

    def create_eid_selector(self):
        self.eid_lbl = QLabel('Event ID')
        self.eid_sbx = QSpinBox()
        self.eid_sbx.setEnabled(False)
        self.vlayout.addWidget(self.eid_lbl)
        self.vlayout.addWidget(self.eid_sbx)

    def create_dmg_state_selector(self):
        self.dmg_state_lbl = QLabel('Damage state')
        self.dmg_state_cbx = QComboBox()
        self.dmg_state_cbx.setEnabled(False)
        self.dmg_state_cbx.currentIndexChanged['QString'].connect(
            self.on_dmg_state_changed)
        self.vlayout.addWidget(self.dmg_state_lbl)
        self.vlayout.addWidget(self.dmg_state_cbx)

    def create_taxonomy_selector(self):
        self.taxonomy_lbl = QLabel('Taxonomy')
        self.taxonomy_cbx = QComboBox()
        self.taxonomy_cbx.setEnabled(False)
        self.vlayout.addWidget(self.taxonomy_lbl)
        self.vlayout.addWidget(self.taxonomy_cbx)

    def create_style_by_selector(self):
        self.style_by_lbl = QLabel('Style by')
        self.style_by_cbx = QComboBox()
        self.vlayout.addWidget(self.style_by_lbl)
        self.vlayout.addWidget(self.style_by_cbx)

    def create_load_selected_only_ckb(self):
        self.load_selected_only_ckb = QCheckBox("Load only the selected items")
        self.load_selected_only_ckb.setChecked(True)
        self.vlayout.addWidget(self.load_selected_only_ckb)

    def create_save_as_shp_ckb(self):
        self.save_as_shp_ckb = QCheckBox("Save the loaded layer as shapefile")
        self.save_as_shp_ckb.setChecked(False)
        self.vlayout.addWidget(self.save_as_shp_ckb)

    def create_zonal_layer_selector(self):
        self.zonal_layer_gbx = QGroupBox()
        self.zonal_layer_gbx.setTitle('Aggregate by zone (optional)')
        self.zonal_layer_gbx.setCheckable(True)
        self.zonal_layer_gbx.setChecked(False)
        self.zonal_layer_gbx_v_layout = QVBoxLayout()
        self.zonal_layer_gbx.setLayout(self.zonal_layer_gbx_v_layout)
        self.zonal_layer_cbx = QComboBox()
        self.zonal_layer_cbx.addItem('')
        self.zonal_layer_lbl = QLabel('Zonal layer')
        self.zonal_layer_tbn = QToolButton()
        self.zonal_layer_tbn.setText('...')
        self.zonal_layer_h_layout = QHBoxLayout()
        self.zonal_layer_h_layout.addWidget(self.zonal_layer_cbx)
        self.zonal_layer_h_layout.addWidget(self.zonal_layer_tbn)
        self.zonal_layer_gbx_v_layout.addWidget(self.zonal_layer_lbl)
        self.zonal_layer_gbx_v_layout.addLayout(self.zonal_layer_h_layout)
        self.zone_id_field_lbl = QLabel('Field containing zone ids')
        self.zone_id_field_cbx = QComboBox()
        self.zonal_layer_gbx_v_layout.addWidget(self.zone_id_field_lbl)
        self.zonal_layer_gbx_v_layout.addWidget(self.zone_id_field_cbx)
        self.vlayout.addWidget(self.zonal_layer_gbx)
        self.zonal_layer_tbn.clicked.connect(self.on_zonal_layer_tbn_clicked)
        self.zonal_layer_cbx.currentIndexChanged[int].connect(
            self.on_zonal_layer_cbx_currentIndexChanged)
        self.zonal_layer_gbx.toggled[bool].connect(
            self.on_zonal_layer_gbx_toggled)

    def pre_populate_zonal_layer_cbx(self):
        for key, layer in \
                QgsMapLayerRegistry.instance().mapLayers().iteritems():
            # populate loss cbx only with layers containing points
            if layer.type() != QgsMapLayer.VectorLayer:
                continue
            if layer.geometryType() == QGis.Polygon:
                self.zonal_layer_cbx.addItem(layer.name())
                self.zonal_layer_cbx.setItemData(
                    self.zonal_layer_cbx.count() - 1, layer.id())

    def on_zonal_layer_cbx_currentIndexChanged(self, new_index):
        self.zone_id_field_cbx.clear()
        zonal_layer = None
        if not self.zonal_layer_cbx.currentText():
            if self.zonal_layer_gbx.isChecked():
                self.ok_button.setEnabled(False)
            return
        zonal_layer_id = self.zonal_layer_cbx.itemData(new_index)
        zonal_layer = QgsMapLayerRegistry.instance().mapLayer(zonal_layer_id)
        # if the zonal_layer doesn't have a field containing a unique zone id,
        # the user can choose to add such unique id
        self.zone_id_field_cbx.addItem("Add field with unique zone id")
        for field in zonal_layer.fields():
            # for the zone id accept both numeric or textual fields
            self.zone_id_field_cbx.addItem(field.name())
            # by default, set the selection to the first textual field
        self.set_ok_button()

    def on_zonal_layer_gbx_toggled(self, on):
        if on and not self.zonal_layer_cbx.currentText():
            self.ok_button.setEnabled(False)
        else:
            self.set_ok_button()

    def on_output_type_changed(self):
        if self.output_type in OQ_TO_LAYER_TYPES:
            self.create_load_selected_only_ckb()
        elif self.output_type in OQ_COMPLEX_CSV_TO_LAYER_TYPES:
            self.create_save_as_shp_ckb()
        self.set_ok_button()

    @pyqtSlot()
    def on_file_browser_tbn_clicked(self):
        path = self.open_file_dialog()
        if path:
            self.populate_out_dep_widgets()
        self.set_ok_button()

    def on_rlz_or_stat_changed(self):
        self.dataset = self.npz_file[self.rlz_or_stat_cbx.currentText()]
        self.set_ok_button()

    def on_loss_type_changed(self):
        self.set_ok_button()

    def on_imt_changed(self):
        self.set_ok_button()

    def on_poe_changed(self):
        self.set_ok_button()

    def on_eid_changed(self):
        self.set_ok_button()

    def on_dmg_state_changed(self):
        self.set_ok_button()

    def open_file_dialog(self):
        """
        Open a file dialog to select the data file to be loaded
        """
        text = self.tr('Select the OQ-Engine output file to import')
        if self.output_type in OQ_CSV_TO_LAYER_TYPES:
            filters = self.tr('CSV files (*.csv)')
        else:
            raise NotImplementedError(self.output_type)
        default_dir = QSettings().value('irmt/load_as_layer_dir',
                                        QDir.homePath())
        path = QFileDialog.getOpenFileName(self, text, default_dir, filters)
        if not path:
            return
        selected_dir = QFileInfo(path).dir().path()
        QSettings().setValue('irmt/load_as_layer_dir', selected_dir)
        self.path = path
        self.path_le.setText(self.path)
        return path

    def populate_out_dep_widgets(self):
        self.populate_rlz_or_stat_cbx()
        self.show_num_sites()

    def get_taxonomies(self):
        raise NotImplementedError()

    def populate_rlz_or_stat_cbx(self):
        self.rlzs_or_stats = [
            key for key in sorted(self.npz_file)
            if key not in ('imtls', 'array')
        ]
        self.rlz_or_stat_cbx.clear()
        self.rlz_or_stat_cbx.setEnabled(True)
        self.rlz_or_stat_cbx.addItems(self.rlzs_or_stats)

    def populate_loss_type_cbx(self, loss_types):
        self.loss_type_cbx.clear()
        self.loss_type_cbx.setEnabled(True)
        self.loss_type_cbx.addItems(loss_types)

    def show_num_sites(self):
        # NOTE: we are assuming all realizations have the same number of sites,
        #       which currently is always true.
        #       If different realizations have a different number of sites, we
        #       need to move this block of code inside on_rlz_or_stat_changed()
        rlz_or_stat_data = self.npz_file[self.rlz_or_stat_cbx.currentText()]
        self.num_sites_lbl.setText(self.num_sites_msg % rlz_or_stat_data.shape)

    def set_ok_button(self):
        raise NotImplementedError()

    def build_layer_name(self, *args, **kwargs):
        raise NotImplementedError()

    def get_field_names(self, **kwargs):
        raise NotImplementedError()

    def add_field_to_layer(self, field_name):
        raise NotImplementedError()

    def read_npz_into_layer(self, field_names, **kwargs):
        raise NotImplementedError()

    def load_from_npz(self):
        raise NotImplementedError()

    def get_investigation_time(self):
        if self.output_type in ('hcurves', 'uhs', 'hmaps'):
            try:
                investigation_time = self.npz_file['investigation_time']
            except KeyError:
                msg = ('investigation_time not found. It is mandatory for %s.'
                       ' Please check if the ouptut was produced by an'
                       ' obsolete version of the OpenQuake Engine'
                       ' Server.') % self.output_type
                log_msg(msg, level='C', message_bar=self.iface.messageBar())
            else:
                return investigation_time
        else:
            # some outputs do not need the investigation time
            return None

    def build_layer(self,
                    rlz_or_stat=None,
                    taxonomy=None,
                    poe=None,
                    loss_type=None,
                    dmg_state=None,
                    gsim=None):
        layer_name = self.build_layer_name(rlz_or_stat=rlz_or_stat,
                                           taxonomy=taxonomy,
                                           poe=poe,
                                           loss_type=loss_type,
                                           dmg_state=dmg_state,
                                           gsim=gsim)
        field_names = self.get_field_names(rlz_or_stat=rlz_or_stat,
                                           taxonomy=taxonomy,
                                           poe=poe,
                                           loss_type=loss_type,
                                           dmg_state=dmg_state)

        # create layer
        self.layer = QgsVectorLayer("Point?crs=epsg:4326", layer_name,
                                    "memory")
        for field_name in field_names:
            if field_name in ['lon', 'lat']:
                continue
            added_field_name = self.add_field_to_layer(field_name)
            if field_name != added_field_name:
                if field_name == self.default_field_name:
                    self.default_field_name = added_field_name
                # replace field_name with the actual added_field_name
                field_name_idx = field_names.index(field_name)
                field_names.remove(field_name)
                field_names.insert(field_name_idx, added_field_name)

        self.read_npz_into_layer(field_names,
                                 rlz_or_stat=rlz_or_stat,
                                 taxonomy=taxonomy,
                                 poe=poe,
                                 loss_type=loss_type,
                                 dmg_state=dmg_state)
        self.layer.setCustomProperty('output_type', self.output_type)
        investigation_time = self.get_investigation_time()
        if investigation_time is not None:
            self.layer.setCustomProperty('investigation_time',
                                         investigation_time)
        if self.engine_version is not None:
            self.layer.setCustomProperty('engine_version', self.engine_version)
        irmt_version = get_irmt_version()
        self.layer.setCustomProperty('irmt_version', irmt_version)
        self.layer.setCustomProperty('calc_id', self.calc_id)
        QgsMapLayerRegistry.instance().addMapLayer(self.layer)
        self.iface.setActiveLayer(self.layer)
        self.iface.zoomToActiveLayer()

    def _set_symbol_size(self, symbol):
        if self.iface.mapCanvas().mapUnits() == QGis.Degrees:
            point_size = 0.05
        elif self.iface.mapCanvas().mapUnits() == QGis.Meters:
            point_size = 4000
        else:
            # it is not obvious how to choose the point size in the other
            # cases, so we conservatively keep the default sizing
            return
        symbol.symbolLayer(0).setSizeUnit(symbol.MapUnit)
        symbol.symbolLayer(0).setSize(point_size)
        map_unit_scale = QgsMapUnitScale()
        map_unit_scale.maxSizeMMEnabled = True
        map_unit_scale.minSizeMMEnabled = True
        map_unit_scale.minSizeMM = 0.5
        map_unit_scale.maxSizeMM = 10
        symbol.symbolLayer(0).setSizeMapUnitScale(map_unit_scale)

    def style_maps(self, layer=None, style_by=None):
        if layer is None:
            layer = self.layer
        if style_by is None:
            style_by = self.default_field_name
        symbol = QgsSymbolV2.defaultSymbol(layer.geometryType())
        # see properties at:
        # https://qgis.org/api/qgsmarkersymbollayerv2_8cpp_source.html#l01073
        symbol.setAlpha(1)  # opacity
        if isinstance(symbol, QgsMarkerSymbolV2):
            # do it only for the layer with points
            self._set_symbol_size(symbol)
            symbol.symbolLayer(0).setOutlineStyle(Qt.PenStyle(Qt.NoPen))

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

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

        # in most cases, we override the user-specified setting, and use
        # instead a setting that was required by scientists
        if self.output_type in OQ_TO_LAYER_TYPES:
            default_qgs_style = QgsStyleV2().defaultStyle()
            default_color_ramp_names = default_qgs_style.colorRampNames()
            if self.output_type in ('dmg_by_asset', 'losses_by_asset',
                                    'avg_losses-stats'):
                # options are EqualInterval, Quantile, Jenks, StdDev, Pretty
                # jenks = natural breaks
                mode = QgsGraduatedSymbolRendererV2.Jenks
                ramp_type_idx = default_color_ramp_names.index('Reds')
                inverted = False
            elif self.output_type in ('hmaps', 'gmf_data', 'ruptures'):
                # options are EqualInterval, Quantile, Jenks, StdDev, Pretty
                if self.output_type == 'ruptures':
                    mode = QgsGraduatedSymbolRendererV2.Pretty
                else:
                    mode = QgsGraduatedSymbolRendererV2.EqualInterval
                ramp_type_idx = default_color_ramp_names.index('Spectral')
                inverted = True
            ramp = default_qgs_style.colorRamp(
                default_color_ramp_names[ramp_type_idx])
        graduated_renderer = QgsGraduatedSymbolRendererV2.createRenderer(
            layer,
            style_by,
            style['classes'],
            mode,
            symbol,
            ramp,
            inverted=inverted)
        label_format = graduated_renderer.labelFormat()
        # label_format.setTrimTrailingZeroes(True)  # it might be useful
        label_format.setPrecision(2)
        graduated_renderer.setLabelFormat(label_format, updateRanges=True)
        # add a class for 0 values, unless while styling ruptures
        if self.output_type != 'ruptures':
            VERY_SMALL_VALUE = 1e-20
            graduated_renderer.updateRangeLowerValue(0, VERY_SMALL_VALUE)
            symbol_zeros = QgsSymbolV2.defaultSymbol(layer.geometryType())
            symbol_zeros.setColor(QColor(240, 240, 240))  # very light grey
            if isinstance(symbol, QgsMarkerSymbolV2):
                # do it only for the layer with points
                self._set_symbol_size(symbol_zeros)
                symbol_zeros.symbolLayer(0).setOutlineStyle(
                    Qt.PenStyle(Qt.NoPen))
            zeros_min = 0.0
            zeros_max = VERY_SMALL_VALUE
            range_zeros = QgsRendererRangeV2(
                zeros_min, zeros_max, symbol_zeros,
                " %.2f - %.2f" % (zeros_min, zeros_max), True)
            graduated_renderer.addClassRange(range_zeros)
            graduated_renderer.moveClass(
                len(graduated_renderer.ranges()) - 1, 0)
        layer.setRendererV2(graduated_renderer)
        layer.setLayerTransparency(30)  # percent
        layer.triggerRepaint()
        self.iface.legendInterface().refreshLayerSymbology(layer)
        self.iface.mapCanvas().refresh()

    def style_categorized(self, layer, style_by):
        # get unique values
        fni = layer.fieldNameIndex(style_by)
        unique_values = layer.dataProvider().uniqueValues(fni)
        # define categories
        categories = []
        for unique_value in unique_values:
            # initialize the default symbol for this geometry type
            symbol = QgsSymbolV2.defaultSymbol(layer.geometryType())
            # configure a symbol layer
            layer_style = {}
            layer_style['color'] = '%d, %d, %d' % (randrange(
                0, 256), randrange(0, 256), randrange(0, 256))
            layer_style['outline'] = '#000000'
            symbol_layer = QgsSimpleFillSymbolLayerV2.create(layer_style)
            # replace default symbol layer with the configured one
            if symbol_layer is not None:
                symbol.changeSymbolLayer(0, symbol_layer)
            # create renderer object
            category = QgsRendererCategoryV2(unique_value, symbol,
                                             str(unique_value))
            # entry for the list of category items
            categories.append(category)
        # create renderer object
        renderer = QgsCategorizedSymbolRendererV2(style_by, categories)
        # assign the created renderer to the layer
        if renderer is not None:
            layer.setRendererV2(renderer)
        layer.triggerRepaint()
        self.iface.legendInterface().refreshLayerSymbology(layer)
        self.iface.mapCanvas().refresh()

    def style_curves(self):
        registry = QgsSymbolLayerV2Registry.instance()
        cross = registry.symbolLayerMetadata("SimpleMarker").createSymbolLayer(
            {
                'name': 'cross2',
                'color': '0,0,0',
                'color_border': '0,0,0',
                'offset': '0,0',
                'size': '1.5',
                'angle': '0'
            })
        symbol = QgsSymbolV2.defaultSymbol(self.layer.geometryType())
        symbol.deleteSymbolLayer(0)
        symbol.appendSymbolLayer(cross)
        self._set_symbol_size(symbol)
        renderer = QgsSingleSymbolRendererV2(symbol)
        effect = QgsOuterGlowEffect()
        effect.setSpread(0.5)
        effect.setTransparency(0)
        effect.setColor(QColor(255, 255, 255))
        effect.setBlurLevel(1)
        renderer.paintEffect().appendEffect(effect)
        renderer.paintEffect().setEnabled(True)
        self.layer.setRendererV2(renderer)
        self.layer.setLayerTransparency(30)  # percent
        self.layer.triggerRepaint()
        self.iface.legendInterface().refreshLayerSymbology(self.layer)
        self.iface.mapCanvas().refresh()

    def open_zonal_layer_dialog(self):
        """
        Open a file dialog to select the zonal layer to be loaded
        :returns: the zonal layer
        """
        text = self.tr('Select zonal layer to import')
        filters = self.tr('Vector shapefiles (*.shp);;SQLite (*.sqlite);;'
                          'All files (*.*)')
        default_dir = QSettings().value('irmt/select_layer_dir',
                                        QDir.homePath())
        file_name, file_type = QFileDialog.getOpenFileNameAndFilter(
            self, text, default_dir, filters)
        if not file_name:
            return None
        selected_dir = QFileInfo(file_name).dir().path()
        QSettings().setValue('irmt/select_layer_dir', selected_dir)
        zonal_layer_plus_stats = self.load_zonal_layer(file_name)
        return zonal_layer_plus_stats

    def load_zonal_layer(self, zonal_layer_path, make_a_copy=False):
        # Load zonal layer
        zonal_layer = QgsVectorLayer(zonal_layer_path, tr('Zonal data'), 'ogr')
        if not zonal_layer.geometryType() == QGis.Polygon:
            msg = 'Zonal layer must contain zone polygons'
            log_msg(msg, level='C', message_bar=self.iface.messageBar())
            return False
        if make_a_copy:
            # Make a copy, where stats will be added
            zonal_layer_plus_stats = ProcessLayer(
                zonal_layer).duplicate_in_memory()
        else:
            zonal_layer_plus_stats = zonal_layer
        # Add zonal layer to registry
        if zonal_layer_plus_stats.isValid():
            QgsMapLayerRegistry.instance().addMapLayer(zonal_layer_plus_stats)
        else:
            msg = 'Invalid zonal layer'
            log_msg(msg, level='C', message_bar=self.iface.messageBar())
            return None
        return zonal_layer_plus_stats

    def on_zonal_layer_tbn_clicked(self):
        zonal_layer_plus_stats = self.open_zonal_layer_dialog()
        if (zonal_layer_plus_stats
                and zonal_layer_plus_stats.geometryType() == QGis.Polygon):
            self.populate_zonal_layer_cbx(zonal_layer_plus_stats)

    def populate_zonal_layer_cbx(self, zonal_layer_plus_stats):
        cbx = self.zonal_layer_cbx
        cbx.addItem(zonal_layer_plus_stats.name())
        last_index = cbx.count() - 1
        cbx.setItemData(last_index, zonal_layer_plus_stats.id())
        cbx.setCurrentIndex(last_index)

    def show_file_size(self):
        file_size = get_file_size(self.path)
        self.file_size_lbl.setText(self.file_size_msg % file_size)

    def accept(self):
        if self.output_type in OQ_EXTRACT_TO_LAYER_TYPES:
            self.load_from_npz()
            if self.output_type in ('losses_by_asset', 'dmg_by_asset',
                                    'avg_losses-stats'):
                # check if also aggregating by zone or not
                if (not self.zonal_layer_cbx.currentText()
                        or not self.zonal_layer_gbx.isChecked()):
                    super(LoadOutputAsLayerDialog, self).accept()
                    return
                loss_layer = self.layer
                self.iface.legendInterface().setLayerVisible(loss_layer, False)
                zonal_layer_id = self.zonal_layer_cbx.itemData(
                    self.zonal_layer_cbx.currentIndex())
                zonal_layer = QgsMapLayerRegistry.instance().mapLayer(
                    zonal_layer_id)
                # if the two layers have different projections, display an
                # error message and return
                have_same_projection, check_projection_msg = ProcessLayer(
                    loss_layer).has_same_projection_as(zonal_layer)
                if not have_same_projection:
                    log_msg(check_projection_msg,
                            level='C',
                            message_bar=self.iface.messageBar())
                    # TODO: load only loss layer
                    super(LoadOutputAsLayerDialog, self).accept()
                    return
                loss_attr_names = [
                    field.name() for field in loss_layer.fields()
                ]
                zone_id_in_losses_attr_name = None
                # index 0 is for "Add field with unique zone id"
                if self.zone_id_field_cbx.currentIndex() == 0:
                    zone_id_in_zones_attr_name = None
                else:
                    zone_id_in_zones_attr_name = \
                        self.zone_id_field_cbx.currentText()
                # aggregate losses by zone (calculate count of points in the
                # zone, sum and average loss values for the same zone)
                loss_layer_is_vector = True
                try:
                    res = calculate_zonal_stats(loss_layer,
                                                zonal_layer,
                                                loss_attr_names,
                                                loss_layer_is_vector,
                                                zone_id_in_losses_attr_name,
                                                zone_id_in_zones_attr_name,
                                                self.iface,
                                                extra=False)
                except TypeError as exc:
                    log_msg(str(exc),
                            level='C',
                            message_bar=self.iface.messageBar())
                    return
                (loss_layer, zonal_layer, loss_attrs_dict) = res
                # sanity check
                assert len(loss_attrs_dict) == 1, (
                    "Only one attribute should be added to the zonal layer."
                    " %s were added insted" % len(loss_attrs_dict))
                # NOTE: in scenario damage, keys are like
                #       u'structural_no_damage_mean', and not just
                #       u'structural', therefore we can't just use the selected
                #       loss type, but we must use the actual only key in the
                #       dict
                [added_loss_attr] = loss_attrs_dict
                style_by = loss_attrs_dict[added_loss_attr]['sum']
                self.style_maps(layer=zonal_layer, style_by=style_by)
        elif self.output_type in OQ_CSV_TO_LAYER_TYPES:
            self.load_from_csv()
        super(LoadOutputAsLayerDialog, self).accept()

    def reject(self):
        if (hasattr(self, 'npz_file') and self.npz_file is not None
                and self.output_type in OQ_TO_LAYER_TYPES):
            self.npz_file.close()
        super(LoadOutputAsLayerDialog, self).reject()
Пример #41
0
class TestQgsArrowSymbolLayer(unittest.TestCase):

    def setUp(self):
        self.iface = get_iface()

        lines_shp = os.path.join(TEST_DATA_DIR, 'lines.shp')
        self.lines_layer = QgsVectorLayer(lines_shp, 'Lines', 'ogr')
        QgsMapLayerRegistry.instance().addMapLayer(self.lines_layer)

        # Create style
        sym2 = QgsLineSymbolV2.createSimple({'color': '#fdbf6f'})
        self.lines_layer.setRendererV2(QgsSingleSymbolRendererV2(sym2))

        self.mapsettings = self.iface.mapCanvas().mapSettings()
        self.mapsettings.setOutputSize(QSize(400, 400))
        self.mapsettings.setOutputDpi(96)
        self.mapsettings.setExtent(QgsRectangle(-113, 28, -91, 40))
        self.mapsettings.setBackgroundColor(QColor("white"))

    def tearDown(self):
        QgsMapLayerRegistry.instance().removeAllMapLayers()

    def test_1(self):
        sym = self.lines_layer.rendererV2().symbol()
        sym_layer = QgsArrowSymbolLayer.create({'head_length': '6.5', 'head_thickness': '6.5'})
        dd = QgsDataDefined("(@geometry_point_num % 4) * 2")
        sym_layer.setDataDefinedProperty("arrow_width", dd)
        dd2 = QgsDataDefined("(@geometry_point_num % 4) * 2")
        sym_layer.setDataDefinedProperty("head_length", dd2)
        dd3 = QgsDataDefined("(@geometry_point_num % 4) * 2")
        sym_layer.setDataDefinedProperty("head_thickness", dd3)
        fill_sym = QgsFillSymbolV2.createSimple({'color': '#8bcfff', 'outline_color': '#000000', 'outline_style': 'solid', 'outline_width': '1'})
        sym_layer.setSubSymbol(fill_sym)
        sym.changeSymbolLayer(0, sym_layer)

        rendered_layers = [self.lines_layer.id()]
        self.mapsettings.setLayers(rendered_layers)

        renderchecker = QgsMultiRenderChecker()
        renderchecker.setMapSettings(self.mapsettings)
        renderchecker.setControlName('expected_arrowsymbollayer_1')
        self.assertTrue(renderchecker.runTest('arrowsymbollayer_1'))

    def test_2(self):
        sym = self.lines_layer.rendererV2().symbol()
        # double headed
        sym_layer = QgsArrowSymbolLayer.create({'arrow_width': '5', 'head_length': '4', 'head_thickness': '6', 'head_type': '2'})
        fill_sym = QgsFillSymbolV2.createSimple({'color': '#8bcfff', 'outline_color': '#000000', 'outline_style': 'solid', 'outline_width': '1'})
        sym_layer.setSubSymbol(fill_sym)
        sym.changeSymbolLayer(0, sym_layer)

        rendered_layers = [self.lines_layer.id()]
        self.mapsettings.setLayers(rendered_layers)

        renderchecker = QgsMultiRenderChecker()
        renderchecker.setMapSettings(self.mapsettings)
        renderchecker.setControlName('expected_arrowsymbollayer_2')
        self.assertTrue(renderchecker.runTest('arrowsymbollayer_2'))

    def test_3(self):
        sym = self.lines_layer.rendererV2().symbol()
        # double headed
        sym_layer = QgsArrowSymbolLayer.create({'arrow_width': '7', 'head_length': '6', 'head_thickness': '8', 'head_type': '0', 'arrow_type': '1', 'is_curved': '0'})
        fill_sym = QgsFillSymbolV2.createSimple({'color': '#8bcfff', 'outline_color': '#000000', 'outline_style': 'solid', 'outline_width': '1'})
        sym_layer.setSubSymbol(fill_sym)
        sym.changeSymbolLayer(0, sym_layer)

        rendered_layers = [self.lines_layer.id()]
        self.mapsettings.setLayers(rendered_layers)

        renderchecker = QgsMultiRenderChecker()
        ms = self.mapsettings
        ms.setExtent(QgsRectangle(-101, 35, -99, 37))
        renderchecker.setMapSettings(ms)
        renderchecker.setControlName('expected_arrowsymbollayer_3')
        self.assertTrue(renderchecker.runTest('arrowsymbollayer_3'))

    def test_unrepeated(self):
        sym = self.lines_layer.rendererV2().symbol()
        # double headed
        sym_layer = QgsArrowSymbolLayer.create({'arrow_width': '7', 'head_length': '6', 'head_thickness': '8', 'head_type': '0', 'arrow_type': '0'})
        # no repetition
        sym_layer.setIsRepeated(False)
        fill_sym = QgsFillSymbolV2.createSimple({'color': '#8bcfff', 'outline_color': '#000000', 'outline_style': 'solid', 'outline_width': '1'})
        sym_layer.setSubSymbol(fill_sym)
        sym.changeSymbolLayer(0, sym_layer)

        rendered_layers = [self.lines_layer.id()]
        self.mapsettings.setLayers(rendered_layers)

        renderchecker = QgsMultiRenderChecker()
        ms = self.mapsettings
        ms.setExtent(QgsRectangle(-119, 17, -82, 50))
        renderchecker.setMapSettings(ms)
        renderchecker.setControlName('expected_arrowsymbollayer_4')
        self.assertTrue(renderchecker.runTest('arrowsymbollayer_4'))

    def testColors(self):
        """
        Test colors, need to make sure colors are passed/retrieved from subsymbol
        """
        sym_layer = QgsArrowSymbolLayer.create()
        sym_layer.setColor(QColor(150, 50, 100))
        self.assertEqual(sym_layer.color(), QColor(150, 50, 100))
        self.assertEqual(sym_layer.subSymbol().color(), QColor(150, 50, 100))
        sym_layer.subSymbol().setColor(QColor(250, 150, 200))
        self.assertEqual(sym_layer.subSymbol().color(), QColor(250, 150, 200))
        self.assertEqual(sym_layer.color(), QColor(250, 150, 200))
Пример #42
0
    def run_tsp(self):
        """
        Main method, preparing the query and displaying the result on
        the canvas.
        """
        layer = self.comboBox_layer.currentLayer()
        coords, _ = get_coords_ids(
            layer, '', on_selected=self.checkBox_selec_features.isChecked())

        if len(coords) < 2:
            return -1

        try:
            self.host = check_host(self.lineEdit_host.text())
            profile = check_profile_name(self.lineEdit_profileName.text())
        except (ValueError, AssertionError) as err:
            print(err)
            self.iface.messageBar().pushMessage(
                "Error",
                "Please provide a valid non-empty URL and profile name",
                duration=10)
            return

        query = ''.join([
            "http://", self.host, "/trip/", profile, "/",
            ";".join(["{},{}".format(c[0], c[1]) for c in coords])
        ])

        try:
            self.parsed = self.query_url(query)
        except Exception as err:
            self.iface.messageBar().pushMessage(
                "Error", "An error occured when trying to contact the OSRM "
                "instance (see QGis log for error traceback)",
                duration=10)
            QgsMessageLog.logMessage(
                'OSRM-plugin error report :\n {}'.format(err),
                level=QgsMessageLog.WARNING)
            return

        try:
            line_geoms = \
                [decode_geom(self.parsed['trips'][i]['geometry'])
                 for i in range(len(self.parsed['trips']))]
        except KeyError:
            self.iface.messageBar().pushMessage("Error", "?...", duration=5)
            return

        tsp_route_layer = QgsVectorLayer(
            "Linestring?crs=epsg:4326&field=id:integer"
            "&field=total_time:integer(20)&field=distance:integer(20)",
            "tsp_solution_osrm{}".format(self.nb_route), "memory")
        my_symb = prepare_route_symbol(self.nb_route)
        tsp_route_layer.setRendererV2(QgsSingleSymbolRendererV2(my_symb))
        features = []
        for idx, feature in enumerate(self.parsed['trips']):
            ft = QgsFeature()
            ft.setGeometry(line_geoms[idx])
            ft.setAttributes([idx, feature['distance'], feature['duration']])
            features.append(ft)
            self.prepare_ordered_marker(coords, idx)
        tsp_route_layer.dataProvider().addFeatures(features)
        tsp_route_layer.updateExtents()
        QgsMapLayerRegistry.instance().addMapLayer(tsp_route_layer)
        self.iface.setActiveLayer(tsp_route_layer)
        self.iface.zoomToActiveLayer()
        put_on_top(self.tsp_marker_lr.id(), tsp_route_layer.id())
        self.nb_route += 1
Пример #43
0
    def download_data(self):

        # Get user selection
        group_code = self.cbGroups.itemData(self.cbGroups.currentIndex())
        domain_code = self.cbDomains.itemData(self.cbDomains.currentIndex())
        element_code = self.cbElements.itemData(self.cbElements.currentIndex())
        item_code = self.cbItems.itemData(self.cbItems.currentIndex())
        download_folder = self.download_folder.text()

        # Check selection
        if group_code is None:
            self.bar.pushMessage(None,
                                 self.tr('Please select a group'),
                                 level=QgsMessageBar.CRITICAL)
        elif domain_code is None:
            self.bar.pushMessage(None,
                                 self.tr('Please select a domain'),
                                 level=QgsMessageBar.CRITICAL)
        elif element_code is None:
            self.bar.pushMessage(None,
                                 self.tr('Please select an element'),
                                 level=QgsMessageBar.CRITICAL)
        elif item_code is None:
            self.bar.pushMessage(None,
                                 self.tr('Please select an item'),
                                 level=QgsMessageBar.CRITICAL)
        elif download_folder is None or len(download_folder) == 0:
            self.bar.pushMessage(None,
                                 self.tr('Please select a download folder'),
                                 level=QgsMessageBar.CRITICAL)
        else:
            # Get data
            data = get_data(domain_code, element_code, item_code)
            # Notify the user
            self.bar.pushMessage(None,
                                 self.tr('Downloaded rows: ') + str(len(data)),
                                 level=QgsMessageBar.INFO)
            # Layer name
            layer_name = self.cbItems.currentText().replace(
                ' ', '_') + '_' + self.cbElements.currentText().replace(
                    ' ', '_')
            folder_name = os.path.join(download_folder, group_code,
                                       domain_code)
            if not os.path.exists(folder_name):
                os.makedirs(folder_name)
            # Copy template layer
            output_file = copy_layer(folder_name, layer_name)
            layer = QgsVectorLayer(output_file, 'layer_name', 'ogr')
            # Add all the years to the layer
            feature_idx = 64
            year_to_be_shown = 2014
            number_of_nulls = 0
            for year in range(2014, 1960, -1):
                progress = (1 + (feature_idx - 64)) * 1.86
                self.progress.setValue(progress)
                self.progress_label.setText('<b>' + self.tr('Progress') +
                                            ': ' + '</b> ' +
                                            self.tr('Adding Year ') +
                                            str(year))
                year_data = self.get_year_data(data, year)
                layer.dataProvider().addAttributes(
                    [QgsField(str(year), QVariant.Double)])
                if len(year_data) > 0:
                    layer.startEditing()
                    for feature in layer.getFeatures():
                        if feature['FAOSTAT'] is not None:
                            feature_code = str(feature['FAOSTAT'])
                            for d in year_data:
                                data_code = str(d['code'])
                                if data_code == feature_code:
                                    value = d['value']
                                    layer.changeAttributeValue(
                                        feature.id(), (feature_idx),
                                        float(value))
                                    tmp_feature = QgsFeature()
                                    tmp_feature.setAttributes([float(value)])
                                    layer.dataProvider().addFeatures(
                                        [tmp_feature])
                                    if value is None:
                                        number_of_nulls += 1
                    layer.commitChanges()
                else:
                    year_to_be_shown -= 1
                feature_idx += 1
            # Add layer to canvas
            if self.add_to_canvas.isChecked():
                renderer = self.create_join_renderer(
                    layer, str(year_to_be_shown), 11,
                    QgsGraduatedSymbolRendererV2.Pretty)
                l = QgsVectorLayer(
                    output_file,
                    layer_name + '(' + str(year_to_be_shown) + ')', 'ogr')
                r = renderer.clone()
                r.setClassAttribute(str(year_to_be_shown))
                l.setRendererV2(r)
                QgsMapLayerRegistry.instance().addMapLayer(l)
                self.iface.legendInterface().setLayerVisible(l, True)
            # Close pop-up
            self.dlg.close()
Пример #44
0
    def get_access_isochrones(self):
        """
        Making the accessibility isochrones in few steps:
        - make a grid of points aroung the origin point,
        - snap each point (using OSRM locate function) on the road network,
        - get the time-distance between the origin point and each of these pts
            (using OSRM table function),
        - make an interpolation grid to extract polygons corresponding to the
            desired time intervals (using matplotlib library),
        - render the polygon.
        """
        try:
            self.host = check_host(self.lineEdit_host.text())
            self.profile = check_profile_name(self.lineEdit_profileName.text())
        except (ValueError, AssertionError) as err:
            self.iface.messageBar().pushMessage(
                "Error", "Please provide a valid non-empty URL", duration=10)
            return

        if 'clicking' in self.comboBox_method.currentText():
            pts = self.get_points_from_canvas()
        elif 'selecting' in self.comboBox_method.currentText():
            layer = self.comboBox_pointlayer.currentLayer()
            pts, ptids = get_coords_ids(
                layer, 'ID', on_selected=self.checkBox_selectedFt.isChecked(
                ))  #HGP: Using fix ID-column here!
            pts = tuple(pts)

        if not pts:
            return

        max_time = self.spinBox_max.value()
        interval_time = self.spinBox_intervall.value()
        nb_inter = int(round(max_time / interval_time)) + 1
        levels = tuple([
            nb
            for nb in xrange(0,
                             int(max_time + 1) + interval_time, interval_time)
        ][:nb_inter])

        self.make_prog_bar()
        self.max_points = 5000  # 1500 if len(pts) == 1 else 500
        self.polygons = []

        pts = [{
            "point": pt,
            "max": max_time,
            "levels": levels,
            "host": self.host,
            "profile": self.profile,
            "max_points": self.max_points
        } for pt in pts]

        pool = ThreadPool(processes=4 if len(pts) >= 4 else len(pts))

        try:
            self.polygons = [i for i in pool.map(prep_access, pts)]
        except Exception as err:
            self.display_error(err, 1)
            return

        if len(self.polygons) == 1:
            self.polygons = self.polygons[0]
        else:
            self.polygons = np.array(
                self.polygons).transpose().tolist()  #HGP: ravel
            self.polygons = \
                [QgsGeometry.unaryUnion(polys) for polys in self.polygons]

        isochrone_layer = QgsVectorLayer(
            "MultiPolygon?crs=epsg:4326&field=id:integer"
            "&field=min:integer(10)"
            "&field=max:integer(10)"
            "&field=origid:integer(10)",
            "isochrone_osrm_{}".format(self.nb_isocr), "memory")
        data_provider = isochrone_layer.dataProvider()
        # Add the features to the layer to display :
        features = []
        levels = levels[1:]
        self.progress.setValue(8.5)
        for i, poly in enumerate(self.polygons):
            if not poly:
                continue
            ft = QgsFeature()
            ft.setGeometry(poly)
            ft.setAttributes(
                [i, levels[i] - interval_time, levels[i], ptids[i % len(pts)]])
            features.append(ft)
        data_provider.addFeatures(features[::-1])
        self.nb_isocr += 1
        self.progress.setValue(9.5)

        # Render the value :
        renderer = self.prepare_renderer(levels, interval_time,
                                         len(self.polygons))
        isochrone_layer.setRendererV2(renderer)
        isochrone_layer.setLayerTransparency(25)
        self.iface.messageBar().clearWidgets()
        QgsMapLayerRegistry.instance().addMapLayer(isochrone_layer)

        self.add_final_pts(pts)
        self.iface.setActiveLayer(isochrone_layer)
    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 = QgsCategorizedSymbolRendererV2("attr", [
            QgsRendererCategoryV2(
                1, QgsMarkerSymbolV2.createSimple({"color": "255,0,0"}),
                "red"),
            QgsRendererCategoryV2(
                2, QgsMarkerSymbolV2.createSimple({"color": "0,0,255"}),
                "blue")
        ])
        ptLayer.setRendererV2(r)

        QgsMapLayerRegistry.instance().addMapLayer(ptLayer)

        # add the point layer to the map settings
        layers = self.mapSettings.layers()
        layers = [ptLayer.id()] + layers
        self.mapSettings.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.mapSettings.setLayers([layers[1]])
        self.mComposition.removeComposerItem(legend)
        QgsMapLayerRegistry.instance().removeMapLayer(ptLayer.id())
Пример #46
0
    def extract_layers(self, tree):
        """Return a list of RFU layers."""

        # Create vector layers..
        l_vertex = QgsVectorLayer(r"Point?crs=epsg:4326&index=yes",
                                  u"Sommet RFU", r"memory")
        l_edge = QgsVectorLayer(r"LineString?crs=epsg:4326&index=yes",
                                u"Limite RFU", r"memory")

        p_vertex = l_vertex.dataProvider()
        p_edge = l_edge.dataProvider()

        # Define default style renderer..

        renderer_vertex = QgsRuleBasedRendererV2(QgsMarkerSymbolV2())
        vertex_root_rule = renderer_vertex.rootRule()
        vertex_rules = (
            (
                 (u"Borne, borne à puce, pierre, piquet, clou ou broche"),
                 (u"$id >= 0 AND \"som_nature\" IN ('Borne',"
                  u"'Borne à puce', 'Pierre', 'Piquet', 'Clou ou broche')"),
                 r"#EC0000", 2.2
            ), (
                 (u"Axe cours d'eau, axe fossé, haut de talus, pied de talus"),
                 (u"$id >= 0 AND \"som_nature\" IN ('Axe cours d\'\'eau',"
                  u"'Axe fossé', 'Haut de talus', 'Pied de talus')"),
                 r"#EE8012", 2.2
            ), (
                 (u"Angle de bâtiment, axe de mur, angle de mur, "
                  u"angle de clôture, pylône et toute autre valeur"),
                 (u"$id >= 0 AND \"som_nature\" NOT IN ('Borne',"
                  u"'Borne à puce', 'Pierre', 'Piquet', 'Clou ou broche',"
                  u"'Axe cours d\'\'eau', 'Axe fossé', 'Haut de talus',"
                  u"'Pied de talus')"),
                 r"#9784EC", 2.2
            ), (
                u"Temporaire", r"$id < 0", "cyan", 2.4
            ))

        for label, expression, color, size in vertex_rules:
            rule = vertex_root_rule.children()[0].clone()
            rule.setLabel(label)
            rule.setFilterExpression(expression)
            rule.symbol().setColor(QColor(color))
            rule.symbol().setSize(size)
            vertex_root_rule.appendChild(rule)

        vertex_root_rule.removeChildAt(0)
        l_vertex.setRendererV2(renderer_vertex)

        renderer_edge = QgsRuleBasedRendererV2(QgsLineSymbolV2())
        edge_root_rule = renderer_edge.rootRule()
        edge_rules = ((r"Limite", r"$id >= 0", "#0A0AFF", 0.5),
                      (r"Temporaire", r"$id < 0", "cyan", 1))

        for label, expression, color, width in edge_rules:
            rule = edge_root_rule.children()[0].clone()
            rule.setLabel(label)
            rule.setFilterExpression(expression)
            rule.symbol().setColor(QColor(color))
            rule.symbol().setWidth(width)
            edge_root_rule.appendChild(rule)

        edge_root_rule.removeChildAt(0)
        l_edge.setRendererV2(renderer_edge)

        # Add fields..
        p_vertex.addAttributes([
                    QgsField(r"@id_noeud", QVariant.Int),
                    # QgsField(r"@changeset", QVariant.Int),
                    # QgsField(r"@timestamp", QVariant.Date),
                    QgsField(r"@version", QVariant.Int),
                    QgsField(r"som_ge_createur", QVariant.String),
                    QgsField(r"som_nature", QVariant.String),
                    QgsField(r"som_precision_rattachement", QVariant.Int),
                    QgsField(r"som_coord_est", QVariant.Double),
                    QgsField(r"som_coord_nord", QVariant.Double),
                    QgsField(r"som_representation_plane", QVariant.String),
                    # QgsField(r"date_creation", QVariant.Date)
                    ])

        p_edge.addAttributes([
                    QgsField(r"@id_arc", QVariant.Int),
                    # QgsField(r"@id_noeud_debut", QVariant.Int),
                    # QgsField(r"@id_noeud_fin", QVariant.Int),
                    # QgsField(r"@changeset", QVariant.Int),
                    # QgsField(r"@timestamp", QVariant.Date),
                    QgsField(r"@version", QVariant.Int),
                    QgsField(r"lim_ge_createur", QVariant.String),
                    # QgsField(r"lim_date_creation", QVariant.Date)
                    ])

        # Add features from xml tree..
        # ..to vertex layer..
        fts_vertex = []
        for e in tree.findall(r"sommet"):

            ft_vertex = QgsFeature()
            ft_vertex.setGeometry(QgsGeometry.fromWkt(e.attrib[r"geometrie"]))

            _id_noeud = int(e.attrib[r"id_noeud"])
            # _changeset = int(e.attrib[r"changeset"])
            # _timestamp = QDateTime(datetime.strptime(
            #                 e.attrib[r"timestamp"], r"%Y-%m-%d %H:%M:%S.%f"))
            _version = int(e.attrib[r"version"])
            som_ge_createur = unicode(e.find(r"./som_ge_createur").text)
            som_nature = unicode(e.find(r"./som_nature").text)
            som_prec_rattcht = int(e.find(r"./som_precision_rattachement").text)
            som_coord_est = float(e.find(r"./som_coord_est").text)
            som_coord_nord = float(e.find(r"./som_coord_nord").text)
            som_repres_plane = unicode(e.find(r"./som_representation_plane").text)
            # som_date_creation = QDate(datetime.strptime(
            #                         e.find(r"./som_date_creation").text, r"%Y-%m-%d").date())

            ft_vertex.setAttributes([
                        _id_noeud,
                        # _changeset,
                        # _timestamp,
                        _version,
                        som_ge_createur,
                        som_nature,
                        som_prec_rattcht,
                        som_coord_est,
                        som_coord_nord,
                        som_repres_plane,
                        # som_date_creation
                        ])

            fts_vertex.append(ft_vertex)

        # ..to edge layer..
        fts_edge = []
        for e in tree.findall(r"limite"):

            ft_edge = QgsFeature()
            ft_edge.setGeometry(QgsGeometry.fromWkt(e.attrib[r"geometrie"]))

            _id_arc = int(e.attrib[r"id_arc"])
            # _id_noeud_debut = int(e.attrib[r"id_noeud_debut"])
            # _id_noeud_fin = int(e.attrib[r"id_noeud_fin"])
            # _changeset = int(e.attrib[r"changeset"])
            # _timestamp = QDateTime(datetime.strptime(
            #                 e.attrib[r"timestamp"], r"%Y-%m-%d %H:%M:%S.%f"))
            _version = int(e.attrib[r"version"])
            lim_ge_createur = unicode(e.find(r"./lim_ge_createur").text)
            # lim_date_creation = QDate(datetime.strptime(
            #                        e.find(r"./lim_date_creation").text, r"%Y-%m-%d").date())

            ft_edge.setAttributes([
                        _id_arc,
                        # _id_noeud_debut,
                        # _id_noeud_fin,
                        # _changeset,
                        # _timestamp,
                        _version,
                        lim_ge_createur,
                        # lim_date_creation
                        ])

            fts_edge.append(ft_edge)

        # Add features to layers..
        p_vertex.addFeatures(fts_vertex)
        p_edge.addFeatures(fts_edge)

        # Update fields..
        l_vertex.updateFields()
        l_edge.updateFields()

        # Update layer's extent..
        l_vertex.updateExtents()
        l_edge.updateExtents()

        # Check if valid..
        if not l_vertex.isValid() or not l_edge.isValid():
            raise Exception(u"Une erreur est survenue lors du chargement de la couche.")

        # Set labelling...
        palyr = QgsPalLayerSettings()
        palyr.enabled = True
        # palyr.readFromLayer(l_vertex)
        palyr.fieldName = r"$id"  # Expression $id
        palyr.placement = 1  # ::OverPoint
        palyr.quadOffset = 2  # ::QuadrantAboveRight
        palyr.setDataDefinedProperty(80, True, True, r"1", "")  # ::OffsetUnits -> ::MM
        palyr.xOffset = 2.0
        palyr.yOffset = -1.0
        palyr.writeToLayer(l_vertex)

        # Then return layers..
        return [l_vertex, l_edge]
    def compute_and_display_cadastral_vulnerability(self, cadastral_layer,
                                                    output_grid_points,
                                                    output_cadastral_points,
                                                    crop_index, crop_name,
                                                    base_path):
        cadastral_points_per_plot = {}
        for p in (output_grid_points + output_cadastral_points):
            if p.cadastral_polygon is None: continue
            if p.lulc_type not in ['agriculture', 'fallow land']: continue
            if p.cadastral_polygon.id() in cadastral_points_per_plot:
                cadastral_points_per_plot[p.cadastral_polygon.id()].append(
                    p.budget.PET_minus_AET_crop_end[crop_index])
            else:
                cadastral_points_per_plot[p.cadastral_polygon.id()] = [
                    p.budget.PET_minus_AET_crop_end[crop_index]
                ]
        for k, v in cadastral_points_per_plot.items():
            if len(v) > 0:
                cadastral_points_per_plot[k] = sum(v) / len(v)
            else:
                del cadastral_points_per_plot[k]

        # print cadastral_points_per_plot
        #	Create duplicate cadastral layer in memory
        memory_cadastral_layer = QgsVectorLayer(
            'Polygon?crs=epsg:32643',
            crop_name + ' Cadastral Level Vulnerability', 'memory')
        memory_cadastral_layer.startEditing()
        memory_cadastral_layer.dataProvider().addAttributes(
            cadastral_layer.qgsLayer.dataProvider().fields().toList())
        memory_cadastral_layer.updateFields()
        dict_new_feature_id_to_old_feature_id = {}
        for old_plot_id in cadastral_points_per_plot:
            result, output_features = memory_cadastral_layer.dataProvider(
            ).addFeatures([cadastral_layer.feature_dict[old_plot_id]])
            dict_new_feature_id_to_old_feature_id[
                output_features[0].id()] = old_plot_id
        memory_cadastral_layer.dataProvider().addAttributes(
            [QgsField('Deficit', QVariant.Double)])
        memory_cadastral_layer.updateFields()
        for new_feature in memory_cadastral_layer.getFeatures():
            new_feature['Deficit'] = cadastral_points_per_plot[
                dict_new_feature_id_to_old_feature_id[new_feature.id()]]
            memory_cadastral_layer.updateFeature(new_feature)
        memory_cadastral_layer.commitChanges()

        #	Graduated Rendering
        graduated_symbol_renderer_range_list = []
        ET_D_max = max(cadastral_points_per_plot.values())
        opacity = 1
        geometry_type = memory_cadastral_layer.geometryType()
        intervals_count = CADASTRAL_VULNERABILITY_DISPLAY_COLOUR_INTERVALS_COUNT
        dict_interval_colour = CADASTRAL_VULNERABILITY_DISPLAY_COLOURS_DICT
        for i in range(intervals_count):
            interval_min = 0 if i == 0 else (ET_D_max * float(i) /
                                             intervals_count) + 0.01
            interval_max = ET_D_max * float(i + 1) / intervals_count
            label = "{0:.2f} - {1:.2f}".format(interval_min, interval_max)
            colour = QColor(*dict_interval_colour[i])
            symbol = QgsSymbolV2.defaultSymbol(geometry_type)
            symbol.setColor(colour)
            symbol.setAlpha(opacity)
            interval_range = QgsRendererRangeV2(interval_min, interval_max,
                                                symbol, label)
            graduated_symbol_renderer_range_list.append(interval_range)
        renderer = QgsGraduatedSymbolRendererV2(
            '', graduated_symbol_renderer_range_list)
        renderer.setMode(QgsGraduatedSymbolRendererV2.EqualInterval)
        renderer.setClassAttribute('Deficit')
        memory_cadastral_layer.setRendererV2(renderer)

        QgsMapLayerRegistry.instance().addMapLayer(memory_cadastral_layer)
        memory_cadastral_layer.setCustomProperty('labeling', 'pal')
        memory_cadastral_layer.setCustomProperty('labeling/enabled', 'true')
        memory_cadastral_layer.setCustomProperty('labeling/fieldName',
                                                 'Number')
        memory_cadastral_layer.setCustomProperty('labeling/fontSize', '10')
        memory_cadastral_layer.setCustomProperty('labeling/placement', '0')

        memory_cadastral_layer.dataProvider().forceReload()
        memory_cadastral_layer.triggerRepaint()

        QgsVectorFileWriter.writeAsVectorFormat(
            memory_cadastral_layer, base_path + '/kharif_' + crop_name +
            '_cadastral_level_vulnerability.shp', "utf-8", None,
            "ESRI Shapefile")
Пример #48
0
    def extract_layers(self, tree):
        """Return a list of RFU layers."""

        # Create vector layers..
        l_vertex = QgsVectorLayer(r"Point?crs=epsg:4326&index=yes",
                                  u"Sommet RFU", r"memory")
        l_edge = QgsVectorLayer(r"LineString?crs=epsg:4326&index=yes",
                                u"Limite RFU", r"memory")

        p_vertex = l_vertex.dataProvider()
        p_edge = l_edge.dataProvider()

        # Define default style renderer..

        renderer_vertex = QgsRuleBasedRendererV2(QgsMarkerSymbolV2())
        vertex_root_rule = renderer_vertex.rootRule()
        vertex_rules = (
            ((u"Borne, borne à puce, pierre, piquet, clou ou broche"),
             (u"$id >= 0 AND \"som_nature\" IN ('Borne',"
              u"'Borne à puce', 'Pierre', 'Piquet', 'Clou ou broche')"),
             r"#EC0000", 2.2),
            ((u"Axe cours d'eau, axe fossé, haut de talus, pied de talus"),
             (u"$id >= 0 AND \"som_nature\" IN ('Axe cours d\'\'eau',"
              u"'Axe fossé', 'Haut de talus', 'Pied de talus')"), r"#EE8012",
             2.2), ((u"Angle de bâtiment, axe de mur, angle de mur, "
                     u"angle de clôture, pylône et toute autre valeur"),
                    (u"$id >= 0 AND \"som_nature\" NOT IN ('Borne',"
                     u"'Borne à puce', 'Pierre', 'Piquet', 'Clou ou broche',"
                     u"'Axe cours d\'\'eau', 'Axe fossé', 'Haut de talus',"
                     u"'Pied de talus')"), r"#9784EC",
                    2.2), (u"Temporaire", r"$id < 0", "cyan", 2.4))

        for label, expression, color, size in vertex_rules:
            rule = vertex_root_rule.children()[0].clone()
            rule.setLabel(label)
            rule.setFilterExpression(expression)
            rule.symbol().setColor(QColor(color))
            rule.symbol().setSize(size)
            vertex_root_rule.appendChild(rule)

        vertex_root_rule.removeChildAt(0)
        l_vertex.setRendererV2(renderer_vertex)

        renderer_edge = QgsRuleBasedRendererV2(QgsLineSymbolV2())
        edge_root_rule = renderer_edge.rootRule()
        edge_rules = ((r"Limite", r"$id >= 0", "#0A0AFF", 0.5),
                      (r"Temporaire", r"$id < 0", "cyan", 1))

        for label, expression, color, width in edge_rules:
            rule = edge_root_rule.children()[0].clone()
            rule.setLabel(label)
            rule.setFilterExpression(expression)
            rule.symbol().setColor(QColor(color))
            rule.symbol().setWidth(width)
            edge_root_rule.appendChild(rule)

        edge_root_rule.removeChildAt(0)
        l_edge.setRendererV2(renderer_edge)

        # Add fields..
        p_vertex.addAttributes([
            QgsField(r"@id_noeud", QVariant.Int),
            # QgsField(r"@changeset", QVariant.Int),
            # QgsField(r"@timestamp", QVariant.Date),
            QgsField(r"@version", QVariant.Int),
            QgsField(r"som_ge_createur", QVariant.String),
            QgsField(r"som_nature", QVariant.String),
            QgsField(r"som_precision_rattachement", QVariant.Int),
            QgsField(r"som_coord_est", QVariant.Double),
            QgsField(r"som_coord_nord", QVariant.Double),
            QgsField(r"som_representation_plane", QVariant.String),
            # QgsField(r"date_creation", QVariant.Date)
        ])

        p_edge.addAttributes([
            QgsField(r"@id_arc", QVariant.Int),
            # QgsField(r"@id_noeud_debut", QVariant.Int),
            # QgsField(r"@id_noeud_fin", QVariant.Int),
            # QgsField(r"@changeset", QVariant.Int),
            # QgsField(r"@timestamp", QVariant.Date),
            QgsField(r"@version", QVariant.Int),
            QgsField(r"lim_ge_createur", QVariant.String),
            # QgsField(r"lim_date_creation", QVariant.Date)
        ])

        # Add features from xml tree..
        # ..to vertex layer..
        fts_vertex = []
        for e in tree.findall(r"sommet"):

            ft_vertex = QgsFeature()
            ft_vertex.setGeometry(QgsGeometry.fromWkt(e.attrib[r"geometrie"]))

            _id_noeud = int(e.attrib[r"id_noeud"])
            # _changeset = int(e.attrib[r"changeset"])
            # _timestamp = QDateTime(datetime.strptime(
            #                 e.attrib[r"timestamp"], r"%Y-%m-%d %H:%M:%S.%f"))
            _version = int(e.attrib[r"version"])
            som_ge_createur = unicode(e.find(r"./som_ge_createur").text)
            som_nature = unicode(e.find(r"./som_nature").text)
            som_prec_rattcht = int(
                e.find(r"./som_precision_rattachement").text)
            som_coord_est = float(e.find(r"./som_coord_est").text)
            som_coord_nord = float(e.find(r"./som_coord_nord").text)
            som_repres_plane = unicode(
                e.find(r"./som_representation_plane").text)
            # som_date_creation = QDate(datetime.strptime(
            #                         e.find(r"./som_date_creation").text, r"%Y-%m-%d").date())

            ft_vertex.setAttributes([
                _id_noeud,
                # _changeset,
                # _timestamp,
                _version,
                som_ge_createur,
                som_nature,
                som_prec_rattcht,
                som_coord_est,
                som_coord_nord,
                som_repres_plane,
                # som_date_creation
            ])

            fts_vertex.append(ft_vertex)

        # ..to edge layer..
        fts_edge = []
        for e in tree.findall(r"limite"):

            ft_edge = QgsFeature()
            ft_edge.setGeometry(QgsGeometry.fromWkt(e.attrib[r"geometrie"]))

            _id_arc = int(e.attrib[r"id_arc"])
            # _id_noeud_debut = int(e.attrib[r"id_noeud_debut"])
            # _id_noeud_fin = int(e.attrib[r"id_noeud_fin"])
            # _changeset = int(e.attrib[r"changeset"])
            # _timestamp = QDateTime(datetime.strptime(
            #                 e.attrib[r"timestamp"], r"%Y-%m-%d %H:%M:%S.%f"))
            _version = int(e.attrib[r"version"])
            lim_ge_createur = unicode(e.find(r"./lim_ge_createur").text)
            # lim_date_creation = QDate(datetime.strptime(
            #                        e.find(r"./lim_date_creation").text, r"%Y-%m-%d").date())

            ft_edge.setAttributes([
                _id_arc,
                # _id_noeud_debut,
                # _id_noeud_fin,
                # _changeset,
                # _timestamp,
                _version,
                lim_ge_createur,
                # lim_date_creation
            ])

            fts_edge.append(ft_edge)

        # Add features to layers..
        p_vertex.addFeatures(fts_vertex)
        p_edge.addFeatures(fts_edge)

        # Update fields..
        l_vertex.updateFields()
        l_edge.updateFields()

        # Update layer's extent..
        l_vertex.updateExtents()
        l_edge.updateExtents()

        # Check if valid..
        if not l_vertex.isValid() or not l_edge.isValid():
            raise Exception(
                u"Une erreur est survenue lors du chargement de la couche.")

        # Set labelling...
        palyr = QgsPalLayerSettings()
        palyr.enabled = True
        # palyr.readFromLayer(l_vertex)
        palyr.fieldName = r"$id"  # Expression $id
        palyr.placement = 1  # ::OverPoint
        palyr.quadOffset = 2  # ::QuadrantAboveRight
        palyr.setDataDefinedProperty(80, True, True, r"1",
                                     "")  # ::OffsetUnits -> ::MM
        palyr.xOffset = 2.0
        palyr.yOffset = -1.0
        palyr.writeToLayer(l_vertex)

        # Then return layers..
        return [l_vertex, l_edge]