Example #1
0
def nodeCopyAsMemory(node,newname=None,position=None,target_node=None):
    """
    nodeMove:               Moves 'node' in position or position 'position' in group 'target_node'
    :param node:            Node to move or name of node to move
    :param target_node:     Target group to move 'node' to or name of the target group
    :return:                moved node or None if source or target node do not exist
    """
    if oeq_global.isStringOrUnicode(node):
        node = nodeByName(node)
        if len(node) == 0:
            return None
        node = node[0]

    if target_node == None:
        target_node = node.parent()
    else:
         if oeq_global.isStringOrUnicode(target_node):
            target_node = nodeByName(target_node)
            if len(target_node) == 0:
                return None
            target_node = target_node[0]
    source_layer = node.layer()
    #print source_layer.name()
    #print source_layer.source()
    #print source_layer.providerType() + u'?crs=' + source_layer.crs().authid()
    #print newname
    new_layer = QgsVectorLayer( 'Polygon' + '?crs=' + source_layer.crs().authid(), newname, "memory")
    new_layer.setProviderEncoding('System')
    QgsMapLayerRegistry.instance().addMapLayer(new_layer, True)
    #oeq_global.OeQ_wait_for_renderer(60000)
    new_node = nodeByName(newname)[0]
    new_node = nodeMove(new_node,position,target_node)
    return new_node
Example #2
0
def nodeCreateMemoryLayer(nodename, position='bottom',target_node=None,source="Point",crs=None,indexfieldname='id'):
    if target_node == None:
        target_node = QgsProject.instance().layerTreeRoot()
    else:
         if oeq_global.isStringOrUnicode(target_node):
            target_node = nodeByName(target_node)
            if len(target_node) == 0:
                return None
            target_node = target_node[0]

    if path == None:
        path= oeq_global.OeQ_project_path()
    if crs == None:
        crs = config.project_crs
    new_layer = QgsVectorLayer(source + '?crs=' + crs, nodename, "memory")
    new_layer.setProviderEncoding('System')
    QgsMapLayerRegistry.instance().addMapLayer(new_layer, True)
    #oeq_global.OeQ_wait_for_renderer(60000)
    new_node = nodeMove(nodename,position,target_node)
    new_layer = new_node.layer()
    dataprovider = new_layer.dataProvider()
    dataprovider.addAttributes([QgsField(indexfieldname,  QVariant.Int)])
    new_layer.updateFields()
    #oeq_global.OeQ_unlockQgis()

    return new_node
Example #3
0
    def test_FilterExpressionWithAccents(self):
        myShpFile = os.path.join(TEST_DATA_DIR, 'france_parts.shp')
        layer = QgsVectorLayer(myShpFile, 'poly', 'ogr')

        layer.setProviderEncoding("ISO-8859-1")
        ids = [feat.id() for feat in layer.getFeatures(QgsFeatureRequest().setFilterExpression("TYPE_1 = 'Région'"))]
        expectedIds = [0, 1, 2, 3]
        myMessage = '\nExpected: {0} features\nGot: {1} features'.format(repr(expectedIds), repr(ids))
        assert ids == expectedIds, myMessage

        layer.setProviderEncoding("UTF-8")
        ids = [feat.id() for feat in layer.getFeatures(QgsFeatureRequest().setFilterExpression("TYPE_1 = 'Région'"))]
        expectedIds = []
        myMessage = '\nExpected: {0} features\nGot: {1} features'.format(repr(expectedIds), repr(ids))
        assert ids == expectedIds, myMessage
def _qgis_layer(uri, schema_name, layer_name, geometry_column, provider,
                qgis_layer_name):
    if geometry_column is not None:
        g_column = "({})".format(geometry_column)
    else:
        g_column = ""
    if provider == "SQLite":
        # use OGR for spatialite loading
        l = QgsVectorLayer(
            "{}|layername={}{}".format(uri, layer_name, g_column),
            qgis_layer_name, "ogr")
        l.setProviderEncoding("UTF-8")
    else:
        if schema_name is not None:
            s_table = '"{}"."{}"'.format(schema_name, layer_name)
        else:
            s_table = '"{}"'.format(layer_name)
        # remove "PG:" in front of the uri
        uri = uri[3:]
        l = QgsVectorLayer(
            "{} table={} {} sql=".format(uri, s_table, g_column),
            qgis_layer_name, "postgres")
    return l
Example #5
0
    def test_FilterExpressionWithAccents(self):
        myShpFile = os.path.join(TEST_DATA_DIR, 'france_parts.shp')
        layer = QgsVectorLayer(myShpFile, 'poly', 'ogr')

        layer.setProviderEncoding("ISO-8859-1")
        ids = [
            feat.id() for feat in layer.getFeatures(
                QgsFeatureRequest().setFilterExpression("TYPE_1 = 'Région'"))
        ]
        expectedIds = [0, 1, 2, 3]
        myMessage = '\nExpected: {0} features\nGot: {1} features'.format(
            repr(expectedIds), repr(ids))
        assert ids == expectedIds, myMessage

        layer.setProviderEncoding("UTF-8")
        ids = [
            feat.id() for feat in layer.getFeatures(
                QgsFeatureRequest().setFilterExpression("TYPE_1 = 'Région'"))
        ]
        expectedIds = []
        myMessage = '\nExpected: {0} features\nGot: {1} features'.format(
            repr(expectedIds), repr(ids))
        assert ids == expectedIds, myMessage
def _qgis_layer(uri, schema_name, layer_name, geometry_column, provider, qgis_layer_name, layer_xpath, layer_pkid):
    if geometry_column is not None:
        g_column = "({})".format(geometry_column)
    else:
        g_column = ""
    if provider == "SQLite":
        # use OGR for spatialite loading
        l = QgsVectorLayer("{}|layername={}{}".format(uri, layer_name, g_column), qgis_layer_name, "ogr")
        l.setProviderEncoding("UTF-8")
    else:
        if schema_name is not None:
            s_table = '"{}"."{}"'.format(schema_name, layer_name)
        else:
            s_table = '"{}"'.format(layer_name)
        # remove "PG:" in front of the uri
        uri = uri[3:]
        l = QgsVectorLayer("{} table={} {} sql=".format(uri, s_table, g_column), qgis_layer_name, "postgres")

    # sets xpath
    if layer_xpath:
        l.setCustomProperty("xpath", layer_xpath)
    l.setCustomProperty("pkid", layer_pkid)
    return l
Example #7
0
 def add_task(self):
     selectedLayer = None
     selectedLayerIndex = self.dlg.comboBox.currentIndex()
     cleanTresholdValue = self.dlg.lineEdit_3.text()
     outLineEdit = self.dlg.lineEdit.text()
     prBar = self.dlg.progressBar
     logTxtLine = self.dlg.label_9
     if selectedLayerIndex <= len(self.filtered_layers) - 1:
         selectedLayer = self.filtered_layers[selectedLayerIndex].layer()
     if selectedLayerIndex > len(self.filtered_layers) - 1:
         selectedLayer = QgsVectorLayer(
             self.dlg.comboBox.currentText(),
             self.dlg.comboBox.currentText().split('/')[-1].split('.')[0],
             "ogr")
     if selectedLayer != None:
         selectedLayer.setProviderEncoding(u'UTF-8')
         selectedLayer.dataProvider().setEncoding(u'UTF-8')
         pt = self.get_point_coordinates()
         if self.dlg.checkBox.isChecked():
             fields_names = []
             fields_names.append(self.dlg.lineEdit_4.text().replace(
                 ' ', ''))
             fields_names.append(self.dlg.lineEdit_5.text().replace(
                 ' ', ''))
             fields_names.append(self.dlg.lineEdit_6.text().replace(
                 ' ', ''))
         else:
             fields_names = ['Rank', 'Value', 'Distance']
         if fields_names[0] != '' and fields_names[
                 1] != '' and fields_names[2] != '':
             if pt != None:
                 ### QgsTask class call ###
                 self.m = self.Worker(QgsApplication, selectedLayer, pt,
                                      cleanTresholdValue, outLineEdit,
                                      QgsProject, prBar, logTxtLine,
                                      fields_names)
                 self.m.StartScriptTask()
Example #8
0
def nodeCreateVectorLayer(nodename, position='bottom',target_node=None,path=None,source="Point",crs=None,providertype="ESRI Shapefile",indexfieldname='id'):
    if target_node == None:
        target_node = QgsProject.instance().layerTreeRoot()
    else:
         if oeq_global.isStringOrUnicode(target_node):
            target_node = nodeByName(target_node)
            if len(target_node) == 0:
                return None
            target_node = target_node[0]

    if path == None:
        path= oeq_global.OeQ_project_path()
    if crs == None:
        crs = config.project_crs
    new_layer = QgsVectorLayer(source + '?crs=' + crs, nodename, "memory")
    new_layer.setProviderEncoding('System')
    #test
    dataprovider = new_layer.dataProvider()
    dataprovider.addAttributes([QgsField(indexfieldname, QVariant.Int)])
    new_layer.updateFields()
    writer = QgsVectorFileWriter.writeAsVectorFormat(new_layer, os.path.join(path , nodename+'.shp'), "System", new_layer.crs(), providertype)
    if writer != QgsVectorFileWriter.NoError:
        oeq_global.OeQ_push_error(title='Write Error:', message=os.path.join(path , nodename+'.shp'))
        return None
    del writer
    oeq_global.OeQ_wait_for_file(os.path.join(path , nodename+'.shp'))
    iface.addVectorLayer(os.path.join(path , nodename+'.shp'),nodename, 'ogr')
    #oeq_global.OeQ_wait_for_renderer(60000)
    new_node = nodeMove(nodename,position,target_node)
    new_layer = new_node.layer()
    #dataprovider = new_layer.dataProvider()
    #dataprovider.addAttributes([QgsField(indexfieldname,  QVariant.Int)])
    #new_layer.updateFields()

    #oeq_global.OeQ_unlockQgis()

    return new_node
    def add_error_layer(self, dbfile):
        """ Adds an database as layers, expects layers: error_point,
        error_linestring and error_polygon. """

        tables = ['error_point', 'error_linestring', 'error_polygon']
        group_name = os.path.splitext(os.path.basename(dbfile))[0]
        legend_group = QgsProject.instance().layerTreeRoot().insertGroup(0, group_name)
        for table in tables:
            # Create new layer
            layer = QgsVectorLayer(dbfile + '|layername=' + table, table, 'ogr')
            if not layer:
                print('error creating layer')
            # Set encoding on the layer
            layer.setProviderEncoding(u'UTF-8')
            layer.dataProvider().setEncoding(u'UTF-8')
            # Add style from file
            style_file = os.path.join(self.plugin_dir, 'styles', '{0}.qml'.format(table))
            if os.path.isfile(style_file):
                layer.loadNamedStyle(style_file)
            # Add layer to qgis - but dont add to legend directly
            if QgsMapLayerRegistry.instance().addMapLayer(layer, False):
                legend_group.addLayer(layer)
            else:
                print('Unable to add layer: {}'.format(table))
Example #10
0
    def generate_layer(self):
        """Generates temporary layers with geometry"""
        self.netz = QgsVectorLayer(self.dlg.mQgsFileWidget_2.filePath(), "netz", "ogr")
        varmix = QgsVectorLayer(self.dlg.mQgsFileWidget.filePath(), "varMix", "ogr")
        varmix.setProviderEncoding(u'UTF-8')
        varmix.dataProvider().setEncoding(u'UTF-8')
        # varmix = QgsVectorLayer("D:\kreis.xls", "varMix", "ogr")

        # d.setEllipsoidalMode(True)
        layer_without = QgsVectorLayer("None", os.path.basename(self.dlg.mQgsFileWidget.filePath()) + " (Ohne Geometrie)", "memory")
        layer_without.startEditing()
        without_data = layer_without.dataProvider()

        without_data.addAttributes(varmix.fields())  #
        layer_without.commitChanges()
        QgsProject.instance().addMapLayer(layer_without)

        layer_points = QgsVectorLayer("point?crs=" + self.netz.crs().authid(), os.path.basename(self.dlg.mQgsFileWidget.filePath()) + " (Punkte)", "memory")
        layer_points.startEditing()
        point_data = layer_points.dataProvider()

        point_data.addAttributes(varmix.fields())  #
        layer_points.commitChanges()
        QgsProject.instance().addMapLayer(layer_points)

        layer_lines = QgsVectorLayer("linestring?crs=" + self.netz.crs().authid(), os.path.basename(self.dlg.mQgsFileWidget.filePath()) + " (Linien)", "memory")
        layer_lines.startEditing()
        lines_data = layer_lines.dataProvider()

        lines_data.addAttributes(varmix.fields())  #
        layer_lines.commitChanges()
        QgsProject.instance().addMapLayer(layer_lines)

        results = varmix.getFeatures()
        vnk = ""
        nnk = ""
        feat = None

        side_dist_field = None;

        for r in results:
            if not (vnk == r['VNK'] and nnk == r['NNK']):
                vnk = r['VNK']
                nnk = r['NNK']
                feat = self.select_section(vnk, nnk)
            if feat is None:
                without_data.addFeatures([r])
            elif r['VST'] == r['BST']:
                if side_dist_field is None:
                    self.pld.show()
                    self.pld.comboBox.clear()
                    self.pld.comboBox.addItem("-- kein seitlicher Abstand --")
                    for f in varmix.fields():
                        self.pld.comboBox.addItem(f.name())
                    self.pld.comboBox.setCurrentIndex(0)
                    result = self.pld.exec_()
                    if result:
                        side_dist_field = self.pld.comboBox.currentIndex()-1
                f = self.cut_point(feat, r, side_dist_field)
                if f is not None:
                    point_data.addFeatures([f])
                else:
                    without_data.addFeatures([r])
            else:
                f = self.cut_line(feat, r)
                if f is not None:
                    lines_data.addFeatures([f])
                else:
                    without_data.addFeatures([r])

        if lines_data.featureCount() == 0:
            QgsProject.instance().removeMapLayer(layer_lines)
        if point_data.featureCount() == 0:
            QgsProject.instance().removeMapLayer(layer_points)
        if without_data.featureCount() == 0:
            QgsProject.instance().removeMapLayer(layer_without)
Example #11
0
    def run(self):
        self.mutex.lock()
        self.stopMe = 0
        self.mutex.unlock()

        interrupted = False

        # create attribute list with uniquie fields
        # from all selected layers
        mergedFields = []
        self.emit(SIGNAL("rangeChanged( PyQt_PyObject )"), len(self.shapes))
        self.emit(SIGNAL("checkStarted()"))

        shapeIndex = 0
        fieldMap = {}
        for fileName in self.shapes:
            layerPath = QFileInfo(self.baseDir + "/" + fileName).absoluteFilePath()
            newLayer = QgsVectorLayer(layerPath, QFileInfo(layerPath).baseName(), "ogr")
            if not newLayer.isValid():
                continue

            newLayer.setProviderEncoding(self.inputEncoding)
            vprovider = newLayer.dataProvider()
            fieldMap[shapeIndex] = {}
            fieldIndex = 0
            for layerField in vprovider.fields():
                fieldFound = False
                for mergedFieldIndex, mergedField in enumerate(mergedFields):
                    if mergedField.name() == layerField.name() and mergedField.type() == layerField.type():
                        fieldFound = True
                        fieldMap[shapeIndex][fieldIndex] = mergedFieldIndex

                        if mergedField.length() < layerField.length():
                            # suit the field size to the field of this layer
                            mergedField.setLength(layerField.length())
                        break

                if not fieldFound:
                    fieldMap[shapeIndex][fieldIndex] = len(mergedFields)
                    mergedFields.append(layerField)

                fieldIndex += 1

            shapeIndex += 1
            self.emit(SIGNAL("featureProcessed()"))
        self.emit(SIGNAL("checkFinished()"))

        # get information about shapefiles
        layerPath = QFileInfo(self.baseDir + "/" + self.shapes[0]).absoluteFilePath()
        newLayer = QgsVectorLayer(layerPath, QFileInfo(layerPath).baseName(), "ogr")
        self.crs = newLayer.crs()
        self.geom = newLayer.wkbType()
        vprovider = newLayer.dataProvider()

        fields = QgsFields()
        for f in mergedFields:
            fields.append(f)

        writer = QgsVectorFileWriter(
            self.outputFileName, self.outputEncoding,
            fields, self.geom, self.crs)

        shapeIndex = 0
        for fileName in self.shapes:
            layerPath = QFileInfo(self.baseDir + "/" + fileName).absoluteFilePath()
            newLayer = QgsVectorLayer(layerPath, QFileInfo(layerPath).baseName(), "ogr")
            if not newLayer.isValid():
                continue
            newLayer.setProviderEncoding(self.inputEncoding)
            vprovider = newLayer.dataProvider()
            nFeat = vprovider.featureCount()
            self.emit(SIGNAL("rangeChanged( PyQt_PyObject )"), nFeat)
            self.emit(SIGNAL("fileNameChanged( PyQt_PyObject )"), fileName)
            inFeat = QgsFeature()
            outFeat = QgsFeature()
            inGeom = QgsGeometry()
            fit = vprovider.getFeatures()
            while fit.nextFeature(inFeat):
                mergedAttrs = [""] * len(mergedFields)

                # fill available attributes with values
                fieldIndex = 0
                for v in inFeat.attributes():
                    if shapeIndex in fieldMap and fieldIndex in fieldMap[shapeIndex]:
                        mergedAttrs[fieldMap[shapeIndex][fieldIndex]] = v
                    fieldIndex += 1

                if inFeat.geometry() is not None:
                    inGeom = QgsGeometry(inFeat.geometry())
                    outFeat.setGeometry(inGeom)
                outFeat.setAttributes(mergedAttrs)
                writer.addFeature(outFeat)
                self.emit(SIGNAL("featureProcessed()"))

            self.emit(SIGNAL("shapeProcessed()"))
            self.mutex.lock()
            s = self.stopMe
            self.mutex.unlock()

            if s == 1:
                interrupted = True
                break

            shapeIndex += 1

        del writer

        if not interrupted:
            self.emit(SIGNAL("processingFinished()"))
        else:
            self.emit(SIGNAL("processingInterrupted()"))
Example #12
0
 def _testLayer(self, filename=None, output=False):
   filepath = self.testDataPath(filename, output)
   layer = QgsVectorLayer(filepath, os.path.splitext(os.path.basename(filepath))[0], "ogr")
   assert layer.isValid(), "failed to load layer"
   layer.setProviderEncoding("SJIS")   #tr
   return layer
    def doLayer(self, item):
        ogrFeature = item.data(Qt.UserRole)
        geom = QgsGeometry.fromWkt(ogrFeature.GetGeometryRef().ExportToWkt())
        self.transform(geom)

        fields = QgsFields()
        fields.append(QgsField("id", QVariant.String))
        fields.append(QgsField("name", QVariant.String))
        fet = QgsFeature()
        fet.initAttributes(2)
        fet.setFields(fields)
        fet.setGeometry(geom)
        fet.setAttribute("id", (ogrFeature.GetFieldAsString('id')))
        fet.setAttribute("name", (ogrFeature.GetFieldAsString('name')))

        vl = None
        if not self.plugin.singleLayer:
            if geom.type() == QgsWkbTypes.PolygonGeometry:
                layerName = "OSMPlaceSearch Polygon"
                layerId = self.MultiPolygonLayerId
            if geom.type() == QgsWkbTypes.LineGeometry:
                layerName = "OSMPlaceSearch Line"
                layerId = self.LineLayerId
            if geom.type() == QgsWkbTypes.PointGeometry:
                layerName = "OSMPlaceSearch Point"
                layerId = self.PointLayerId

            vl = QgsProject.instance().mapLayer(layerId)
            if vl is not None:
                pr = vl.dataProvider()
            else:
                if geom.type() == QgsWkbTypes.PolygonGeometry:
                    vl = QgsVectorLayer("MultiPolygon", layerName, "memory")
                    self.MultiPolygonLayerId = vl.id()
                if geom.type() == QgsWkbTypes.LineGeometry:
                    vl = QgsVectorLayer("MultiLineString", layerName, "memory")
                    self.LineLayerId = vl.id()
                if geom.type() == QgsWkbTypes.PointGeometry:
                    vl = QgsVectorLayer("Point", layerName, "memory")
                    self.PointLayerId = vl.id()

                if vl is not None:
                    pr = vl.dataProvider()
                    # ajout de champs
                    pr.addAttributes(fields.toList())

                QgsProject.instance().addMapLayer(vl)
        else:
            layerName = "OSM "+ogrFeature.GetFieldAsString('id')

            # creer une nouvelle couche si n'existe pas encore
            if geom.type() == QgsWkbTypes.PolygonGeometry:
                vl = QgsVectorLayer("MultiPolygon", layerName, "memory")
            if geom.type() == QgsWkbTypes.LineGeometry:
                vl = QgsVectorLayer("MultiLineString", layerName, "memory")
            if geom.type() == QgsWkbTypes.PointGeometry:
                vl = QgsVectorLayer("Point", layerName, "memory")

            if vl is not None:
                pr = vl.dataProvider()
                # ajout de champs
                pr.addAttributes(fields.toList())
                vl.setCrs(self.plugin.canvas.mapSettings().destinationCrs())

            QgsProject.instance().addMapLayer(vl)

        if vl is not None:
            vl.setProviderEncoding('UTF-8')
            vl.startEditing()
            pr.addFeatures([fet])
            vl.commitChanges()

            # mise a jour etendue de la couche
            vl.updateExtents()

            layerTree = QgsProject.instance().layerTreeRoot().findLayer(vl)
            if layerTree:
                self.plugin.iface.layerTreeView()\
                    .layerTreeModel().refreshLayerLegend(layerTree)  # Refresh legend

            self.go(item, False)
Example #14
0
    def init(self):
        proj = QgsProject.instance()
        path = proj.readEntry("QGYF", "dataPath")[0]
        db = proj.readEntry("QGYF", 'activeDataBase')[0]

        con = spatialite_connect("{}\{}".format(path, db))
        cur = con.cursor()

        cur.execute('DROP VIEW IF EXISTS polygon_class')
        cur.execute('DROP VIEW IF EXISTS line_class')
        cur.execute('DROP VIEW IF EXISTS point_class')

        cur.execute("""CREATE VIEW polygon_class AS
            SELECT  polygon_object.id AS id,
                class.gid AS gid,
                class.geometri_typ,
                class.grupp AS grupp,
                class.kvalitet AS kvalitet,
                class.faktor AS faktor,
                polygon_object.yta AS yta,
                polygon_object.geom AS geom
            FROM polygon_object
            JOIN classification AS class ON (polygon_object.gid = class.gid)
            WHERE class.geometri_typ = 'yta';""")

        cur.execute("""INSERT OR IGNORE INTO views_geometry_columns
            (view_name, view_geometry, view_rowid, f_table_name, f_geometry_column, read_only)
            VALUES ('polygon_class', 'geom', 'id', 'polygon_object', 'geom', 1);""")

        cur.execute("""CREATE VIEW line_class AS
            SELECT line_object.id AS id,
                class.gid AS gid,
                class.geometri_typ,
                class.grupp AS grupp,
                class.kvalitet AS kvalitet,
                class.faktor AS faktor,
                line_object.yta AS yta,
                line_object.geom AS geom
            FROM line_object
            JOIN classification AS class ON (line_object.gid = class.gid)
            WHERE class.geometri_typ = 'linje';""")

        cur.execute("""INSERT OR IGNORE INTO views_geometry_columns
            (view_name, view_geometry, view_rowid, f_table_name, f_geometry_column, read_only)
            VALUES ('line_class', 'geom', 'id', 'line_object', 'geom', 1);""")

        cur.execute("""CREATE VIEW point_class AS
            SELECT point_object.id AS id,
                class.gid AS gid,
                class.geometri_typ,
                class.grupp AS grupp,
                class.kvalitet AS kvalitet,
                class.faktor AS faktor,
                point_object.yta AS yta,
                point_object.geom AS geom
            FROM point_object
            JOIN classification AS class ON (point_object.gid = class.gid)
            WHERE class.geometri_typ = 'punkt';""")

        cur.execute("""INSERT OR IGNORE INTO views_geometry_columns
            (view_name, view_geometry, view_rowid, f_table_name, f_geometry_column, read_only)
            VALUES ('point_class', 'geom', 'id', 'point_object', 'geom', 1);""")

        con.commit()
        cur.close()
        con.close()

        root = proj.layerTreeRoot()
        mygroup = root.findGroup('Kvaliteter')
        if not mygroup:
            mygroup = root.insertGroup(1, 'Kvaliteter')

        self.style = Style()
        self.style.visibility('Klassificering', False)

        views = ['point_class', 'line_class', 'polygon_class']
        view_names =	{
		  'point_class': 'Punktkvalitet',
		  'line_class': 'Linjekvalitet',
		  'polygon_class': 'Ytkvalitet'
		}

        for view in views:
            lyr = proj.mapLayersByName(view_names[view])
            if not lyr:
                pathLayer = '{}\{}|layername={}'.format(path, db, view)
                vlayer = QgsVectorLayer(pathLayer, view_names[view], 'ogr')
                vlayer.setProviderEncoding("utf-8")
                self.style.oneColor(vlayer)
                proj.addMapLayer(vlayer, False)
                mygroup.addLayer(vlayer)
            else:
                lyr[0].triggerRepaint()
    def doLayer(self, item):
        ogrFeature = item.data(Qt.UserRole)
        geom = QgsGeometry.fromWkt(ogrFeature.GetGeometryRef().ExportToWkt())

        fields = QgsFields()
        fields.append(QgsField("id", QVariant.String))
        fields.append(QgsField("name",  QVariant.String))
        fet = QgsFeature()
        fet.initAttributes(2)
        fet.setFields(fields)
        fet.setGeometry(geom)
        fet.setAttribute("id", (ogrFeature.GetFieldAsString('id')))
        fet.setAttribute("name", (ogrFeature.GetFieldAsString('name')))

        vl = None
        if not self.plugin.singleLayer:
            if geom.type() == QgsWkbTypes.PolygonGeometry:
                layerName = "OSMPlaceSearch Polygon"
                layerId = self.MultiPolygonLayerId
            if geom.type() == QgsWkbTypes.LineGeometry:
                layerName = "OSMPlaceSearch Line"
                layerId = self.LineLayerId
            if geom.type() == QgsWkbTypes.PointGeometry:
                layerName = "OSMPlaceSearch Point"
                layerId = self.PointLayerId

            vl = QgsProject.instance().mapLayer(layerId)
            if vl is not None:
                pr = vl.dataProvider()
            else:
                if geom.type() == QgsWkbTypes.PolygonGeometry:
                    vl = QgsVectorLayer("MultiPolygon", layerName, "memory")
                    self.MultiPolygonLayerId = vl.id()
                if geom.type() == QgsWkbTypes.LineGeometry:
                    vl = QgsVectorLayer("MultiLineString", layerName, "memory")
                    self.LineLayerId = vl.id()
                if geom.type() == QgsWkbTypes.PointGeometry:
                    vl = QgsVectorLayer("Point", layerName, "memory")
                    self.PointLayerId = vl.id()

                if vl is not None:
                    pr = vl.dataProvider()
                    # ajout de champs
                    pr.addAttributes(fields.toList())

                QgsProject.instance().addMapLayer(vl)
        else:
            layerName = "OSM "+ogrFeature.GetFieldAsString('id')

            # creer une nouvelle couche si n'existe pas encore
            if geom.type() == QgsWkbTypes.PolygonGeometry:
                vl = QgsVectorLayer("MultiPolygon", layerName, "memory")
            if geom.type() == QgsWkbTypes.LineGeometry:
                vl = QgsVectorLayer("MultiLineString", layerName, "memory")
            if geom.type() == QgsWkbTypes.PointGeometry:
                vl = QgsVectorLayer("Point", layerName, "memory")

            if vl is not None:
                pr = vl.dataProvider()
                # ajout de champs
                pr.addAttributes(fields.toList())

            QgsProject.instance().addMapLayer(vl)

        if vl is not None:
            vl.setProviderEncoding('UTF-8')
            vl.startEditing()
            pr.addFeatures([fet])
            vl.commitChanges()

            # mise a jour etendue de la couche
            vl.updateExtents()

            layerTree = QgsProject.instance().layerTreeRoot().findLayer(vl)
            if layerTree:
                self.plugin.iface.layerTreeView()\
                    .layerTreeModel().refreshLayerLegend(layerTree)  # Refresh legend

            self.go(item, False)
class NLSGeoPackageLoader:
    """QGIS Plugin Implementation."""
    def __init__(self, iface):
        """Constructor.

        :param iface: An interface instance that will be passed to this class
            which provides the hook by which you can manipulate the QGIS
            application at run time.
        :type iface: QgsInterface
        """
        # Save reference to the QGIS interface
        self.iface = iface
        # initialize plugin directory
        self.plugin_dir = os.path.dirname(__file__)
        # initialize locale
        locale = QSettings().value('locale/userLocale')[0:2]
        locale_path = os.path.join(self.plugin_dir, 'i18n',
                                   'NLSGeoPackageLoader_{}.qm'.format(locale))

        if os.path.exists(locale_path):
            self.translator = QTranslator()
            self.translator.load(locale_path)

            if qVersion() > '4.3.3':
                QCoreApplication.installTranslator(self.translator)

        # Declare instance attributes
        self.actions = []
        self.menu = self.tr(u'&NLS GeoPackage Downloader')

        # Check if plugin was started the first time in current QGIS session
        # Must be set in initGui() to survive plugin reloads
        self.first_start = None

        self.path = os.path.dirname(__file__)
        self.data_download_dir = self.path

        self.nls_user_key_dialog = uic.loadUi(
            os.path.join(self.path, NLS_USER_KEY_DIALOG_FILE))
        self.first_run = QSettings().value("/NLSgpkgloader/first_run",
                                           True,
                                           type=bool)
        if self.first_run:
            QSettings().setValue("/NLSgpkgloader/first_run", False)

    # 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 QCoreApplication.translate('NLSGeoPackageLoader', message)

    def add_action(self,
                   icon_path,
                   text,
                   callback,
                   enabled_flag=True,
                   add_to_menu=True,
                   add_to_toolbar=True,
                   status_tip=None,
                   whats_this=None,
                   parent=None):
        """Add a toolbar icon to the toolbar.

        :param icon_path: Path to the icon for this action. Can be a resource
            path (e.g. ':/plugins/foo/bar.png') or a normal file system path.
        :type icon_path: str

        :param text: Text that should be shown in menu items for this action.
        :type text: str

        :param callback: Function to be called when the action is triggered.
        :type callback: function

        :param enabled_flag: A flag indicating if the action should be enabled
            by default. Defaults to True.
        :type enabled_flag: bool

        :param add_to_menu: Flag indicating whether the action should also
            be added to the menu. Defaults to True.
        :type add_to_menu: bool

        :param add_to_toolbar: Flag indicating whether the action should also
            be added to the toolbar. Defaults to True.
        :type add_to_toolbar: bool

        :param status_tip: Optional text to show in a popup when mouse pointer
            hovers over the action.
        :type status_tip: str

        :param parent: Parent widget for the new action. Defaults None.
        :type parent: QWidget

        :param whats_this: Optional text to show in the status bar when the
            mouse pointer hovers over the action.

        :returns: The action that was created. Note that the action is also
            added to self.actions list.
        :rtype: QAction
        """

        icon = QIcon(icon_path)
        action = QAction(icon, text, parent)
        action.triggered.connect(callback)
        action.setEnabled(enabled_flag)

        if status_tip is not None:
            action.setStatusTip(status_tip)

        if whats_this is not None:
            action.setWhatsThis(whats_this)

        if add_to_toolbar:
            # Adds plugin icon to Plugins toolbar
            self.iface.addToolBarIcon(action)

        if add_to_menu:
            self.iface.addPluginToMenu(self.menu, action)

        self.actions.append(action)

        return action

    def initGui(self):
        """Create the menu entries and toolbar icons inside the QGIS GUI."""

        icon_path = ':/plugins/nls_geopackage_loader/icon.png'
        self.add_action(icon_path,
                        text=self.tr(u'NLS GeoPackage Downloader'),
                        callback=self.run,
                        parent=self.iface.mainWindow())

        # will be set False in run()
        self.first_start = True

    def unload(self):
        """Removes the plugin menu item and icon from QGIS GUI."""
        for action in self.actions:
            self.iface.removePluginMenu(self.tr(u'&NLS GeoPackage Downloader'),
                                        action)
            self.iface.removeToolBarIcon(action)

    def run(self):
        """Run method that performs all the real work"""
        self.nls_user_key = QSettings().value("/NLSgpkgloader/userKey",
                                              "",
                                              type=str)
        self.data_download_dir = QSettings().value(
            "/NLSgpkgloader/dataDownloadDir", "", type=str)
        self.fileName = QSettings().value("/NLSgpkgloader/defaultFileName",
                                          "mtk.gpkg",
                                          type=str)
        self.addDownloadedDataAsLayer = QSettings().value(
            "/NLSgpkgloader/addDownloadedDataAsLayer", True, type=bool)
        self.showMunicipalitiesAsLayer = QSettings().value(
            "/NLSgpkgloader/showMunicipalitiesAsLayer", True, type=bool)
        self.showUTMGridsAsLayer = QSettings().value(
            "/NLSgpkgloader/showUTMGridsAsLayer", False, type=bool)
        self.showSeatilesAsLayer = QSettings().value(
            "/NLSgpkgloader/showSeatilesAsLayer", False, type=bool)

        if self.nls_user_key == "":
            res = self.showSettingsDialog()
            if not res: return
        if not self.loadLayers():
            QMessageBox.critical(
                self.iface.mainWindow(), self.tr(u'Failed to load data'),
                self.tr(u'Check that necessary files exist in data folder'))
            return

        self.product_types = self.downloadNLSProductTypes()

        self.municipalities_dialog = uic.loadUi(
            os.path.join(self.path, MUNICIPALITIES_DIALOG_FILE))
        self.municipalities_dialog.settingsPushButton.clicked.connect(
            self.showSettingsDialog)
        self.municipalities_dialog.fileNameEdit.setValue(self.fileName)
        self.municipalities_dialog.loadLayers.setChecked(
            self.addDownloadedDataAsLayer)
        self.municipalities_dialog.loadMunLayer.setChecked(
            self.showMunicipalitiesAsLayer)
        self.municipalities_dialog.loadUtmGrids.setChecked(
            self.showUTMGridsAsLayer)
        self.municipalities_dialog.loadSeaGrids.setChecked(
            self.showSeatilesAsLayer)
        self.municipalities_dialog.loadLayers.stateChanged.connect(
            self.toggleLayers)
        self.municipalities_dialog.loadMunLayer.stateChanged.connect(
            self.toggleLayers)
        self.municipalities_dialog.loadUtmGrids.stateChanged.connect(
            self.toggleLayers)
        self.municipalities_dialog.loadSeaGrids.stateChanged.connect(
            self.toggleLayers)
        self.toggleLayers()

        for feature in self.municipality_layer.getFeatures():
            item = QListWidgetItem(feature['NAMEFIN'])
            self.municipalities_dialog.municipalityListWidget.addItem(item)

        for key, value in self.product_types.items():
            item = QListWidgetItem(value)
            self.municipalities_dialog.productListWidget.addItem(item)
            if value in MTK_PRESELECTED_PRODUCTS:
                self.municipalities_dialog.productListWidget.setCurrentItem(
                    item)

        self.municipalities_dialog.show()

        result = self.municipalities_dialog.exec_()
        if result:
            self.fileName = self.municipalities_dialog.fileNameEdit.text(
            ).strip()
            if self.fileName == "":
                QMessageBox.critical(self.iface.mainWindow(),
                                     self.tr(u'Invalid filename'),
                                     self.tr(u'Please enter a filename'))
                return
            if self.fileName.split('.')[-1].lower() != 'gpkg':
                self.fileName += '.gpkg'
            QSettings().setValue("/NLSgpkgloader/defaultFileName",
                                 self.fileName)
            self.gpkg_path = os.path.join(self.data_download_dir,
                                          self.fileName)
            if os.path.isfile(self.gpkg_path):
                reply = QMessageBox.question(
                    self.iface.mainWindow(), 'Overwrite?',
                    'Overwrite file ' + self.gpkg_path + '?', QMessageBox.Yes,
                    QMessageBox.No)
                if reply == QMessageBox.Yes:
                    os.remove(self.gpkg_path)
                else:
                    return

            self.progress_dialog = uic.loadUi(
                os.path.join(self.path, NLS_PROGRESS_DIALOG_FILE))
            self.progress_dialog.progressBar.hide()
            self.progress_dialog.label.setText('Initializing...')
            self.progress_dialog.show()

            self.utm25lr_features = []
            self.selected_geoms = []
            for feature in self.utm25lr_layer.selectedFeatures():
                self.utm25lr_features.append(feature)
                self.selected_geoms.append(feature.geometry())
            grids = [
                self.utm5_layer, self.utm10_layer, self.utm25_layer,
                self.utm50_layer, self.utm100_layer, self.utm200_layer
            ]
            for grid in grids:
                for feature in grid.selectedFeatures():
                    self.selected_geoms.append(feature.geometry())

            selected_mun_names = []
            for item in self.municipalities_dialog.municipalityListWidget.selectedItems(
            ):
                selected_mun_names.append(item.text())
            for feature in self.municipality_layer.getFeatures():
                if feature["NAMEFIN"] in selected_mun_names:
                    self.selected_geoms.append(feature.geometry())

            for feature in self.municipality_layer.selectedFeatures():
                self.selected_geoms.append(feature.geometry())
            for feature in self.seatile_layer.selectedFeatures():
                self.selected_geoms.append(feature.geometry())

            product_types = {
            }  # TODO ask from the user via dialog that lists types based on NLS Atom service
            self.selected_mtk_product_types = []
            for selected_prod_title in self.municipalities_dialog.productListWidget.selectedItems(
            ):  # TODO: clean up the loop
                for key, value in list(self.product_types.items()):
                    if selected_prod_title.text() == value:
                        if key.startswith(
                                MTK_LAYERS_KEY_PREFIX):  # Individual MTK layer
                            self.selected_mtk_product_types.append(
                                selected_prod_title.text())
                            product_types[
                                MTK_ALL_PRODUCTS_URL] = MTK_ALL_PRODUCTS_TITLE
                        else:
                            product_types[key] = value

            if len(product_types) > 0 and len(self.selected_geoms) > 0:
                QCoreApplication.processEvents()

                self.getIntersectingFeatures(
                    self.municipality_layer.selectedFeatures(),
                    self.utm25lr_layer, selected_mun_names)
                self.getIntersectingFeatures(
                    self.seatile_layer.selectedFeatures(), self.utm25lr_layer)
                for grid in grids:
                    self.getIntersectingFeatures(grid.selectedFeatures(),
                                                 self.utm25lr_layer)

                self.downloadData(product_types)

            else:
                self.progress_dialog.hide()
                QMessageBox.critical(self.iface.mainWindow(),
                                     self.tr(u'Invalid selection'),
                                     self.tr(u'Found nothing to download!'))
                return

    def toggleLayers(self):
        '''Load municipality and map tile layers'''
        self.addDownloadedDataAsLayer = self.municipalities_dialog.loadLayers.isChecked(
        )
        self.showMunicipalitiesAsLayer = self.municipalities_dialog.loadMunLayer.isChecked(
        )
        self.showUTMGridsAsLayer = self.municipalities_dialog.loadUtmGrids.isChecked(
        )
        self.showSeatilesAsLayer = self.municipalities_dialog.loadSeaGrids.isChecked(
        )
        QSettings().setValue("/NLSgpkgloader/addDownloadedDataAsLayer",
                             self.addDownloadedDataAsLayer)
        QSettings().setValue("/NLSgpkgloader/showMunicipalitiesAsLayer",
                             self.showMunicipalitiesAsLayer)
        QSettings().setValue("/NLSgpkgloader/showUTMGridsAsLayer",
                             self.showUTMGridsAsLayer)
        QSettings().setValue("/NLSgpkgloader/showSeatilesAsLayer",
                             self.showSeatilesAsLayer)

        found_utm5_layer = found_utm10_layer = found_utm25lr_layer = \
            found_utm25_layer = found_utm50_layer = found_utm100_layer = \
                found_utm200_layer = found_seatiles_layer = found_municipality_layer = False

        current_layers = self.getLayers(self.instance.layerTreeRoot())

        for current_layer in current_layers:
            if current_layer.layer() == self.utm5_layer:
                found_utm5_layer = True
                current_layer.setItemVisibilityChecked(
                    self.showUTMGridsAsLayer)
            if current_layer.layer() == self.utm10_layer:
                found_utm10_layer = True
                current_layer.setItemVisibilityChecked(
                    self.showUTMGridsAsLayer)
            if current_layer.layer() == self.utm25lr_layer:
                found_utm25lr_layer = True
                current_layer.setItemVisibilityChecked(
                    self.showUTMGridsAsLayer)
            if current_layer.layer() == self.utm25_layer:
                found_utm25_layer = True
                current_layer.setItemVisibilityChecked(
                    self.showUTMGridsAsLayer)
            if current_layer.layer() == self.utm50_layer:
                found_utm50_layer = True
                current_layer.setItemVisibilityChecked(
                    self.showUTMGridsAsLayer)
            if current_layer.layer() == self.utm100_layer:
                found_utm100_layer = True
                current_layer.setItemVisibilityChecked(
                    self.showUTMGridsAsLayer)
            if current_layer.layer() == self.utm200_layer:
                found_utm200_layer = True
                current_layer.setItemVisibilityChecked(
                    self.showUTMGridsAsLayer)
            if current_layer.layer() == self.seatile_layer:
                found_seatiles_layer = True
                current_layer.setItemVisibilityChecked(
                    self.showSeatilesAsLayer)
            if current_layer.layer() == self.municipality_layer:
                found_municipality_layer = True
                current_layer.setItemVisibilityChecked(
                    self.showMunicipalitiesAsLayer)

        if self.showUTMGridsAsLayer:
            try:
                if not found_utm200_layer and self.utm200_layer:
                    self.instance.addMapLayer(self.utm200_layer)
                if not found_utm100_layer and self.utm100_layer:
                    self.instance.addMapLayer(self.utm100_layer)
                if not found_utm50_layer and self.utm50_layer:
                    self.instance.addMapLayer(self.utm50_layer)
                if not found_utm25_layer and self.utm25_layer:
                    self.instance.addMapLayer(self.utm25_layer)
                if not found_utm25lr_layer:
                    self.instance.addMapLayer(self.utm25lr_layer)
                if not found_utm10_layer and self.utm10_layer:
                    self.instance.addMapLayer(self.utm10_layer)
                if not found_utm5_layer and self.utm5_layer:
                    self.instance.addMapLayer(self.utm5_layer)
            except:
                self.loadLayers()
                if not found_utm200_layer and self.utm200_layer:
                    self.instance.addMapLayer(self.utm200_layer)
                if not found_utm100_layer and self.utm100_layer:
                    self.instance.addMapLayer(self.utm100_layer)
                if not found_utm50_layer and self.utm50_layer:
                    self.instance.addMapLayer(self.utm50_layer)
                if not found_utm25_layer and self.utm25_layer:
                    self.instance.addMapLayer(self.utm25_layer)
                if not found_utm25lr_layer:
                    self.instance.addMapLayer(self.utm25lr_layer)
                if not found_utm10_layer and self.utm10_layer:
                    self.instance.addMapLayer(self.utm10_layer)
                if not found_utm5_layer and self.utm5_layer:
                    self.instance.addMapLayer(self.utm5_layer)

        if self.showSeatilesAsLayer and not found_seatiles_layer:
            try:
                self.instance.addMapLayer(self.seatile_layer)
            except:
                self.loadLayers()
                self.instance.addMapLayer(self.seatile_layer)

        if self.showMunicipalitiesAsLayer and not found_municipality_layer:
            try:
                self.instance.addMapLayer(self.municipality_layer)
            except:
                self.loadLayers()
                self.instance.addMapLayer(self.municipality_layer)

    def loadLayers(self):
        self.municipality_layer = QgsVectorLayer(
            os.path.join(self.path, "data/SuomenKuntajako_2018_10k.shp"),
            "municipalities", "ogr")
        if not self.municipality_layer.isValid():
            QgsMessageLog.logMessage('Failed to load the municipality layer',
                                     'NLSgpkgloader', 2)
            self.iface.messageBar().pushMessage(
                "Error",
                "Failed to load the municipality layer",
                level=2,
                duration=5)
            return False
        self.municipality_layer.setProviderEncoding('ISO-8859-1')
        self.utm5_layer = QgsVectorLayer(
            os.path.join(self.path, "data/utm5.shp"), "utm5", "ogr")
        if not self.utm5_layer.isValid():
            QgsMessageLog.logMessage('Failed to load the UTM 5 grid layer',
                                     'NLSgpkgloader', 1)
            self.iface.messageBar().pushMessage(
                "Error",
                "Failed to load the UTM 5 grid layer",
                level=1,
                duration=5)
            self.utm5_layer = False
        self.utm10_layer = QgsVectorLayer(
            os.path.join(self.path, "data/utm10.shp"), "utm10", "ogr")
        if not self.utm10_layer.isValid():
            QgsMessageLog.logMessage('Failed to load the UTM 10 grid layer',
                                     'NLSgpkgloader', 1)
            self.iface.messageBar().pushMessage(
                "Error",
                "Failed to load the UTM 10 grid layer",
                level=1,
                duration=5)
            self.utm10_layer = False
        self.utm25lr_layer = QgsVectorLayer(
            os.path.join(self.path, "data/utm25LR.shp"), "utm25lr", "ogr")
        if not self.utm25lr_layer.isValid():
            QgsMessageLog.logMessage('Failed to load the UTM 25LR grid layer',
                                     'NLSgpkgloader', 2)
            self.iface.messageBar().pushMessage(
                "Error",
                "Failed to load the UTM 25LR grid layer",
                level=2,
                duration=5)
            return False
        self.utm25_layer = QgsVectorLayer(
            os.path.join(self.path, "data/utm25.shp"), "utm25", "ogr")
        if not self.utm25_layer.isValid():
            QgsMessageLog.logMessage('Failed to load the UTM 25 grid layer',
                                     'NLSgpkgloader', 1)
            self.iface.messageBar().pushMessage(
                "Error",
                "Failed to load the UTM 25 grid layer",
                level=1,
                duration=5)
            self.utm25_layer = False
        self.utm50_layer = QgsVectorLayer(
            os.path.join(self.path, "data/utm50.shp"), "utm50", "ogr")
        if not self.utm50_layer.isValid():
            QgsMessageLog.logMessage('Failed to load the UTM 50 grid layer',
                                     'NLSgpkgloader', 1)
            self.iface.messageBar().pushMessage(
                "Error",
                "Failed to load the UTM 50 grid layer",
                level=1,
                duration=5)
            self.utm50_layer = False
        self.utm100_layer = QgsVectorLayer(
            os.path.join(self.path, "data/utm100.shp"), "utm100", "ogr")
        if not self.utm100_layer.isValid():
            QgsMessageLog.logMessage('Failed to load the UTM 100 grid layer',
                                     'NLSgpkgloader', 1)
            self.iface.messageBar().pushMessage(
                "Error",
                "Failed to load the UTM 100 grid layer",
                level=1,
                duration=5)
            self.utm100_layer = False
        self.utm200_layer = QgsVectorLayer(
            os.path.join(self.path, "data/utm200.shp"), "utm200", "ogr")
        if not self.utm200_layer.isValid():
            QgsMessageLog.logMessage('Failed to load the UTM 200 grid layer',
                                     'NLSgpkgloader', 1)
            self.iface.messageBar().pushMessage(
                "Error",
                "Failed to load the UTM 200 grid layer",
                level=1,
                duration=5)
            self.utm200_layer = False

        expression = '"product_group_id" = 5'
        self.seatile_layer = QgsVectorLayer(
            os.path.join(self.path, "data/seatiles_3067.gpkg"), "seatiles",
            "ogr")
        self.seatile_layer.setSubsetString(expression)
        if not self.seatile_layer.isValid():
            QgsMessageLog.logMessage('Failed to load the ocean grid layer',
                                     'NLSgpkgloader', 2)
            self.iface.messageBar().pushMessage(
                "Error",
                "Failed to load the sea grid layer",
                level=2,
                duration=5)
            self.seatile_layer = False

        self.instance = QgsProject.instance()
        current_layers = self.getLayers(self.instance.layerTreeRoot())

        for lnode in current_layers:
            if lnode.layer().dataProvider().dataSourceUri(
            ) == self.municipality_layer.dataProvider().dataSourceUri():
                self.municipality_layer = lnode.layer()
            if lnode.layer().dataProvider().dataSourceUri(
            ) == self.seatile_layer.dataProvider().dataSourceUri():
                self.seatile_layer = lnode.layer()
            if lnode.layer().dataProvider().dataSourceUri(
            ) == self.utm5_layer.dataProvider().dataSourceUri():
                self.utm5_layer = lnode.layer()
            if lnode.layer().dataProvider().dataSourceUri(
            ) == self.utm10_layer.dataProvider().dataSourceUri():
                self.utm10_layer = lnode.layer()
            if lnode.layer().dataProvider().dataSourceUri(
            ) == self.utm25_layer.dataProvider().dataSourceUri():
                self.utm25_layer = lnode.layer()
            if lnode.layer().dataProvider().dataSourceUri(
            ) == self.utm25lr_layer.dataProvider().dataSourceUri():
                self.utm25lr_layer = lnode.layer()
            if lnode.layer().dataProvider().dataSourceUri(
            ) == self.utm50_layer.dataProvider().dataSourceUri():
                self.utm50_layer = lnode.layer()
            if lnode.layer().dataProvider().dataSourceUri(
            ) == self.utm100_layer.dataProvider().dataSourceUri():
                self.utm100_layer = lnode.layer()
            if lnode.layer().dataProvider().dataSourceUri(
            ) == self.utm200_layer.dataProvider().dataSourceUri():
                self.utm200_layer = lnode.layer()

        return True

    def getLayers(self, root):
        layers = []
        for node in root.children():
            if isinstance(node, QgsLayerTreeGroup):
                layers.extend(self.getLayers(node))
            else:
                layers.append(node)
        return layers

    def getIntersectingFeatures(self,
                                features,
                                layer,
                                selected_mun_names=None):
        if selected_mun_names:
            expression = ''
            for mun in selected_mun_names:
                expression += u'"NAMEFIN" = \'' + mun + u'\' OR '
            expression = expression[:-4]

            iter = self.municipality_layer.getFeatures(expression)
            for feature in iter:
                mun_geom = feature.geometry()
                for layer_feature in layer.getFeatures():
                    layer_geom = layer_feature.geometry()
                    if mun_geom.intersects(layer_geom):
                        if feature not in self.utm25lr_features:
                            self.utm25lr_features.append(layer_feature)

        for feature in features:
            feat_geom = feature.geometry()
            for layer_feature in layer.getFeatures():
                layer_geom = layer_feature.geometry()
                if feat_geom.intersects(layer_geom):
                    if feature not in self.utm25lr_features:
                        self.utm25lr_features.append(layer_feature)

    def downloadData(self, product_types):

        self.all_urls = []
        self.total_download_count = 0
        self.download_count = 0
        self.layers_added_count = 0

        for product_key, product_title in product_types.items():
            urls = self.createDownloadURLS(product_key, product_title)
            self.all_urls.extend(urls)
            self.total_download_count += len(urls)

        try:
            percentage = self.download_count / float(
                self.total_download_count) * 100.0
            percentage_text = "%.2f" % round(percentage, 2)
        except ZeroDivisionError:
            QMessageBox.critical(self.iface.mainWindow(),
                                 self.tr(u'Invalid selection'),
                                 self.tr(u'Found nothing to download!'))
            self.progress_dialog.hide()
            return

        self.progress_dialog.progressBar.reset()
        self.progress_dialog.progressBar.show()
        self.progress_dialog.label.setText('Downloading data...')
        QTimer.singleShot(1000, self.downloadOneFile)

    def downloadNLSProductTypes(self):
        products = {}

        url = "https://tiedostopalvelu.maanmittauslaitos.fi/tp/feed/mtp?api_key=" + self.nls_user_key
        # TODO: use qgis.gui.QgsFileDownloader?
        self.verify = True
        try:
            r = requests.get(url, verify=self.verify)
        except requests.exceptions.SSLError:
            # TODO: warn user of certification fail
            self.verify = False
            r = requests.get(url, verify=self.verify)

        e = xml.etree.ElementTree.fromstring(r.text)

        for entry in e.findall('{http://www.w3.org/2005/Atom}entry'):
            title = entry.find('{http://www.w3.org/2005/Atom}title')
            QgsMessageLog.logMessage(title.text, 'NLSgpkgloader', 0)
            id = entry.find('{http://www.w3.org/2005/Atom}id')
            QgsMessageLog.logMessage(id.text, 'NLSgpkgloader', 0)

            if title.text == 'Maastotietokanta, kaikki kohteet':
                # TODO let user choose in the options dialog if the individual layers can be selected
                for mtk_product_name in MTK_PRODUCT_NAMES:
                    products[MTK_LAYERS_KEY_PREFIX +
                             mtk_product_name] = mtk_product_name
            else:
                # products[id.text] = title.text
                pass

        return products

    def downloadOneFile(self):
        if self.download_count == self.total_download_count or self.download_count >= len(
                self.all_urls):
            QgsMessageLog.logMessage(
                "download_count == total_download_count or download_count >= len(all_urls)",
                'NLSgpkgloader', 2)
            return

        url = self.all_urls[self.download_count][0]
        # QgsMessageLog.logMessage(url, 'NLSgpkgloader', 0)
        r = requests.get(url, stream=True, verify=self.verify)
        # TODO check r.status_code & r.ok

        url_parts = url.split('/')
        file_name = url_parts[-1].split('?')[0]

        data_dir_name = self.all_urls[self.download_count][1]
        data_dir_name = data_dir_name.replace(":", "_suhde_")
        dir_path = os.path.join(self.data_download_dir, data_dir_name)

        #QgsMessageLog.logMessage(dir_path, 'NLSgpkgloader', 0)
        if not os.path.exists(dir_path):
            try:
                os.makedirs(dir_path)
            except OSError as exc:
                QgsMessageLog.logMessage(str(exc.errno), 'NLSgpkgloader', 2)
        if not os.path.exists(dir_path):
            QgsMessageLog.logMessage("dir not created", 'NLSgpkgloader', 2)

        # TODO: don't keep zipfiles
        #z = zipfile.ZipFile(StringIO.StringIO(r.content))
        #z.extractall(os.path.join(self.data_download_dir, value))
        with open(os.path.join(dir_path, file_name), 'wb') as f:
            f.write(r.content)

        if "zip" in file_name:
            dir_path = os.path.join(dir_path, file_name.split('.')[0])
            try:
                z = zipfile.ZipFile(io.BytesIO(r.content))
                z.extractall(dir_path)
            except BadZipFile:
                QgsMessageLog.logMessage("Bad zip file: " + file_name,
                                         'NLSgpkgloader', 1)

        self.download_count += 1
        percentage = self.download_count / float(
            self.total_download_count) * 100.0
        self.progress_dialog.progressBar.setValue(percentage)

        if self.download_count == self.total_download_count:
            QgsMessageLog.logMessage("done downloading data", 'NLSgpkgloader',
                                     0)
            self.createGeoPackage()
        else:
            QTimer.singleShot(10, self.downloadOneFile)

    def createGeoPackage(self):
        '''Creates a GeoPackage from the downloaded MTK data'''
        self.progress_dialog.progressBar.reset()
        self.progress_dialog.label.setText('Writing layers to GeoPackage...')

        writeTask = CreateGeoPackageTask('Write GML to GPKG', self.all_urls, self.total_download_count, \
            self.selected_mtk_product_types, self.data_download_dir, self.gpkg_path)
        dissolveTask = DissolveFeaturesTask("Dissolve features",
                                            self.gpkg_path)
        clipTask = ClipLayersTask("Clip layers", self.selected_geoms,
                                  self.gpkg_path)
        cleanupTask = CleanUpTask("Delete temporary tables", self.path,
                                  self.gpkg_path)

        writeTask.taskCompleted.connect(lambda: self.runTask(dissolveTask))
        dissolveTask.taskCompleted.connect(lambda: self.runTask(clipTask))
        clipTask.taskCompleted.connect(lambda: self.runTask(cleanupTask))
        cleanupTask.taskCompleted.connect(lambda: self.finishProcessing())

        self.runTask(writeTask)

    def runTask(self, task):
        self.progress_dialog.label.setText(task.description())
        task.progressChanged.connect(
            lambda: self.progress_dialog.progressBar.setValue(task.progress()))
        QgsApplication.taskManager().addTask(task)

    def finishProcessing(self):
        if self.addDownloadedDataAsLayer:
            self.progress_dialog.label.setText("Adding layers to QGIS")
            self.progress_dialog.progressBar.hide()
            conn = ogr.Open(self.gpkg_path)
            for i in conn:
                if i.GetName() in MTK_STYLED_LAYERS.values() or i.GetName(
                )[3:] in MTK_PRODUCT_NAMES:
                    self.instance.addMapLayer(
                        QgsVectorLayer(
                            self.gpkg_path + "|layername=" + i.GetName(),
                            i.GetName(), "ogr"))
        self.iface.messageBar().pushMessage(self.tr(u'GeoPackage creation finished'), \
            self.tr(u'NLS data download finished. Data located under ') + \
            self.gpkg_path, level=3)
        self.progress_dialog.hide()
        return True

    def showSettingsDialog(self):
        self.nls_user_key_dialog.dataLocationQgsFileWidget.setStorageMode(
            QgsFileWidget.GetDirectory)
        self.nls_user_key_dialog.userKeyLineEdit.setText(self.nls_user_key)
        self.nls_user_key_dialog.dataLocationQgsFileWidget.setFilePath(
            QSettings().value("/NLSgpkgloader/dataDownloadDir",
                              os.path.join(self.path, "data"),
                              type=str))

        self.nls_user_key_dialog.show()
        result = self.nls_user_key_dialog.exec_()
        if result:
            self.nls_user_key = self.nls_user_key_dialog.userKeyLineEdit.text(
            ).strip()
            if self.nls_user_key == "":
                # cannot work without the key, so user needs to be notified
                QMessageBox.critical(
                    self.iface.mainWindow(), self.tr(u'User-key is needed'),
                    self.tr(u'Data cannot be downloaded without the NLS key'))
                return False
            self.data_download_dir = self.nls_user_key_dialog.dataLocationQgsFileWidget.filePath(
            )

            QSettings().setValue("/NLSgpkgloader/userKey", self.nls_user_key)
            QSettings().setValue("/NLSgpkgloader/dataDownloadDir",
                                 self.data_download_dir)
            return True

        else:
            # cannot work without the key, so user needs to be notified
            QMessageBox.critical(
                self.iface.mainWindow(), self.tr(u'User-key is needed'),
                self.tr(u'Data cannot be downloaded without the NLS key'))
            return False

    def createDownloadURLS(self, product_key, product_title):
        urls = []
        if product_key == "https://tiedostopalvelu.maanmittauslaitos.fi/tp/feed/mtp/maastotietokanta/kaikki":
            for utm_feature in self.utm25lr_features:
                sheet_name = utm_feature["LEHTITUNNU"]
                sn1 = sheet_name[:2]
                sn2 = sheet_name[:3]
                modified_key = product_key.replace("/feed/mtp",
                                                   "/tilauslataus/tuotteet")
                url = modified_key + "/etrs89/gml/" + sn1 + "/" + sn2 + "/" + sheet_name + "_mtk.zip?api_key=" + self.nls_user_key
                urls.append((url, product_title, product_key, "gml"))
        else:
            QgsMessageLog.logMessage(
                'Unknown product ' + product_title +
                ', please send error report to the author', 'NLSgpkgloader', 2)
            self.iface.messageBar().pushMessage(
                'Unknown product ' + product_title +
                ', please send error report to the author',
                level=2,
                duration=10)

        return urls
Example #17
0
    def agregacio(self,
                  llegenda,
                  nomCapa: str,
                  zona: str,
                  tipusAgregacio: str,
                  renderParams: QvMapRendererParams,
                  campAgregat: str = '',
                  simple=True,
                  tipusDistribucio: str = "Total",
                  campExtensio: str = mv.MAP_EXTENSIO,
                  filtre: str = '',
                  veure: bool = True,
                  form: QDialog = None) -> bool:
        """ Realiza la agragación de los datos por zona, la generación del mapa y su simbología.
        
        Arguments:
            llegenda {QvLlegenda} -- Leyenda
            nomCapa {str} -- Nombre de la capa del mapa a generar
            zona {str} -- Zona de agregación
            tipusAgregacio {str} -- Tipo de agregación
            renderParams {QvMapRendererParams} -- Parámetros de simbología
        
        Keyword Arguments:
            campAgregat {str} -- Campo que se utiliza en el cálculo de la agragación (default: {''})
            tipusDistribucio {str} -- Tipo de distribución (default: {"Total"})
            campExtensio {str} -- Nombre del campo que indica la extensión del mapa (default: {''})
            filtre {str} -- Expresión para filtrar los datos (default: {''})
            veure {bool} -- Si es True, añade la nueva capa con el mapa en la leyenda (default: {True})
            form {QDialog} -- Formulario desde donde se invoca la función (default: {None})
        
        Returns:
            bool -- False si hubo errores (mensaje de error en self.msgError)
        """

        if not PANDAS_ENABLED:
            self.msgError = PANDAS_ERROR
            return False

        self.fMapa = ''
        self.fSQL = ''
        self.llegenda = llegenda
        self.msgError = ''
        self.form = form
        self.descripcio = "Arxiu de dades: " + self.fZones + '\n' + \
            "Data: " +  QDate.currentDate().toString(QvApp().locale.dateFormat(QvApp().locale.ShortFormat)) + '\n' + \
            "Zona: " + zona + '\n' + \
            "Tipus d'agregació: " + tipusAgregacio + '\n' + \
            "Camp de càlcul: " + campAgregat
        if not simple:
            self.descripcio += '\n' + \
                "Filtre: " + filtre + '\n' + \
                "Distribució: " + tipusDistribucio

        if not self.verifZona(zona):
            self.msgError = "Error en zona"
            return False

        if campAgregat is not None and campAgregat != '':
            self.campAgregat = campAgregat
        elif tipusAgregacio == 'Recompte' and campAgregat == '':
            self.campAgregat = '*'
        else:
            self.msgError = "Error en campAgregat"
            return False

        if tipusAgregacio is None or tipusAgregacio not in mv.MAP_AGREGACIO.keys(
        ):
            self.msgError = "Error en tipusAgregacio"
            return False
        self.tipusAgregacio = mv.MAP_AGREGACIO[tipusAgregacio].format(
            self.campAgregat)

        if tipusDistribucio is None or tipusDistribucio not in mv.MAP_DISTRIBUCIO.keys(
        ):
            self.msgError = "Error en tipusDistribucio"
            return False
        self.tipusDistribucio = mv.MAP_DISTRIBUCIO[tipusDistribucio]

        self.filtre = filtre
        self.nomCapa = self.netejaString(nomCapa, True)

        # if not self.generaCapaQgis(nomCapa):
        #     return False

        if not self.generaCapaGpd(self.nomCapa, tipusAgregacio,
                                  tipusDistribucio, renderParams,
                                  campExtensio):
            return False

        # Carga capa de agregación
        mapLyr = QgsVectorLayer(self.fSQL, nomCapa, "ogr")
        mapLyr.setProviderEncoding("UTF-8")
        if not mapLyr.isValid():
            self.msgError = "No s'ha pogut carregar capa de agregació: " + self.fSQL
            return False

        # Renderer para mapificar
        mapRenderer = renderParams.mapRenderer(self.llegenda)
        self.renderer = mapRenderer.calcRender(mapLyr)
        if self.renderer is None:
            self.msgError = "No s'ha pogut elaborar el mapa"
            return False
        else:
            mapLyr.setRenderer(self.renderer)

        # Identificador de mapificación para qVista
        QgsExpressionContextUtils.setLayerVariable(mapLyr, mv.MAP_ID,
                                                   self.descripcio)
        mapLyr.setDisplayExpression(renderParams.campCalculat)

        # Guarda simbología en GPKG
        err = self.llegenda.saveStyleToGeoPackage(mapLyr, mv.MAP_ID)
        if err != '':
            self.msgError = "Hi ha hagut problemes al desar la simbologia\n({})".format(
                err)
            return False

        # Fin correcto
        self.fMapa = self.fSQL
        if veure:
            self.llegenda.project.addMapLayer(mapLyr)
        return True