def createReferencingLayer():
    layer = QgsVectorLayer("Point?field=fldtxt:string&field=foreignkey:integer", "referencinglayer", "memory")
    pr = layer.dataProvider()
    f1 = QgsFeature()
    f1.setFields(layer.pendingFields())
    f1.setAttributes(["test1", 123])
    f1.setGeometry(QgsGeometry.fromPoint(QgsPoint(100, 200)))
    f2 = QgsFeature()
    f2.setFields(layer.pendingFields())
    f2.setAttributes(["test2", 123])
    f2.setGeometry(QgsGeometry.fromPoint(QgsPoint(101, 201)))
    assert pr.addFeatures([f1, f2])
    return layer
    def add_flooded_field(self, shapefile_path):
        """Create the layer from the local shp adding the flooded field.

        .. versionadded:: 3.3

        Use this method to add a calculated field to a shapefile. The shapefile
        should have a field called 'count' containing the number of flood
        reports for the field. The field values will be set to 0 if the count
        field is < 1, otherwise it will be set to 1.

        :param shapefile_path: Path to the shapefile that will have the flooded
            field added.
        :type shapefile_path: basestring

        :return: A vector layer with the flooded field added.
        :rtype: QgsVectorLayer
        """
        layer = QgsVectorLayer(
            shapefile_path, self.tr('Jakarta Floods'), 'ogr')
        # Add a calculated field indicating if a poly is flooded or not
        # from PyQt4.QtCore import QVariant
        layer.startEditing()
        # Add field with integer from 0 to 4 which represents the flood
        # class. Its the same as 'state' field except that is being treated
        # as a string.
        # This is used for cartography
        flood_class_field = QgsField('floodclass', QVariant.Int)
        layer.dataProvider().addAttributes([flood_class_field])
        layer.commitChanges()
        layer.startEditing()
        flood_class_idx = layer.fieldNameIndex('floodclass')
        flood_class_expression = QgsExpression('to_int(state)')
        flood_class_expression.prepare(layer.pendingFields())

        # Add field with boolean flag to say if the area is flooded
        # This is used by the impact function
        flooded_field = QgsField('flooded', QVariant.Int)
        layer.dataProvider().addAttributes([flooded_field])
        layer.commitChanges()
        layer.startEditing()
        flooded_idx = layer.fieldNameIndex('flooded')
        flood_flag_expression = QgsExpression('state > 0')
        flood_flag_expression.prepare(layer.pendingFields())
        for feature in layer.getFeatures():
            feature[flood_class_idx] = flood_class_expression.evaluate(feature)
            feature[flooded_idx] = flood_flag_expression.evaluate(feature)
            layer.updateFeature(feature)
        layer.commitChanges()
        return layer
def createReferencingLayer():
    layer = QgsVectorLayer("Point?field=fldtxt:string&field=foreignkey:integer",
                           "referencinglayer", "memory")
    pr = layer.dataProvider()
    f1 = QgsFeature()
    f1.setFields(layer.pendingFields())
    f1.setAttributes(["test1", 123])
    f2 = QgsFeature()
    f2.setFields(layer.pendingFields())
    f2.setAttributes(["test2", 123])
    f3 = QgsFeature()
    f3.setFields(layer.pendingFields())
    f3.setAttributes(["foobar'bar", 124])
    assert pr.addFeatures([f1, f2, f3])
    return layer
Exemple #4
0
 def __createMemoryLayer(self, layer_name, gtype, geometries, attributes, fNames, fTypes):
     """
     Create a memory layer from parameters
     :param layer_name: name for the layer
     :param gtype: geometry type of the layer
     :param geometries: objects geometries
     :param attributes: objects attributes
     :param fNames: fields names
     :param fTypes: fields types
     """
     layerList = QgsMapLayerRegistry.instance().mapLayersByName(layer_name)
     if layerList:
         QgsMapLayerRegistry.instance().removeMapLayers([layerList[0].id()])
     epsg = self.canvas().mapRenderer().destinationCrs().authid()
     fieldsParam = ""
     for i in range(len(fNames)):
         fieldsParam += "&field=" + fNames[i] + ":" + fTypes[i]
     layer = QgsVectorLayer(gtype + "?crs=" + epsg + fieldsParam + "&index=yes", layer_name, "memory")
     QgsMapLayerRegistry.instance().addMapLayer(layer)
     layer.startEditing()
     for i in range(len(geometries)):
         feature = QgsFeature()
         feature.setGeometry(QgsGeometry().fromWkt(geometries[i]))
         fields = layer.pendingFields()
         feature.setFields(fields)
         for j in range(len(fNames)):
             feature.setAttribute(fNames[j], attributes[i][j])
         layer.addFeature(feature)
     layer.commitChanges()
    def add_flooded_field(self, shapefile_path):
        """Create the layer from the local shp adding the flooded field.

        .. versionadded:: 3.3

        Use this method to add a calculated field to a shapefile. The shapefile
        should have a field called 'count' containing the number of flood
        reports for the field. The field values will be set to 0 if the count
        field is < 1, otherwise it will be set to 1.

        :param shapefile_path: Path to the shapefile that will have the flooded
            field added.
        :type shapefile_path: basestring

        :return: A vector layer with the flooded field added.
        :rtype: QgsVectorLayer
        """
        layer = QgsVectorLayer(
            shapefile_path, self.tr('Jakarta Floods'), 'ogr')
        # Add a calculated field indicating if a poly is flooded or not
        # from PyQt4.QtCore import QVariant
        layer.startEditing()
        field = QgsField('flooded', QVariant.Int)
        layer.dataProvider().addAttributes([field])
        layer.commitChanges()
        layer.startEditing()
        idx = layer.fieldNameIndex('flooded')
        expression = QgsExpression('state > 0')
        expression.prepare(layer.pendingFields())
        for feature in layer.getFeatures():
            feature[idx] = expression.evaluate(feature)
            layer.updateFeature(feature)
        layer.commitChanges()
        return layer
def createReferencedLayer():
    layer = QgsVectorLayer(
        "Point?field=x:string&field=y:integer&field=z:integer",
        "referencedlayer", "memory")
    pr = layer.dataProvider()
    f1 = QgsFeature()
    f1.setFields(layer.pendingFields())
    f1.setAttributes(["foo", 123, 321])
    f2 = QgsFeature()
    f2.setFields(layer.pendingFields())
    f2.setAttributes(["bar", 456, 654])
    f3 = QgsFeature()
    f3.setFields(layer.pendingFields())
    f3.setAttributes(["foobar'bar", 789, 554])
    assert pr.addFeatures([f1, f2, f3])
    return layer
Exemple #7
0
    def processAlgorithm(self, progress):
        layers = self.getParameterValue(self.INPUT_DATASOURCES)
        query = self.getParameterValue(self.INPUT_QUERY)
        uid_field = self.getParameterValue(self.INPUT_UID_FIELD)
        geometry_field = self.getParameterValue(self.INPUT_GEOMETRY_FIELD)
        geometry_type = self.getParameterValue(self.INPUT_GEOMETRY_TYPE)
        geometry_crs = self.getParameterValue(self.INPUT_GEOMETRY_CRS)

        df = QgsVirtualLayerDefinition()
        layerIdx = 1
        if layers:
            for layerSource in layers.split(';'):
                layer = dataobjects.getObjectFromUri(layerSource)
                if layer:
                    df.addSource('input{}'.format(layerIdx), layer.id())

        if query == '':
            raise GeoAlgorithmExecutionException(
                self.tr('Empty SQL. Please enter valid SQL expression and try again.'))
        else:
            df.setQuery(query)

        if uid_field:
            df.setUid(uid_field)

        if geometry_type == 1:  # no geometry
            df.setGeometryWkbType(QgsWkbTypes.NullGeometry)
        else:
            if geometry_field:
                df.setGeometryField(geometry_field)
            if geometry_type > 1:
                df.setGeometryWkbType(geometry_type - 1)
            if geometry_crs:
                crs = QgsCoordinateReferenceSystem(geometry_crs)
                if crs.isValid():
                    df.setGeometrySrid(crs.postgisSrid())

        vLayer = QgsVectorLayer(df.toString(), "temp_vlayer", "virtual")
        if not vLayer.isValid():
            raise GeoAlgorithmExecutionException(vLayer.dataProvider().error().message())

        writer = self.getOutputFromName(self.OUTPUT_LAYER).getVectorWriter(
            vLayer.pendingFields().toList(),
            # Create a point layer (without any points) if 'no geometry' is chosen
            vLayer.wkbType() if geometry_type != 1 else 1,
            vLayer.crs())

        features = vector.features(vLayer)
        total = 100.0 / len(features)
        outFeat = QgsFeature()
        for current, inFeat in enumerate(features):
            outFeat.setAttributes(inFeat.attributes())
            if geometry_type != 1:
                outFeat.setGeometry(inFeat.geometry())
            writer.addFeature(outFeat)
            progress.setPercentage(int(current * total))
        del writer
    def loadData(self, resultFile, chunkId):
        """ Load data to the map """
        
        if isMimeTypeVector(self.mimeType, True) != None:                 
            # Memory layer:
            geometryTypes = ["Point","LineString","Polygon","Unknown", "NoGeometry"]
            vlayer = QgsVectorLayer(resultFile, "chunk", "ogr")

            if self.__bFirstChunk:    
                self.__bFirstChunk = False
                self.__geometryType = geometryTypes[vlayer.geometryType()]
                self.__bGeomMulti = vlayer.wkbType() in [4,5,6,11,12,13]
                self.__memoryLayer = QgsVectorLayer(self.__geometryType,"Streamed data","memory")
                self.__memoryLayer.dataProvider().addAttributes(vlayer.pendingFields().values())
                self.__memoryLayer.updateFieldMap()            

            provider = vlayer.dataProvider()
            allAttrs = provider.attributeIndexes()
            vlayer.select(allAttrs)  
            
            # Visualize temporal geometries during the downloading process
            # Don't add temporal geometries if last chunk
            if self.DEBUG: print "Loaded chunkId:",chunkId           
            res = self.__memoryLayer.dataProvider().addFeatures( [feat for feat in vlayer] )
            self.__deliveredChunks += 1      
            
            if not self.allChunksDelivered():
                inFeat = QgsFeature()
                inGeom = QgsGeometry()
                self.createTempGeometry(chunkId, self.__geometryType)
                while provider.nextFeature( inFeat ):
                    inGeom = inFeat.geometry()
                    featList = self.extractAsSingle(self.__geometryType, inGeom) if self.__bGeomMulti else [inGeom]
                    for geom in featList:
                        self.addTempGeometry(chunkId, self.__geometryType, geom)  
            else:
                self.finishLoading()
                                
        # Raster data
        elif isMimeTypeRaster(self.mimeType, True) != None:
            # We can directly attach the new layer
            if self.__bFirstChunk:    
                self.__bFirstChunk = False
                self.__groupIndex = self.__legend.addGroup("Streamed-raster")
                
            rLayer = QgsRasterLayer(resultFile, "raster_"+str(chunkId))
            bLoaded = QgsMapLayerRegistry.instance().addMapLayer(rLayer)
            self.stretchRaster(rLayer)
            self.__legend.moveLayer(rLayer, self.__groupIndex + 1)
            
            self.__deliveredChunks += 1
            
            if self.allChunksDelivered():
                self.finishLoading()
Exemple #9
0
    def test_ExpressionFieldNestedGeometry(self):
        myShpFile = os.path.join(TEST_DATA_DIR, 'points.shp')
        layer = QgsVectorLayer(myShpFile, 'Points', 'ogr')
        self.assertTrue(layer.isValid())

        cnt = layer.pendingFields().count()
        idx = layer.addExpressionField('$x*2', QgsField('exp1', QVariant.LongLong))
        idx = layer.addExpressionField('"exp1"/1.5', QgsField('exp2', QVariant.LongLong))

        fet = next(layer.getFeatures(QgsFeatureRequest().setFlags(QgsFeatureRequest.NoGeometry).setSubsetOfAttributes(['exp2'], layer.fields())))
        # nested virtual fields should have made geometry be fetched
        self.assertEqual(fet['exp2'], -156)
        self.assertEqual(fet['exp1'], -234)
Exemple #10
0
    def test_ExpressionFieldNested(self):
        myShpFile = os.path.join(TEST_DATA_DIR, 'points.shp')
        layer = QgsVectorLayer(myShpFile, 'Points', 'ogr')
        self.assertTrue(layer.isValid())

        cnt = layer.pendingFields().count()
        idx = layer.addExpressionField('"Staff"*2', QgsField('exp1', QVariant.LongLong))
        idx = layer.addExpressionField('"exp1"-1', QgsField('exp2', QVariant.LongLong))

        fet = next(layer.getFeatures(QgsFeatureRequest().setSubsetOfAttributes(['exp2'], layer.fields())))
        self.assertEqual(fet['Class'], NULL)
        # nested virtual fields should make all these attributes be fetched
        self.assertEqual(fet['Staff'], 2)
        self.assertEqual(fet['exp2'], 3)
        self.assertEqual(fet['exp1'], 4)
    def test_ExpressionFieldNestedCircular(self):
        """ test circular virtual field definitions """

        myShpFile = os.path.join(TEST_DATA_DIR, 'points.shp')
        layer = QgsVectorLayer(myShpFile, 'Points', 'ogr')
        self.assertTrue(layer.isValid())

        cnt = layer.pendingFields().count()  # NOQA
        idx = layer.addExpressionField('"exp3"*2', QgsField('exp1', QVariant.LongLong))  # NOQA
        idx = layer.addExpressionField('"exp1"-1', QgsField('exp2', QVariant.LongLong))  # NOQA
        idx = layer.addExpressionField('"exp2"*3', QgsField('exp3', QVariant.LongLong))  # NOQA

        # really just testing that this doesn't hang/crash... there's no good result here!
        fet = next(layer.getFeatures(QgsFeatureRequest().setSubsetOfAttributes(['exp2'], layer.fields())))
        self.assertEqual(fet['Class'], NULL)
Exemple #12
0
    def processAlgorithm(self, progress):
        self.progress = progress
        self.progress.setPercentage(0)

        file_path = self.getParameterValue(self.FILE)

        # Creating the dict for columns
        white_list_values = {}
        for layer in self.LAYERS:
            value = self.getParameterValue(self.WHITE_LIST[layer])

            # Delete space and tabs in OSM keys
            # Processing return a 'None' value as unicode
            value = re.sub('\s', '', value)
            if value == '' or value == 'None':
                value = None

            if value:
                if value != ',':
                    white_list_values[layer] = value.split(',')
                else:
                    white_list_values[layer] = ','
            else:
                white_list_values[layer] = None

        # Call the OSM Parser and connect signals
        parser = OsmParser(file_path, self.LAYERS, white_list_values)
        parser.signalText.connect(self.set_info)
        parser.signalPercentage.connect(self.set_percentage)

        # Start to parse
        layers = parser.parse()

        layers_outputs = {}
        for key, values in layers.iteritems():
            layer = QgsVectorLayer(values['geojsonFile'], "test", "ogr")

            output_parameter = self.getOutputValue(self.OUTPUT_LAYERS[key])
            layers_outputs[key] = QgsVectorFileWriter(
                output_parameter,
                'UTF-8',
                layer.pendingFields(),
                values['geomType'],
                layer.crs())

            for feature in layer.getFeatures():
                layers_outputs[key].addFeature(feature)
    def storyDescriptionLinkClicked(self, url):
        url = url.toString()
        if url == "search":
            dlg = SearchDialog()
            dlg.exec_()
            if dlg.mapstory is not None:
                story = Story.storyFromNumberId(dlg.mapstory)
                if story is None:
                    QMessageBox.warning(iface.mainWindow(), "MapStory", "Cannot get MapStory data.\nCheck that the provided ID is correct.")
                else:
                    self.updateCurrentStory(story)
        elif url == "download":
            outDir = QFileDialog.getExistingDirectory(self,
                                                  self.tr("Select output directory"),
                                                  "."
                                                 )
            if not outDir:
                return

            QDir().mkpath(outDir)

            settings = QSettings()
            systemEncoding = settings.value('/UI/encoding', 'System')
            startProgressBar(len(self.story.storyLayers()), "Download layers for off-line use:")
            for i, layer in enumerate(self.story.storyLayers()):
                filename = os.path.join(outDir, layer.name() + ".shp")
                uri = "%s?srsname=%s&typename=geonode:%s&version=1.0.0&request=GetFeature&service=WFS" % (layer.wfsUrl(), layer.crs(), layer.name())
                qgslayer = QgsVectorLayer(uri, layer.name(), "WFS")
                writer = QgsVectorFileWriter(filename, systemEncoding,
                                             qgslayer.pendingFields(),
                                             qgslayer.dataProvider().geometryType(),
                                             qgslayer.crs())
                for feat in qgslayer.getFeatures():
                    writer.addFeature(feat)
                del writer

                fieldname = self._getTimeField(qgslayer)

                if fieldname is not None:
                    filename = os.path.join(outDir, layer.name() + ".timefield")
                    with open(filename, "w") as f:
                        f.write(fieldname)
                setProgress(i+1)

            closeProgressBar()
            iface.messageBar().pushMessage("MapStory", "Layers have been correctly saved as QGIS project.", level=QgsMessageBar.INFO, duration=3)
    def rotation_test(self):
        # We will create a polygon layer with a rotated rectangle.
        # Then we will make it the object layer for the atlas,
        # rotate the map and test that the bounding rectangle
        # is smaller than the bounds without rotation.
        polygonLayer = QgsVectorLayer('Polygon', 'test_polygon', 'memory')
        poly = QgsFeature(polygonLayer.pendingFields())
        points = [(10, 15), (15, 10), (45, 40), (40, 45)]
        poly.setGeometry(QgsGeometry.fromPolygon([[QgsPointXY(x[0], x[1]) for x in points]]))
        polygonLayer.dataProvider().addFeatures([poly])
        QgsProject.instance().addMapLayer(polygonLayer)

        # Recreating the composer locally
        composition = QgsComposition(QgsProject.instance())
        composition.setPaperSize(297, 210)

        # the atlas map
        atlasMap = QgsComposerMap(composition, 20, 20, 130, 130)
        atlasMap.setFrameEnabled(True)
        atlasMap.setLayers([polygonLayer])
        atlasMap.setNewExtent(QgsRectangle(0, 0, 100, 50))
        composition.addComposerMap(atlasMap)

        # the atlas
        atlas = composition.atlasComposition()
        atlas.setCoverageLayer(polygonLayer)
        atlas.setEnabled(True)
        composition.setAtlasMode(QgsComposition.ExportAtlas)

        atlasMap.setAtlasDriven(True)
        atlasMap.setAtlasScalingMode(QgsComposerMap.Auto)
        atlasMap.setAtlasMargin(0.0)

        # Testing
        atlasMap.setMapRotation(0.0)
        atlas.firstFeature()
        nonRotatedExtent = QgsRectangle(atlasMap.currentMapExtent())

        atlasMap.setMapRotation(45.0)
        atlas.firstFeature()
        rotatedExtent = QgsRectangle(atlasMap.currentMapExtent())

        assert rotatedExtent.width() < nonRotatedExtent.width() * 0.9
        assert rotatedExtent.height() < nonRotatedExtent.height() * 0.9

        QgsProject.instance().removeMapLayer(polygonLayer)
            def f():
                crs = iface.mapCanvas().mapRenderer().destinationCrs()
                uri = "%s?srsname=%s&typename=geonode:%s&version=1.0.0&request=GetFeature&service=WFS" % (url, crs.authid(), name)
                qgslayer = QgsVectorLayer(uri, name, "WFS")
                if not qgslayer.isValid():
                    raise Exception ("Layer at %s is not a valid layer" % uri)

                fieldname = self._getTimeField(qgslayer)

                if fieldname is None:
                    QgsMapLayerRegistry.instance().addMapLayers([qgslayer])
                else:
                    memlayer = QgsVectorLayer("%s?crs=%s" % (GEOM_TYPE_MAP[qgslayer.wkbType()], crs.authid()), name, "memory")
                    memlayer.startEditing()
                    for field in qgslayer.pendingFields():
                        memlayer.addAttribute(field)
                    for feat in qgslayer.getFeatures():
                        memlayer.addFeatures([feat])
                    memlayer.commitChanges()
                    QgsMapLayerRegistry.instance().addMapLayers([memlayer])
                    memlayer.setSelectedFeatures([])
                    addWfsAnimation(memlayer, fieldname)
Exemple #16
0
    def test_ExpressionFieldNestedCircular(self):
        """ test circular virtual field definitions """

        myShpFile = os.path.join(TEST_DATA_DIR, 'points.shp')
        layer = QgsVectorLayer(myShpFile, 'Points', 'ogr')
        self.assertTrue(layer.isValid())

        cnt = layer.pendingFields().count()  # NOQA
        idx = layer.addExpressionField('"exp3"*2',
                                       QgsField('exp1',
                                                QVariant.LongLong))  # NOQA
        idx = layer.addExpressionField('"exp1"-1',
                                       QgsField('exp2',
                                                QVariant.LongLong))  # NOQA
        idx = layer.addExpressionField('"exp2"*3',
                                       QgsField('exp3',
                                                QVariant.LongLong))  # NOQA

        # really just testing that this doesn't hang/crash... there's no good result here!
        fet = next(
            layer.getFeatures(QgsFeatureRequest().setSubsetOfAttributes(
                ['exp2'], layer.fields())))
        self.assertEqual(fet['Class'], NULL)
Exemple #17
0
shp_filename = sys.argv[2]

try:
  m = crayfish.Mesh(sys.argv[1])
except ValueError:
  print "Failed to load mesh in %s" % sys.argv[1]
  sys.exit(1)


from qgis.core import QgsApplication, QgsVectorLayer, QgsVectorFileWriter, QgsPoint, QgsGeometry, QgsFeature
a = QgsApplication([], True)
a.initQgis()

vl = QgsVectorLayer("Point?field=node_id:integer&field=value:double", "nodes", "memory")
flds = vl.pendingFields()

o = m.dataset(0).output(0)

lst = []
for index, n in enumerate(m.nodes()):
  f = QgsFeature()
  f.setFields(flds)
  f.setGeometry(QgsGeometry.fromPoint(QgsPoint(n.x, n.y)))
  f[0] = n.id
  f[1] = o.value(index)
  lst.append(f)

vl.dataProvider().addFeatures(lst)

QgsVectorFileWriter.writeAsVectorFormat(vl, shp_filename, '', None)
    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
Exemple #19
0
class mesh_canvas(QgsMapCanvas):
    
    def __init__(self,iface,tile_name,tile_credit,tile_url,tile_zmin,tile_zmax,tile_bbox):
    
        QgsMapCanvas.__init__(self)
        self.iface = iface
        self.setWheelAction(QgsMapCanvas.WheelZoom,1)
        self.setDestinationCrs(self.iface.mapCanvas().mapSettings().destinationCrs())
        self.setCrsTransformEnabled(True)
        
        self.iface.mapCanvas().destinationCrsChanged.connect(self.onCrsChanged)
        self.iface.mapCanvas().extentsChanged.connect(self.onExtentsChanged)
        self.iface.mapCanvas().scaleChanged.connect(self.onScaleChanged)
        
        layerdef = TileLayerDefinition(tile_name,
                                       tile_credit,
                                       tile_url,
                                       zmin=tile_zmin,
                                       zmax=tile_zmax,
                                       bbox=tile_bbox)
        creditVisibility=True

        plugin = plugins.get("TileLayerPlugin")
        self.chirin_layer = TileLayer(plugin,layerdef, creditVisibility)
        QgsMapLayerRegistry.instance().addMapLayer(self.chirin_layer,False)
        
        self.meshPolyLayer = QgsVectorLayer("polygon?crs=postgis:4612",u"地域メッシュインデックス","memory")
        
        renderer = self.meshPolyLayer.rendererV2()
        renderer.symbols()[0].symbolLayers()[0].setFillColor(QtGui.QColor(0,0,0,0))
        renderer.symbols()[0].symbolLayers()[0].setBorderWidth(0.1)
        
        self.meshPolyLayer.label().setLabelField(0,0)
        
        self.meshPolyLayer.startEditing()
        self.meshPolyLayer.addAttribute(QgsField("meshC",QtCore.QVariant.String))
        self.meshPolyLayer.commitChanges()
        
        QgsMapLayerRegistry.instance().addMapLayer(self.meshPolyLayer,False)
        
        main_crs =  self.iface.mapCanvas().mapSettings().destinationCrs()
        self.Trs_laln = QgsCoordinateTransform(main_crs,QgsCoordinateReferenceSystem(4612))
        self.redraw_mesh()
             
        layers = []
        layers.append(QgsMapCanvasLayer(self.meshPolyLayer))
        layers.append(QgsMapCanvasLayer(self.chirin_layer))
        
        self.setLayerSet(layers)
        self.setExtent( self.iface.mapCanvas().extent() )
        self.setWindowFlags(QtCore.Qt.WindowStaysOnTopHint)
        self.resize(self.iface.mapCanvas().size()/2)
        
    def onCrsChanged(self):
        main_crs =  self.iface.mapCanvas().mapSettings().destinationCrs()
        self.setDestinationCrs(main_crs)

        
    def onExtentsChanged(self):
        self.setExtent( self.iface.mapCanvas().extent() )    
        self.redraw_mesh()
        self.refresh()
        
    def onScaleChanged(self):
        self.resize(self.iface.mapCanvas().size()/2)
        
    def PPopend(self):
        self.iface.mapCanvas().extentsChanged.disconnect()
        self.iface.mapCanvas().scaleChanged.disconnect()
        
    def res_mesh_index(self,latitude,longitude):
        x1d = math.floor(longitude - 100)
        x2d = math.floor((longitude - x1d - 100 ) * 8 )
        x3d = math.floor((longitude - x1d - 100 - x2d/8.0 )*80 )
        y1d = math.floor(latitude*1.5)
        y2d = math.floor((latitude*1.5 - y1d ) * 8 )
        y3d = math.floor((latitude*1.5 - y1d - y2d/8.0 )*80 ) 
        
        return (x1d,x2d,x3d,y1d,y2d,y3d)
        
    def res_extent_mesh(self):
        main_crs =  self.iface.mapCanvas().mapSettings().destinationCrs()
        self.Trs_laln.setSourceCrs(main_crs)
        
        my_rect = self.iface.mapCanvas().extent()        
        laln_rect = self.Trs_laln.transform(my_rect)        
        
        x_min = laln_rect.xMinimum()
        x_max = laln_rect.xMaximum()
        y_min = laln_rect.yMinimum()
        y_max = laln_rect.yMaximum()

        Lx1d,Lx2d,Lx3d,Ly1d,Ly2d,Ly3d = self.res_mesh_index(y_min, x_min)
        Rx1d,Rx2d,Rx3d,Uy1d,Uy2d,Uy3d = self.res_mesh_index(y_max, x_max)
        x_range = x_max - x_min
        y_range = y_max - y_min
        
        return {"Lx1d":Lx1d,"Lx2d":Lx2d,"Lx3d":Lx3d,
                "Rx1d":Rx1d,"Rx2d":Rx2d,"Rx3d":Rx3d,
                "Ly1d":Ly1d,"Ly2d":Ly2d,"Ly3d":Ly3d,
                "Uy1d":Uy1d,"Uy2d":Uy2d,"Uy3d":Uy3d,
                "xRange":x_range,"yRange":y_range}
        
    def draw_m1d(self):
        x = self.e_mesh["Lx1d"] -1
        while x <= self.e_mesh["Rx1d"] + 1:
                 
            y = self.e_mesh["Ly1d"] 
            while y <= self.e_mesh["Uy1d"]:
                
                f = QgsFeature(self.meshPolyLayer.pendingFields())
                f.setGeometry(QgsGeometry.fromPolygon(
                        [[QgsPoint(x+100,y/1.5),QgsPoint(x+100,(y+1)/1.5),
                        QgsPoint(x+101,(y+1)/1.5),QgsPoint(x+101,y/1.5)]]))
                
                m1d_str = str(int(y)) + str(int(x))
            
                f.setAttribute("meshC",m1d_str)
                self.meshPolyLayer.addFeature(f)
                y += 1
        
            x += 1
            
    def draw_m2d(self):
        x = self.e_mesh["Lx1d"] + self.e_mesh["Lx2d"] / 8.0 - 1 / 8.0      
        while x <= self.e_mesh["Rx1d"] + self.e_mesh["Rx2d"] / 8.0 + 1 / 8.0:
            
            x1d = math.floor(x)
            x2d = math.floor((x-x1d)*8)
                 
            y = self.e_mesh["Ly1d"] + self.e_mesh["Ly2d"] / 8.0 - 1 / 8.0 
            while y <= self.e_mesh["Uy1d"] + self.e_mesh["Uy2d"] + 1 / 8.0:
                
                y1d = math.floor(y)
                y2d = math.floor((y-y1d)*8)
                
                f = QgsFeature(self.meshPolyLayer.pendingFields())
                f.setGeometry(QgsGeometry.fromPolygon(
                        [[QgsPoint(x+100,y/1.5),QgsPoint(x+100,(y+1/8.0)/1.5),
                        QgsPoint(x+100+1/8.0,(y+1/8.0)/1.5),QgsPoint(x+100+1/8.0,y/1.5)]]))
                
                m1d_str = str(int(y1d)) + str(int(x1d))
                m2d_str = str(int(y2d)) + str(int(x2d))
                mesh_str = m1d_str + m2d_str
                    
                f.setAttribute("meshC",mesh_str)                                
                self.meshPolyLayer.addFeature(f)
                
                y += 1/8.0
                
            x += 1/8.0
  
    def draw_m3d(self):
        x = self.e_mesh["Lx1d"] + self.e_mesh["Lx2d"] / 8.0 + self.e_mesh["Lx3d"] / 80.0 - 1 / 80.0
        while x <= self.e_mesh["Rx1d"] + self.e_mesh["Rx2d"] / 8.0 + self.e_mesh["Rx3d"] / 80.0 + 1 / 80.0:
            
            x1d = math.floor(x)
            x2d = math.floor((x-x1d)*8)
            x3d = math.floor((x-x1d-x2d/8.0)*80)
                 
            y = self.e_mesh["Ly1d"] + self.e_mesh["Ly2d"] / 8.0 + self.e_mesh["Ly3d"] / 80.0 - 1 / 80.0
            while y <= self.e_mesh["Uy1d"] + self.e_mesh["Uy2d"] / 8.0 + self.e_mesh["Uy3d"] / 80.0 + 1 / 80.0:
                
                y1d = math.floor(y)
                y2d = math.floor((y-y1d)*8)
                y3d = math.floor((y-y1d-y2d/8.0)*80)
                
                f = QgsFeature(self.meshPolyLayer.pendingFields())
                f.setGeometry(QgsGeometry.fromPolygon(
                        [[QgsPoint(x+100,y/1.5),QgsPoint(x+100,(y+1/80.0)/1.5),
                        QgsPoint(x+100+1/80.0,(y+1/80.0)/1.5),QgsPoint(x+100+1/80.0,y/1.5)]]))
                
                m1d_str = str(int(y1d)) + str(int(x1d))
                m2d_str = str(int(y2d)) + str(int(x2d))
                m3d_str = str(int(y3d)) + str(int(x3d))
                mesh_str = m1d_str + m2d_str + m3d_str
                    
                f.setAttribute("meshC",mesh_str)                                
                self.meshPolyLayer.addFeature(f)
                
                y += 1/80.0
                
            x += 1/80.0              
    
                
                
    def draw_m5x(self):
        x = self.e_mesh["Lx1d"] - 1
        while x <= self.e_mesh["Rx1d"]+1:
            
            x1d = math.floor(x)
            x2d = math.floor((x-x1d)*8)
            x5x = math.floor((x-x1d-x2d/8.0)*16)
                 
            y = self.e_mesh["Ly1d"] - 1 
            while y <= self.e_mesh["Uy1d"]+1:
                
                y1d = math.floor(y)
                y2d = math.floor((y-y1d)*8)
                y5x = math.floor((y-y1d-y2d/8.0)*16)
                
                f = QgsFeature(self.meshPolyLayer.pendingFields())
                f.setGeometry(QgsGeometry.fromPolygon(
                        [[QgsPoint(x+100,y/1.5),QgsPoint(x+100,(y+1/16.0)/1.5),
                        QgsPoint(x+100+1/16.0,(y+1/16.0)/1.5),QgsPoint(x+100+1/16.0,y/1.5)]]))
                
                m1d_str = str(int(y1d)) + str(int(x1d))
                m2d_str = str(int(y2d)) + str(int(x2d))
                m5x_str = str(int(x5x+y5x*2+1))
                mesh_str = m1d_str + "-" + m2d_str + "-" + m5x_str
                    
                f.setAttribute("meshC",mesh_str)                                
                self.meshPolyLayer.addFeature(f)
                
                y += 1/16.0
                
            x += 1/16.0
            
        
    def redraw_mesh(self):
        
        self.e_mesh = self.res_extent_mesh()
        if self.e_mesh["xRange"] < 50:
        
            self.meshPolyLayer.startEditing()
            self.meshPolyLayer.selectAll()
            self.meshPolyLayer.deleteSelectedFeatures()

            if self.e_mesh["xRange"]  > 2.0:
                self.draw_m1d()
            elif self.e_mesh["xRange"] > 1.0/8.0:
                self.draw_m2d()
            else:
                self.draw_m3d()
        
            self.meshPolyLayer.commitChanges()
            
            self.meshPolyLayer.enableLabels(self.e_mesh["xRange"] <= 8.0)
        
    def closeEvent(self,event):
        QgsMapLayerRegistry.instance().removeMapLayers(
            [ self.meshPolyLayer.id(), self.chirin_layer.id() ])
        self.iface.mapCanvas().destinationCrsChanged.disconnect()
        self.iface.mapCanvas().extentsChanged.disconnect()
        self.iface.mapCanvas().scaleChanged.disconnect()
Exemple #20
0
def open_file(dialog=None,
              osm_file=None,
              output_geom_types=None,
              white_list_column=None,
              output_format=None,
              layer_name="OsmFile",
              config_outputs=None,
              output_dir=None,
              prefix_file=None):
    """
    open an osm file
    """
    outputs = get_outputs(output_dir, output_format, prefix_file, layer_name)

    # Parsing the file
    osm_parser = OsmParser(osm_file=osm_file,
                           layers=output_geom_types,
                           white_list_column=white_list_column)

    osm_parser.signalText.connect(dialog.set_progress_text)
    osm_parser.signalPercentage.connect(dialog.set_progress_percentage)
    layers = osm_parser.parse()

    # Finishing the process with geojson or shapefile
    num_layers = 0
    if output_format == "shape":
        dialog.set_progress_text(tr("QuickOSM", u"From GeoJSON to Shapefile"))

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

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

            # Transforming the vector file
            osm_geometries = {
                'points': QGis.WKBPoint,
                'lines': QGis.WKBLineString,
                'multilinestrings': QGis.WKBMultiLineString,
                'multipolygons': QGis.WKBMultiPolygon
            }
            geojson_layer = QgsVectorLayer(item['geojsonFile'], "temp", "ogr")

            encoding = get_default_encoding()
            if output_format == "shape":
                writer = QgsVectorFileWriter(outputs[layer], encoding,
                                             geojson_layer.pendingFields(),
                                             osm_geometries[layer],
                                             geojson_layer.crs(),
                                             "ESRI Shapefile")
            else:
                writer = QgsVectorFileWriter(outputs[layer], encoding,
                                             geojson_layer.pendingFields(),
                                             osm_geometries[layer],
                                             geojson_layer.crs(), "GeoJSON")

            for f in geojson_layer.getFeatures():
                writer.addFeature(f)

            del writer

            # Loading the final vector file
            new_layer = QgsVectorLayer(outputs[layer], final_layer_name, "ogr")

            # Try to set styling if defined
            if config_outputs and config_outputs[layer]['style']:
                new_layer.loadNamedStyle(config_outputs[layer]['style'])
            else:
                # Loading default styles
                if layer == "multilinestrings" or layer == "lines":
                    if "colour" in item['tags']:
                        new_layer.loadNamedStyle(
                            join(dirname(dirname(abspath(__file__))), "styles",
                                 layer + "_colour.qml"))

            # Add action about OpenStreetMap
            actions = new_layer.actions()
            actions.addAction(
                QgsAction.OpenUrl, "OpenStreetMap Browser",
                'http://www.openstreetmap.org/browse/'
                '[% "osm_type" %]/[% "osm_id" %]', False)
            actions.addAction(
                QgsAction.GenericPython, 'JOSM',
                'from QuickOSM.CoreQuickOSM.Actions import Actions;'
                'Actions.run("josm","[% "full_id" %]")', False)
            actions.addAction(
                QgsAction.OpenUrl, "User default editor",
                'http://www.openstreetmap.org/edit?'
                '[% "osm_type" %]=[% "osm_id" %]', False)

            for link in ['url', 'website', 'wikipedia', 'ref:UAI']:
                if link in item['tags']:
                    link = link.replace(":", "_")
                    actions.addAction(
                        QgsAction.GenericPython, link,
                        'from QuickOSM.core.actions import Actions;'
                        'Actions.run("' + link + '","[% "' + link + '" %]")',
                        False)

            if 'network' in item['tags'] and 'ref' in item['tags']:
                actions.addAction(
                    QgsAction.GenericPython, "Sketchline",
                    'from QuickOSM.core.actions import Actions;'
                    'Actions.run_sketch_line("[% "network" %]","[% "ref" %]")',
                    False)

            # Add index if possible
            if output_format == "shape":
                new_layer.dataProvider().createSpatialIndex()

            QgsMapLayerRegistry.instance().addMapLayer(new_layer)
            num_layers += 1

    return num_layers
Exemple #21
0
def open_file(
        dialog=None,
        osm_file=None,
        output_geom_types=None,
        white_list_column=None,
        output_format=None,
        layer_name="OsmFile",
        config_outputs=None,
        output_dir=None,
        prefix_file=None):
    """
    open an osm file
    """
    outputs = get_outputs(output_dir, output_format, prefix_file, layer_name)

    # Parsing the file
    osm_parser = OsmParser(
        osm_file=osm_file,
        layers=output_geom_types,
        white_list_column=white_list_column)

    osm_parser.signalText.connect(dialog.set_progress_text)
    osm_parser.signalPercentage.connect(dialog.set_progress_percentage)
    layers = osm_parser.parse()

    # Finishing the process with geojson or shapefile
    num_layers = 0
    if output_format == "shape":
        dialog.set_progress_text(tr("QuickOSM", u"From GeoJSON to Shapefile"))
    if output_format == "spatialite":
        dialog.set_progress_text(tr("QuickOSM", u"From GeoJSON to SpatiaLite"))
        # create spatialite DB
        conn = sqlitedb.connect(outputs['file'])
        cur = conn.cursor()
        cur.execute("SELECT initSpatialMetadata(1)")
        conn.close()

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

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

            # Transforming the vector file
            osm_geometries = {
                'points': QGis.WKBPoint,
                'lines': QGis.WKBLineString,
                'multilinestrings': QGis.WKBMultiLineString,
                'multipolygons': QGis.WKBMultiPolygon}
            geojson_layer = QgsVectorLayer(item['geojsonFile'], "temp", "ogr")

            encoding = get_default_encoding()
            if output_format == "shape":
                provider = "ESRI Shapefile"
            elif output_format == "geojson":
                provider = "GeoJSON"
               
            if output_format == "spatialite":
                uri = QgsDataSourceURI()
                uri.setDatabase(outputs['file'])
                uri.setDataSource('', outputs[layer], 'geom')
                layer_source = uri.uri()
                layer_provider = 'spatialite'
                writer = QgsVectorLayerImport(
                    layer_source,
                    layer_provider,
                    geojson_layer.pendingFields(),
                    osm_geometries[layer],
                    geojson_layer.crs())
            else:
                layer_source = outputs[layer]
                layer_provider = 'ogr'
                writer = QgsVectorFileWriter(
                    layer_source,
                    encoding,
                    geojson_layer.pendingFields(),
                    osm_geometries[layer],
                    geojson_layer.crs(),
                    provider)

            for f in geojson_layer.getFeatures():
                writer.addFeature(f)

            del writer

            # Loading the final vector file
            new_layer = QgsVectorLayer(layer_source, final_layer_name, layer_provider)

            # Try to set styling if defined
            if config_outputs and config_outputs[layer]['style']:
                new_layer.loadNamedStyle(config_outputs[layer]['style'])
            else:
                # Loading default styles
                if layer == "multilinestrings" or layer == "lines":
                    if "colour" in item['tags']:
                        new_layer.loadNamedStyle(
                            join(dirname(dirname(abspath(__file__))),
                                 "styles",
                                 layer + "_colour.qml"))

            # Add action about OpenStreetMap
            actions = new_layer.actions()
            actions.addAction(
                QgsAction.OpenUrl,
                "OpenStreetMap Browser",
                'http://www.openstreetmap.org/browse/'
                '[% "osm_type" %]/[% "osm_id" %]',
                False)
            actions.addAction(
                QgsAction.GenericPython,
                'JOSM',
                'from QuickOSM.CoreQuickOSM.Actions import Actions;'
                'Actions.run("josm","[% "full_id" %]")',
                False)
            actions.addAction(
                QgsAction.OpenUrl,
                "User default editor",
                'http://www.openstreetmap.org/edit?'
                '[% "osm_type" %]=[% "osm_id" %]',
                False)

            for link in ['url', 'website', 'wikipedia', 'ref:UAI']:
                if link in item['tags']:
                    link = link.replace(":", "_")
                    actions.addAction(
                        QgsAction.GenericPython,
                        link,
                        'from QuickOSM.core.actions import Actions;'
                        'Actions.run("' + link + '","[% "' + link + '" %]")',
                        False)

            if 'network' in item['tags'] and 'ref' in item['tags']:
                actions.addAction(
                    QgsAction.GenericPython,
                    "Sketchline",
                    'from QuickOSM.core.actions import Actions;'
                    'Actions.run_sketch_line("[% "network" %]","[% "ref" %]")',
                    False)

            # Add index if possible
            if output_format == "shape" or output_format == "spatialite":
                new_layer.dataProvider().createSpatialIndex()

            QgsMapLayerRegistry.instance().addMapLayer(new_layer)
            num_layers += 1

    return num_layers
Exemple #22
0
class mesh_canvas(QgsMapCanvas):
    def __init__(self, iface, tile_name, tile_credit, tile_url, tile_zmin,
                 tile_zmax, tile_bbox):

        QgsMapCanvas.__init__(self)
        self.iface = iface
        self.setWheelAction(QgsMapCanvas.WheelZoom, 1)
        self.setDestinationCrs(
            self.iface.mapCanvas().mapSettings().destinationCrs())
        self.setCrsTransformEnabled(True)

        self.iface.mapCanvas().destinationCrsChanged.connect(self.onCrsChanged)
        self.iface.mapCanvas().extentsChanged.connect(self.onExtentsChanged)
        self.iface.mapCanvas().scaleChanged.connect(self.onScaleChanged)

        layerdef = TileLayerDefinition(tile_name,
                                       tile_credit,
                                       tile_url,
                                       zmin=tile_zmin,
                                       zmax=tile_zmax,
                                       bbox=tile_bbox)
        creditVisibility = True

        plugin = plugins.get("TileLayerPlugin")
        self.chirin_layer = TileLayer(plugin, layerdef, creditVisibility)
        QgsMapLayerRegistry.instance().addMapLayer(self.chirin_layer, False)

        self.meshPolyLayer = QgsVectorLayer("polygon?crs=postgis:4612",
                                            u"地域メッシュインデックス", "memory")

        renderer = self.meshPolyLayer.rendererV2()
        renderer.symbols()[0].symbolLayers()[0].setFillColor(
            QtGui.QColor(0, 0, 0, 0))
        renderer.symbols()[0].symbolLayers()[0].setBorderWidth(0.1)

        self.meshPolyLayer.label().setLabelField(0, 0)

        self.meshPolyLayer.startEditing()
        self.meshPolyLayer.addAttribute(
            QgsField("meshC", QtCore.QVariant.String))
        self.meshPolyLayer.commitChanges()

        QgsMapLayerRegistry.instance().addMapLayer(self.meshPolyLayer, False)

        main_crs = self.iface.mapCanvas().mapSettings().destinationCrs()
        self.Trs_laln = QgsCoordinateTransform(
            main_crs, QgsCoordinateReferenceSystem(4612))
        self.redraw_mesh()

        layers = []
        layers.append(QgsMapCanvasLayer(self.meshPolyLayer))
        layers.append(QgsMapCanvasLayer(self.chirin_layer))

        self.setLayerSet(layers)
        self.setExtent(self.iface.mapCanvas().extent())
        self.setWindowFlags(QtCore.Qt.WindowStaysOnTopHint)
        self.resize(self.iface.mapCanvas().size() / 2)

    def onCrsChanged(self):
        main_crs = self.iface.mapCanvas().mapSettings().destinationCrs()
        self.setDestinationCrs(main_crs)

    def onExtentsChanged(self):
        self.setExtent(self.iface.mapCanvas().extent())
        self.redraw_mesh()
        self.refresh()

    def onScaleChanged(self):
        self.resize(self.iface.mapCanvas().size() / 2)

    def PPopend(self):
        self.iface.mapCanvas().extentsChanged.disconnect()
        self.iface.mapCanvas().scaleChanged.disconnect()

    def res_mesh_index(self, latitude, longitude):
        x1d = math.floor(longitude - 100)
        x2d = math.floor((longitude - x1d - 100) * 8)
        x3d = math.floor((longitude - x1d - 100 - x2d / 8.0) * 80)
        y1d = math.floor(latitude * 1.5)
        y2d = math.floor((latitude * 1.5 - y1d) * 8)
        y3d = math.floor((latitude * 1.5 - y1d - y2d / 8.0) * 80)

        return (x1d, x2d, x3d, y1d, y2d, y3d)

    def res_extent_mesh(self):
        main_crs = self.iface.mapCanvas().mapSettings().destinationCrs()
        self.Trs_laln.setSourceCrs(main_crs)

        my_rect = self.iface.mapCanvas().extent()
        laln_rect = self.Trs_laln.transform(my_rect)

        x_min = laln_rect.xMinimum()
        x_max = laln_rect.xMaximum()
        y_min = laln_rect.yMinimum()
        y_max = laln_rect.yMaximum()

        Lx1d, Lx2d, Lx3d, Ly1d, Ly2d, Ly3d = self.res_mesh_index(y_min, x_min)
        Rx1d, Rx2d, Rx3d, Uy1d, Uy2d, Uy3d = self.res_mesh_index(y_max, x_max)
        x_range = x_max - x_min
        y_range = y_max - y_min

        return {
            "Lx1d": Lx1d,
            "Lx2d": Lx2d,
            "Lx3d": Lx3d,
            "Rx1d": Rx1d,
            "Rx2d": Rx2d,
            "Rx3d": Rx3d,
            "Ly1d": Ly1d,
            "Ly2d": Ly2d,
            "Ly3d": Ly3d,
            "Uy1d": Uy1d,
            "Uy2d": Uy2d,
            "Uy3d": Uy3d,
            "xRange": x_range,
            "yRange": y_range
        }

    def draw_m1d(self):
        x = self.e_mesh["Lx1d"] - 1
        while x <= self.e_mesh["Rx1d"] + 1:

            y = self.e_mesh["Ly1d"]
            while y <= self.e_mesh["Uy1d"]:

                f = QgsFeature(self.meshPolyLayer.pendingFields())
                f.setGeometry(
                    QgsGeometry.fromPolygon([[
                        QgsPoint(x + 100, y / 1.5),
                        QgsPoint(x + 100, (y + 1) / 1.5),
                        QgsPoint(x + 101, (y + 1) / 1.5),
                        QgsPoint(x + 101, y / 1.5)
                    ]]))

                m1d_str = str(int(y)) + str(int(x))

                f.setAttribute("meshC", m1d_str)
                self.meshPolyLayer.addFeature(f)
                y += 1

            x += 1

    def draw_m2d(self):
        x = self.e_mesh["Lx1d"] + self.e_mesh["Lx2d"] / 8.0 - 1 / 8.0
        while x <= self.e_mesh["Rx1d"] + self.e_mesh["Rx2d"] / 8.0 + 1 / 8.0:

            x1d = math.floor(x)
            x2d = math.floor((x - x1d) * 8)

            y = self.e_mesh["Ly1d"] + self.e_mesh["Ly2d"] / 8.0 - 1 / 8.0
            while y <= self.e_mesh["Uy1d"] + self.e_mesh["Uy2d"] + 1 / 8.0:

                y1d = math.floor(y)
                y2d = math.floor((y - y1d) * 8)

                f = QgsFeature(self.meshPolyLayer.pendingFields())
                f.setGeometry(
                    QgsGeometry.fromPolygon([[
                        QgsPoint(x + 100, y / 1.5),
                        QgsPoint(x + 100, (y + 1 / 8.0) / 1.5),
                        QgsPoint(x + 100 + 1 / 8.0, (y + 1 / 8.0) / 1.5),
                        QgsPoint(x + 100 + 1 / 8.0, y / 1.5)
                    ]]))

                m1d_str = str(int(y1d)) + str(int(x1d))
                m2d_str = str(int(y2d)) + str(int(x2d))
                mesh_str = m1d_str + m2d_str

                f.setAttribute("meshC", mesh_str)
                self.meshPolyLayer.addFeature(f)

                y += 1 / 8.0

            x += 1 / 8.0

    def draw_m3d(self):
        x = self.e_mesh["Lx1d"] + self.e_mesh["Lx2d"] / 8.0 + self.e_mesh[
            "Lx3d"] / 80.0 - 1 / 80.0
        while x <= self.e_mesh["Rx1d"] + self.e_mesh[
                "Rx2d"] / 8.0 + self.e_mesh["Rx3d"] / 80.0 + 1 / 80.0:

            x1d = math.floor(x)
            x2d = math.floor((x - x1d) * 8)
            x3d = math.floor((x - x1d - x2d / 8.0) * 80)

            y = self.e_mesh["Ly1d"] + self.e_mesh["Ly2d"] / 8.0 + self.e_mesh[
                "Ly3d"] / 80.0 - 1 / 80.0
            while y <= self.e_mesh["Uy1d"] + self.e_mesh[
                    "Uy2d"] / 8.0 + self.e_mesh["Uy3d"] / 80.0 + 1 / 80.0:

                y1d = math.floor(y)
                y2d = math.floor((y - y1d) * 8)
                y3d = math.floor((y - y1d - y2d / 8.0) * 80)

                f = QgsFeature(self.meshPolyLayer.pendingFields())
                f.setGeometry(
                    QgsGeometry.fromPolygon([[
                        QgsPoint(x + 100, y / 1.5),
                        QgsPoint(x + 100, (y + 1 / 80.0) / 1.5),
                        QgsPoint(x + 100 + 1 / 80.0, (y + 1 / 80.0) / 1.5),
                        QgsPoint(x + 100 + 1 / 80.0, y / 1.5)
                    ]]))

                m1d_str = str(int(y1d)) + str(int(x1d))
                m2d_str = str(int(y2d)) + str(int(x2d))
                m3d_str = str(int(y3d)) + str(int(x3d))
                mesh_str = m1d_str + m2d_str + m3d_str

                f.setAttribute("meshC", mesh_str)
                self.meshPolyLayer.addFeature(f)

                y += 1 / 80.0

            x += 1 / 80.0

    def draw_m5x(self):
        x = self.e_mesh["Lx1d"] - 1
        while x <= self.e_mesh["Rx1d"] + 1:

            x1d = math.floor(x)
            x2d = math.floor((x - x1d) * 8)
            x5x = math.floor((x - x1d - x2d / 8.0) * 16)

            y = self.e_mesh["Ly1d"] - 1
            while y <= self.e_mesh["Uy1d"] + 1:

                y1d = math.floor(y)
                y2d = math.floor((y - y1d) * 8)
                y5x = math.floor((y - y1d - y2d / 8.0) * 16)

                f = QgsFeature(self.meshPolyLayer.pendingFields())
                f.setGeometry(
                    QgsGeometry.fromPolygon([[
                        QgsPoint(x + 100, y / 1.5),
                        QgsPoint(x + 100, (y + 1 / 16.0) / 1.5),
                        QgsPoint(x + 100 + 1 / 16.0, (y + 1 / 16.0) / 1.5),
                        QgsPoint(x + 100 + 1 / 16.0, y / 1.5)
                    ]]))

                m1d_str = str(int(y1d)) + str(int(x1d))
                m2d_str = str(int(y2d)) + str(int(x2d))
                m5x_str = str(int(x5x + y5x * 2 + 1))
                mesh_str = m1d_str + "-" + m2d_str + "-" + m5x_str

                f.setAttribute("meshC", mesh_str)
                self.meshPolyLayer.addFeature(f)

                y += 1 / 16.0

            x += 1 / 16.0

    def redraw_mesh(self):

        self.e_mesh = self.res_extent_mesh()
        if self.e_mesh["xRange"] < 50:

            self.meshPolyLayer.startEditing()
            self.meshPolyLayer.selectAll()
            self.meshPolyLayer.deleteSelectedFeatures()

            if self.e_mesh["xRange"] > 2.0:
                self.draw_m1d()
            elif self.e_mesh["xRange"] > 1.0 / 8.0:
                self.draw_m2d()
            else:
                self.draw_m3d()

            self.meshPolyLayer.commitChanges()

            self.meshPolyLayer.enableLabels(self.e_mesh["xRange"] <= 8.0)

    def closeEvent(self, event):
        QgsMapLayerRegistry.instance().removeMapLayers(
            [self.meshPolyLayer.id(),
             self.chirin_layer.id()])
        self.iface.mapCanvas().destinationCrsChanged.disconnect()
        self.iface.mapCanvas().extentsChanged.disconnect()
        self.iface.mapCanvas().scaleChanged.disconnect()
Exemple #23
0
class InputNetworkTabManager(QtCore.QObject):
    ''' Class to hide managing of relative tab
    '''
    projectModified = QtCore.pyqtSignal()

    def __init__(self, parent=None):
        '''constructor'''
        super(InputNetworkTabManager, self).__init__(parent)

        # parent is the dock widget with all graphical elements
        self.gui = parent
        
        # init some globals
        self.applicationPath = os.path.dirname(os.path.realpath(__file__))
        self.project = None
        self.projectPath = None
        self.roadLayer = None
        self.roadLayerId = None
        
        # retrieve the current tab index
        self.initTabTabIndex()
        
        # disable tab at the beginning
        self.gui.tabWidget.setTabEnabled(self.tabIndex, False)
        
        # set basic events
        self.gui.inputLayer_lineEdit.returnPressed.connect(self.loadLayer)
        self.gui.selectLayer_TButton.clicked.connect(self.askLayer)
        self.gui.selectFile_TButton.clicked.connect(self.askLayerFile)
        self.gui.inputNetwork_validate_PButton.clicked.connect(self.validateWithNotification)

    def initTabTabIndex(self):
        ''' Retrieve what tab index refer the current tab manager
        '''
        for tabIndex in range(self.gui.tabWidget.count()):
            if self.gui.tabWidget.tabText(tabIndex) == "Input Network":
                self.tabIndex = tabIndex
    
    def setProject(self, project=None):
        ''' setting the new project on which the tab is based
        '''
        self.project = project
        if self.project:
            # set some globals
            confFileName = self.project.fileName()
            self.projectPath = os.path.dirname(confFileName)
            
            # emit configurationLoaded with the status of loading
            self.setTabGUIBasingOnProject()
            
            # enable current tab because project has been loaded
            self.gui.tabWidget.setTabEnabled(self.tabIndex, True)
        
        else:
            # disable current tab because no project has been loaded yet
            self.gui.tabWidget.setTabEnabled(self.tabIndex, False)
    
    def setTabGUIBasingOnProject(self):
        '''Set tab basing on project conf 
        '''
        if not self.project:
            return
        
        # get conf parameters
        inputLayerFile = self.project.value('InputNetwork/inputLayer', '')
        columnRoadType = self.project.value('InputNetwork/columnRoadType', '')
        columnRoadLenght = self.project.value('InputNetwork/columnRoadLenght', '')
        columnRoadSlope = self.project.value('InputNetwork/columnRoadSlope', '')
        
        # if layer exist load it otherwise only reset comboboxes
        if os.path.exists(inputLayerFile):
            # check if layer is already loaded in layer list checking it's source
            # that would be equal to the inputLayerFile (for this reason is not simple 
            # to work with db data)
            found = False
            for layerName, layer in QgsMapLayerRegistry.instance().mapLayers().items():
                if inputLayerFile == layer.publicSource():
                    # set the found layer as roadLayer
                    self.roadLayer = layer
                    found = True
                    break
            
            # if layer is not loaded... load it
            if not found:
                # get layer name to set as public name in the legend
                layerName = os.path.splitext( os.path.basename(inputLayerFile) )[0]
                
                # load layer
                self.roadLayer = QgsVectorLayer(inputLayerFile, layerName, 'ogr')
                if not self.roadLayer.isValid():
                    message = self.tr("Error loading layer: %s" % self.roadLayer.error().message(QgsErrorMessage.Text))
                    iface.messageBar().pushMessage(message, QgsMessageBar.CRITICAL)
                    return
                
                # show layer in the canvas
                QgsMapLayerRegistry.instance().addMapLayer(self.roadLayer)
            
            # now layer is available
            self.roadLayerId = self.roadLayer.id()
        else:
            message = self.tr("Input network does not exist: %s" % inputLayerFile)
            iface.messageBar().pushMessage(message, QgsMessageBar.WARNING)
            
            self.roadLayer = None
            self.roadLayerId = None
        
        # avoid emitting signal in case of reset of indexes
        try:
            # to avoid add multiple listener, remove previous listener
            self.gui.inputLayer_lineEdit.returnPressed.disconnect(self.saveTabOnProject)
            self.gui.roadType_CBox.currentIndexChanged.disconnect(self.saveTabOnProject)
            self.gui.roadLenght_CBox.currentIndexChanged.disconnect(self.saveTabOnProject)
            self.gui.roadGradient_CBox.currentIndexChanged.disconnect(self.saveTabOnProject)
        except (Exception) as ex:
            pass
        
        # set text of loaded layer
        if self.roadLayer:
            self.gui.inputLayer_lineEdit.setText(self.roadLayer.publicSource())
        else:
            self.gui.inputLayer_lineEdit.setText(inputLayerFile)
            
        # now populare combo boxes with layer colums
        if self.roadLayer:
            fieldNames = sorted([field.name() for field in self.roadLayer.pendingFields().toList()])
        else:
            fieldNames = []
        unknownIndex = -1
        
        self.gui.roadType_CBox.clear()
        self.gui.roadLenght_CBox.clear()
        self.gui.roadGradient_CBox.clear()
        
        self.gui.roadType_CBox.addItems(fieldNames)
        self.gui.roadLenght_CBox.addItems(fieldNames)
        self.gui.roadGradient_CBox.addItems(fieldNames)
        
       # select the combobox item as in the project file... if not available then "Please select"
        index = self.gui.roadType_CBox.findText(columnRoadType)
        self.gui.roadType_CBox.setCurrentIndex( index if index >= 0 else unknownIndex )
        
        index = self.gui.roadLenght_CBox.findText(columnRoadLenght)
        self.gui.roadLenght_CBox.setCurrentIndex( index if index >= 0 else unknownIndex )
        
        index = self.gui.roadGradient_CBox.findText(columnRoadSlope)
        self.gui.roadGradient_CBox.setCurrentIndex( index if index >= 0 else unknownIndex )
        
        # add all modification events to notify project modification
        self.gui.inputLayer_lineEdit.returnPressed.connect(self.saveTabOnProject)
        self.gui.roadType_CBox.currentIndexChanged.connect(self.saveTabOnProject)
        self.gui.roadLenght_CBox.currentIndexChanged.connect(self.saveTabOnProject)
        self.gui.roadGradient_CBox.currentIndexChanged.connect(self.saveTabOnProject)
        
        
        #
        #  set parameters for vechicle count/speed columns
        #
        # get parameters fron project
        columnPassengerCars = self.project.value('VehicleCountSpeed/columnPassengerCars', '')
        columnLightDutyVehicle = self.project.value('VehicleCountSpeed/columnLightDutyVehicle', '')
        columnHeavyDutyVechicle = self.project.value('VehicleCountSpeed/columnHeavyDutyVechicle', '')
        columnUrbanBuses = self.project.value('VehicleCountSpeed/columnUrbanBuses', '')
        
        columnMotorcycle = self.project.value('VehicleCountSpeed/columnMotorcycle', '')
        columnCouch = self.project.value('VehicleCountSpeed/columnCouch', '')
        columnAverageSpeed = self.project.value('VehicleCountSpeed/columnAverageSpeed', '')
        
        # avoid emitting signal in case of reset of indexes
        try:
            # to avoid add multiple listener, remove previous listener
            self.gui.passengerCarsCount_CBox.currentIndexChanged.disconnect(self.saveTabOnProject)
            self.gui.lightDutyVehicleCount_CBox.currentIndexChanged.disconnect(self.saveTabOnProject)
            self.gui.heavyDutyVehicleCount_CBox.currentIndexChanged.disconnect(self.saveTabOnProject)
            self.gui.urbanBusesCount_CBox.currentIndexChanged.disconnect(self.saveTabOnProject)
            self.gui.coachesCount_CBox.currentIndexChanged.disconnect(self.saveTabOnProject)
            self.gui.motorcycleCount_CBox.currentIndexChanged.disconnect(self.saveTabOnProject)
            self.gui.averageVehicleSpeed_Cbox.currentIndexChanged.disconnect(self.saveTabOnProject)
        except (Exception) as ex:
            pass
        
        # now populare combo boxes with layer colums
        self.gui.passengerCarsCount_CBox.clear()
        self.gui.lightDutyVehicleCount_CBox.clear()
        self.gui.heavyDutyVehicleCount_CBox.clear()
        self.gui.urbanBusesCount_CBox.clear()
        self.gui.coachesCount_CBox.clear()
        self.gui.motorcycleCount_CBox.clear()
        self.gui.averageVehicleSpeed_Cbox.clear()
        
        self.gui.passengerCarsCount_CBox.addItems(fieldNames)
        self.gui.lightDutyVehicleCount_CBox.addItems(fieldNames)
        self.gui.heavyDutyVehicleCount_CBox.addItems(fieldNames)
        self.gui.urbanBusesCount_CBox.addItems(fieldNames)
        self.gui.coachesCount_CBox.addItems(fieldNames)
        self.gui.motorcycleCount_CBox.addItems(fieldNames)
        self.gui.averageVehicleSpeed_Cbox.addItems(fieldNames)
        
        # select the combobox item as in the project file... if not available then "Please select"
        index = self.gui.passengerCarsCount_CBox.findText(columnPassengerCars)
        self.gui.passengerCarsCount_CBox.setCurrentIndex( index if index >= 0 else unknownIndex )
        
        index = self.gui.lightDutyVehicleCount_CBox.findText(columnLightDutyVehicle)
        self.gui.lightDutyVehicleCount_CBox.setCurrentIndex( index if index >= 0 else unknownIndex )
        
        index = self.gui.heavyDutyVehicleCount_CBox.findText(columnHeavyDutyVechicle)
        self.gui.heavyDutyVehicleCount_CBox.setCurrentIndex( index if index >= 0 else unknownIndex )
        
        index = self.gui.urbanBusesCount_CBox.findText(columnUrbanBuses)
        self.gui.urbanBusesCount_CBox.setCurrentIndex( index if index >= 0 else unknownIndex )
        
        index = self.gui.coachesCount_CBox.findText(columnCouch)
        self.gui.coachesCount_CBox.setCurrentIndex( index if index >= 0 else unknownIndex )
        
        index = self.gui.motorcycleCount_CBox.findText(columnMotorcycle)
        self.gui.motorcycleCount_CBox.setCurrentIndex( index if index >= 0 else unknownIndex )
        
        index = self.gui.averageVehicleSpeed_Cbox.findText(columnAverageSpeed)
        self.gui.averageVehicleSpeed_Cbox.setCurrentIndex( index if index >= 0 else unknownIndex )
    
        # add all modification events to notify project modification
        self.gui.passengerCarsCount_CBox.currentIndexChanged.connect(self.saveTabOnProject)
        self.gui.lightDutyVehicleCount_CBox.currentIndexChanged.connect(self.saveTabOnProject)
        self.gui.heavyDutyVehicleCount_CBox.currentIndexChanged.connect(self.saveTabOnProject)
        self.gui.urbanBusesCount_CBox.currentIndexChanged.connect(self.saveTabOnProject)
        self.gui.coachesCount_CBox.currentIndexChanged.connect(self.saveTabOnProject)
        self.gui.motorcycleCount_CBox.currentIndexChanged.connect(self.saveTabOnProject)
        self.gui.averageVehicleSpeed_Cbox.currentIndexChanged.connect(self.saveTabOnProject)
    
    def saveTabOnProject(self):
        ''' Save tab configuration in the project basing on GUI values
        '''
        if self.sender():
            message = "QTraffic: saveTabOnProject by sender {}".format(self.sender().objectName())
            QgsLogger.debug(message, debuglevel=3)
        
        # get values from the GUI
        inputLayerFile = self.gui.inputLayer_lineEdit.text()
        columnRoadType = self.gui.roadType_CBox.currentText()
        columnRoadLenght = self.gui.roadLenght_CBox.currentText()
        columnRoadSlope = self.gui.roadGradient_CBox.currentText()
        
        # set conf parameters
        self.project.setValue('InputNetwork/inputLayer', inputLayerFile)
        self.project.setValue('InputNetwork/columnRoadType', columnRoadType)
        self.project.setValue('InputNetwork/columnRoadLenght', columnRoadLenght)
        self.project.setValue('InputNetwork/columnRoadSlope', columnRoadSlope)
        
        #
        #  save parameters for vechicle count/speed columns
        #
        # get values from the GUI
        columnPassengerCars = self.gui.passengerCarsCount_CBox.currentText()
        columnLightDutyVehicle = self.gui.lightDutyVehicleCount_CBox.currentText()
        columnHeavyDutyVechicle = self.gui.heavyDutyVehicleCount_CBox.currentText()
        columnUrbanBuses = self.gui.urbanBusesCount_CBox.currentText()
        
        columnCouch = self.gui.coachesCount_CBox.currentText()
        columnMotorcycle = self.gui.motorcycleCount_CBox.currentText()
        columnAverageSpeed = self.gui.averageVehicleSpeed_Cbox.currentText()
        
        # set conf parameters
        self.project.setValue('VehicleCountSpeed/columnPassengerCars', columnPassengerCars)
        self.project.setValue('VehicleCountSpeed/columnLightDutyVehicle', columnLightDutyVehicle)
        self.project.setValue('VehicleCountSpeed/columnHeavyDutyVechicle', columnHeavyDutyVechicle)
        self.project.setValue('VehicleCountSpeed/columnUrbanBuses', columnUrbanBuses)
        self.project.setValue('VehicleCountSpeed/columnMotorcycle', columnMotorcycle)
        self.project.setValue('VehicleCountSpeed/columnCouch', columnCouch)
        self.project.setValue('VehicleCountSpeed/columnAverageSpeed', columnAverageSpeed)
        
        # notify project modification
        self.projectModified.emit()
    
    def askLayer(self):
        ''' Ask for the layer to load
            Look for layer already loaded in the layer list 
        '''
        # create dialog to select layer
        dlg = SelectLayerDialog(self.gui)
        ret = dlg.exec_()
        if ret:
            # get selected layer
            newLayer = dlg.selectLayer_CBox.currentLayer()
            
            # set gui with the new layer name
            self.gui.inputLayer_lineEdit.setText(newLayer.publicSource())
            
            # then load layer
            self.loadLayer()
        
    def askLayerFile(self):
        ''' Ask for the layer file to load
            Don't load it if already loaded comparing source of tre layer
        '''
        if not self.project:
            return
        
        # if a layer is present in the project start from the path of that layer
        oldLayer = self.project.value('InputNetwork/inputLayer', '')
        if oldLayer:
            startPath = os.path.dirname(oldLayer)
        else:
            startPath = self.projectPath
        
        # get porject path
        layerFileName = QtGui.QFileDialog.getOpenFileName(self.gui, "Select road layer", startPath, 
                                                          self.tr("Shp (*.shp);;All (*)"))
        if not layerFileName:
            return
        
        # set gui with the new layer name
        self.gui.inputLayer_lineEdit.setText(layerFileName)
        
        # then load layer
        self.loadLayer()
    
    def loadLayer(self):
        ''' Load a shape layer 
        '''
        # get layer filename
        layerFileName = self.gui.inputLayer_lineEdit.text()
        if not layerFileName:
            return
        if not os.path.exists(layerFileName):
            title = self.tr("Warning")
            message = self.tr("Layer does not exist")
            iface.messageBar().pushMessage(message, QgsMessageBar.WARNING)
            return
        
        currentLayerFile = self.project.value('InputNetwork/inputLayer', '')
        if currentLayerFile != layerFileName:
            self.project.setValue('InputNetwork/inputLayer', layerFileName)
        self.setTabGUIBasingOnProject()
        
        # notify project modification if layer source is modified
        if currentLayerFile != layerFileName:
            self.projectModified.emit()
    
    def getRoadLayer(self):
        return self.roadLayer
    
    def getRoadLayerId(self):
        return self.roadLayerId
    
    def removeRoadLayer(self):
        ''' Remove current road layer from canvas
        '''
        if self.roadLayer and self.roadLayer.isValid():
            # do nothing if layer already removed by user
            QgsMapLayerRegistry.instance().removeMapLayer(self.roadLayer.id())
    
    def validateWithNotification(self):
        ''' Do validation and notify if it success
        ''' 
        if self.validate():
            message = self.tr("QTraffic: Input Network validation passed successfully")
            iface.messageBar().pushMessage(message, QgsMessageBar.SUCCESS)
    
    def validate(self):
        ''' Validate parameters inserted in the Input Network tab:
            Validation performed is:
            Mandatory parameters:
                Input layer
                Road Type
                Road lenght
                Road Gradient
                Average vehicle speed
                At least one of vehicle count
            Value validation:
                Road Type have to be integer
                Road lenght, lenght, Gradient have to be float
                Average vehicle speed have to be lfoat
                Count column have to be float or integer
            Inter tab validation
                Road type column values have to be present as categories in Fleet Distribution classes
            This method notify the error in case of validation failure
            This method notify success in case of correct validation
            @return: True is validated or False if not 
        '''
        if not self.project:
            return False
        
        inputLayerFile = self.gui.inputLayer_lineEdit.text()
        columnRoadType = self.gui.roadType_CBox.currentText()
        columnRoadLenght = self.gui.roadLenght_CBox.currentText()
        columnRoadSlope = self.gui.roadGradient_CBox.currentText()
        columnAverageSpeed = self.gui.averageVehicleSpeed_Cbox.currentText()

        columnPassengerCars = self.gui.passengerCarsCount_CBox.currentText()
        columnLightDutyVehicle = self.gui.lightDutyVehicleCount_CBox.currentText()
        columnHeavyDutyVechicle = self.gui.heavyDutyVehicleCount_CBox.currentText()
        columnUrbanBuses = self.gui.urbanBusesCount_CBox.currentText()
        columnCouch = self.gui.coachesCount_CBox.currentText()
        columnMotorcycle = self.gui.motorcycleCount_CBox.currentText()
        
        # mandatory fields
        if not inputLayerFile:
            message = self.tr("Validation error: Input shape have to be choosed")
            iface.messageBar().pushMessage(message, QgsMessageBar.CRITICAL)
            return False
        
        if not columnRoadType:
            message = self.tr("Validation error: Road type column have to be selected from input layer")
            iface.messageBar().pushMessage(message, QgsMessageBar.CRITICAL)
            return False
        
        if not columnRoadLenght:
            message = self.tr("Validation error: Road lenght column have to be selected from input layer")
            iface.messageBar().pushMessage(message, QgsMessageBar.CRITICAL)
            return False
        
        if not columnRoadSlope:
            message = self.tr("Validation error: Road gradient column have to be selected from input layer")
            iface.messageBar().pushMessage(message, QgsMessageBar.CRITICAL)
            return False
        
        if not columnRoadLenght:
            message = self.tr("Validation error: Road slope column have to be selected from input layer")
            iface.messageBar().pushMessage(message, QgsMessageBar.CRITICAL)
            return False
        
        if not columnAverageSpeed:
            message = self.tr("Validation error: Average vechicle speed column have to be selected from input layer")
            iface.messageBar().pushMessage(message, QgsMessageBar.CRITICAL)
            return False
        
        # at least one column count have to be selected
        if (not columnPassengerCars and
            not columnLightDutyVehicle and
            not columnHeavyDutyVechicle and
            not columnUrbanBuses and
            not columnCouch and
            not columnMotorcycle):
            message = self.tr("Validation error: At least a vehicle count column have to be selected from input layer")
            iface.messageBar().pushMessage(message, QgsMessageBar.CRITICAL)
            return False
        
        # value validations
        fields = self.roadLayer.pendingFields()
        checkDict = {
            columnRoadType: [QtCore.QVariant.Int, QtCore.QVariant.LongLong],
            columnRoadLenght: [QtCore.QVariant.Int, QtCore.QVariant.Double, QtCore.QVariant.LongLong],
            columnRoadSlope: [QtCore.QVariant.Int, QtCore.QVariant.Double, QtCore.QVariant.LongLong],
            columnAverageSpeed: [QtCore.QVariant.Int, QtCore.QVariant.Double, QtCore.QVariant.LongLong],
            columnPassengerCars: [QtCore.QVariant.Int, QtCore.QVariant.Double, QtCore.QVariant.LongLong],
            columnLightDutyVehicle: [QtCore.QVariant.Int, QtCore.QVariant.Double, QtCore.QVariant.LongLong],
            columnHeavyDutyVechicle: [QtCore.QVariant.Int, QtCore.QVariant.Double, QtCore.QVariant.LongLong],
            columnUrbanBuses: [QtCore.QVariant.Int, QtCore.QVariant.Double, QtCore.QVariant.LongLong],
            columnCouch: [QtCore.QVariant.Int, QtCore.QVariant.Double, QtCore.QVariant.LongLong],
            columnMotorcycle: [QtCore.QVariant.Int, QtCore.QVariant.Double, QtCore.QVariant.LongLong],
        }
        
        for columnName, admissibleTypes in checkDict.items():
            if not columnName:
                continue
            
            field = fields.field(columnName)
            if not field.type() in admissibleTypes:
                message = self.tr("Validation error: column {} has incompatible type {}".format(columnName, field.typeName()))
                iface.messageBar().pushMessage(message, QgsMessageBar.CRITICAL)
                return False
        
        # inter tab validation
        index = self.roadLayer.fieldNameIndex(columnRoadType)
        roadTypes = self.roadLayer.uniqueValues(index, -1)
        if len(roadTypes) == 0:
            message = self.tr("Validation error: column {} has no values".format(columnRoadType))
            iface.messageBar().pushMessage(message, QgsMessageBar.CRITICAL)
            return False
        
        # check if each road type is present in the list of road types in the fleet distribution tab
        fleetDistributionRoadTypes = self.gui.getRoadTypes()
        for roadType in roadTypes:
            if not str(roadType) in fleetDistributionRoadTypes:
                message = self.tr("Validation error: Road type value {} is not defined in Fleet Composition tab".format(roadType))
                iface.messageBar().pushMessage(message, QgsMessageBar.CRITICAL)
                return False
        
        return True
    
    # noinspection PyMethodMayBeStatic
    def tr(self, message):
        """Get the translation for a string using Qt translation API.

        We implement this ourselves since we do not inherit QObject.

        :param message: String for translation.
        :type message: str, QString

        :returns: Translated version of message.
        :rtype: QString
        """
        # noinspection PyTypeChecker,PyArgumentList,PyCallByClass
        return QtCore.QCoreApplication.translate('QTraffic', message)
Exemple #24
0
    def save_hazard_data(self):
        hazard_geojson = PetaJakartaAPI.get_aggregate_report(
            self.duration, self.level)

        if not hazard_geojson:
            raise PetaJakartaAPIError("Can't access PetaJakarta REST API")

        with open(self.hazard_path, 'w+') as f:
            f.write(hazard_geojson)

        # Save the layer as shp
        file_info = QFileInfo(self.hazard_path)
        hazard_layer = QgsVectorLayer(self.hazard_path, file_info.baseName(),
                                      'ogr', False)

        target_name = 'flood_data.shp'
        self.hazard_path = os.path.join(self.report_path, target_name)
        QgsVectorFileWriter.writeAsVectorFormat(hazard_layer, self.hazard_path,
                                                'CP1250', None,
                                                'ESRI Shapefile')

        file_info = QFileInfo(self.hazard_path)
        hazard_layer = QgsVectorLayer(self.hazard_path, file_info.baseName(),
                                      'ogr')

        hazard_layer.startEditing()
        field = QgsField('flooded', QVariant.Int)
        hazard_layer.dataProvider().addAttributes([field])
        hazard_layer.commitChanges()
        idx = hazard_layer.fieldNameIndex('flooded')
        expression = QgsExpression('count > 0')
        expression.prepare(hazard_layer.pendingFields())

        hazard_layer.startEditing()
        for feature in hazard_layer.getFeatures():
            feature[idx] = expression.evaluate(feature)
            hazard_layer.updateFeature(feature)

        hazard_layer.commitChanges()

        # writing keywords
        keyword_io = KeywordIO()

        keywords = {
            'field': 'flooded',
            'hazard': 'flood',
            'hazard_category': 'single_event',
            'keyword_version': '3.3',
            'layer_geometry': 'polygon',
            'layer_mode': 'classified',
            'layer_purpose': 'hazard',
            'title': 'Flood',
            'value_map': '{"wet": [1], "dry": [0]}',
            'vector_hazard_classification': 'flood_vector_hazard_classes'
        }

        keyword_io.write_keywords(hazard_layer, keywords)

        # archiving hazard layer
        with ZipFile(self.hazard_zip_path, 'w') as zf:
            for root, dirs, files in os.walk(self.report_path):
                for f in files:
                    _, ext = os.path.splitext(f)
                    if 'flood_data' in f:
                        filename = os.path.join(root, f)
                        zf.write(filename, arcname=f)
Exemple #25
0
    def run(self):
        """Run method that performs all the real work"""
        # Add items to Management Practices & Soil Type
        k_lists = []
        m_lists = []

        k_lists = self.k_list()
        m_lists = self.m_list()

        self.dlg.comboBox.addItems(k_lists)
        self.dlg.comboBox_2.addItems(m_lists)

        # show dialog box
        self.dlg.show()

        # Run the dialog event loop
        result = self.dlg.exec_()
        # See if OK was pressed
        if result:

            # Save paths of input directories
            selectedBoundary = self.dlg.lineEdit.text()
            selectedDEM = self.dlg.lineEdit_2.text()
            selectedRLayer = self.dlg.lineEdit_3.text()

            selectedOutput = self.dlg.lineEdit_4.text()
            for letter in selectedOutput:
                if letter == "\\":
                    selectedOutput = selectedOutput.replace(letter, "/")

            print(selectedBoundary)
            print(selectedDEM)
            print(selectedRLayer)
            print(selectedOutput)

            # Save indices for K and M
            selectedKLayer = self.dlg.comboBox.currentIndex()
            selectedMLayer = self.dlg.comboBox_2.currentIndex()

            boundary = QgsVectorLayer(selectedBoundary, 'Boundary', 'ogr')
            QgsMapLayerRegistry.instance().addMapLayer(boundary)

            entries = []

            # Retrieve K and M values

            k_value = self.k_index(selectedKLayer)
            m_value = self.m_index(selectedMLayer)

            km_value = k_value * m_value
            km_value = str(km_value)

            # Process R index

            ## CSV to Layer
            uri = 'file:///' + selectedRLayer + '?delimiter=%s&xField=%s&yField=%s&crs=%s' % (
                ",", "x", "y", "EPSG:4326")
            rainfall_unedited = QgsVectorLayer(uri, "rainfall",
                                               "delimitedtext")
            QgsMapLayerRegistry.instance().addMapLayer(rainfall_unedited)
            spatRef = QgsCoordinateReferenceSystem(
                4326, QgsCoordinateReferenceSystem.EpsgCrsId)

            ## CSV points to editable shapefile
            rainfall_edited = QgsVectorFileWriter(
                selectedOutput + '/rainfall_edited.shp', None,
                rainfall_unedited.pendingFields(), QGis.WKBPoint, spatRef)

            pt = QgsPoint()
            outFeature = QgsFeature()

            for feat in rainfall_unedited.getFeatures():
                attrs = feat.attributes()
                pt.setX(feat['x'])
                pt.setY(feat['y'])
                outFeature.setAttributes(attrs)
                outFeature.setGeometry(QgsGeometry.fromPoint(pt))
                rainfall_edited.addFeature(outFeature)
            del rainfall_edited

            rainfall_edited2 = QgsVectorLayer(
                selectedOutput + '/rainfall_edited.shp', 'rainfall_edited',
                'ogr')

            ## Add and calculate average field
            rainfall_edited2.startEditing()

            avgField = QgsField('average', QVariant.Double)
            rainfall_edited2.dataProvider().addAttributes([avgField])
            rainfall_edited2.updateFields()
            idx = rainfall_edited2.fieldNameIndex('average')

            time_count = idx - 2
            str_output = ''
            for i in range(1, time_count + 1):
                if i == 1:
                    a = str(i)
                    str_output += 'time' + a

                else:
                    a = str(i)
                    str_output += '+ time' + a

            e = QgsExpression(str_output)
            e.prepare(rainfall_edited2.pendingFields())

            for f in rainfall_edited2.getFeatures():
                f[idx] = e.evaluate(f) / time_count
                rainfall_edited2.updateFeature(f)

            rainfall_edited2.commitChanges()

            rainfall_edited3 = QgsVectorLayer(
                selectedOutput + '/rainfall_edited.shp', 'rainfall_edited',
                'ogr')
            QgsMapLayerRegistry.instance().addMapLayer(rainfall_edited3)

            ## Interpolating average using IDW
            ### Parameters for interpolation
            idx = rainfall_edited3.fieldNameIndex('average')

            layer_data = qgis.analysis.QgsInterpolator.LayerData()
            layer_data.vectorLayer = rainfall_edited3
            layer_data.zCoordInterpolation = False
            layer_data.interpolationAttribute = idx
            layer_data.mInputType = 1

            idw_interpolator = QgsIDWInterpolator([layer_data])

            ### Output parameter
            export_path = selectedOutput + "/interpolated_r_{}.asc".format(idx)
            rect = boundary.extent()
            res = 0.0001
            ncol = (rect.xMaximum() - rect.xMinimum()) / res
            nrows = (rect.yMaximum() - rect.yMinimum()) / res

            interpolated_r = QgsGridFileWriter(idw_interpolator,
                                               export_path, rect, int(ncol),
                                               int(nrows), res, res)
            interpolated_r.writeFile(True)

            interpolated_r2 = QgsRasterLayer(export_path, "interpolated_r")

            ## Clip output to boundary
            clippedR = processing.runandload(
                'gdalogr:cliprasterbymasklayer',
                interpolated_r2,  #INPUT <ParameterRaster>
                boundary,  #MASK <ParameterVector>
                "-9999",  #NO_DATA <ParameterString>
                False,  #ALPHA_BAND <ParameterBoolean>
                False,  #CROP_TO_CUTLINE <ParameterBoolean>
                False,  #KEEP_RESOLUTION <ParameterBoolean>
                5,  #RTYPE <ParameterSelection>
                4,  #COMPRESS <ParameterSelection>
                1,  #JPEGCOMPRESSION <ParameterNumber>
                6,  #ZLEVEL <ParameterNumber>
                1,  #PREDICTOR <ParameterNumber>
                False,  #TILED <ParameterBoolean>
                2,  #BIGTIFF <ParameterSelection>
                False,  #TFW <ParameterBoolean>
                "",  #EXTRA <ParameterString>
                selectedOutput +
                '/clip_interpolated_r.tif')  #OUTPUT <OutputRaster>

            r_layer = QgsRasterLayer(
                selectedOutput + '/clip_interpolated_r.tif', "R-index")
            boh4 = QgsRasterCalculatorEntry()
            boh4.ref = 'boh4@1'
            boh4.raster = r_layer
            boh4.bandNumber = 1
            entries.append(boh4)

            # Process S index
            ## Load DEM

            bohLayer1 = QgsRasterLayer(selectedDEM, "DEM")
            boh2 = QgsRasterCalculatorEntry()
            boh2.ref = 'boh2@1'
            boh2.raster = bohLayer1
            boh2.bandNumber = 1
            entries.append(boh2)

            ## Clip output to boundary
            clippedOutput2 = processing.runandload(
                'gdalogr:cliprasterbymasklayer',
                bohLayer1,  # INPUT <ParameterRaster>
                boundary,  # MASK <ParameterVector>
                "-9999",  # NO_DATA <ParameterString>
                False,  # ALPHA_BAND <ParameterBoolean>
                False,  # CROP_TO_CUTLINE <ParameterBoolean>
                False,  # KEEP_RESOLUTION <ParameterBoolean>
                5,  # RTYPE <ParameterSelection>
                4,  # COMPRESS <ParameterSelection>
                1,  # JPEGCOMPRESSION <ParameterNumber>
                6,  # ZLEVEL <ParameterNumber>
                1,  # PREDICTOR <ParameterNumber>
                False,  # TILED <ParameterBoolean>
                2,  # BIGTIFF <ParameterSelection>
                False,  # TFW <ParameterBoolean>
                "",  # EXTRA <ParameterString>
                selectedOutput + '/clip_dem.tif')  # OUTPUT <OutputRaster>

            bohLayer5 = QgsRasterLayer(selectedOutput + '/clip_dem.tif',
                                       "DEM-clipped")
            boh5 = QgsRasterCalculatorEntry()
            boh5.ref = 'boh5@1'
            boh5.raster = bohLayer5
            boh5.bandNumber = 1
            entries.append(boh5)

            ## GDAL algorithm for slope
            processing.runalg('gdalogr:slope', bohLayer5, 1, False, True, True,
                              111120, selectedOutput + '/slope(percent).tif')

            bohLayer6 = QgsRasterLayer(selectedOutput + '/slope(percent).tif',
                                       "slope(percent)")
            QgsMapLayerRegistry.instance().addMapLayer(bohLayer6)
            boh6 = QgsRasterCalculatorEntry()
            boh6.ref = 'boh6@1'
            boh6.raster = bohLayer6
            boh6.bandNumber = 1
            entries.append(boh6)

            # Process calculation with input extent and resolution
            calc = QgsRasterCalculator('(boh4@1 * boh6@1) *' + km_value,
                                       selectedOutput + '/soil_risk.tif',
                                       'GTiff', bohLayer6.extent(),
                                       bohLayer6.width(), bohLayer6.height(),
                                       entries)

            calc.processCalculation()
            bohLayer4 = QgsRasterLayer(selectedOutput + '/soil_risk.tif',
                                       "Soil_Risk")
            QgsMapLayerRegistry.instance().addMapLayer(bohLayer4)
Exemple #26
0
    def prepareReclassification(self, cl, areaLyr, centroidLyr, relateDict):
        """
        area without centroid: destid = -1
        area with conflicted centroid: destid = 0
        """
        destIdx = areaLyr.fieldNameIndex('destid')
        for id in relateDict[cl].keys():
            numberOfCentroids = len(relateDict[cl][id])
            if numberOfCentroids == 1:
                if relateDict[cl][id][0]['cl'] == cl:
                    # perfect case - must be reclassified
                    areaLyr.dataProvider().changeAttributeValues(
                        {id: {
                            destIdx: relateDict[cl][id][0]['featid']
                        }})
            elif numberOfCentroids == 0:
                # area without centroid - this must become a flag
                areaLyr.dataProvider().changeAttributeValues(
                    {id: {
                        destIdx: -1000
                    }})
            else:
                #first sweep: identify centroids with conflicted classes
                conflictedCentroids = [
                    feat for feat in relateDict[cl][id] if feat['cl'] <> cl
                ]
                conflictedChildCentroids = [
                    feat['child'] for feat in relateDict[cl][id]
                ]
                conflictedDict = dict()
                for conf in conflictedChildCentroids:
                    conflictedDict[conf] = 1
                if len(conflictedCentroids) > 0:
                    areaLyr.dataProvider().changeAttributeValues(
                        {id: {
                            destIdx: -2000
                        }})
                elif len(conflictedDict.keys()) > 1:
                    areaLyr.dataProvider().changeAttributeValues(
                        {id: {
                            destIdx: -2000
                        }})
                else:
                    sameClassCentroids = relateDict[cl][id]
                    #get original centroid layer
                    auxLyr = QgsVectorLayer(
                        self.abstractDb.getURI(cl,
                                               False,
                                               geomColumn='centroid').uri(),
                        relateDict[cl][id][0][0], "postgres")
                    #get all field names
                    fieldNames = [
                        field.name() for field in auxLyr.pendingFields()
                    ]
                    #we must not consider these fields
                    notAllowedFields = [
                        name for name in fieldNames
                        if (name in ['id', 'geom', 'centroid'] or 'id_' in name
                            )
                    ]
                    #check by index is easier, therefore, this step
                    notAllowedIndexes = []
                    for notAllowedField in notAllowedFields:
                        notAllowedIndexes.append(
                            auxLyr.fieldNameIndex(notAllowedField))

                    #comparing centroid attributes
                    duplicated = True  # aux variable
                    firstCentroid = [
                        feat for feat in auxLyr.dataProvider().getFeatures(
                            QgsFeatureRequest(relateDict[cl][id][0][1]))
                    ][0]
                    firstAttributes = firstCentroid.attributes()
                    for i in range(1, len(sameClassCentroids)):
                        centroid = [
                            feat for feat in auxLyr.dataProvider().getFeatures(
                                QgsFeatureRequest(sameClassCentroids[i][1]))
                        ][0]
                        attributes = centroid.attributes()
                        for j in range(len(attributes)):
                            if j not in notAllowedIndexes:
                                #in this case the attribute j is not equal, we must flag this out
                                if centroid[j] != firstCentroid[j]:
                                    duplicated = False
                                    break
                        break
                    if duplicated:
                        areaLyr.dataProvider().changeAttributeValues(
                            {id: {
                                destIdx: relateDict[cl][id][0]['featid']
                            }})
                    else:
                        areaLyr.dataProvider().changeAttributeValues(
                            {id: {
                                destIdx: -2000
                            }})
Exemple #27
0
class AutoFieldsTests( unittest.TestCase ):

    @classmethod
    def setUpClass( self ):
        self.msg = MessageManager( 'debug', None ) 
        self.msg.show( "Info! SetUp started", 'info', True )
        #Initialize QGIS app
        app = QgsApplication([], True)
        QgsApplication.setPrefixPath("/usr", True)
        QgsApplication.initQgis()
        
        #Configure QSettings (organization and application name)
        self.settings = QSettings("GeoTux", "QGIS-Plugin-Test") 

        #Load layer, add field f1, and add layer to Registry
        baseDir = os.path.dirname( os.path.realpath( __file__ ) )
        self.layerPath = os.path.join( baseDir, 'test_data', 'test_points.shp' )
        self.layer = QgsVectorLayer( self.layerPath, 'puntos', 'ogr' )   
        self.layer.dataProvider().addAttributes([QgsField('f1', QVariant.Double)])
        self.layer.updateFields()
        QgsMapLayerRegistry.instance().addMapLayer( self.layer )  
        
        #Instantiate AutoFieldManager
        self.autoFieldManager = AutoFieldManager( self.msg, None, '/AutoFieldsTest', 'GeoTux', 'QGIS-Plugin-Test' )
        
            
    def readStoredSettings( self, layer, fieldName ):
        """ Helper function to get a dictionary of stored QSettings for an AutoField """
        dictTmpProperties = {}
        autoFieldId = self.autoFieldManager.buildAutoFieldId( layer, fieldName )
        self.settings.beginGroup('/AutoFieldsTest/data/' + autoFieldId)
        dictTmpProperties['layer'] = self.settings.value( "layer", "", type=str )
        dictTmpProperties['field'] = self.settings.value( "field", u"", type=unicode )
        dictTmpProperties['expression'] = self.settings.value( "expression", u"", type=unicode )
        dictTmpProperties['layer2'] = self.settings.value( "layer2", "", type=str )
        dictTmpProperties['field2'] = self.settings.value( "field2", "", type=str )            
        dictTmpProperties['enabled'] = self.settings.value( "enabled", False, type=bool )
        self.settings.endGroup()
                
        return dictTmpProperties

    def test01CreateEnabledAutoField( self ):
        """ QSettings should be properly stored, AutoField should be enabled """
        self.msg.show( "Info! Test 1 started", 'info', True )

        self.autoFieldManager.createAutoField(
            layer=self.layer, 
            fieldName=u'f1', 
            expression=u'$x'
        )

        dictTmpProperties = self.readStoredSettings( self.layer, u'f1' )      
        dictExpectedProperties = {
            'layer':self.layerPath,
            'field':u'f1',
            'expression':u'$x',
            'layer2':"",
            'field2':"",
            'enabled':True
        }
        
        self.assertEqual( dictTmpProperties, dictExpectedProperties )
        
        
    def test02AvoidTwoAutoFieldsOnSameField( self ):
        """ AutoField should not be created if another one already exists on the same field."""
        self.msg.show( "Info! Test 2 started", 'info', True )

        res = self.autoFieldManager.createAutoField(
            layer=self.layer, 
            fieldName=u'f1', 
            expression=u'$y'
        )
        
        self.assertFalse( res )
        
        
    def test03EditAutoFieldLayer( self ):
        """ AutoField value should be updated if a feature is added.
            Note: It cannot handle the case when writing directly to the provider,
              as QGIS doesn't have a SIGNAL for that.
              self.layer.dataProvider().addFeatures( [ tmpFeature ] )        
         """
        self.msg.show( "Info! Test 3 started", 'info', True )

        tmpFeature = QgsFeature( self.layer.pendingFields() )
        tmpFeature.setGeometry( QgsGeometry.fromPoint( QgsPoint(-74.4, 4.5) ) )

        # Either 1:
        self.layer.startEditing()
        self.layer.addFeature( tmpFeature )
        self.layer.commitChanges()
        
        # Or 2:
        #with edit( self.layer ):
        #    self.layer.addFeature( tmpFeature )
            
        addedFeature = self.layer.getFeatures().next()
        self.assertEquals( addedFeature['f1'], -74.4 )


    def test04ChangeAttributeValue( self ):
        """ AutoField value should be updated if another AutoField value is changed """
        self.msg.show( "Info! Test 4 started", 'info', True )

        self.autoFieldManager.createAutoField(
            layer=self.layer, 
            fieldName=u'modified', 
            expression=u'\'now: \' + to_string("f1")'
        )

        self.layer.startEditing()
        self.layer.changeAttributeValue( 0, self.layer.fieldNameIndex( u'id' ), 1 )
        self.layer.commitChanges()
            
        feature = self.layer.getFeatures().next()
        self.assertEquals( feature['modified'], 'now: -74.4' )

    
    def test05FieldRemovedThenDisableAutoField( self ):
        """ AutoField should be disabled if its base field is removed """
        self.msg.show( "Info! Test 5 started", 'info', True )

        fieldIndex = self.layer.fieldNameIndex( u'f1' )
        self.layer.startEditing()
        self.layer.deleteAttribute( fieldIndex )
        self.layer.commitChanges()
        dictTmpProperties = self.readStoredSettings( self.layer, u'f1' )    
        
        self.assertFalse( dictTmpProperties['enabled'] )        
            

    def test06MissingFieldAddedThenEnableAutoField( self ):
        """ AutoField should be enabled if missing field is added """
        self.msg.show( "Info! Test 6 started", 'info', True )    

        self.layer.startEditing()
        self.layer.addAttribute( QgsField( 'f1', QVariant.Double, len=10, prec=2 ) )
        self.layer.commitChanges()
        
        dictTmpProperties = self.readStoredSettings( self.layer, u'f1' )    
        
        self.assertTrue( dictTmpProperties['enabled'] )   

        
    def test07LayerRemovedThenDisableAutoField( self ):
        """ AutoField should be disabled if its base layer is removed """
        self.msg.show( "Info! Test 7 started", 'info', True )

        QgsMapLayerRegistry.instance().removeMapLayer( self.layer.id() )

        # removeMapLayer deletes the underlying object, so create it again
        self.layer = QgsVectorLayer( self.layerPath, 'puntos', 'ogr' )   
        dictTmpProperties = self.readStoredSettings( self.layer, u'f1' )    
        
        self.assertFalse( dictTmpProperties['enabled'] )
        
     
    def test08MissingLayerAddedThenEnableAutoField( self ):
        """ AutoField should be enabled if missing layer is added """
        self.msg.show( "Info! Test 8 started", 'info', True )

        # test07 deletes the layer object, so create it again
        self.layer = QgsVectorLayer( self.layerPath, 'puntos', 'ogr' )
        QgsMapLayerRegistry.instance().addMapLayer( self.layer )  
        dictTmpProperties = self.readStoredSettings( self.layer, u'f1' )    
        
        self.assertTrue( dictTmpProperties['enabled'] )
           
        
    def test09RemoveAutoField( self ):
        """ QSettings should be deleted for the removed AutoField """
        self.msg.show( "Info! Test 9 started", 'info', True )

        # test07 deletes the layer object, so create it again
        self.layer = QgsVectorLayer( self.layerPath, 'puntos', 'ogr' )
        autoFieldId = self.autoFieldManager.buildAutoFieldId( self.layer, u'f1')
        self.autoFieldManager.removeAutoField( autoFieldId )
        dictTmpProperties = self.readStoredSettings( self.layer, u'f1' ) 
        
        self.assertEqual( dictTmpProperties, {'layer':"",'field':"",'expression':"",'layer2':"",'field2':"",'enabled':False} )
        

    @classmethod    
    def tearDownClass( self ):   
        self.msg.show( "Info! TearDown started", 'info', True )
    
        # test07 deletes the layer object, so create it again
        self.layer = QgsVectorLayer( self.layerPath, 'puntos', 'ogr' )

        #Remove AutoField modified
        autoFieldId = self.autoFieldManager.buildAutoFieldId( self.layer, u'modified' )
        self.autoFieldManager.removeAutoField( autoFieldId )

        #Delete field f1
        fieldIndex = self.layer.fieldNameIndex('f1')
        self.layer.dataProvider().deleteAttributes( [fieldIndex] )
        self.layer.updateFields()
        
        #Delete features from test layer
        fIds = self.layer.allFeatureIds()
        self.layer.dataProvider().deleteFeatures( fIds )
        
        #Remove layer from Registry
        QgsMapLayerRegistry.instance().removeMapLayer( self.layer.id() )
        self.msg.show( "Info! TearDown finished", 'info', True )

        QgsApplication.exitQgis()
Exemple #28
0
    def start_progress(self):
        import datetime
        start = datetime.datetime.now()
        # Check OS and dep
        if sys.platform == 'darwin':
            gdal_os_dep = '/Library/Frameworks/GDAL.framework/Versions/Current/Programs/'
        else:
            gdal_os_dep = ''

        if self.dlg.canvasButton.isChecked():
            # Map Canvas
            extentCanvasCRS = self.iface.mapCanvas()
            srs = extentCanvasCRS.mapSettings().destinationCrs()
            crs = str(srs.authid())
            # old_crs = osr.SpatialReference()
            # old_crs.ImportFromEPSG(int(crs[5:]))
            can_crs = QgsCoordinateReferenceSystem(int(crs[5:]))
            # can_wkt = extentCanvasCRS.mapRenderer().destinationCrs().toWkt()
            # can_crs = osr.SpatialReference()
            # can_crs.ImportFromWkt(can_wkt)
            # Raster Layer
            dem_layer = self.layerComboManagerDEM.currentLayer()
            dem_prov = dem_layer.dataProvider()
            dem_path = str(dem_prov.dataSourceUri())
            dem_raster = gdal.Open(dem_path)
            projdsm = osr.SpatialReference(wkt=dem_raster.GetProjection())
            projdsm.AutoIdentifyEPSG()
            projdsmepsg = int(projdsm.GetAttrValue('AUTHORITY', 1))
            dem_crs = QgsCoordinateReferenceSystem(projdsmepsg)

            # dem_wkt = dem_raster.GetProjection()
            # dem_crs = osr.SpatialReference()
            # dem_crs.ImportFromWkt(dem_wkt)
            if can_crs != dem_crs:
                extentCanvas = self.iface.mapCanvas().extent()
                extentDEM = dem_layer.extent()

                transformExt = QgsCoordinateTransform(can_crs, dem_crs)
                # transformExt = osr.CoordinateTransformation(can_crs, dem_crs)

                canminx = extentCanvas.xMinimum()
                canmaxx = extentCanvas.xMaximum()
                canminy = extentCanvas.yMinimum()
                canmaxy = extentCanvas.yMaximum()

                canxymin = transformExt.TransformPoint(canminx, canminy)
                canxymax = transformExt.TransformPoint(canmaxx, canmaxy)

                extDiffminx = canxymin[0] - extentDEM.xMinimum(
                )  # If smaller than zero = warning
                extDiffminy = canxymin[1] - extentDEM.yMinimum(
                )  # If smaller than zero = warning
                extDiffmaxx = canxymax[0] - extentDEM.xMaximum(
                )  # If larger than zero = warning
                extDiffmaxy = canxymax[0] - extentDEM.yMaximum(
                )  # If larger than zero = warning

                if extDiffminx < 0 or extDiffminy < 0 or extDiffmaxx > 0 or extDiffmaxy > 0:
                    QMessageBox.warning(
                        None,
                        "Warning! Extent of map canvas is larger than raster extent.",
                        "Change to an extent equal to or smaller than the raster extent."
                    )
                    return

        # Extent
        self.yMax = self.dlg.lineEditNorth.text()
        self.yMin = self.dlg.lineEditSouth.text()
        self.xMin = self.dlg.lineEditWest.text()
        self.xMax = self.dlg.lineEditEast.text()

        if not self.DSMoutputfile:
            QMessageBox.critical(None, "Error", "Specify a raster output file")
            return

        if self.dlg.checkBoxPolygon.isChecked() and not self.OSMoutputfile:
            QMessageBox.critical(None, "Error",
                                 "Specify an output file for OSM data")
            return

        # Acquiring geodata and attributes
        dem_layer = self.layerComboManagerDEM.currentLayer()
        if dem_layer is None:
            QMessageBox.critical(None, "Error",
                                 "No valid raster layer is selected")
            return
        else:
            provider = dem_layer.dataProvider()
            filepath_dem = str(provider.dataSourceUri())
        demRaster = gdal.Open(filepath_dem)
        dem_layer_crs = osr.SpatialReference()
        dem_layer_crs.ImportFromWkt(demRaster.GetProjection())
        self.dem_layer_unit = dem_layer_crs.GetAttrValue("UNIT")
        posUnits = [
            'metre', 'US survey foot', 'meter', 'm', 'ft', 'feet', 'foot',
            'ftUS', 'International foot'
        ]  # Possible units
        if not self.dem_layer_unit in posUnits:
            QMessageBox.critical(
                None, "Error",
                "Raster projection is not in metre or foot. Please reproject.")
            return

        polygon_layer = self.layerComboManagerPolygon.currentLayer()
        osm_layer = self.dlg.checkBoxOSM.isChecked()
        if polygon_layer is None and osm_layer is False:
            QMessageBox.critical(None, "Error",
                                 "No valid building height layer is selected")
            return
        elif polygon_layer:
            vlayer = QgsVectorLayer(polygon_layer.source(), "buildings", "ogr")
            fileInfo = QFileInfo(polygon_layer.source())
            polygon_ln = fileInfo.baseName()

            polygon_field = self.layerComboManagerPolygonField.currentField()
            idx = vlayer.fieldNameIndex(polygon_field)
            flname = vlayer.attributeDisplayName(idx)

            if idx == -1:
                QMessageBox.critical(
                    None, "Error",
                    "An attribute with unique fields must be selected")
                return

        ### main code ###

        self.dlg.progressBar.setRange(0, 5)

        self.dlg.progressBar.setValue(1)

        if self.dlg.checkBoxOSM.isChecked():
            # TODO replace osr.CoordinateTransformation with QgsCoordinateTransform
            dem_original = gdal.Open(filepath_dem)
            dem_wkt = dem_original.GetProjection()
            ras_crs = osr.SpatialReference()
            ras_crs.ImportFromWkt(dem_wkt)
            rasEPSG = ras_crs.GetAttrValue("PROJCS|AUTHORITY", 1)
            if self.dlg.layerButton.isChecked():
                old_crs = ras_crs
            elif self.dlg.canvasButton.isChecked():
                canvasCRS = self.iface.mapCanvas()
                outputWkt = canvasCRS.mapRenderer().destinationCrs().toWkt()
                old_crs = osr.SpatialReference()
                old_crs.ImportFromWkt(outputWkt)

            wgs84_wkt = """
            GEOGCS["WGS 84",
                DATUM["WGS_1984",
                    SPHEROID["WGS 84",6378137,298.257223563,
                        AUTHORITY["EPSG","7030"]],
                    AUTHORITY["EPSG","6326"]],
                PRIMEM["Greenwich",0,
                    AUTHORITY["EPSG","8901"]],
                UNIT["degree",0.01745329251994328,
                    AUTHORITY["EPSG","9122"]],
                AUTHORITY["EPSG","4326"]]"""

            new_crs = osr.SpatialReference()
            new_crs.ImportFromWkt(wgs84_wkt)

            transform = osr.CoordinateTransformation(old_crs, new_crs)

            minx = float(self.xMin)
            miny = float(self.yMin)
            maxx = float(self.xMax)
            maxy = float(self.yMax)
            lonlatmin = transform.TransformPoint(minx, miny)
            lonlatmax = transform.TransformPoint(maxx, maxy)

            if ras_crs != old_crs:
                rasTrans = osr.CoordinateTransformation(old_crs, ras_crs)
                raslonlatmin = rasTrans.TransformPoint(float(self.xMin),
                                                       float(self.yMin))
                raslonlatmax = rasTrans.TransformPoint(float(self.xMax),
                                                       float(self.yMax))
                #else:
                #raslonlatmin = [float(self.xMin), float(self.yMin)]
                #raslonlatmax = [float(self.xMax), float(self.yMax)]

                self.xMin = raslonlatmin[0]
                self.yMin = raslonlatmin[1]
                self.xMax = raslonlatmax[0]
                self.yMax = raslonlatmax[1]

            # Make data queries to overpass-api
            urlStr = 'http://overpass-api.de/api/map?bbox=' + str(
                lonlatmin[0]) + ',' + str(lonlatmin[1]) + ',' + str(
                    lonlatmax[0]) + ',' + str(lonlatmax[1])
            osmXml = urllib.urlopen(urlStr).read()
            #print urlStr

            # Make OSM building file
            osmPath = self.plugin_dir + '/temp/OSM_building.osm'
            osmFile = open(osmPath, 'w')
            osmFile.write(osmXml)
            if os.fstat(osmFile.fileno()).st_size < 1:
                urlStr = 'http://api.openstreetmap.org/api/0.6/map?bbox=' + str(
                    lonlatmin[0]) + ',' + str(lonlatmin[1]) + ',' + str(
                        lonlatmax[0]) + ',' + str(lonlatmax[1])
                osmXml = urllib.urlopen(urlStr).read()
                osmFile.write(osmXml)
                #print 'Open Street Map'
                if os.fstat(osmFile.fileno()).st_size < 1:
                    QMessageBox.critical(None, "Error",
                                         "No OSM data available")
                    return

            osmFile.close()

            outputshp = self.plugin_dir + '/temp/'

            osmToShape = gdal_os_dep + 'ogr2ogr --config OSM_CONFIG_FILE "' + self.plugin_dir + '/osmconf.ini" -skipfailures -t_srs EPSG:' + str(
                rasEPSG
            ) + ' -overwrite -nlt POLYGON -f "ESRI Shapefile" "' + outputshp + '" "' + osmPath + '"'

            if sys.platform == 'win32':
                si = subprocess.STARTUPINFO()
                si.dwFlags |= subprocess.STARTF_USESHOWWINDOW
                subprocess.call(osmToShape, startupinfo=si)
            else:
                os.system(osmToShape)

            driver = ogr.GetDriverByName('ESRI Shapefile')
            driver.DeleteDataSource(outputshp + 'lines.shp')
            driver.DeleteDataSource(outputshp + 'multilinestrings.shp')
            driver.DeleteDataSource(outputshp + 'other_relations.shp')
            driver.DeleteDataSource(outputshp + 'points.shp')

            osmPolygonPath = outputshp + 'multipolygons.shp'
            vlayer = QgsVectorLayer(osmPolygonPath, 'multipolygons', 'ogr')
            polygon_layer = vlayer
            fileInfo = QFileInfo(polygon_layer.source())
            polygon_ln = fileInfo.baseName()

            def renameField(srcLayer, oldFieldName, newFieldName):
                ds = gdal.OpenEx(srcLayer.source(),
                                 gdal.OF_VECTOR | gdal.OF_UPDATE)
                ds.ExecuteSQL('ALTER TABLE {} RENAME COLUMN {} TO {}'.format(
                    srcLayer.name(), oldFieldName, newFieldName))
                srcLayer.reload()

            vlayer.startEditing()
            renameField(vlayer, 'building_l', 'bld_levels')
            renameField(vlayer, 'building_h', 'bld_hght')
            renameField(vlayer, 'building_c', 'bld_colour')
            renameField(vlayer, 'building_m', 'bld_materi')
            renameField(vlayer, 'building_u', 'bld_use')
            vlayer.commitChanges()

            vlayer.startEditing()
            vlayer.dataProvider().addAttributes(
                [QgsField('bld_height', QVariant.Double, 'double', 3, 2)])
            vlayer.updateFields()
            bld_lvl = vlayer.fieldNameIndex('bld_levels')
            hght = vlayer.fieldNameIndex('height')
            bld_hght = vlayer.fieldNameIndex('bld_hght')
            bld_height = vlayer.fieldNameIndex('bld_height')

            bldLvlHght = float(self.dlg.doubleSpinBoxBldLvl.value())
            illegal_chars = string.ascii_letters + "!#$%&'*+^_`|~:" + " "
            counterNone = 0
            counter = 0
            #counterWeird = 0
            for feature in vlayer.getFeatures():
                if feature[hght]:
                    try:
                        #feature[bld_height] = float(re.sub("[^0-9]", ".", str(feature[hght])))
                        feature[bld_height] = float(
                            str(feature[hght]).translate(None, illegal_chars))
                    except:
                        counterNone += 1
                elif feature[bld_hght]:
                    try:
                        #feature[bld_height] = float(re.sub("[^0-9]", ".", str(feature[bld_hght])))
                        feature[bld_height] = float(
                            str(feature[bld_hght]).translate(
                                None, illegal_chars))
                    except:
                        counterNone += 1
                elif feature[bld_lvl]:
                    try:
                        #feature[bld_height] = float(re.sub("[^0-9]", "", str(feature[bld_lvl])))*bldLvlHght
                        feature[bld_height] = float(
                            str(feature[bld_lvl]).translate(
                                None, illegal_chars)) * bldLvlHght
                    except:
                        counterNone += 1
                else:
                    counterNone += 1
                vlayer.updateFeature(feature)
                counter += 1
            vlayer.commitChanges()
            flname = vlayer.attributeDisplayName(bld_height)
            counterDiff = counter - counterNone

        # Zonal statistics
        vlayer.startEditing()
        zoneStat = QgsZonalStatistics(vlayer, filepath_dem, "stat_", 1,
                                      QgsZonalStatistics.Mean)
        zoneStat.calculateStatistics(None)
        vlayer.dataProvider().addAttributes(
            [QgsField('height_asl', QVariant.Double)])
        vlayer.updateFields()
        e = QgsExpression('stat_mean + ' + flname)
        e.prepare(vlayer.pendingFields())
        idx = vlayer.fieldNameIndex('height_asl')

        for f in vlayer.getFeatures():
            f[idx] = e.evaluate(f)
            vlayer.updateFeature(f)

        vlayer.commitChanges()

        vlayer.startEditing()
        idx2 = vlayer.fieldNameIndex('stat_mean')
        vlayer.dataProvider().deleteAttributes([idx2])
        vlayer.updateFields()
        vlayer.commitChanges()

        self.dlg.progressBar.setValue(2)

        # Convert polygon layer to raster

        # Define pixel_size and NoData value of new raster
        pixel_size = self.dlg.spinBox.value()  # half picture size

        # Create the destination data source

        gdalrasterize = gdal_os_dep + 'gdal_rasterize -a ' + 'height_asl' + ' -te ' + str(self.xMin) + ' ' + str(self.yMin) + ' ' + str(self.xMax) + ' ' + str(self.yMax) +\
                        ' -tr ' + str(pixel_size) + ' ' + str(pixel_size) + ' -l "' + str(polygon_ln) + '" "' \
                         + str(polygon_layer.source()) + '" "' + self.plugin_dir + '/temp/clipdsm.tif"'

        # gdalclipdem = gdal_os_dep + 'gdalwarp -dstnodata -9999 -q -overwrite -te ' + str(self.xMin) + ' ' + str(self.yMin) + ' ' + str(self.xMax) + ' ' + str(self.yMax) +\
        #               ' -tr ' + str(pixel_size) + ' ' + str(pixel_size) + \
        #               ' -of GTiff ' + '"' + filepath_dem + '" "' + self.plugin_dir + '/temp/clipdem.tif"'

        # Rasterize
        if sys.platform == 'win32':
            si = subprocess.STARTUPINFO()
            si.dwFlags |= subprocess.STARTF_USESHOWWINDOW
            subprocess.call(gdalrasterize, startupinfo=si)
            # subprocess.call(gdalclipdem, startupinfo=si)
            gdal.Warp(self.plugin_dir + '/temp/clipdem.tif',
                      filepath_dem,
                      xRes=pixel_size,
                      yRes=pixel_size)
        else:
            os.system(gdalrasterize)
            # os.system(gdalclipdem)
            gdal.Warp(self.plugin_dir + '/temp/clipdem.tif',
                      filepath_dem,
                      xRes=pixel_size,
                      yRes=pixel_size)

        # Remove gdalwarp with gdal.Translate
        # bigraster = gdal.Open(filepath_dem)
        # bbox = (self.xMin, self.yMax, self.xMax, self.yMin)
        # gdal.Translate(self.plugin_dir + '/data/clipdem.tif', bigraster, projWin=bbox)

        self.dlg.progressBar.setValue(3)

        # Adding DSM to DEM
        # Read DEM
        dem_raster = gdal.Open(self.plugin_dir + '/temp/clipdem.tif')
        dem_array = np.array(dem_raster.ReadAsArray().astype(np.float))
        dsm_raster = gdal.Open(self.plugin_dir + '/temp/clipdsm.tif')
        dsm_array = np.array(dsm_raster.ReadAsArray().astype(np.float))

        indx = dsm_array.shape
        for ix in range(0, int(indx[0])):
            for iy in range(0, int(indx[1])):
                if int(dsm_array[ix, iy]) == 0:
                    dsm_array[ix, iy] = dem_array[ix, iy]

        if self.dlg.checkBoxPolygon.isChecked():
            vlayer.startEditing()
            idxHght = vlayer.fieldNameIndex('height_asl')
            idxBld = vlayer.fieldNameIndex('building')
            features = vlayer.getFeatures()
            #for f in vlayer.getFeatures():
            for f in features:
                geom = f.geometry()
                posUnitsMetre = ['metre', 'meter', 'm']  # Possible metre units
                posUnitsFt = [
                    'US survey foot', 'ft', 'feet', 'foot', 'ftUS',
                    'International foot'
                ]  # Possible foot units
                if self.dem_layer_unit in posUnitsMetre:
                    sqUnit = 1
                elif self.dem_layer_unit in posUnitsFt:
                    sqUnit = 10.76
                if int(geom.area()) > 50000 * sqUnit:
                    vlayer.deleteFeature(f.id())

                #if not f[idxHght]:
                #vlayer.deleteFeature(f.id())
                #elif not f[idxBld]:
                #vlayer.deleteFeature(f.id())
            vlayer.updateFields()
            vlayer.commitChanges()
            QgsVectorFileWriter.writeAsVectorFormat(vlayer,
                                                    str(self.OSMoutputfile),
                                                    "UTF-8", None,
                                                    "ESRI Shapefile")

        else:
            vlayer.startEditing()
            idx3 = vlayer.fieldNameIndex('height_asl')
            vlayer.dataProvider().deleteAttributes([idx3])
            vlayer.updateFields()
            vlayer.commitChanges()

        self.dlg.progressBar.setValue(4)

        # Save raster
        def saveraster(
            gdal_data, filename, raster
        ):  # gdal_data = raster extent, filename = output filename, raster = numpy array (raster to be saved)
            rows = gdal_data.RasterYSize
            cols = gdal_data.RasterXSize

            outDs = gdal.GetDriverByName("GTiff").Create(
                filename, cols, rows, int(1), gdal.GDT_Float32)
            outBand = outDs.GetRasterBand(1)

            # write the data
            outBand.WriteArray(raster, 0, 0)
            # flush data to disk, set the NoData value and calculate stats
            outBand.FlushCache()
            outBand.SetNoDataValue(-9999)

            # georeference the image and set the projection
            outDs.SetGeoTransform(gdal_data.GetGeoTransform())
            outDs.SetProjection(gdal_data.GetProjection())

        saveraster(dsm_raster, self.DSMoutputfile, dsm_array)

        # Load result into canvas
        rlayer = self.iface.addRasterLayer(self.DSMoutputfile)

        # Trigger a repaint
        if hasattr(rlayer, "setCacheImage"):
            rlayer.setCacheImage(None)
        rlayer.triggerRepaint()

        self.dlg.progressBar.setValue(5)

        #runTime = datetime.datetime.now() - start

        if self.dlg.checkBoxOSM.isChecked():
            QMessageBox.information(
                self.dlg, 'DSM Generator', 'Operation successful! ' +
                str(counterDiff) + ' building polygons out of ' +
                str(counter) + ' contained height values.')
            #self.iface.messageBar().pushMessage("DSM Generator. Operation successful! " + str(counterDiff) + " buildings out of " + str(counter) + " contained height values.", level=QgsMessageBar.INFO, duration=5)
        else:
            #self.iface.messageBar().pushMessage("DSM Generator. Operation successful!", level=QgsMessageBar.INFO, duration=5)
            QMessageBox.information(self.dlg, 'DSM Generator',
                                    'Operation successful!')

        self.resetPlugin()
Exemple #29
0
    def loadData(self, resultFile, chunkId):
        """ Load data to the map """

        if isMimeTypeVector(self.mimeType, True) != None:
            # Memory layer:
            geometryTypes = [
                "Point", "LineString", "Polygon", "Unknown", "NoGeometry"
            ]
            vlayer = QgsVectorLayer(resultFile, "chunk", "ogr")

            if self.__bFirstChunk:
                self.__bFirstChunk = False
                self.__geometryType = geometryTypes[vlayer.geometryType()]
                self.__bGeomMulti = vlayer.wkbType() in [4, 5, 6, 11, 12, 13]
                self.__memoryLayer = QgsVectorLayer(self.__geometryType,
                                                    "Streamed data", "memory")
                self.__memoryLayer.dataProvider().addAttributes(
                    list(vlayer.pendingFields().values()))
                self.__memoryLayer.updateFieldMap()

            provider = vlayer.dataProvider()
            allAttrs = provider.attributeIndexes()
            vlayer.select(allAttrs)

            # Visualize temporal geometries during the downloading process
            # Don't add temporal geometries if last chunk
            if self.DEBUG:  # fix_print_with_import
                # fix_print_with_import
                print("Loaded chunkId:", chunkId)
            res = self.__memoryLayer.dataProvider().addFeatures(
                [feat for feat in vlayer])
            self.__deliveredChunks += 1

            if not self.allChunksDelivered():
                inFeat = QgsFeature()
                inGeom = QgsGeometry()
                self.createTempGeometry(chunkId, self.__geometryType)
                while provider.nextFeature(inFeat):
                    inGeom = inFeat.geometry()
                    featList = self.extractAsSingle(
                        self.__geometryType,
                        inGeom) if self.__bGeomMulti else [inGeom]
                    for geom in featList:
                        self.addTempGeometry(chunkId, self.__geometryType,
                                             geom)
            else:
                self.finishLoading()

        # Raster data
        elif isMimeTypeRaster(self.mimeType, True) != None:
            # We can directly attach the new layer
            if self.__bFirstChunk:
                self.__bFirstChunk = False
                self.__groupIndex = self.__legend.addGroup("Streamed-raster")

            rLayer = QgsRasterLayer(resultFile, "raster_" + str(chunkId))
            bLoaded = QgsProject.instance().addMapLayer(rLayer)
            self.stretchRaster(rLayer)
            self.__legend.moveLayer(rLayer, self.__groupIndex + 1)

            self.__deliveredChunks += 1

            if self.allChunksDelivered():
                self.finishLoading()
Exemple #30
0
class MdbLayer:
    """ Pretend we are a data provider """

    dirty = False
    doing_attr_update = False

    def __init__(self,
                 mdb_path,
                 mdb_table,
                 mdb_columns='*',
                 mdb_hide_columns=''):
        """ Initialize the layer by reading a Access mdb file, creating a memory layer, and adding records to it

        :param mdb_path: Path to the database you wish to access.
        :type mdb_path: str

        :param mdb_table: Table name of the table to open.
        :type mdb_table: str

        :param mdb_columns: Comma separated list of columns to use for this layer. Defaults to all (*).
        :type mdb_columns: str

        :param mdb_hide_columns: Comma separated list of columns to hide for this layer.
            Use in combination with mdb_columns='*'
        :type mdb_hide_columns: str
        """

        self.mdb_path = mdb_path
        self.mdb_table = mdb_table
        self.mdb_columns = mdb_columns
        self.mdb_hide_columns = [
            x.strip() for x in mdb_hide_columns.split(",")
        ]
        self.record_count = 0
        self.progress = object
        self.old_pk_values = {}
        self.read_only = READ_ONLY

        # connect to the database
        constr = "DRIVER={Microsoft Access Driver (*.mdb, *.accdb)};FIL={MS Access};DBQ=" + self.mdb_path
        try:
            conn = pyodbc.connect(constr, timeout=3)
            self.cur = conn.cursor()
        except Exception as e:
            logger("Couldn't connect. Error: {}".format(e))
            return

        # determine primary key(s) if table
        table = self.cur.tables(table=self.mdb_table).fetchone()
        if table.table_type == 'TABLE':
            self.pk_cols = [
                row[8] for row in self.cur.statistics(self.mdb_table)
                if row[5] == 'PrimaryKey'
            ]
        elif table.table_type == 'VIEW':
            self.pk_cols = []
        else:
            logger("Database object type '{}' not supported".format(
                table.table_type))
            return

        # get record count
        try:
            self.cur.execute("SELECT COUNT(*) FROM {}".format(self.mdb_table))
            self.record_count = self.cur.fetchone()[0]
        except Exception as e:
            self.iface.messageBar().pushWarning(
                "MDB Layer",
                "There's a problem with this table or query. Error: {}".format(
                    e))
            return

        # get records from the table
        sql = "SELECT {} FROM {}".format(self.mdb_columns, self.mdb_table)
        self.cur.execute(sql)

        # create a dictionary with fieldname:type
        # QgsField only supports: String / Int / Double
        # falling back to string for: bytearray, bool, datetime.datetime, datetime.date, datetime.time, ?
        field_name_types = []
        field_type_map = {
            str: QVariant.String,
            unicode: QVariant.String,
            int: QVariant.Int,
            float: QVariant.Double
        }

        # create a list with a QgsFields for every db column
        for column in self.cur.description:
            if column[0] not in self.mdb_hide_columns:
                if column[1] in field_type_map:
                    field_name_types.append(
                        QgsField(column[0], field_type_map[column[1]]))
                else:
                    field_name_types.append(
                        QgsField(column[0], QVariant.String))
                    self.read_only = True  # no reliably editing for other data types

        # create the layer, add columns
        self.lyr = QgsVectorLayer("None", 'mdb_' + mdb_table, 'memory')
        provider = self.lyr.dataProvider()
        provider.addAttributes(field_name_types)
        self.lyr.updateFields()

        # add the records
        self.add_records()

        # set read only or make connections/triggers
        # if there are no primary keys there is no way to edit
        if self.read_only or not self.pk_cols:
            self.lyr.setReadOnly()
        else:
            self.lyr.beforeCommitChanges.connect(self.before_commit)

        # add the layer the map
        QgsMapLayerRegistry.instance().addMapLayer(self.lyr)

    def add_records(self):
        """ Add records to the memory layer by stepping through the query result """

        self.setup_progressbar(
            "Loading {} records from table {}...".format(
                self.record_count, self.lyr.name()), self.record_count)

        provider = self.lyr.dataProvider()
        for i, row in enumerate(self.cur):
            feature = QgsFeature()
            feature.setGeometry(QgsGeometry())
            feature.setAttributes([flds for flds in row])
            provider.addFeatures([feature])
            self.update_progressbar(i)

        iface.messageBar().clearWidgets()
        iface.messageBar().pushMessage("Ready",
                                       "{} records added to {}".format(
                                           str(self.record_count),
                                           self.lyr.name()),
                                       level=QgsMessageBar.INFO)

    def before_commit(self):
        """" Just before a definitive commit (update to the memory layer) try
         updating the database"""
        # fixme: implement rollback on db fail

        # Update attribute values
        # ---------------------------------------------------------------------
        # changes: { fid: {pk1: value, pk2: value, etc}}
        changes = self.lyr.editBuffer().changedAttributeValues()
        field_names = [field.name() for field in self.lyr.pendingFields()]
        row_count = 0

        for fid, attributes in changes.iteritems():
            feature = self.lyr.dataProvider().getFeatures(
                QgsFeatureRequest(fid)).next()
            fields = [field_names[att_id] + " = (?)" for att_id in attributes]
            params = tuple(attributes.values())

            # assemble SQL query
            where_clause, params = self.get_where_clause(feature, params)
            sql = "UPDATE {} SET {}".format(self.mdb_table, ", ".join(fields))
            sql += where_clause

            logger(sql + " : " + str(params))
            self.cur.execute(sql, params)
            row_count += self.cur.rowcount

        self.cur.commit()
        logger("changed:  " + str(row_count))

        # Delete features: 'DELETE * FROM spoor WHERE pk = id
        # ---------------------------------------------------------------------
        row_count = 0
        fids = self.lyr.editBuffer().deletedFeatureIds()
        for feature in self.lyr.dataProvider().getFeatures(
                QgsFeatureRequest().setFilterFids(fids)):

            where_clause, params = self.get_where_clause(feature)

            # assemble SQL query
            sql = "DELETE * FROM {}".format(self.mdb_table)
            sql += where_clause

            logger(sql + " : " + str(params))
            self.cur.execute(sql, params)
            row_count += self.cur.rowcount

        self.cur.commit()
        logger("deleted:  " + str(row_count))

        # Add features
        # ---------------------------------------------------------------------
        # fixme: implement

    def get_where_clause(self, feature, params=()):
        """ Return where_clause with pk fields and updated params"""
        where_clause = []
        for pk in self.pk_cols:
            params += (feature[pk], )
            where_clause.append(pk + " = (?)")

        where_clause = " WHERE " + " AND ".join(where_clause)
        return where_clause, params

    def setup_progressbar(self, message, maximum):
        if not SHOW_PROGRESSBAR: return

        progress_message_bar = iface.messageBar().createMessage(message)
        self.progress = QProgressBar()
        self.progress.setMaximum(maximum)
        self.progress.setAlignment(Qt.AlignLeft | Qt.AlignVCenter)
        progress_message_bar.layout().addWidget(self.progress)
        iface.messageBar().pushWidget(progress_message_bar,
                                      iface.messageBar().INFO)

    def update_progressbar(self, progress):
        if SHOW_PROGRESSBAR:
            self.progress.setValue(progress)
Exemple #31
0
def open_file(
    dialog=None,
    osm_file=None,
    output_geom_types=None,
    white_list_column=None,
    output_format=None,
    layer_name="OsmFile",
    config_outputs=None,
    output_dir=None,
    prefix_file=None,
):
    """
    open an osm file
    """
    outputs = get_outputs(output_dir, output_format, prefix_file, layer_name)

    # Parsing the file
    osm_parser = OsmParser(osm_file=osm_file, layers=output_geom_types, white_list_column=white_list_column)

    osm_parser.signalText.connect(dialog.set_progress_text)
    osm_parser.signalPercentage.connect(dialog.set_progress_percentage)
    layers = osm_parser.parse()

    # Finishing the process with geojson or shapefile
    num_layers = 0
    if output_format == "shape":
        dialog.set_progress_text(tr("QuickOSM", u"From GeoJSON to Shapefile"))

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

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

            # Transforming the vector file
            osm_geometries = {
                "points": QGis.WKBPoint,
                "lines": QGis.WKBLineString,
                "multilinestrings": QGis.WKBMultiLineString,
                "multipolygons": QGis.WKBMultiPolygon,
            }
            geojson_layer = QgsVectorLayer(item["geojsonFile"], "temp", "ogr")

            encoding = get_default_encoding()
            if output_format == "shape":
                writer = QgsVectorFileWriter(
                    outputs[layer],
                    encoding,
                    geojson_layer.pendingFields(),
                    osm_geometries[layer],
                    geojson_layer.crs(),
                    "ESRI Shapefile",
                )
            else:
                writer = QgsVectorFileWriter(
                    outputs[layer],
                    encoding,
                    geojson_layer.pendingFields(),
                    osm_geometries[layer],
                    geojson_layer.crs(),
                    "GeoJSON",
                )

            for f in geojson_layer.getFeatures():
                writer.addFeature(f)

            del writer

            # Loading the final vector file
            new_layer = QgsVectorLayer(outputs[layer], final_layer_name, "ogr")

            # Try to set styling if defined
            if config_outputs and config_outputs[layer]["style"]:
                new_layer.loadNamedStyle(config_outputs[layer]["style"])
            else:
                # Loading default styles
                if layer == "multilinestrings" or layer == "lines":
                    if "colour" in item["tags"]:
                        new_layer.loadNamedStyle(
                            join(dirname(dirname(abspath(__file__))), "styles", layer + "_colour.qml")
                        )

            # Add action about OpenStreetMap
            actions = new_layer.actions()
            actions.addAction(
                QgsAction.OpenUrl,
                "OpenStreetMap Browser",
                "http://www.openstreetmap.org/browse/" '[% "osm_type" %]/[% "osm_id" %]',
                False,
            )
            actions.addAction(
                QgsAction.GenericPython,
                "JOSM",
                "from QuickOSM.CoreQuickOSM.Actions import Actions;" 'Actions.run("josm","[% "full_id" %]")',
                False,
            )
            actions.addAction(
                QgsAction.OpenUrl,
                "User default editor",
                "http://www.openstreetmap.org/edit?" '[% "osm_type" %]=[% "osm_id" %]',
                False,
            )

            for link in ["url", "website", "wikipedia", "ref:UAI"]:
                if link in item["tags"]:
                    link = link.replace(":", "_")
                    actions.addAction(
                        QgsAction.GenericPython,
                        link,
                        "from QuickOSM.core.actions import Actions;"
                        'Actions.run("' + link + '","[% "' + link + '" %]")',
                        False,
                    )

            if "network" in item["tags"] and "ref" in item["tags"]:
                actions.addAction(
                    QgsAction.GenericPython,
                    "Sketchline",
                    "from QuickOSM.core.actions import Actions;"
                    'Actions.run_sketch_line("[% "network" %]","[% "ref" %]")',
                    False,
                )

            # Add index if possible
            if output_format == "shape":
                new_layer.dataProvider().createSpatialIndex()

            QgsMapLayerRegistry.instance().addMapLayer(new_layer)
            num_layers += 1

    return num_layers
Exemple #32
0
    def ECOIDF(self):

        #Cria a lista da relacão tempo em horas
        relacaoTempo = self.dadosUsuario()[2]
        prec_line = self.dadosUsuario()[0]
        lat_line = self.dadosUsuario()[4]
        long_line = self.dadosUsuario()[5]
        transformacaoHoras = []
        for i in relacaoTempo:
            transformacaoHoras.append(i / 60)

        # Cria uma layer tipo ponto, já em WGS84
        point_layer = QgsVectorLayer("Point?crs=EPSG:4326", "coordenada",
                                     "memory")
        provider = point_layer.dataProvider()
        # Adiciona primeiro ponto
        pt = QgsFeature()
        point = QgsPoint(float(lat_line), float(long_line))
        pt.setGeometry(QgsGeometry.fromPoint(point))
        provider.addFeatures([pt])
        # Diz para o vetor ponto para buscar mudanças com o provedor
        point_layer.updateExtents()
        #Adiciona o ponto ao mapa
        QgsMapLayerRegistry.instance().addMapLayer(point_layer)
        #point_layer é o ponto criado

        #Encontra o caminho do plugin em cada computador
        plugin_path = os.path.dirname(os.path.realpath(__file__))
        #Abrir o shape das Isozona que está na pasta do plugin
        pol_layer = QgsVectorLayer(plugin_path, "isozonas", "ogr")
        #Adiciona a Layer isozonas ao mapa (NÃO É NECESSÁRIO)
        #QgsMapLayerRegistry.instance().addMapLayer(pol_layer)

        #Extrai a feição do shape das Isozonas e cruza com o shape do ponto das coordenadas
        #Como resultado a variável Isozona_zone_layer com a zona extraída
        ebl_out = processing.runalg('qgis:extractbylocation', pol_layer,
                                    point_layer, u'intersects', 0, None)
        if ebl_out is None:
            ebl_out = processing.runalg('qgis:extractbylocation', pol_layer,
                                        point_layer, u'intersects', None)
        Isozona_zone = ebl_out['OUTPUT']
        Isozona_zone_layer = QgsVectorLayer(Isozona_zone, "Isozona_zone",
                                            "ogr")
        #Adiciona a Layer Isozona_zone_layer ao mapa
        QgsMapLayerRegistry.instance().addMapLayers([Isozona_zone_layer])

        #Salva em txt os campos da layer extraída separado por vírgula
        filename = self.dadosUsuario()[3] + '\dadosIsozona.txt'
        output_file = open(filename, 'w')
        #Escreve o valor de precipitação e duração inseridos pelo usuário
        output_file.write("%s\n" % (prec_line))
        #Escreve os valores da feição do shape das isozonas
        Isozona_fields = Isozona_zone_layer.pendingFields()
        Isozona_fieldnames = [field.name() for field in Isozona_fields]
        for f in Isozona_zone_layer.getFeatures():
            line = '\n'.join(unicode(f[x]) for x in Isozona_fieldnames)
            unicode_line = line.encode('utf-8')
            output_file.write(unicode_line)
            output_file.close()

        #Abre o arquivo txt para leitura
        output_file = open(filename, 'r')
        #Separa os valores em lista
        porcentagemChuva = output_file.read().split('\n')
        #Remove os primeiros valores da lista
        del porcentagemChuva[0:3]
        #Transforma a lista em float
        floatChuva = []
        for i in porcentagemChuva:
            floatChuva.append(float(i))
        #Multiplica a precipitação inserida pelo usuário pelos valores da porcentagem da chuva
        chuvaFinal = []
        for i in floatChuva:
            chuvaFinal.append(i * (float(prec_line) / 100))

        #Cria a lista da intensidade dividindo a precipitação pela relacaoTempo em horas
        intensidade = [
            chuvaFinali / transformacaoHorasi
            for chuvaFinali, transformacaoHorasi in zip(
                chuvaFinal, transformacaoHoras)
        ]

        #self.ECOIDF()[0] e self.ECOIDF()[1]
        return chuvaFinal, intensidade
Exemple #33
0
from qgis.core import QGis, QgsMapLayerRegistry, QgsFeature, QgsVectorLayer


def touchesLayer(point, exclude_id, layer):
    for feature in layer.getFeatures():
        vertex_list = feature.geometry().asPolyline()
        if feature.id() != exclude_id and point.compare(
                vertex_list[0]) or point.compare(vertex_list[-1]):
            return True
    return False


intersectionLayer = QgsVectorLayer("Point?crs=epsg:3857&field=rif_id:integer",
                                   "nodi", "memory")
if layer.geometryType() == QGis.Line:
    features = []
    for feature in layer.getFeatures():
        vertex_list = feature.geometry().asPolyline()
        for node in (vertex_list[0], vertex_list[-1]):
            if touchesLayer(node, feature.id(), layer):
                new_feature = QgsFeature(intersectionLayer.pendingFields())
                new_feature.setAttribute('rif_id', feature.id())
                new_feature.setGeometry(QgsGeometry.fromPoint(node))
                features.append(new_feature)
    intersectionLayer.dataProvider().addFeatures(features)
    QgsMapLayerRegistry.instance().addMapLayer(intersectionLayer)
    def run(self):
        """Run method that performs all the real work"""
        # show the dialog
        self.dlg.show()
        # Run the dialog event loop
        result = self.dlg.exec_()
        GTFSDir = self.dlg.GTFSLocation.text()
        StopsFile = self.dlg.StopsFile.text()
        StopsShapefileName = self.dlg.StopsShapefileName.text()
        #####output_shp = 
        ##output_file = open(filename, 'w')
        # See if OK was pressed
        if result:
            print "one"
            stop_id = "UNK"
            stop_name = "UNK"
            stop_lat = "UNK"
            stop_lon = "UNK"
            c_stop_id = 0
            c_stop_name = 0
            c_stop_lat = 0
            c_stop_lon = 0
            counter = 0
            text_file = os.path.join(GTFSDir, StopsFile)
            #text_file = 'C:/UWGIS/Geog569/Data/Test/stops.txt' 
            ##
            EPSG_code = 4326
            EPSG_code_WM = 3857
            StopsShapefilePath = os.path.join(GTFSDir, StopsShapefileName + ".shp")
            StopsShapefilePathWM = os.path.join(GTFSDir, StopsShapefileName + "WM.shp")
            ###export_shp = "C:/UWGIS/Geog569/Data/Test/stoptest1.shp"
            spatialReference = osgeo.osr.SpatialReference() #will create a spatial reference locally to tell the system what the reference will be
            spatialReference.ImportFromEPSG(int(EPSG_code)) #here we define this reference to be the EPSG code
            driver = osgeo.ogr.GetDriverByName('ESRI Shapefile') # will select the driver for our shp-file creation.
            shapeData = driver.CreateDataSource(StopsShapefilePath) #so there we will store our data
            layer = shapeData.CreateLayer('layer', spatialReference, osgeo.ogr.wkbPoint) #this will create a corresponding layer for our data with given spatial information.
            layer_defn = layer.GetLayerDefn() # gets parameters of the current shapefile
            index = 0
            spatialReferenceWM = osgeo.osr.SpatialReference() #will create a spatial reference locally to tell the system what the reference will be			
            spatialReferenceWM.ImportFromEPSG(int(EPSG_code_WM)) #here we define this reference to be the EPSG code
            driver = osgeo.ogr.GetDriverByName('ESRI Shapefile') # will select the driver for our shp-file creation.
            shapeDataWM = driver.CreateDataSource(StopsShapefilePathWM) #so there we will store our data
            layerWM = shapeDataWM.CreateLayer('layerWM', spatialReferenceWM, osgeo.ogr.wkbPoint) #this will create a corresponding layer for our data with given spatial information.
            layerWM_defn = layerWM.GetLayerDefn() # gets parameters of the current shapefile
            index = 0
			###print "two"
            fieldnames = []
            with open(text_file, 'r') as f:
                first_line = f.readline()
            fl = first_line.split(",")
            for fn in fl:
                fieldnames.append(fn)
            for f in fl:
                #print f
                if f == "stop_id":
                    c_stop_id = counter
                if f == "stop_name":
                    c_stop_name = counter
                if f == "stop_lat":
                    c_stop_lat = counter
                    print "c_stop_lat"
                    print c_stop_lat
                if f == "stop_lon":
                    c_stop_lon = counter
                new_field = ogr.FieldDefn(f, ogr.OFTString) #we will create a new field with the content of our header
                print "three"
                layer.CreateField(new_field)
                ##layerWM.CreateField(new_field)
                counter = counter + 1
            print "four"
            stop_layer = QgsVectorLayer(StopsShapefilePath, "stop_layer", "ogr")
            stop_layer.startEditing()
            #stop_layer = iface.addVectorLayer(StopsShapefilePath, "stop_layer", "ogr")
            if not stop_layer:
                print "Layer failed to load!"
            ##for line in text_file:
            with open(text_file, 'r') as f:
                lines = f.readlines()
                #print "len(line)"
                #print len(line)
                #l = str(line).split(",")
                #print line
                for line in lines:
                    #print line
                    l = str(line).split(",")
                    #print l[0]
                    #print "c_stop_lat, c_stop_lon"					
                    #print c_stop_lat, c_stop_lon
                    if l[c_stop_id] != "stop_id":
                        stop_id = l[c_stop_id]
                    if l[c_stop_name] != "stop_name":
                        stop_name = l[c_stop_name]
                    if l[c_stop_lat] != "stop_lat":
                        stop_lat = float(l[c_stop_lat])
                    if l[c_stop_lon] != "stop_lon":
                        stop_lon = float(l[c_stop_lon])
                        ##DICT_stop_lon [l[c_stop_id]] = l[c_stop_lon]
                    ##print(stop_lat, stop_lon)
                    if type(stop_lat) == float:
                        if type (stop_lon) == float:
                    	    print(stop_lat, stop_lon)
                    	    caps = stop_layer.dataProvider().capabilities()
                    	    caps_string = stop_layer.dataProvider().capabilitiesString()
                    	    print caps_string
                    	    # Check if a particular capability is supported:
                    	    ##caps & QgsVectorDataProvider.DeleteFeatures
                    	    # Print 2 if DeleteFeatures is supported
                    	    #caps = layer.dataProvider().capabilities()
                    	    if caps & QgsVectorDataProvider.AddFeatures:
                    	        feat = QgsFeature(stop_layer.pendingFields())
                    	        #feat.setAttributes([0, 'hello'])
                    	        #feat.setAttributes(['stop_id', str(stop_id)])
                    	        #feat.setAttributes([0, 'hello'])
                    	        # Or set a single attribute by key or by index:
                    	        #feat.setAttribute('stop_id', stop_id)
                    	        feat.setAttribute(2, 'hello')
                    	        feat.setGeometry(QgsGeometry.fromPoint(QgsPoint(float(stop_lon), float(stop_lat))))
                    	        (res, outFeats) = stop_layer.dataProvider().addFeatures([feat])
                    	        top_layer.commitChanges()
Exemple #35
0
class NewObject(QDockWidget, Ui_NewObject):
    def __init__(self, iface, objecttype, project, lang_dict, lang):
        # setup UI and connect the buttons
        QDockWidget.__init__(self)
        self.iface = iface
        self.setupUi(self)

        # get variable references from "GeODinQGIS_Main"
        self.obj_type = objecttype.name
        self.loctype = objecttype.gen_desc
        self.path = project.parent.filepath
        self.dbtype = project.parent.options["connection"]
        self.alias = project.parent.name
        self.project_names = project.name
        self.proj_ID = project.id
        self.plugin_dir = os.path.dirname(__file__)
        self.saveFileFolder = self.plugin_dir + "/tmp/"

        self.lgr = logging.getLogger('GeODinQGIS.NewObject')

        self.lang_dict = lang_dict
        self.lang = lang

        # select whole table row instead of single cell
        self.coord_tab.setSelectionBehavior(QAbstractItemView.SelectRows)

        # some empty lists to store coordinates from map canvas
        self.x_list = []
        self.y_list = []
        self.id_list = []
        self.rows = []
        self.attrs_list = []

        self.shortname = None
        self.easting = None
        self.northing = None

        # reference to the map canvas
        self.canvas = self.iface.mapCanvas()

        # define button signals for vector file management
        self.btn_createshp.clicked.connect(self.createVector)
        self.btn_openshp.clicked.connect(self.openVector)
        self.btn_dragshp.clicked.connect(self.dragVector)

        # set behavior to load an existing vector file from layer registry to coordinate table
        self.open = False
        self.drag = False

        #self.btn_dragshp.setEnabled(False)
        self.btn_geodin.setEnabled(False)
        self.btn_del.setEnabled(False)
        self.btn_desel.setEnabled(False)
        self.cmb_short.setEnabled(True)

        # connect buttons to their functions
        self.btn_geodin.clicked.connect(self.geodin)
        self.btn_close.clicked.connect(self.close)
        self.btn_del.clicked.connect(self.delete)
        self.btn_desel.clicked.connect(self.deselect)
        self.cmb_short.currentIndexChanged.connect(self.shortNameChoose)
        self.cmb_east.currentIndexChanged.connect(self.eastingChoose)
        self.cmb_north.currentIndexChanged.connect(self.northingChoose)

        # manage button icons
        self.btn_createshp.setIcon(
            QIcon(":\plugins\GeODinQGIS\icons\point_create_n.png"))
        self.btn_openshp.setIcon(
            QIcon(":\plugins\GeODinQGIS\icons\point_add_n.png"))
        self.btn_dragshp.setIcon(
            QIcon(":\plugins\GeODinQGIS\icons\point_drag_n.png"))
        self.btn_del.setIcon(QIcon(":\plugins\GeODinQGIS\icons\delete.png"))
        self.btn_geodin.setIcon(QIcon(":\plugins\GeODinQGIS\icons\logo.png"))
        self.btn_desel.setIcon(QIcon(":\plugins\GeODinQGIS\icons\minus.png"))
        self.btn_del.setIconSize(QSize(24, 24))
        self.btn_geodin.setIconSize(QSize(24, 24))
        self.btn_desel.setIconSize(QSize(24, 24))
        self.btn_createshp.setIconSize(QSize(24, 24))
        self.btn_openshp.setIconSize(QSize(24, 24))
        self.btn_dragshp.setIconSize(QSize(24, 24))

        # manage tool tips
        createshp = self.lang_dict.getWord(self.lang, "Create new shape file")
        loadshp = self.lang_dict.getWord(self.lang,
                                         "Load shape file from file system")
        dragshp = self.lang_dict.getWord(self.lang,
                                         "Load shape file from layers panel")

        deleteRow = self.lang_dict.getWord(self.lang, "Delete selected rows")
        deselectRow = self.lang_dict.getWord(self.lang, "Deselect rows")
        openGeodin = self.lang_dict.getWord(self.lang, "Import to GeODin")

        self.btn_createshp.setToolTip(createshp)
        self.btn_openshp.setToolTip(loadshp)
        self.btn_dragshp.setToolTip(dragshp)

        self.btn_del.setToolTip(deleteRow)
        self.btn_desel.setToolTip(deselectRow)
        self.btn_geodin.setToolTip(openGeodin)

        # # set headers for child nodes
        # if self.obj_type == "All Objects":
        # self.le_obtyp.setText("All Objects")

        # else:
        # self.le_obtyp.setText(self.obj_type)

        self.delete = False
        self.editMode = False

        # clear coordinate table
        self.coord_tab.setRowCount(0)

        # decimal places
        self.dp = 8

        #
        self.coord_tab.itemChanged.connect(self.Changed)
        #self.coord_tab.cellClicked.connect(self.clicked)

        self.coord_tab.itemSelectionChanged.connect(self.selectionChanged)

        self.root = QgsProject.instance().layerTreeRoot()

    def dragVector(self):
        # open layer list table to drag shape into coordinate table
        sel = DragShp(self.iface, self.lang_dict, self.lang)
        sel.show()
        sel.exec_()

        # set open file name for shape (filePath)
        # add shape to coordinate table
        if sel.accepted:
            self.drag = True
            self.openName = sel.filePath
            self.loadVector()

    def onremovedChildren(self, node, indexFrom, indexTo):
        # execute if a layer has been removed from QGIS layer list
        # ,ap over layer ID's in layer list
        ids = self.root.findLayerIds()

        # deleted, if layer ID cannot be found in layer list
        if self.layerID not in ids:
            # if layer was loaded in coordinate table, empty it
            self.coord_tab.setRowCount(0)

    def Started(self):
        # if editing mode has been toggled on
        self.editMode = True
        self.cmb_short.setEnabled(False)
        # table cell is only editable if has been double clicked
        if not QAbstractItemView == None:
            self.coord_tab.setEditTriggers(QAbstractItemView.DoubleClicked)

        # if one or more item have been selected, deletion allowed
        if len(self.coord_tab.selectedItems()) > 0:
            self.btn_del.setEnabled(True)

    def Stopped(self):
        # turn edit triggers and deletion off
        self.editMode = False
        if not QAbstractItemView == None:
            self.coord_tab.setEditTriggers(QAbstractItemView.NoEditTriggers)

        self.btn_del.setEnabled(False)
        self.cmb_short.setEnabled(True)

        if len(self.cmb_short.currentText()) > 0:
            self.shortname = self.cmb_short.currentText()
        else:
            self.shortname = None

        if len(self.cmb_east.currentText()) > 0:
            self.easting = self.cmb_east.currentText()
        else:
            self.easting = None

        if len(self.cmb_north.currentText()) > 0:
            self.northing = self.cmb_north.currentText()
        else:
            self.northing = None

        # read attribute table and insert items into coordinate table
        self.insertItem()

        self.v_points.updateFields()
        self.selectionChanged()

    def Changed(self, item):
        # if item has been changed in coordinate table
        # editing mode is required
        # print self.coord_tab.currentColumn()
        # print self.coord_tab.currentRow()
        if self.v_points.isEditable():
            # print self.coord_tab.currentItem()
            # print self.coord_tab.currentColumn()
            # print self.coord_tab.currentRow()
            # coordinate which has been edited (only one at a time)
            coord_edit = float(self.coord_tab.currentItem().text())

            # change coordinate equals "coord_edit"
            if self.coord_tab.currentColumn() == 1:
                x = coord_edit
                y = float(self.coord_tab.item(self.rows[0], 2).text())

            elif self.coord_tab.currentColumn() == 2:
                x = float(self.coord_tab.item(self.rows[0], 1).text())
                y = coord_edit

            # QGIS internal functions
            # move vertex to new coordinates
            ch = QgsVectorLayerEditUtils(self.v_points)
            ch.moveVertex(x, y, self.rows[0], 0)

    def selectionChanged(self):
        #its = self.coord_tab.selectedItems()
        # write list with indices of all selected rows
        lines = self.coord_tab.selectionModel().selectedRows()

        self.btn_desel.setEnabled(True)

        # new empty list
        # loop over lines and add to rowlist
        # sort reversed
        self.rows = []
        for idx in lines:
            self.rows.append(idx.row())

        self.rows.sort(reverse=True)

        if len(self.rows) == 1:
            # get coordinates from selection
            self.coord_x = self.coord_tab.item(self.rows[0], 1).text()
            self.coord_y = self.coord_tab.item(self.rows[0], 2).text()
            self.name = self.coord_tab.item(self.rows[0], 0).text()
            self.btn_geodin.setEnabled(True)
        else:
            self.btn_geodin.setEnabled(False)

        self.sel_x = []
        self.sel_y = []
        self.sel_id = []
        self.sel_attrs = []

        for i in self.rows:
            id = self.id_list[i]
            self.sel_id.append(id)
            x_coord = self.x_list[i]
            self.sel_x.append(x_coord)
            y_coord = self.y_list[i]
            self.sel_y.append(y_coord)

        if self.editMode:
            self.btn_del.setEnabled(True)

    def delete(self):
        self.delete = True

        # delete entries from coordinate list and from temporary shape file
        #	self.le_east.clear()
        #	self.le_north.clear()
        self.rows.sort(reverse=True)

        # map over vector layer and get attributes
        features = self.v_points.getFeatures()
        for f in features:
            fid = str(f.id())
            # map over selected ID's
            # check if feature ID matches selected ID
            for i in self.sel_id:
                if i == fid:
                    self.v_points.deleteFeature(f.id())
                    self.v_points.dataProvider().forceReload()
                    self.v_points.triggerRepaint()
                    #delete from self.coord_tab

        for row in self.rows:
            self.coord_tab.removeRow(row)

        self.rows = []
        self.btn_del.setEnabled(False)

        self.delete = False

    def openVector(self):
        # load vector file from file system
        self.open = True

        # get path of vector file
        self.openName = QFileDialog.getOpenFileName(self, "Load Vector Layer",
                                                    ".", "Shape (*.shp)")

        # if open dialog has been aborted
        if not self.openName:
            return

        # take file path and load vector file
        self.loadVector()

    def loadVector(self):
        self.v_points = None
        # name of loaded shape file equals geodin object type
        self.display_name = self.obj_type

        # get reference of shape
        self.v_points = QgsVectorLayer(self.openName, self.display_name, "ogr")

        # vector file must be a point shape
        # important for vector drag from layer list
        if not self.v_points.wkbType() == QgsWkbTypes.Point:
            QMessageBox.information(
                None, self.lang_dict.getWord(self.lang, "Wrong Datatype"),
                self.lang_dict.getWord(self.lang,
                                       "You must load a Point Shape"))
            return

        # if vector file has been loaded from file system
        if self.open == True:
            # add file to map canvas
            QgsProject.instance().addMapLayer(self.v_points)
            self.addVector()
            self.open = False

        # if vector file has been dragged from layer list
        elif self.drag == True:
            self.addVector()
            self.drag = False

    def addVector(self):
        # get reference from layer list to loaded vector layer
        # build coordinate table
        # map over layer list
        layers = QgsProject.instance().mapLayers()

        # split into layer ID and layer instance
        for ID, layer in layers.iteritems():
            source = layer.source()

            # if paths of vector layer equal each other
            # take instance of vector layer from layer list
            if self.openName == source:
                self.v_points = layer
                self.layerID = ID

        # execute if layer has been removed
        self.root.removedChildren.connect(self.onremovedChildren)

        # select short name, easting and northing from attribute table
        self.cmb_short.clear()
        self.cmb_east.clear()
        self.cmb_north.clear()

        self.cmb_short.addItem("")
        self.cmb_east.addItem("")
        self.cmb_north.addItem("")

        for field in self.v_points.pendingFields():
            self.cmb_short.addItem(field.name())
            self.cmb_east.addItem(field.name())
            self.cmb_north.addItem(field.name())

        # fill coordinate table and update attribute table
        self.insertItem()

        # toggle editing modes
        self.v_points.editingStarted.connect(self.Started)
        self.v_points.editingStopped.connect(self.Stopped)

    def createVector(self):
        # name of shape file equals object type
        self.display_name = self.obj_type

        # create temporary shape file
        tmplayer = QgsVectorLayer("Point", self.display_name, "memory")

        provider = tmplayer.dataProvider()

        # Enter editing mode
        tmplayer.startEditing()

        # add attribute fields to shape
        provider.addAttributes([
            QgsField("INVID", QVariant.String),
            QgsField("SHORTNAME", QVariant.String),
            QgsField("LONGNAME", QVariant.String),
            QgsField("XCOORD", QVariant.Double),
            QgsField("YCOORD", QVariant.Double),
            QgsField("DBTYPE", QVariant.String),
            QgsField("DATABASE", QVariant.String),
            QgsField("PRJNAME", QVariant.String),
            QgsField("PRJID", QVariant.String),
            QgsField("OBJECTTYPE", QVariant.String)
        ])

        tmplayer.commitChanges()

        # get file name to be saved
        outName = QFileDialog.getSaveFileName(
            self, "Save Vector Layer",
            self.saveFileFolder + self.display_name.replace(" ", "_"),
            "Shape (*.shp)")
        if not outName:
            return
        self.saveFileFolder = os.path.dirname(outName) + "/"

        # declare options for temporary shape layer
        QgsVectorFileWriter.writeAsVectorFormat(tmplayer, outName, "CP1250",
                                                None, "ESRI Shapefile")

        # turn temporary layer into QGIS vector layer
        self.v_points = QgsVectorLayer(outName, self.display_name, "ogr")

        # add vector file to QGIS layer registry
        QgsMapLayerRegistry.instance().addMapLayer(self.v_points)

        # find layer ID's of all layer in layer registry
        ids = self.root.findLayerIds()

        # if layer registry is empty, return
        if not ids:
            return
        # if layer registry is not empty, take top level layer ID
        else:
            self.layerID = ids[0]

        # exeute if layer has been removed
        self.root.removedChildren.connect(self.onremovedChildren)

        # toggle editing modes
        self.v_points.editingStarted.connect(self.Started)
        self.v_points.editingStopped.connect(self.Stopped)

    def shortNameChoose(self, shortname):
        self.shortname = shortname
        self.insertItem(True)

    def eastingChoose(self, easting):
        self.easting = easting
        self.insertItem(True)

    def northingChoose(self, northing):
        self.northing = northing
        self.insertItem(True)

    def insertItem(self, chooseField=False):

        #print shortname, easting, northing
        # create empty coordinate and ID lists
        self.x_list = []
        self.y_list = []
        self.id_list = []
        self.short_list = []

        # touch vector file and get feature information
        features = self.v_points.getFeatures()
        fields = self.v_points.pendingFields()

        # map over features (row in attribute table, object/point in canvas)
        for f in features:

            fid = str(f.id())
            geom = f.geometry()
            #print f.attributes()

            # get feature coordinates from the map
            x = str(round(geom.asPoint().x(), self.dp))
            y = str(round(geom.asPoint().y(), self.dp))
            attrs = f.attributes()
            #			a = attrs[1]

            # build lists with feature information

            if self.easting:
                if fields[fields.fieldNameIndex(self.easting)].type() == 6:
                    self.x_list.append(f[self.easting])
                else:
                    self.x_list.append('')
            else:
                self.x_list.append(x)

            if self.northing:
                if fields[fields.fieldNameIndex(self.northing)].type() == 6:
                    self.y_list.append(f[self.northing])
                else:
                    self.y_list.append('')
            else:
                self.y_list.append(y)

            self.id_list.append(fid)

            # short name is None, if nothing was selected, 1st column will be empty
            # if short name exists, append to list to write into table

            if self.shortname and not f[self.shortname] == None:
                self.short_list.append(f[self.shortname])
            else:
                self.short_list.append('')

        self.coord_tab.setRowCount(len(self.x_list))

        try:

            # insert short name into table
            for i, row in enumerate(self.short_list):
                short_input = QTableWidgetItem(row)
                self.coord_tab.setItem(i, 0, short_input)

            # insert x-coordinate into table
            for j, row in enumerate(self.x_list):
                x_input = QTableWidgetItem(str(row))
                self.coord_tab.setItem(j, 1, x_input)

            # insert y-coordinate into table
            for k, row in enumerate(self.y_list):
                y_input = QTableWidgetItem(str(row))
                self.coord_tab.setItem(k, 2, y_input)
        except TabError as te:
            msg = QMessageBox()
            msg.setIcon(QMessageBox.Critical)
            msg.setText(str(te))
            msg.exec_()
        except Exception as ex:
            msg = QMessageBox()
            msg.setIcon(QMessageBox.Critical)
            msg.setText(str(ex))
            msg.exec_()

        # touch vector file again and update attribute table
        # important if information had been changed in coordinate table
        # need to be in editing mode
        # features = self.v_points.getFeatures()

        if not chooseField:
            caps = self.v_points.dataProvider().capabilities()
            for i, f in enumerate(features):
                fid = f.id()

                # get coordinates from coordinate table
                x = self.coord_tab.item(i, 1).text()
                y = self.coord_tab.item(i, 2).text()

                # enter information into attribute table
                if caps & QgsVectorDataProvider.ChangeAttributeValues:
                    attrs = {
                        3: x,
                        4: y,
                        5: self.dbtype,
                        6: self.path,
                        7: self.project_names,
                        8: self.proj_ID,
                        9: self.obj_type
                    }

                    self.v_points.dataProvider().changeAttributeValues(
                        {fid: attrs})

    def keyPressEvent(self, event):
        #Did the user press the Enter key?
        if event.key() == Qt.Key_Return or event.key(
        ) == Qt.Key_Enter or event.key(
        ) == Qt.Key_Tab:  #QtCore.Qt.Key_Escape is a value that equates to what the operating system passes to python from the keyboard when the escape key is pressed.
            #Yes: Close the window
            print("key pressed")
        #No:  Do nothing.

    def clicked(self, currentRow):
        print("clicked")
        # write list with indices of all selected rows
        line = self.coord_tab.selectionModel().selectedRows()

        self.btn_desel.setEnabled(True)

        # new empty list
        # loop over lines and add to rowlist
        # sort reversed
        self.rows = []
        for idx in line:
            self.rows.append(idx.row())

        self.rows.sort(reverse=True)

        if len(self.rows) == 1:
            self.btn_geodin.setEnabled(True)

        self.sel_x = []
        self.sel_y = []
        self.sel_id = []
        self.sel_attrs = []

        # get coordinates from selection
        self.coord_x = self.coord_tab.item(self.rows[0], 1).text()
        self.coord_y = self.coord_tab.item(self.rows[0], 2).text()
        self.name = self.coord_tab.item(self.rows[0], 0).text()

        for i in self.rows:
            id = self.id_list[i]
            self.sel_id.append(id)
            x_coord = self.x_list[i]
            self.sel_x.append(x_coord)
            y_coord = self.y_list[i]
            self.sel_y.append(y_coord)

    #	self.le_east.clear()
    #	self.le_north.clear()

    #	self.le_east.insert(self.coord_x)
    #	self.le_north.insert(self.coord_y)

        if len(self.rows) != 1:
            #	self.le_east.clear()
            #	self.le_north.clear()
            self.btn_geodin.setEnabled(False)

        if self.editMode:
            self.btn_del.setEnabled(True)

    def geodin(self):
        #self.lgr.warning('GeODin COM')
        # connect to GeODin COM functions

        for cell in self.coord_tab.selectedItems():
            shortname = cell.text()
            break

        FieldValues = ""
        features = self.v_points.getFeatures()
        for feature in features:
            if feature[self.shortname] == shortname:
                for field in feature.fields():
                    #print field.name().lower()
                    #if field.name() != self.shortname and field.name() != self.easting and field.name() != self.northing and field.name().lower() != 'invid' and field.name().lower() != 'objecttype':
                    if not str(feature[field.name()]) == 'NULL' and not str(
                            feature[field.name()]) == '':
                        FieldValues += field.name() + "=" + str(
                            feature[field.name()]) + "\n"

        try:
            GeODin = win32com.client.Dispatch("GeODin.GeODinApplication")

            #	x = self.le_east.text()
            #	y = self.le_north.text()
            short = "NAME=B101"

            if len(self.coord_x) == 0:
                QMessageBox.information(
                    None, self.lang_dict.getWord(self.lang, "Selection Error"),
                    self.lang_dict.getWord(
                        self.lang,
                        "Nothing to read. Please select the row to be written into GeODin."
                    ))

            else:
                # select object type in GeODin obeject manager
                Params = "[Params]\n"
                Database = "Database="
                Username = "******"
                Password = "******"
                Objecttype = "\nObjectType=1"
                Parentnode = "\nParentNode=ProjectQueries"
                Object_ID = "\nObjectID="
                Expand = "\nExpand=true"

                params = Params + Database + self.alias + Username + Password + Objecttype + Parentnode + Object_ID + self.proj_ID + Expand
                print(params)
                #self.lgr.warning(params)
                # execute method
                GeODin.SelectObject(params)

                # set parameters to create a new object
                Params = "[Params]\n"
                ApplyFieldValues = "ApplyFieldValues=True"
                XCOORDS = "\nXCOORD="
                YCOORDS = "\nYCOORD="
                OBJECTTYPE = "\nOBJECTTYPE="
                NAME = "\nNAME="
                PRJID = "\nPRJID="
                FieldValueSection = "\n[FieldValues]\n"

                params = Params + ApplyFieldValues + XCOORDS + self.coord_x + YCOORDS + self.coord_y + OBJECTTYPE + self.loctype + NAME + self.name + PRJID + self.proj_ID + FieldValueSection + FieldValues
                print(params)
                #self.lgr.warning(params)
                # execute method to create new object
                error = GeODin.ExecuteMethodParams(39, params)
                if error:
                    #print "Error ID:"+ str(GeODin.ExceptionValue)
                    self.lgr.info("Error ID: " + str(GeODin.ExceptionValue))
                    #print "Error Message:"+GeODin.ExceptionMsg
                    self.lgr.info("Error Message: " + GeODin.ExceptionMsg)

            time.sleep(3)
        except:
            print("Unexpected error:", sys.exc_info()[0])
        GeODin = None

    def deselect(self):
        self.rows = []
        self.sel_x = []
        self.sel_y = []

        selected = self.coord_tab.selectedRanges()
        for i in range(len(selected)):
            self.coord_tab.setRangeSelected(selected[i], False)

    #	self.le_east.clear()
    #	self.le_north.clear()

        self.btn_desel.setEnabled(False)
class ReorderProcess():
    """Along line point reordering

    according to given destination"""
    def __init__(self, exutoire, point_reseau):
        """Set all informations needed to order the network"""

        self.exutoire_layer = exutoire
        self.point_reseau_layer = point_reseau
        self.crs = QgsCoordinateReferenceSystem(
            self.point_reseau_layer.crs().authid())

        # Create ouput
        self.output = QgsVectorLayer("Point", "point", "memory")
        self.output.setCrs(self.crs)

        # Add fields
        name_T_id = "T_id"
        name_L_id = "L_id"
        name_P_id = "P_id"
        name_nat = "nature"
        provider = self.output.dataProvider()
        caps = provider.capabilities()
        if caps & QgsVectorDataProvider.AddAttributes:
            res = provider.addAttributes([
                QgsField(name_T_id, QVariant.String),
                QgsField(name_L_id, QVariant.String),
                QgsField(name_P_id, QVariant.String),
                QgsField(name_nat, QVariant.String)
            ])
            self.output.updateFields()
        # Save field index
        self.index_nat = self.point_reseau_layer.fieldNameIndex('nature')
        self.index_pid = self.point_reseau_layer.fieldNameIndex('P_id')
        self.index_order = self.point_reseau_layer.fieldNameIndex('order')
        self.l_done = []

    def reorder(self, pt, count_order):

        feat = QgsFeature(self.output.pendingFields())
        pt_geom = pt.geometry()
        feat.setGeometry(pt_geom)

        tid = pt.attribute("T_id")
        lid = pt.attribute("L_id")
        ppid = pt.attribute("P_id")
        nat = pt.attribute("nature")

        if nat == 'start':
            self.output.startEditing()
            feat.setAttributes([tid, str(count_order), ppid, nat])
            print 'reorder: %s' % ([tid, lid, ppid, nat, str(count_order)])
            self.output.dataProvider().addFeatures([feat])
            self.output.commitChanges()
            self.output.updateExtents()
            while nat != 'end':
                expr = QgsExpression('L_id = %s and P_id = %s' %
                                     (lid, str(int(ppid) + 1)))
                req = QgsFeatureRequest(expr)
                n_pt_it = self.point_reseau_layer.getFeatures(req)
                n_pt = n_pt_it.next()
                n_pt_it = None

                feat = QgsFeature(self.output.pendingFields())
                n_pt_geom = n_pt.geometry()
                feat.setGeometry(n_pt_geom)

                tid = n_pt.attribute("T_id")
                lid = n_pt.attribute("L_id")
                ppid = n_pt.attribute("P_id")
                nat = n_pt.attribute("nature")

                self.output.startEditing()
                feat.setAttributes([tid, str(count_order), ppid, nat])
                print[tid, lid, ppid, nat, str(count_order)]
                self.output.dataProvider().addFeatures([feat])
                self.output.commitChanges()
                self.output.updateExtents()
        else:
            pid = 0
            self.output.startEditing()
            feat.setAttributes([tid, str(count_order), str(pid), 'start'])
            print[tid, lid, str(pid), 'start', str(count_order)]
            self.output.dataProvider().addFeatures([feat])
            self.output.commitChanges()
            self.output.updateExtents()
            nat = None
            feat = None
            while nat != 'start':
                ppid = str(int(ppid) - 1)
                expr = QgsExpression('L_id = %s and P_id = %s' % (lid, ppid))
                req = QgsFeatureRequest(expr)
                n_pt_it = self.point_reseau_layer.getFeatures(req)
                n_pt = n_pt_it.next()
                n_pt_it = None

                feat = QgsFeature(self.output.pendingFields())
                n_pt_geom = n_pt.geometry()
                feat.setGeometry(n_pt_geom)

                tid = n_pt.attribute("T_id")
                nat = n_pt.attribute("nature")
                if nat != 'start':
                    pid += 1
                    self.output.startEditing()
                    feat.setAttributes([tid, str(count_order), str(pid), nat])
                    print[tid, lid, str(pid), nat, str(count_order)]
                    self.output.dataProvider().addFeatures([feat])
                    self.output.commitChanges()
                    self.output.updateExtents()
                    feat = None
                else:
                    pid += 1
                    self.output.startEditing()
                    feat.setAttributes(
                        [tid, str(count_order),
                         str(pid), 'end'])
                    print[tid, lid, str(pid), 'end', str(count_order)]
                    self.output.dataProvider().addFeatures([feat])
                    self.output.commitChanges()
                    self.output.updateExtents()
                    feat = None

    def executeReorder(self):

        count_order = 0
        # loop over exutoire features to process several network
        for exutoire in self.exutoire_layer.getFeatures():
            exutoire_geom = exutoire.geometry().buffer(1, 4).boundingBox()
            # Select the start point that intersects the outlet
            req = QgsFeatureRequest().setFilterRect(exutoire_geom)
            pts_reseau_sortie = self.point_reseau_layer.getFeatures(req)
            for pt_sortie in pts_reseau_sortie:
                count_order += 1
                L_id = pt_sortie.attribute("L_id")
                # Reorder the points of the first line of the network
                self.reorder(pt_sortie, count_order)
                nat = 'end'
                string = "L_id = %s AND nature = '%s'" % (count_order, nat)
                print string
                expr = QgsExpression(string)
                reque = QgsFeatureRequest(expr)
                # Select the last point of the first line
                pt_end_it = self.output.getFeatures(reque)
                pt_end = pt_end_it.next()
                pt_end_it = None
                # Make a buffer around the point to define a boundingBox
                pt_end_geom = pt_end.geometry().buffer(1, 4).boundingBox()
                req = QgsFeatureRequest(
                    QgsExpression("L_id != %s" %
                                  (str(L_id)))).setFilterRect(pt_end_geom)
                # Select the next points
                next_ls = self.point_reseau_layer.getFeatures(req)
                self.l_done.append(L_id)
                list_next = []
                # Fill next_ls list with the next features
                for next_l in next_ls:
                    list_next.append(next_l)
                # While there is features in list_next, reorder process continues
                while len(list_next) != 0:
                    current_list = list_next
                    list_next = []
                    # Loop over the next features
                    for next_pt in current_list:
                        # Get line id
                        L_id = next_pt.attribute("L_id")
                        print L_id
                        # if the line has not been already reorder
                        if L_id not in self.l_done:
                            count_order += 1
                            #then reorder
                            self.reorder(next_pt, count_order)
                            string = "L_id = %s AND nature='%s'" % (
                                count_order, nat)
                            print string
                            expr = QgsExpression(string)
                            req = QgsFeatureRequest(QgsExpression(expr))
                            pt_end_it = self.output.getFeatures(req)
                            pt_end = pt_end_it.next()
                            pt_end_it = None
                            pt_end_geom = pt_end.geometry().buffer(
                                1, 4).boundingBox()
                            # Find the next feature
                            reque = QgsFeatureRequest(
                                QgsExpression(
                                    "L_id != %s" %
                                    (L_id))).setFilterRect(pt_end_geom)
                            next_ls = self.point_reseau_layer.getFeatures(
                                reque)
                            self.l_done.append(L_id)
                            # Fill next_ls list again and loop
                            for next_l in next_ls:
                                list_next.append(next_l)
                    print len(list_next)

        expr = QgsExpression("nature = 'end'")
        req = QgsFeatureRequest(expr)
        end_pts = self.output.getFeatures(req)
        change_dict = {}
        change_list = []
        rm_ids = []
        #clean lines that aren't a cross border anymore because a small part has been removed
        for end_pt in end_pts:
            end_pt_geom = end_pt.geometry().buffer(1, 4).boundingBox()
            end_pt_id = end_pt.id()
            end_lid = end_pt.attribute("L_id")
            end_pid = end_pt.attribute("P_id")
            expr = QgsExpression("L_id != '%s'" % (end_lid))
            req = QgsFeatureRequest(expr).setFilterRect(end_pt_geom)
            int_pts = []
            for int_pt in self.output.getFeatures(req):
                lid_int_pt = int_pt.attribute("L_id")
                int_pts.append(int_pt)
            if len(int_pts) == 1:
                rm_ids.append(end_pt_id)
                if int(end_lid) in change_dict:
                    change_dict[int(lid_int_pt)] = change_dict[int(end_lid)]
                else:
                    change_dict[int(lid_int_pt)] = int(end_lid)
        print change_dict
        change_dict = sorted(change_dict.items(), key=lambda t: t[0])
        for ch_tuple in change_dict:
            print ch_tuple[0]
            end_lid = str(ch_tuple[1])
            end_pid = None
            for end_pt in self.output.getFeatures(
                    QgsFeatureRequest(
                        QgsExpression("L_id = '%s' and nature = '%s'" %
                                      (end_lid, "end")))):
                if end_pid is None:
                    end_pid = end_pt.attribute("P_id")
                elif int(end_pid) < int(end_pt.attribute("P_id")):
                    end_pid = end_pt.attribute("P_id")
            expr = QgsExpression("L_id = '%s'" % (str(ch_tuple[0])))
            req = QgsFeatureRequest(expr)
            for ch_pt in self.output.getFeatures(req):
                ch_pt_id = ch_pt.id()
                if ch_pt.attribute("nature") == "start":
                    rm_ids.append(ch_pt_id)
                else:
                    ch_tid = ch_pt.attribute("T_id")
                    ch_nature = ch_pt.attribute("nature")
                    self.output.startEditing()
                    self.output.changeAttributeValue(ch_pt_id, 1, end_lid)
                    self.output.changeAttributeValue(ch_pt_id, 2, end_pid)
                    self.output.commitChanges()
                    end_pid = int(end_pid) + 1
        self.output.startEditing()
        self.output.deleteFeatures(rm_ids)
        self.output.commitChanges()

        return self.output, self.crs