Пример #1
1
def createContours(canvas, dhm):
    contourLyr = dhm['contour']
    contourName = "Hoehenlinien_" + dhm['name']
    
    # Get current CRS of qgis project
    s = QSettings()
    oldValidation = s.value("/Projections/defaultBehaviour")
    crs = canvas.mapSettings().destinationCrs()
    crsEPSG = crs.authid()
    # If project and raster CRS are equal and set correctly
    if crsEPSG == dhm['spatialRef'] and "USER" not in crsEPSG:
        s.setValue("/Projections/defaultBehaviour", "useProject")
    else:
        crs = dhm['layer'].crs()
    
    # If contours exist, remove them
    if contourLyr:
        QgsProject.instance().removeMapLayer(contourLyr.id())
        contourLyr = None
    
    # If no contours exist, create them
    else:
        outputPath = os.path.join(os.path.dirname(dhm['path']), contourName + '.shp')
        if os.path.exists(outputPath):
            contourLyr = QgsVectorLayer(outputPath, contourName, "ogr")
        else:
            processingParams = {
                'INPUT': dhm['layer'],
                'BAND': 1,
                'INTERVAL': 20,
                'FIELD_NAME': "Hoehe",
                'OUTPUT': outputPath
            }
            algOutput = run("gdal:contour", processingParams)
            contourLyr = QgsVectorLayer(algOutput['OUTPUT'], contourName, "ogr")
        # contourLyr the same CRS as qgis project
        contourLyr.setCrs(crs)
        QgsProject.instance().addMapLayer(contourLyr)
        s.setValue("/Projections/defaultBehaviour", oldValidation)
        
    # More useful stuff
    # uri = "linestring?crs=epsg:{}".format(crsNum)
    # contourName = "Hoehenlinien_" + self.dhm['name']
    # contour = QgsVectorLayer(uri, contourName,  "memory")
    
    return contourLyr
Пример #2
0
    def loadLayerTable(self, carhabLayer, tableName):

        # Retrieve layer from provider.
        uri = QgsDataSourceURI()
        uri.setDatabase(carhabLayer.dbPath)

        schema = ''
        geom_column = 'the_geom'
        uri.setDataSource(schema, tableName, geom_column)

        display_name = carhabLayer.getName()+'_'+tableName

        layer = QgsVectorLayer(uri.uri(), display_name, 'spatialite')
        crsType = QgsCoordinateReferenceSystem.EpsgCrsId
        crsVal = 2154
        crs = QgsCoordinateReferenceSystem(crsVal, crsType)
        layer.setCrs(crs)

        # "Bind" layer to carhab layer.
        if self.getCarhabLayerByDbPath(carhabLayer.dbPath):
            layer.setCustomProperty('carhabLayer', carhabLayer.id)

        # Add layer to map (False to add to group)
        QgsMapLayerRegistry.instance().addMapLayer(layer, False)

        iface.mapCanvas().setExtent(layer.extent())

        return layer
    def requestShapeFile(self, shapeFilePath, epsg=None, layerName=None, groupName=None, useLayerFromTree=True, addToCanvas=False):
        try:
            #QMessageBox.information(None, "Info", "LOAD SHP")
            layer = None
            if not layerName:
                layerName = os.path.basename(shapeFilePath)
                root, ext = os.path.splitext(layerName)
                if ext == '.shp':
                    layerName = root

            if useLayerFromTree:
                layer = self.findShapeFileLayerInTree(shapeFilePath)

            if layer is None:
                layer = QgsVectorLayer(shapeFilePath, layerName, "ogr")
                if epsg != None:
                    layer.setCrs(QgsCoordinateReferenceSystem(epsg, QgsCoordinateReferenceSystem.EpsgCrsId))

                if addToCanvas:
                    self.addLayerToCanvas(layer, groupName)

            return layer
        except Exception as e:
            QMessageBox.warning(None, "Error Loading Shape File", u"{0}".format(e))
            return None
  def createVectorLayer(self, layerName):
    """Creates a vector layer in memory.

    Args:
      layerName: str, name of the layer to create.
    Returns:
      QgsVectorLayer instance
    """
    # We change the setting that by default asks user to choose a CRS for newly
    # created layers. This # setting is restored to its original value once
    # the layer is created.
    s = QSettings()
    oldValue = s.value('/Projections/defaultBehaviour')
    s.setValue('/Projections/defaultBehaviour', 'useGlobal')
    vectorLayer = QgsVectorLayer('Polygon', layerName, 'memory')
    vectorLayer.setCrs(worldCrs)
    s.setValue('/Projections/defaultBehaviour', oldValue)
    self.dataProvider = vectorLayer.dataProvider()
    self.dataProvider.addAttributes(
        [QgsField('Project Identifier', QVariant.String),
         QgsField('Map Resource Identifier', QVariant.String),
         QgsField('Resource Identifier', QVariant.String),
         QgsField('Parent Resource Identifier', QVariant.String),
         QgsField('Resource Type', QVariant.String),
         QgsField('Resource Name', QVariant.String),
         QgsField('Data Source Type', QVariant.String)])
    return vectorLayer
def create_grid(size):
    """Create a polygonal grid using Processing.

    :param size: The cell size.
    :type size: int

    :return: The grid layer in memory.
    :rtype: QgsVectorLayer
    """
    output_filename = unique_filename(prefix='grid', suffix='.shp')

    result = processing.runalg(
        'qgis:vectorgrid',
        '336199.970553,352338.397991,7636164.67975,7648562.41208',
        size,  # X spacing
        size,  # Y spacing
        0,  # Output as polygons
        output_filename)

    layer = QgsVectorLayer(output_filename, 'grid', 'ogr')
    layer.setCrs(QgsCoordinateReferenceSystem(32740))

    remove_fields(layer, ['xmin', 'xmax', 'ymin', 'ymax'])

    # Make a copy in memory
    memory = create_memory_layer(
        'grid', layer.geometryType(), layer.crs(), layer.fields())
    copy_layer(layer, memory)

    print "NB cells : %s" % layer.featureCount()

    return memory
Пример #6
0
 def createQgisVectorLayer(self, layerFilePath):
     settings = QSettings()
     oldProjValue = settings.value("/Projections/defaultBehaviour", "prompt", type=str)
     settings.setValue("/Projections/defaultBehaviour", "useProject")
     qgisLayer = QgsVectorLayer(layerFilePath, "geometry", "ogr")
     qgisLayer.setCrs(QgsCoordinateReferenceSystem(2154, QgsCoordinateReferenceSystem.EpsgCrsId))
     settings.setValue("/Projections/defaultBehaviour", oldProjValue)
     return qgisLayer
Пример #7
0
    def create_layer(self, parameters, name, is_memory, dest_crs, layer_style=None):
        save_as = parameters.file_path
        file_format = parameters.file_format
        # save paramaters
        serialized = base64.b64encode(parameters.serialize(with_style=False, with_geometry=False))

        # save geometry
        layer = QgsVectorLayer("MultiPolygon?crs=%s" % dest_crs.authid(), name, "memory")
        pr = layer.dataProvider()
        layer.startEditing()
        layer.addAttribute(QgsField("params", QVariant.String))
        fet1 = QgsFeature(0)
        fet1.setFields(layer.fields())
        fet1.setAttribute("params", str(serialized)[2:-1])
        fet1.setGeometry(parameters.geometry)
        pr.addFeatures([fet1])
        layer.commitChanges()

        # copy layer style
        if layer_style is not None:
            self.set_layer_style(layer, layer_style)

        if is_memory:
            return layer

        if os.path.isfile(save_as):
            # delete first if already exists
            if save_as.endswith(".shp"):
                QgsVectorFileWriter.deleteShapeFile(save_as)
            else:
                os.unlink(save_as)

        # create the disk layer
        QgsMessageLog.logMessage("Mask saving '{}' as {}".format(save_as, file_format),
                                 'Extensions')
        error = QgsVectorFileWriter.writeAsVectorFormat(layer, save_as, "System", dest_crs,
                                                        file_format)

        if error == 0:
            nlayer = QgsVectorLayer(save_as, name, "ogr")
            if not nlayer.dataProvider().isValid():
                return None
            if not nlayer.hasGeometryType():
                return None
            # force CRS
            nlayer.setCrs(dest_crs)

            # copy layer style
            layer_style = self.get_layer_style(layer)
            self.set_layer_style(nlayer, layer_style)
            return nlayer
        else:
            raise RuntimeError(error)

        return None
Пример #8
0
 def loadEDGVLayer(self, uri, layer_name, provider):
     vlayer = QgsVectorLayer(uri.uri(), layer_name, provider)
     vlayer.setCrs(self.crs)
     QgsMapLayerRegistry.instance().addMapLayer(vlayer) #added due to api changes
     if self.isSpatialite and (self.dbVersion == '3.0' or self.dbVersion == '2.1.3'):
         lyr = '_'.join(layer_name.replace('\r', '').split('_')[1::])
     else:
         lyr = layer_name.replace('\r','')
     vlayerQml = os.path.join(self.qmlPath, lyr+'.qml')
     vlayer.loadNamedStyle(vlayerQml, False)
     QgsMapLayerRegistry.instance().addMapLayer(vlayer)
     if not vlayer.isValid():
         QgsMessageLog.logMessage(vlayer.error().summary(), "DSG Tools Plugin", QgsMessageLog.CRITICAL)
def pointsAlongLine(distance):
    ''' Create a new memory layer and add a distance attribute'''
    vl = QgsVectorLayer("Point", "distance nodes", "memory")
    pr = vl.dataProvider()
    pr.addAttributes( [ QgsField("distance", QVariant.Int) ] )
    layer = iface.mapCanvas().currentLayer()
    vl.setCrs(layer.crs())
    # Loop though all the selected features
    for feature in layer.getFeatures():
        geom = feature.geometry()
        features = createPointsAt(distance, geom)
        pr.addFeatures(features)
        vl.updateExtents()

    QgsMapLayerRegistry.instance().addMapLayer(vl)
Пример #10
0
def load(fileName, name=None, crs=None, style=None):
    """Loads a layer/table into the current project, given its file.
    """

    if fileName is None:
        return
    prjSetting = None
    settings = QSettings()
    if crs is not None:
        prjSetting = settings.value('/Projections/defaultBehaviour')
        settings.setValue('/Projections/defaultBehaviour', '')
    if name is None:
        name = os.path.split(fileName)[1]
    qgslayer = QgsVectorLayer(fileName, name, 'ogr')
    if qgslayer.isValid():
        if crs is not None and qgslayer.crs() is None:
            qgslayer.setCrs(crs, False)
        if style is None:
            if qgslayer.geometryType() == QGis.Point:
                style = ProcessingConfig.getSetting(ProcessingConfig.VECTOR_POINT_STYLE)
            elif qgslayer.geometryType() == QGis.Line:
                style = ProcessingConfig.getSetting(ProcessingConfig.VECTOR_LINE_STYLE)
            else:
                style = ProcessingConfig.getSetting(ProcessingConfig.VECTOR_POLYGON_STYLE)
        qgslayer.loadNamedStyle(style)
        QgsMapLayerRegistry.instance().addMapLayers([qgslayer])
    else:
        qgslayer = QgsRasterLayer(fileName, name)
        if qgslayer.isValid():
            if crs is not None and qgslayer.crs() is None:
                qgslayer.setCrs(crs, False)
            if style is None:
                style = ProcessingConfig.getSetting(ProcessingConfig.RASTER_STYLE)
            qgslayer.loadNamedStyle(style)
            QgsMapLayerRegistry.instance().addMapLayers([qgslayer])
            iface.legendInterface().refreshLayerSymbology(qgslayer)
        else:
            if prjSetting:
                settings.setValue('/Projections/defaultBehaviour', prjSetting)
            raise RuntimeError('Could not load layer: ' + unicode(fileName)
                               + '\nCheck the procesing framework log to look for errors')
    if prjSetting:
        settings.setValue('/Projections/defaultBehaviour', prjSetting)

    return qgslayer
Пример #11
0
def spQgsVectorLayer(name):
    spatial = robjects.r.get(name)
    type = spType(spatial)
    layer = QgsVectorLayer(type, unicode(name), "memory")
    crs = QgsCoordinateReferenceSystem()
    proj = spatial.do_slot('proj4string').do_slot('projargs')[0]
    if crs.createFromProj4(proj):
        layer.setCrs(crs)
    else:
        print "Error: unable to parse proj4string: using QGIS default"
    provider = layer.dataProvider()
    fields = spFields(spatial)
    provider.addAttributes(fields)
    feats = spData(spatial)
    features = [spFeature(*feat) for feat in feats]
    provider.addFeatures(features)
    layer.updateExtents()
    return layer
Пример #12
0
    def testLayerChangeDirtiesProject(self):
        """
        Test that making changes to certain layer properties results in dirty projects
        """
        p = QgsProject()
        l = QgsVectorLayer(os.path.join(TEST_DATA_DIR, "points.shp"), "points", "ogr")
        self.assertTrue(l.isValid())
        self.assertTrue(p.addMapLayers([l]))
        p.setDirty(False)

        l.setCrs(QgsCoordinateReferenceSystem('EPSG:3111'))
        self.assertTrue(p.isDirty())
        p.setDirty(False)

        l.setName('test')
        self.assertTrue(p.isDirty())
        p.setDirty(False)

        self.assertTrue(l.setSubsetString('class=\'a\''))
        self.assertTrue(p.isDirty())
Пример #13
0
    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_()

        # See if OK was pressed






        if result:
            # Do something useful here - delete the line containing pass and
            # substitute with your code.

            
            ##################################################################################### CODIGO

            ###PATHS

            delaupath = homedir+"/.qgis2/processing/outputs/delau3.shp"  #HITF
            # delaupath = "/../../../processing/outputs/delau.shp" #trying to use relative path rather than absolute, maybe in future
            xymeanpath  = homedir+"/.qgis2/processing/outputs/XYmean2.shp" #HITF
            point2spath = homedir+"/.qgis2/processing/outputs/datapoints3.shp" #HITF
            contourpath = homedir+"/.qgis2/processing/outputs/contour2017.shp" #HITF
            # contourpath2 = homedir+"/.qgis2/processing/outputs/contour4.shp" #HITF
            # outpath = homedir+"/report.txt" #HITF

            deleteIfExists(delaupath) #CAREFUL
            # deleteIfExists(xymeanpath)
            # deleteIfExists(point2spath)
            deleteIfExists(contourpath)
            
            ###PATHS

            self.dlg.botaoinput.clicked.connect

            filename = self.dlg.input2.text()
            
            # print filename
            
            path2 = filename+"?delimiter=%s&xField=%s&yField=%s" % (",", "X", "Y")

            datapoints = QgsVectorLayer(path2, "pontos", "delimitedtext")


                
            datapoints.setCrs(self.dlg.crsSel.crs())


            

            processing.runalg("qgis:delaunaytriangulation",datapoints,delaupath)

            triangles = QgsVectorLayer(delaupath,"triangles","ogr")

            

            processing.runalg("qgis:meancoordinates",datapoints,None,None,xymeanpath)

            xymean = QgsVectorLayer(xymeanpath,"pmed","ogr")


            ##passando todos para o CRS selecionado
            triangles.setCrs(self.dlg.crsSel.crs())
            xymean.setCrs(self.dlg.crsSel.crs())





            # # # # # # # # # # # # #FUTURE FEATURE: IF CRS IS ORTHO, TRANSLADE ALL POINTS TO THE TOPOCENTER
            # # # # # # # # if self.dlg.crsSel.crs() == crsOrt:
            # # # # # # # #     pass

            # # # # # # # # vlayer = datapoints
            # # # # # # # # # u = QgsVectorLayerEditUtils( vlayer )
            # # # # # # # # vlayer.beginEditCommand("Translate")
            # # # # # # # # for feat in vlayer.getFeatures():
            # # # # # # # #     ff = feat.id()
            # # # # # # # #     # vlayer.translateFeature(ff,1000,1000)
            # # # # # # # #     ox = feat.geometry().asPoint().x()
            # # # # # # # #     oy = feat.geometry().asPoint().y()
            # # # # # # # #     tx = 10000
            # # # # # # # #     ty = 1000
            # # # # # # # #     geom = QgsGeometry.fromPoint(QgsPoint(ox+tx,oy+ty))

            # # # # # # # #     vlayer.dataProvider().changeGeometryValues({ ff : geom })

            # # # # # # # #     vlayer.updateFeature(feat)
            # # # # # # # #     # vlayer.updateExtents()

            # # # # # # # #     ox2 = feat.geometry().asPoint().x()

            # # # # # # # #     # print ox-ox2
            # # # # # # # # # vlayer.beginEditCommand("Translate")
            # # # # # # # # vlayer.commitChanges()
            # # # # # # # # vlayer.endEditCommand()

            # vlayer.updateExtents()

            # # # # # # ok

            # x = retrieve_att(datapoints,1,0)



            #definindo a maior e a menor altitude
            MIN = min(column(retrieve_atts(datapoints),3))
            MAX = max(column(retrieve_atts(datapoints),3))

            ## DEFINIÇÃO DA ALTITUDE DE CALCULO
            # hcal = float(self.dlg.hCalc.text())
            hcal = self.dlg.hCalc.value()

            ## booleanos para apenas corte ou aterro


            #vector with heights, indexes of points and finally height of each point
            heigths = column(retrieve_atts(datapoints),3)

            # print heigths

            #defining the global option
            op = define_op(MIN,MAX,hcal)
            
            iP1 = column(retrieve_atts(triangles),0)
            iP2 = column(retrieve_atts(triangles),1)
            iP3 = column(retrieve_atts(triangles),2)

            Hp1 = []
            Hp2 = []
            Hp3 = []

            for ind in iP1:
                Hp1.append(heigths[int(ind)])

            for ind in iP2:
                Hp2.append(heigths[int(ind)])

            for ind in iP3:
                Hp3.append(heigths[int(ind)])


            
            # print [len(Hp1),len(Hp2),len(Hp3),len(iP1),len(heigths)] #COMMENT

            # areas = get_areas(triangles)

            # print areas

            # print [Hp1,Hp2,Hp3]
            
            vec_triangles = get_triangles(triangles,Hp1,Hp2,Hp3,op,hcal)

            # print vec_triangles[0].poly[0]
            # print [vec_triangles[0].interPT1[0],vec_triangles[0].interPT1[1]]
            
            #geracao da polilinha da curva, quando aplicavel
            planCalculated = False
            if op == 3:
                # poly = []
                # distList = []
                # index = 0
                contour = QgsVectorLayer("LineString","line2","memory")
                contour.setCrs(self.dlg.crsSel.crs())
                # contour2.setCrs(self.dlg.crsSel.crs())
                prov = contour.dataProvider()
                prov.addAttributes([QgsField("id", QVariant.Int)])
                # writer = QgsVectorFileWriter(contourpath, prov.encoding(), prov.fields(),"LineString", prov.crs())
                for triang in vec_triangles:
                    if triang.case != 4:
                        f1 = QgsFeature()
                        # f2 = QgsFeature()
                        f1.setAttributes([1])
                        # f2.setAttributes([triang.dp2])
                        f1.setGeometry(QgsGeometry.fromPolyline([triang.interPT1,triang.interPT2]))
                        # f1.setGeometry(QgsGeometry.fromPoint(triang.interPT1))
                        # f2.setGeometry(QgsGeometry.fromPoint(triang.interPT2))
                        prov.addFeatures([f1])
                        # poly.append(triang.interPT1)
                        # poly.append(triang.interPT2)
                        # distList.append(triang.dp1)
                        # distList.append(triang.dp2)
                        # index += 1
                # line = QgsGeometry.fromPolyline(poly)
                # prov = contour.dataProvider()
                # feat = QgsFeature()
                # feat.setGeometry(line)
                # prov.addFeatures([feat])

                contour.updateFields()
                contour.updateExtents()
                contour.commitChanges()

                #Geracao da curva de nivel como uma geometria unica
                #  nao os segmentos separadpos

                processing.runalg("qgis:singlepartstomultipart",contour,"id",contourpath)
                contour2 = QgsVectorLayer(contourpath,"CalcContour","ogr")
                self.add_layer_canvas(contour)
                feature = contour2.getFeatures().next()

                #gerando os pontos a serem locados
                interpolatedPoints = QgsVectorLayer("Point","pontosLocac","memory")
                interpolatedPoints.setCrs(self.dlg.crsSel.crs())
                prov2 = interpolatedPoints.dataProvider()

                contourLen = feature.geometry().length()
                accum = 0.0
                incr = self.dlg.espac.value() #
                points = []
                while (accum < contourLen):
                    point = feature.geometry().interpolate(accum)
                    points.append(point.asPoint())
                    P = QgsFeature()
                    P.setGeometry(point)
                    accum += incr
                    prov2.addFeatures([P])

                interpolatedPoints.updateFields()
                interpolatedPoints.updateExtents()
                interpolatedPoints.commitChanges()


                # line = QgsGeometry.fromPolyline(poly)
                # prov = contour.dataProvider()
                # feat = QgsFeature()
                # feat.setGeometry(line)
                # prov.addFeatures([feat])

            
                print "pass1" #COMMENT
                #### Calculos e geração dos dados para a planilha de locacao
                if self.dlg.calcLoc.isChecked() and self.dlg.stationSelec.count() != 0:
                    if  self.dlg.stationSelec.currentText() != self.dlg.oriSelec.currentText():
                        #uníco booleano para geração da planilha mais tarde 
                        planCalculated = True

                        expEst = QgsExpression("ID = '"+self.dlg.stationSelec.currentText()+"'")
                        expOri = QgsExpression("ID = '"+self.dlg.oriSelec.currentText()+"'")

                        reqEst = QgsFeatureRequest(expEst)
                        reqOri = QgsFeatureRequest(expOri)

                        itEst = datapoints.getFeatures(reqEst)
                        itOri = datapoints.getFeatures(reqOri)

                        featEst = itEst.next()
                        featOri = itOri.next()

                        pEst = featEst.geometry().asPoint()
                        pOri = featOri.geometry().asPoint()

                        zEst = featEst[3] + self.dlg.hEquip.value()
                        zOri = featOri[3] + self.dlg.hBast.value()

                        Est = (pEst[0],pEst[1],zEst)
                        Ori = (pOri[0],pOri[1],zOri)

                        dhEO = euclideanDistanceTuple2D(Est,Ori)
                        diEO = euclideanDistanceTuple3D(Est,Ori)

                        aZpart = azimuth2points(Est,Ori)

                        angZEO = gdec2gms(azimuth2points((0,0),(dhEO,Ori[2]-Est[2])))

                        data=[]

                        locLines = QgsVectorLayer("LineString","locLines","memory")
                        locLines.setCrs(self.dlg.crsSel.crs())
                        prov3 = locLines.dataProvider()
                        prov3.addAttributes([QgsField("Tipo", QVariant.String)])

                        f1 = QgsFeature()
                        f1.setAttributes(["Referencia"])
                        f1.setGeometry(QgsGeometry.fromPolyline([pEst,pOri]))
                        prov3.addFeatures([f1])


                        for ppoint in points:
                            P3D = (ppoint[0],ppoint[1],hcal)
                            DI = euclideanDistanceTuple3D(Est,P3D)
                            DH = euclideanDistanceTuple3D(Est,P3D)
                            AzVante = azimuth2points(Est,P3D)
                            angHdec = angleFromAz(aZpart,AzVante)
                            vZ = P3D[2] - Est[2]
                            angZdec = azimuth2points((0,0),(DH,vZ))
                            angH = gdec2gms(angHdec)
                            angZ =  gdec2gms(angZdec)
                            pointData = [angH,angZ,DI,DH]
                            data.append(pointData)
                            f1 = QgsFeature()
                            f1.setAttributes(["Ponto Na Curva"])
                            f1.setGeometry(QgsGeometry.fromPolyline([pEst,ppoint]))
                            prov3.addFeatures([f1])                            

                        locLines.updateFields()
                        locLines.updateExtents()
                        locLines.commitChanges()
                    



            ######################################################DEVEM ESTAR NO FINAL DO CODIGO

            # # #Relatorio de saida
            if self.dlg.outputTxt.text()  != "":
                nl = "\n"

                file = open(self.dlg.outputTxt.text(),"w")
                file.write("########################### ~~VOLUMATOR 0.1 ~~ ###########################"+nl)
                file.write("                   Relatorio de Saida do Processamento"+nl+nl+nl)

                sumCt = 0.0
                sumAt = 0.0
                sumArea = 0.0

                for tri in vec_triangles:
                    sumCt   += tri.volCt
                    sumAt   += tri.volAt
                    sumArea += tri.area
                    # print tri.area


                file.write("Volume de Corte: " +str(sumCt)+" m3 (metros cubicos)"+nl)
                file.write("Volume de Aterro: "+str(sumAt)+" m3 (metros cubicos)"+nl+nl)


                file.write("Area Total no Plano de Projecao: "+str(sumArea)+" m2 (metros quadrados)"+nl+nl+nl)

                file.write("Dados de Entrada: "+nl)
                file.write("Arquivo de Entrada: "+self.dlg.input2.text()+nl)
                file.write("Altura (ou \"cota\") utilizada para calculo: "+str(hcal)+nl)
                file.write("Altura Max. "+str(MAX)+nl)
                file.write("Altura Min. "+str(MIN)+nl)
                if hcal < MIN and sumArea != 0:
                    file.write("Altura de passagem (mesmo volume de Corte e Aterro): "+str(hcal+(sumCt/sumArea))+nl+nl)
                    pass    

                if planCalculated:
                    file.write("Planilha de Locação da Curva com a Altitude de Calculo: "+nl)
                    file.write("Considerado o Angulo Horario, Zerando no ponto utilizado para Orientacao"+nl)
                    file.write("Espaçamento Escolhido: "+str(self.dlg.espac.value())+nl)
                    if self.dlg.both.isChecked() or self.dlg.trid.isChecked():
                        file.write("Altura Para o Equipamento: "+str(self.dlg.hEquip.value())+", ")
                        file.write("Altura Para o Bastao: "+str(self.dlg.hBast.value())+nl)
                    file.write("Ponto Escolhido como Estacao: "+self.dlg.stationSelec.currentText()+nl)
                    file.write("de Coordenadas: "+TupleAsString(Est)+nl)
                    file.write("Ponto Escolhido para Orientacao (\"Re\"): "+self.dlg.oriSelec.currentText()+nl)
                    file.write("de Coordenadas: "+TupleAsString(Ori)+nl)
                    file.write("Distancia no Plano (\"Horizontal\"): "+ str(dhEO)+nl)
                    if self.dlg.both.isChecked() or self.dlg.trid.isChecked():
                        file.write("Distancia Espacial (\"Inclinada\"): " + str(diEO)+nl)
                        file.write("Angulo Zenital: "+TupleAsString(angZEO)+nl+nl)
                    # file.write(""+nl+nl)
                    if self.dlg.both.isChecked():
                        file.write("Hg Hm Hs Vg Vm Vs DI DH"+nl)
                    elif self.dlg.plan.isChecked():
                        file.write("Hg Hm Hs DH"+nl)
                    elif self.dlg.trid.isChecked():
                        file.write("Hg Hm Hs Vg Vm Vs DI"+nl)
                    for entry in data:
                        if self.dlg.both.isChecked():
                            file.write(TupleAsString2(entry[0])+TupleAsString2(entry[1])+float2str(entry[2])+" "+float2str(entry[3])+nl)
                        elif self.dlg.plan.isChecked():
                            file.write(TupleAsString2(entry[0])+float2str(entry[3])+nl)
                        elif self.dlg.trid.isChecked():
                            file.write(TupleAsString2(entry[0])+TupleAsString2(entry[1])+float2str(entry[2])+nl+nl)

                
                file.write(nl+"Criado por Kauê de Moraes Vestena (2017), Programa em Fase de Testes"+nl)
                file.write("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~")
                file.close()
            # # ####



            ### projeto com o CRS escolhido
            iface.mapCanvas().mapRenderer().setDestinationCrs(self.dlg.crsSel.crs())


            #Modificando Estilos
            # pColors = QgsColorRampShader(0.0,255.0)
            # myMin = 50.1
            # myMax = 100
            # myRangeList = []
            # myOpacity = 1
            # myLabel = 'Group 2'
            # myColour = QColor('#00eeff')
            # mySymbol2 = QgsSymbolV2.defaultSymbol(datapoints.geometryType())
            # mySymbol2.setColor(myColour)
            # mySymbol2.setAlpha(myOpacity)
            # myRange2 = QgsRendererRangeV2(myMin, myMax, mySymbol2, myLabel)
            # myRangeList.append(myRange2)
            # myRenderer = QgsGraduatedSymbolRendererV2('', myRangeList)
            # myRenderer.setMode(QgsGraduatedSymbolRendererV2.EqualInterval)
            # myRenderer.setClassAttribute("Z")
            # datapoints.setRendererV2(myRenderer)

            # props = triangles.rendererV2().symbol().symbolLayer(0).properties()
            # props['color'] = 'yellow'


            #### adicionando na visualização
            self.add_layer_canvas(triangles)
            self.add_layer_canvas(datapoints)
            if op == 3:
                self.add_layer_canvas(contour2)
                
                if planCalculated:
                    self.add_layer_canvas(locLines)
                    # pass #layer com linhas de locacao
                # self.add_layer_canvas(interpolatedPoints)
                # self.add_layer_canvas(contour)
            # self.add_layer_canvas(xymean)  #COMMENT


            #####################################################################################
            # pass

            # print self.dlg.both.isChecked()
            print "end" #COMMENT
            
Пример #14
0
def layer_empty_points(tmp_dir, layer_points):
    dp: QgsVectorDataProvider = layer_points.dataProvider()
    layer = QgsVectorLayer('Point', 'test_point', 'memory')
    layer.setCrs(dp.crs())
    assert layer.isValid()
    return layer
Пример #15
0
class mapillary_coverage:

    expire_time = datetime.timedelta(hours=12)

    def __init__(self, iface):
        self.iface = iface
        self.cache_dir = os.path.join(tempfile.gettempdir(), 'go2mapillary')
        print("CACHE_DIR", self.cache_dir)
        if not os.path.exists(self.cache_dir):
            os.makedirs(self.cache_dir)
        self.actual_ranges = None
        self.images = None

    def transformToWGS84(self, pPoint):
        # transformation from the current SRS to WGS84
        crcMappaCorrente = self.iface.mapCanvas().mapSettings().destinationCrs(
        )  # get current crs
        crsSrc = crcMappaCorrente
        crsDest = QgsCoordinateReferenceSystem(4326)  # WGS 84
        xform = QgsCoordinateTransform(crsSrc, crsDest, QgsProject.instance())
        return xform.transform(pPoint)  # forward transformation: src -> dest

    def download_tiles(self):

        #calculate zoom_level con current canvas extents
        ex = self.iface.mapCanvas().extent()
        wgs84_minimum = self.transformToWGS84(
            QgsPointXY(ex.xMinimum(), ex.yMinimum()))
        wgs84_maximum = self.transformToWGS84(
            QgsPointXY(ex.xMaximum(), ex.yMaximum()))
        bounds = (wgs84_minimum.x(), wgs84_minimum.y(), wgs84_maximum.x(),
                  wgs84_maximum.y())
        map_units_per_pixel = (wgs84_maximum.x() - wgs84_minimum.x()
                               ) / self.iface.mapCanvas().width()
        zoom_level = ZoomForPixelSize(map_units_per_pixel)
        if zoom_level > 14:
            zoom_level = 14

        ranges = getTileRange(bounds, zoom_level)

        #print ("ZOOM_LEVEL", zoom_level, "RANGES", self.actual_ranges, ranges)
        if not self.actual_ranges or not (
                ranges[0][0] == self.actual_ranges[0][0]
                and ranges[0][1] == self.actual_ranges[0][1]
                and ranges[1][0] == self.actual_ranges[1][0]
                and ranges[1][1] == self.actual_ranges[1][1]):
            print("ZOOM_LEVEL", zoom_level, "NEW RANGES", ranges,
                  "LAST RANGES", self.actual_ranges)
            self.actual_ranges = ranges
            x_range = ranges[0]
            y_range = ranges[1]

            overview_features = []
            coverage_features = []
            images_features = []

            for y in range(y_range[0], y_range[1] + 1):
                for x in range(x_range[0], x_range[1] + 1):
                    folderPath = os.path.join(self.cache_dir, str(zoom_level),
                                              str(x))
                    filePathMvt = os.path.join(folderPath, str(y) + '.mvt')
                    #filePathJson = os.path.join(folderPath, str(y) + '.json')
                    if not os.path.exists(folderPath):
                        os.makedirs(folderPath)
                    res = None

                    if not os.path.exists(filePathMvt) or (
                            datetime.datetime.fromtimestamp(
                                os.path.getmtime(filePathMvt)) <
                        (datetime.datetime.now() - self.expire_time)):
                        # make the URL
                        url = getURL(x, y, zoom_level, SERVER_URL)
                        res = requests.get(url, proxies=getProxiesConf())
                        print('MISS', x, y, zoom_level, res, url)
                        if res.status_code == 200:
                            with open(filePathMvt, 'wb') as f:
                                f.write(res.content)
                            print(os.path.getmtime(filePathMvt))

                    if os.path.exists(filePathMvt):
                        if not res:
                            with open(filePathMvt, "rb") as f:
                                mvt = f.read()
                            print('CACHE', x, y, zoom_level)
                        else:
                            mvt = res.content

                        bounds = mercantile.bounds(x, y, zoom_level)
                        tile_box = (bounds.west, bounds.south, bounds.east,
                                    bounds.north)
                        json_data = mapbox_vector_tile.decode(
                            mvt, quantize_bounds=tile_box)
                        if "mapillary-sequence-overview" in json_data:
                            overview_features = overview_features + json_data[
                                "mapillary-sequence-overview"]["features"]
                        elif "mapillary-sequences" in json_data:
                            coverage_features = coverage_features + json_data[
                                "mapillary-sequences"]["features"]
                        if "mapillary-images" in json_data:
                            images_features = images_features + json_data[
                                "mapillary-images"]["features"]

            geojson_overview_file = os.path.join(self.cache_dir,
                                                 "mapillary_overview.geojson")
            if overview_features:
                self.overview = True
                geojson_overview = {
                    "type": "FeatureCollection",
                    "features": overview_features
                }

                with open(geojson_overview_file, 'w') as outfile:
                    json.dump(geojson_overview, outfile)
            else:
                self.overview = None
                if os.path.exists(geojson_overview_file):
                    os.remove(geojson_overview_file)

            geojson_coverage_file = os.path.join(self.cache_dir,
                                                 "mapillary_coverage.geojson")
            if coverage_features:
                self.coverage = True
                geojson_coverage = {
                    "type": "FeatureCollection",
                    "features": coverage_features
                }

                with open(geojson_coverage_file, 'w') as outfile:
                    json.dump(geojson_coverage, outfile)
            else:
                self.coverage = None
                if os.path.exists(geojson_coverage_file):
                    os.remove(geojson_coverage_file)

            geojson_images_file = os.path.join(self.cache_dir,
                                               "mapillary_images.geojson")
            if zoom_level == 14 and images_features:
                self.images = True
                geojson_images = {
                    "type": "FeatureCollection",
                    "features": images_features
                }

                with open(geojson_images_file, 'w') as outfile:
                    json.dump(geojson_images, outfile)
            else:
                self.images = None
                if os.path.exists(geojson_images_file):
                    os.remove(geojson_images_file)
        else:
            pass
            #print ("SAME RANGES")

    def has_overview(self):
        return self.overview

    def has_coverage(self):
        return self.coverage

    def has_images(self):
        return self.images

    def get_overview_layer(self):
        if self.overview:
            self.mapillary_overview_layer = QgsVectorLayer(
                os.path.join(self.cache_dir, 'mapillary_overview.geojson'),
                "Mapillary Coverage", "ogr")
            self.mapillary_overview_layer.setCrs(
                QgsCoordinateReferenceSystem(4326))
        else:
            self.mapillary_overview_layer = None
        return self.mapillary_overview_layer

    def get_coverage_layer(self):
        if self.coverage:
            self.mapillary_coverage_layer = QgsVectorLayer(
                os.path.join(self.cache_dir, 'mapillary_coverage.geojson'),
                "Mapillary Coverage", "ogr")
            self.mapillary_coverage_layer.setCrs(
                QgsCoordinateReferenceSystem(4326))
        else:
            self.mapillary_coverage_layer = None
        return self.mapillary_coverage_layer

    def get_images_layer(self):
        if self.images:
            self.mapillary_images_layer = QgsVectorLayer(
                os.path.join(self.cache_dir, 'mapillary_images.geojson'),
                "Mapillary Images", "ogr")
            self.mapillary_images_layer.setCrs(
                QgsCoordinateReferenceSystem(4326))
        else:
            self.mapillary_images_layer = None
        return self.mapillary_images_layer

    def update_coverage(self):
        self.download_tiles()
class FirstPageClass:
    def __init__(self , currentDlg):
        self.__dlg = currentDlg
        self.__demComboBox = currentDlg.findChild(QtWidgets.QComboBox , "DemComboBox")
        self.__countyComboBox = currentDlg.findChild(QtWidgets.QComboBox , "CountyComboBox")

        self.__nextButton = currentDlg.findChild(QtWidgets.QPushButton , "NextButton")


        # initial comboBox
        self.__initialDemComboBox()
        self.__initialCountyComboBox()

        # setting connection
        self.__demComboBox.activated.connect(lambda:self.__initialDemComboBox())
        self.__nextButton.clicked.connect(lambda:self.__toNextPage())

        # output parameter
        self.__splitLineLayer = None
        self.__demLayer = None

        # edit county
        self.__editCounty = None

        # check isClosed
        self.__isClose = False

    # output function
    #----------------------------------------------------------------------------
    def getSplitLineLayer(self):
        return self.__splitLineLayer

    def getEditorCounty(self):
        return self.__editCounty


    def getDemLayer(self):
        return self.__demLayer

    def isClosed(self):
        return self.__isClose

    # demGui
    #----------------------------------------------------------------------------
    def __initialDemComboBox(self):
        self.__demComboBox.clear()
        for layer in AtQgisGui().getRasterLayer():
            self.__demComboBox.addItem(layer.name() , layer)

    # CountyComboBox
    #----------------------------------------------------------------------------
    def __initialCountyComboBox(self):
        self.__countyComboBox.clear()
        try:
            request = requests.get("https://h2-demo.pointing.tw/api/cross-sections/")
            for county in request.json():
                countyName = str(county["basinName"])
                self.__countyComboBox.addItem(countyName , str(county["basinId"]))
        except:
            traceback.print_exc()
            self.__countyComboBox.addItem("連結伺服器失敗")

    # NextButtonGui
    #----------------------------------------------------------------------------
    def __toNextPage(self):
      
      #check every input layer is exist
      #----------------------------------------------------------------------
        checker = 0
        self.__nextButton.setEnabled(False)

      # ckeckDem
        if self.__demComboBox.currentText == "":
            Exception("splitLine could not be null")
            checker = 1
            self.__nextButton.setEnabled(True)

      # turn to next page
        if checker == 0:
            
            # get crossSection json file
            crossSectionTemptPath = QgsProcessingUtils.tempFolder() + str("\\crossSection.json")
            try:
                # save crossSection json to file
                # request = requests.get("https://h2-demo.pointing.tw/api/cross-sections/" + self.__countyComboBox.currentData())
                # temptJson = json.loads(request.text)
                
                
                # test
                temptJson = None
                temptPath = os.path.dirname(__file__)
                with open(temptPath + "/testCrossSection.json") as temptText:
                    temptJson = json.load(temptText)
                
                self.__editCounty = self.__countyComboBox.currentData()

                # make the geometry only has start and endPoint in it
                for feature in temptJson["features"]:
                    temptGeometryPoints = feature["geometry"]["coordinates"]
                    
                    # outList, add a buffer to start-end point (each side for 3m)
                    outGeometryPoints =[]
                    startPoint = temptGeometryPoints[0]
                    endPoint = temptGeometryPoints[-1]
                    geometryLength = pow(pow(startPoint[0] - endPoint[0] ,2) + pow(startPoint[1] - endPoint[1] ,2),0.5)

                    startDirection = [(startPoint[0]-endPoint[0])*(3.0/geometryLength) , (startPoint[1]-endPoint[1])*(3.0/geometryLength)]
                    endDirection = [startDirection[0]*-1 , startDirection[1]*-1]

                    outGeometryPoints.append([startPoint[0]+startDirection[0] , startPoint[1]+startDirection[1]])
                    outGeometryPoints.append([endPoint[0]+endDirection[0] , endPoint[1]+endDirection[1]])
                    feature["geometry"]["coordinates"] = outGeometryPoints

                    # remove not necessary feild
                    try:
                        del feature["properties"]["originalId"]
                    except:
                        pass
                    try:
                        del feature["properties"]["node_py"]
                    except:
                        pass
                    try:
                        del feature["properties"]["node_px"]
                    except:
                        pass
                    try:
                        del feature["properties"]["node_nm"]
                    except:
                        pass
                    
                # write json to temptFile
                writer = AtFileWriter(json.dumps(temptJson), crossSectionTemptPath).textWriter("")

                # load tempt jsonFile as layer
                self.__splitLineLayer = QgsVectorLayer(crossSectionTemptPath,"crossSection" , "ogr")
                self.__splitLineLayer.setCrs(QgsCoordinateReferenceSystem(3826),True)
                self.__splitLineLayer.loadNamedStyle(temptPath + '/style/crossSectionStyle.qml')
                QgsProject.instance().addMapLayer(self.__splitLineLayer)

            except:
                traceback.print_exc()

            # setting output paramter
            self.__demLayer = self.__demComboBox.currentData()

            # disconnect
            self.__nextButton.disconnect()
            self.__demComboBox.disconnect()

            # close dlg and open another
            self.__dlg.done(0)
            self.__isClose = True
            self.__dlg = PlotPage()
            self.__dlg.show()

            # create plotPageClass
            PlotPageClass(self.__dlg , self)
Пример #17
0
def layer_empty_lines(tmp_dir, layer_lines):
    dp: QgsVectorDataProvider = layer_lines.dataProvider()
    layer = QgsVectorLayer('LineString', 'test_lines', 'memory')
    layer.setCrs(dp.crs())
    assert layer.isValid()
    return layer
Пример #18
0
class CatalogDialogTool(QObject):
    """
    Tool for managing the search and export functionality
    """
    def __init__(self, iface, dialog_ui, bbox_tool):
        """
        Constructor for the dialog tool
        :param iface: The QGIS Interface
        :param dialog_ui: The dialog GUI
        :param bbox_tool The bounding box tool
        :return: dialog tool
        """
        QObject.__init__(self, None)
        self.iface = iface
        self.dialog_ui = dialog_ui
        self.bbox_tool = bbox_tool

        self.progress_bar = None
        self.progress_message_bar = None
        self.progress_message_bar_widget = None
        self.search_thread_pool = QThreadPool()
        self.search_lock = Lock()
        self.export_thread_pool = QThreadPool()
        self.export_lock = Lock()
        self.query = None
        self.previous_credentials = None
        self.export_file = None
        self.footprint_layer = None

        self.filters = CatalogFilters(self.dialog_ui)

        self.dialog_ui.aoi_button.clicked.connect(self.aoi_button_clicked)
        self.dialog_ui.reset_button.clicked.connect(self.reset_button_clicked)
        self.dialog_ui.export_button.clicked.connect(
            self.export_button_clicked)
        self.bbox_tool.released.connect(self.search)
        self.model = None

    def init_progress_bar(self, progress_max):
        """
        Sets up the progress bar for search functionality
        :return: None
        """
        if not self.progress_message_bar:
            self.progress_message_bar = self.iface.messageBar().createMessage(
                "Querying for data")
            self.progress_bar = QProgressBar()
            self.progress_bar.setMinimum(0)
            self.progress_bar.setMaximum(progress_max)
            self.progress_bar.setAlignment(Qt.AlignLeft | Qt.AlignCenter)
            self.progress_message_bar.layout().addWidget(self.progress_bar)
            self.progress_message_bar_widget = self.iface.messageBar(
            ).pushWidget(self.progress_message_bar,
                         self.iface.messageBar().INFO)

    def init_layers(self):
        """
        Sets up the layers for rendering the items
        :return: None
        """
        if self.footprint_layer:
            QgsMapLayerRegistry.instance().removeMapLayer(
                self.footprint_layer.id())

        self.footprint_layer = QgsVectorLayer("Polygon?crs=EPSG:4326",
                                              "Catalog Footprints", "memory")
        self.footprint_layer.setCrs(QgsCoordinateReferenceSystem(4326), True)
        self.footprint_layer.dataProvider().addAttributes(
            CatalogAcquisitionFeature.get_fields())
        QgsMapLayerRegistry.instance().addMapLayer(self.footprint_layer)

    def clear_widgets(self):
        """
        Clears the progress bar
        :return: None
        """
        self.progress_bar = None
        self.progress_message_bar = None
        if self.progress_message_bar_widget:
            self.iface.messageBar().popWidget(self.progress_message_bar_widget)
        self.progress_message_bar_widget = None

    def is_searching(self):
        """
        Check to see if the system is still searching (checks if there's work in the search thread pool)
        :return: True if searching; False otherwise
        """
        return self.get_search_active_thread_count() > 0

    def is_exporting(self):
        """
        Check to see if the system is still exporting (checks if there's work in the export thread pool)
        :return: True if searching; False otherwise
        """
        return self.get_export_active_thread_count() > 0

    def get_search_active_thread_count(self):
        """
        Gets the number of active threads in the search thread pool
        :return:
        """
        with self.search_lock:
            return self.search_thread_pool.activeThreadCount()

    def get_export_active_thread_count(self):
        """
        Gets the number of active threads in the export thread pool
        :return:
        """
        with self.export_lock:
            return self.export_thread_pool.activeThreadCount()

    def aoi_button_clicked(self):
        """
        Validates and runs the search if validation successful
        :return: None
        """
        # can't run search during export
        if self.is_exporting():
            self.iface.messageBar().pushMessage(
                "Error",
                "Cannot run search while export is running.",
                level=QgsMessageBar.CRITICAL)
        # can't run multiple search
        elif self.is_searching():
            self.iface.messageBar().pushMessage(
                "Error",
                "Cannot run a new search while a search is running.",
                level=QgsMessageBar.CRITICAL)
        else:
            self.bbox_tool.reset()
            self.iface.mapCanvas().setMapTool(self.bbox_tool)

    def reset_button_clicked(self):
        """
        Resets filters.
        :return: None
        """
        self.reset()

    def export_button_clicked(self):
        """
        Validates and runs the export if validation successful
        :return: None
        """
        # can't run export during search
        if self.is_searching():
            self.iface.messageBar().pushMessage(
                "Error",
                "Cannot run export while search is running.",
                level=QgsMessageBar.CRITICAL)
        # can't run multiple exports
        elif self.is_exporting():
            self.iface.messageBar().pushMessage(
                "Error",
                "Cannot run a new export while a export is running.",
                level=QgsMessageBar.CRITICAL)
        else:
            self.export()

    def search(self, top, bottom, left, right):
        self.search_thread_pool.waitForDone(0)

        # validate credentials if they changed
        errors = []
        username, password, api_key, max_items_to_return = SettingsOps.get_settings(
        )
        credentials = [username, password, api_key]
        if not self.previous_credentials or self.previous_credentials != credentials:
            SettingsOps.validate_stored_info(username, password, api_key,
                                             max_items_to_return, errors)
        self.previous_credentials = credentials

        # validate filters
        if not errors:
            self.filters.validate(errors)

        if errors:
            self.iface.messageBar().pushMessage(
                "Error",
                "The following errors occurred: " + "<br />".join(errors),
                level=QgsMessageBar.CRITICAL)
        else:
            self.init_layers()

            self.dialog_ui.tab_widget.setCurrentIndex(RESULTS_TAB_INDEX)

            next_x_list = self.drange_list(
                float(left) + INCREMENTAL_INTERVAL, float(right),
                INCREMENTAL_INTERVAL)
            next_y_list = self.drange_list(
                float(bottom) + INCREMENTAL_INTERVAL, float(top),
                INCREMENTAL_INTERVAL)
            self.init_progress_bar(len(next_x_list) * len(next_y_list))

            self.model = CatalogTableModel(self.dialog_ui.table_view)
            self.dialog_ui.table_view.setModel(self.model)
            self.dialog_ui.table_view.selectionModel(
            ).selectionChanged.connect(self.selection_changed)

            if not self.query:
                self.query = GBDQuery(username=username,
                                      password=password,
                                      api_key=api_key)

            filters = self.filters.get_query_filters()
            time_begin = self.filters.get_datetime_begin()
            time_end = self.filters.get_datetime_end()

            current_x = float(left)
            current_y = float(bottom)
            for next_x in next_x_list:
                for next_y in next_y_list:
                    search_runnable = CatalogSearchRunnable(
                        self.query,
                        self.model,
                        self,
                        top=next_y,
                        left=current_x,
                        right=next_x,
                        bottom=current_y,
                        time_begin=time_begin,
                        time_end=time_end,
                        filters=filters)
                    search_runnable.task_object.task_complete.connect(
                        self.on_search_complete)
                    self.search_thread_pool.start(search_runnable)
                    current_y = next_y
                current_y = bottom
                current_x = next_x

    def reset(self):
        self.filters.remove_all()

    def export(self):
        self.export_thread_pool.waitForDone(0)
        acquisitions = None
        if self.model is not None:
            acquisitions = self.model.data

        if not acquisitions:
            self.iface.messageBar().pushMessage("Error",
                                                "No data to export.",
                                                level=QgsMessageBar.CRITICAL)
        else:
            # open file ui
            select_file_ui = QFileDialog()
            starting_file = self.export_file or os.path.expanduser("~")
            export_file = select_file_ui.getSaveFileName(
                None, "Choose output file", starting_file, SELECT_FILTER)

            if export_file:
                self.export_file = export_file
                self.init_progress_bar(0)
                export_runnable = CatalogExportRunnable(
                    acquisitions, self.export_file)
                export_runnable.task_object.task_complete.connect(
                    self.on_export_complete)
                self.export_thread_pool.start(export_runnable)

    @pyqtSlot()
    def on_search_complete(self):
        thread_count = self.get_search_active_thread_count()
        if self.progress_message_bar:
            self.progress_bar.setValue(self.progress_bar.value() + 1)
        if thread_count == 0:
            self.clear_widgets()
            self.dialog_ui.table_view.resizeColumnsToContents()

    @pyqtSlot()
    def on_export_complete(self):
        thread_count = self.get_export_active_thread_count()
        if self.progress_message_bar:
            self.progress_bar.setValue(self.progress_bar.value() + 1)
        if thread_count == 0:
            self.clear_widgets()
            self.iface.messageBar().pushMessage(
                "Info",
                'File export has completed to "%s".' % self.export_file)

    def selection_changed(self, selected, deselected):
        self.footprint_layer.startEditing()

        # draw footprints for selected rows
        selected_rows = set()
        for index in selected.indexes():
            selected_rows.add(index.row())
        for row in selected_rows:
            acquisition = self.model.get(row)
            feature_id = self.model.generate_feature_id()
            self.model.set_feature_id(acquisition, feature_id)
            feature = CatalogAcquisitionFeature(feature_id, acquisition)
            self.footprint_layer.dataProvider().addFeatures([feature])

        # remove footprints for deselected rows
        deselected_rows = set()
        for index in deselected.indexes():
            deselected_rows.add(index.row())
        feature_ids_to_remove = []
        for row in deselected_rows:
            acquisition = self.model.get(row)
            feature_id = self.model.get_feature_id(acquisition)
            feature_ids_to_remove.append(feature_id)
            self.model.remove_feature_id(acquisition)
        if feature_ids_to_remove:
            self.footprint_layer.dataProvider().deleteFeatures(
                feature_ids_to_remove)

        self.footprint_layer.commitChanges()
        self.footprint_layer.updateExtents()
        self.footprint_layer.triggerRepaint()

    def drange_list(self, start, stop, step):
        drange_list = []
        r = start
        while r < stop:
            drange_list.append(r)
            r += step
        if not drange_list:
            drange_list.append(stop)
        return drange_list
Пример #19
0
class Print_utility(QObject):
    progressBarUpdated = pyqtSignal(int, int)

    HOME = os.environ['PYARCHINIT_HOME']
    REPORT_PATH = '{}{}{}'.format(HOME, os.sep, "pyarchinit_Report_folder")
    FILEPATH = os.path.dirname(__file__)
    LAYER_STYLE_PATH = '{}{}{}{}'.format(FILEPATH, os.sep, 'styles', os.sep)
    LAYER_STYLE_PATH_SPATIALITE = '{}{}{}{}'.format(FILEPATH, os.sep,
                                                    'styles_spatialite',
                                                    os.sep)
    SRS = 3004

    layerUS = ""
    layerQuote = ""
    ##  layerCL = ""
    ##  layerGriglia = "" #sperimentale da riattivare

    USLayerId = ""
    CLayerId = ""
    QuoteLayerId = ""
    GrigliaLayerId = ""

    mapHeight = ""
    mapWidth = ""

    tav_num = ""
    us = ""
    uri = ""

    def __init__(self, iface, data):
        super().__init__()
        self.iface = iface
        self.data = data
        # self.area = area
        # self.us = us
        self.canvas = self.iface.mapCanvas()

    # set host name, port, database name, username and password
    """
    def on_pushButton_runTest_pressed(self):
        self.first_batch_try()
    """

    def first_batch_try(self, server):

        if server == 'postgres':
            for i in range(len(self.data)):
                test = self.charge_layer_postgis(self.data[i].sito,
                                                 self.data[i].area,
                                                 self.data[i].us)
                self.us = self.data[i].us
                self.periodo_iniziale = self.data[i].periodo_iniziale
                self.periodo_fianle = self.data[i].fase_finale
                if test != 0:
                    if self.layerUS.featureCount() > 0:
                        self.test_bbox()
                        tav_num = i
                        self.print_map(tav_num)
                        self.progressBarUpdated.emit(i, len(self.data) - 1)
                        QApplication.processEvents()
                    else:
                        self.remove_layer()
                if test == 0:
                    Report_path = '{}{}{}'.format(self.REPORT_PATH, os.sep,
                                                  'report_errori.txt')
                    f = open(Report_path, "w")
                    f.write(str("Presenza di errori nel layer"))
                    f.close()

        elif server == 'sqlite':
            for i in range(len(self.data)):
                test = self.charge_layer_sqlite(self.data[i].sito,
                                                self.data[i].area,
                                                self.data[i].us)
                self.us = self.data[i].us
                if test != 0:
                    if self.layerUS.featureCount() > 0:
                        self.test_bbox()
                        tav_num = i
                        self.print_map(tav_num)
                        self.progressBarUpdated.emit(i, len(self.data) - 1)
                        QApplication.processEvents()
                    else:
                        self.remove_layer()
                if test == 0:
                    Report_path = '{}{}{}'.format(self.REPORT_PATH, os.sep,
                                                  'report_errori.txt')
                    f = open(Report_path, "w")
                    f.write(str("Presenza di errori nel layer"))
                    f.close()

    def converter_1_20(self, n):
        n *= 100
        res = n / 20
        return res

    def test_bbox(self):
        # f = open("/test_type.txt", "w")
        # ff.write(str(type(self.layerUS)))
        # ff.close()

        self.layerUS.select([])  # recuperi tutte le geometrie senza attributi
        #  featPoly = QgsFeature()  # crei una feature vuota per il poligono

        dizionario_id_contains = {}
        lista_quote = []

        it = self.layerUS.getFeatures()
        featPoly = next(
            it
        )  # cicli sulle feature recuperate, featPoly conterra la feature poligonale attuale
        bbox = featPoly.geometry().boundingBox(
        )  # recupera i punti nel bbox del poligono
        self.height = self.converter_1_20(float(
            bbox.height())) * 10  # la misura da cm e' portata in mm
        self.width = self.converter_1_20(float(
            bbox.width())) * 10  # la misura da cm e' portata in mm

        # f = open("/test_paper_size_5.txt", "w")
        # f.write(str(self.width))
        # f.close()

    def getMapExtentFromMapCanvas(self, mapWidth, mapHeight, scale):
        # code from easyPrint plugin
        # print "in methode: " + str(scale)

        xmin = self.canvas.extent().xMinimum()
        xmax = self.canvas.extent().xMaximum()
        ymin = self.canvas.extent().yMinimum()
        ymax = self.canvas.extent().yMaximum()
        xcenter = xmin + (xmax - xmin) / 2
        ycenter = ymin + (ymax - ymin) / 2

        mapWidth = mapWidth * scale / 1000  # misura in punti
        mapHeight = mapHeight * scale / 1000  # misura in punti

        # f = open("/test_paper_size_3.txt", "w")
        # f.write(str(mapWidth))
        # f.close()

        minx = xcenter - mapWidth / 2
        miny = ycenter - mapHeight / 2
        maxx = xcenter + mapWidth / 2
        maxy = ycenter + mapHeight / 2

        return QgsRectangle(minx, miny, maxx, maxy)

    def print_map(self, tav_num):
        self.tav_num = tav_num

        p = QgsProject.instance()
        crs = QgsCoordinateReferenceSystem()
        crs.createFromSrid(self.SRS)
        p.setCrs(crs)

        l = QgsLayout(p)
        l.initializeDefaults()
        page = l.pageCollection().page(0)

        # map - this item tells the libraries where to put the map itself. Here we create a map and stretch it over the whole paper size:
        x, y = 0, 0  # angolo 0, o in alto a sx

        if (0 <= self.width <= 297) and (0 <= self.height <= 210):
            width, height = 297, 210  # Formato A4 Landscape
        elif (0 <= self.height <= 297) and (0 <= self.width <= 210):
            width, height = 210, 297  # Formato A4

        elif (0 <= self.width <= 420) and (0 <= self.height <= 297):
            width, height = 297, 420  # Formato A3 Landscape
        elif (0 <= self.height <= 420) and (0 <= self.width <= 297):
            width, height = 240, 297  # Formato A4

        elif (0 <= self.width <= 1189) and (0 <= self.height <= 841):
            width, height = 1189, 841  # Formato A0 Landscape
        elif (0 <= self.height <= 1189) and (0 <= self.width <= 841):
            width, height = 841, 1189  # Formato A0
        else:
            width, height = self.width * 1.2, self.height * 1.2  # self.width*10, self.height*10 da un valore alla larghezza e altezza del foglio aumentato di 5 per dare un margine

        size = QgsLayoutSize(width, height)
        page.setPageSize(size)

        map = QgsLayoutItemMap(l)

        rect = self.getMapExtentFromMapCanvas(page.pageSize().width(),
                                              page.pageSize().height(), 20.0)

        map.attemptSetSceneRect(
            QRectF(0, 0,
                   page.pageSize().width(),
                   page.pageSize().height()))
        map.setExtent(rect)
        map.setLayers([self.layerUS])
        l.setReferenceMap(map)
        l.addLayoutItem(map)

        intestazioneLabel = QgsLayoutItemLabel(l)
        txt = "Tavola %s - US:%d " % (self.tav_num + 1, self.us)
        intestazioneLabel.setText(txt)
        intestazioneLabel.adjustSizeToText()
        intestazioneLabel.attemptMove(QgsLayoutPoint(1, 0), page=0)
        intestazioneLabel.setFrameEnabled(False)
        l.addLayoutItem(intestazioneLabel)

        scaleLabel = QgsLayoutItemLabel(l)
        txt = "Scala: "
        scaleLabel.setText(txt)
        scaleLabel.adjustSizeToText()
        scaleLabel.attemptMove(QgsLayoutPoint(1, 5), page=0)
        scaleLabel.setFrameEnabled(False)
        l.addLayoutItem(scaleLabel)

        # aggiunge la scale bar
        scaleBarItem = QgsLayoutItemScaleBar(l)
        scaleBarItem.setStyle('Numeric')  # optionally modify the style
        scaleBarItem.setLinkedMap(map)
        scaleBarItem.applyDefaultSize()
        scaleBarItem.attemptMove(QgsLayoutPoint(10, 5), page=0)
        scaleBarItem.setFrameEnabled(False)
        l.addLayoutItem(scaleBarItem)

        le = QgsLayoutExporter(l)
        settings = QgsLayoutExporter.ImageExportSettings()
        settings.dpi = 100

        MAPS_path = '{}{}{}'.format(self.HOME, os.sep,
                                    "pyarchinit_MAPS_folder")
        tav_name = "Tavola_{}_us_{}.png".format(self.tav_num + 1, self.us)
        filename_png = '{}{}{}'.format(MAPS_path, os.sep, tav_name)

        le.exportToImage(filename_png, settings)

        self.remove_layer()

    def open_connection_postgis(self):
        cfg_rel_path = os.path.join(os.sep, 'pyarchinit_DB_folder',
                                    'config.cfg')
        file_path = '{}{}'.format(self.HOME, cfg_rel_path)
        conf = open(file_path, "r")
        con_sett = conf.read()
        conf.close()
        settings = Settings(con_sett)
        settings.set_configuration()
        self.uri = QgsDataSourceUri()
        self.uri.setConnection(settings.HOST, settings.PORT, settings.DATABASE,
                               settings.USER, settings.PASSWORD)

    def open_connection_sqlite(self):
        cfg_rel_path = os.path.join(os.sep, 'pyarchinit_DB_folder',
                                    'config.cfg')
        file_path = '{}{}'.format(self.HOME, cfg_rel_path)
        conf = open(file_path, "r")
        con_sett = conf.read()
        conf.close()
        settings = Settings(con_sett)
        settings.set_configuration()
        self.uri = QgsDataSourceUri()
        self.uri.setConnection(settings.DATABASE)

    def remove_layer(self):
        if self.USLayerId != "":
            QgsProject.instance().removeMapLayer(self.USLayerId)
            self.USLayerId = ""

        if self.QuoteLayerId != "":
            QgsProject.instance().removeMapLayer(self.QuoteLayerId)
            self.QuoteLayerId = ""

    def charge_layer_sqlite(self, sito, area, us):

        cfg_rel_path = os.path.join(os.sep, 'pyarchinit_DB_folder',
                                    'config.cfg')
        file_path = '{}{}'.format(self.HOME, cfg_rel_path)
        conf = open(file_path, "r")
        con_sett = conf.read()
        conf.close()

        settings = Settings(con_sett)
        settings.set_configuration()

        sqliteDB_path = os.path.join(os.sep, 'pyarchinit_DB_folder',
                                     settings.DATABASE)

        db_file_path = '{}{}'.format(self.HOME, sqliteDB_path)
        uri = QgsDataSourceUri()
        uri.setDatabase(db_file_path)
        #srs = QgsCoordinateReferenceSystem(self.SRS, QgsCoordinateReferenceSystem.PostgisCrsId)

        gidstr = "scavo_s = '%s' and area_s = '%s' and us_s = '%s'" % (
            sito, area, us)

        #uri = QgsDataSourceUri()
        #uri.setDatabase(db_file_path)

        uri.setDataSource('', 'pyarchinit_us_view', 'the_geom', gidstr,
                          "ROWID")
        self.layerUS = QgsVectorLayer(uri.uri(), 'pyarchinit_us_view',
                                      'spatialite')

        if self.layerUS.isValid():
            #self.layerUS.setCrs(srs)
            self.USLayerId = self.layerUS.id()
            # self.mapLayerRegistry.append(USLayerId)
            style_path = '{}{}'.format(self.LAYER_STYLE_PATH_SPATIALITE,
                                       'us_view.qml')
            self.layerUS.loadNamedStyle(style_path)
            self.iface.mapCanvas().setExtent(self.layerUS.extent())
            QgsProject.instance().addMapLayer(self.layerUS, True)
        else:
            QMessageBox.warning(None, "Errore", "Non Valido", QMessageBox.Ok)
            return 0
            # QMessageBox.warning(self, "Messaggio", "Geometria inesistente", QMessageBox.Ok)

        gidstr = "sito_q = '%s' and area_q = '%s' and us_q = '%d'" % (sito,
                                                                      area, us)

        uri.setDataSource('', 'pyarchinit_quote_view', 'the_geom', gidstr,
                          "ROWID")
        self.layerQuote = QgsVectorLayer(uri.uri(), 'pyarchinit_quote_view',
                                         'spatialite')

        if self.layerQuote.isValid():
            #self.layerQuote.setCrs(srs)
            self.QuoteLayerId = self.layerQuote.id()
            # self.mapLayerRegistry.append(QuoteLayerId)
            style_path = '{}{}'.format(self.LAYER_STYLE_PATH_SPATIALITE,
                                       'stile_quote.qml')
            self.layerQuote.loadNamedStyle(style_path)
            QgsProject.instance().addMapLayer(self.layerQuote, True)

    def charge_layer_postgis(self, sito, area, us):
        self.open_connection_postgis()

        srs = QgsCoordinateReferenceSystem(
            self.SRS, QgsCoordinateReferenceSystem.PostgisCrsId)

        gidstr = "scavo_s = '%s' and area_s = '%s' and us_s = '%d'" % (
            sito, area, us)

        self.uri.setDataSource("public", "pyarchinit_us_view", "the_geom",
                               gidstr, 'gid')

        self.layerUS = QgsVectorLayer(self.uri.uri(), "US", "postgres")

        if self.layerUS.isValid():
            self.layerUS.setCrs(srs)
            self.USLayerId = self.layerUS.id()
            # self.mapLayerRegistry.append(USLayerId)
            #style_path = '{}{}'.format(self.LAYER_STYLE_PATH, 'us_caratterizzazioni.qml')
            #self.layerUS.loadNamedStyle(style_path)
            self.iface.mapCanvas().setExtent(self.layerUS.extent())
            QgsProject.instance().addMapLayer(self.layerUS, True)
        else:
            return 0

        gidstr = "sito_q = '%s' and area_q = '%s' and us_q = '%d'" % (sito,
                                                                      area, us)

        self.uri.setDataSource("public", "pyarchinit_quote", "the_geom",
                               gidstr, 'gid')
        self.layerQuote = QgsVectorLayer(self.uri.uri(), "Quote", "postgres")

        if self.layerQuote.isValid():
            self.layerQuote.setCrs(srs)
            self.QuoteLayerId = self.layerQuote.id()
            # self.mapLayerRegistry.append(QuoteLayerId)
            #style_path = '{}{}'.format(self.LAYER_STYLE_PATH, 'stile_quote.qml')
            #self.layerQuote.loadNamedStyle(style_path)
            QgsProject.instance().addMapLayer(self.layerQuote, True)
Пример #20
0
class oivImportFileWidget(QDockWidget, FORM_CLASS):
    """the actions class for the import"""

    parentWidget = None
    canvas = None
    selectTool = None
    importLayer = None
    layerImportType = None
    mappingDict = {}
    layerTypes = ['Point', 'LineString', 'Polygon']

    def __init__(self, parent=None):
        """Constructor."""
        super(oivImportFileWidget, self).__init__(parent)
        self.iface = iface
        self.setupUi(self)
        self.select_file.clicked.connect(self.selectfile)
        self.terug.clicked.connect(self.close_import)
        self.mapping.clicked.connect(self.run_mapping)
        self.import_file.clicked.connect(self.inlezen)
        self.hide_all()

    def selectfile(self):
        """select the import shape or dxf file"""
        dxfInfo = None
        importFile = QFileDialog.getOpenFileName(
            None, "Selecteer bestand:", None,
            "AutoCad (*.dxf);;Shape (*.shp);;GeoPackage (*.gpkg)")[0]
        self.bestandsnaam.setText(importFile)
        if importFile:
            if importFile.endswith('.dxf'):
                self.layerImportType, ok = DxfDialogObject.getGeometryType()
                dxfInfo = "|layername=entities|geometrytype=" + self.layerImportType
                importFileFeat = importFile + dxfInfo
                if not self.layerImportType or not ok:
                    return
                self.importLayer = QgsVectorLayer(importFileFeat, "import",
                                                  "ogr")
            elif importFile.endswith('.gpkg'):
                layerNames = [l.GetName() for l in ogr.Open(importFile)]
                GpkgDialog.layerNames = layerNames
                layerName, dummy = GpkgDialog.getLayerName()
                gpkgInfo = "|layername={}".format(layerName)
                importFileFeat = importFile + gpkgInfo
                self.importLayer = QgsVectorLayer(importFileFeat, "import",
                                                  "ogr")
            else:
                importFileFeat = importFile
                self.importLayer = QgsVectorLayer(importFileFeat, "import",
                                                  "ogr")
                if self.importLayer.geometryType() < 3:
                    self.layerImportType = self.layerTypes[
                        self.importLayer.geometryType()]
                else:
                    return
        else:
            return
        crs = self.importLayer.crs()
        crs.createFromId(28992)
        self.importLayer.setCrs(crs)
        QgsProject.instance().addMapLayer(self.importLayer, True)
        fields = self.importLayer.fields()
        for field in fields:
            self.type.addItem(field.name())
        self.label3.setVisible(True)
        self.type.setVisible(True)
        self.label6.setVisible(True)
        self.mapping.setVisible(True)

    def read_types(self):
        types = {}
        actionList, dummy, dummy = get_actions('config_object')
        for lst in actionList:
            tempList = []
            for action in lst:
                layerName = action[0]
                layer = getlayer_byname(layerName)
                layerType = check_layer_type(layer)
                tempList.append(action[1])
            tempList.append("niet importeren")
            if layerType in types:
                types[layerType].update({layerName: tempList})
            else:
                types.update({layerType: {layerName: tempList}})
        return types

    def inlezen(self):
        """import the file after all settings wehere made"""
        importAttr = self.type.currentText()
        invalidCount = 0
        for importType in self.mappingDict:
            if self.mappingDict[importType]["targetType"] != 'niet importeren':
                checkConv = False
                expr = QgsExpression('"{}"= \'{}\''.format(
                    importAttr, importType))
                featureIt = self.importLayer.getFeatures(
                    QgsFeatureRequest(expr))
                targetFeature = QgsFeature()
                targetLayerName = self.mappingDict[importType]["layerName"]
                if 'Labels' in targetLayerName:
                    LabelDialog.attributes = [
                        self.type.itemText(i) for i in range(self.type.count())
                    ]
                    LabelDialog.importType = importType
                    labelField, dummy = LabelDialog.getLabelAtrribute()
                targetLayer = getlayer_byname(targetLayerName)
                targetFields = targetLayer.fields()
                targetFeature.initAttributes(targetFields.count())
                targetFeature.setFields(targetFields)
                if self.mappingDict[importType][
                        "convType"] != self.layerImportType:
                    checkConv = True
                query = "SELECT foreign_key, identifier, input_label FROM config_object WHERE child_layer = '{}'".format(
                    targetLayerName)
                attrs = read_settings(query, False)[0]
                targetFeature[
                    attrs[1]] = self.mappingDict[importType]["targetType"]
                targetFeature[attrs[0]] = self.object_id.text()
                targetLayer.startEditing()

                for feat in featureIt:
                    geom = None
                    if not checkConv:
                        geom = getfeature_geometry(feat.geometry(),
                                                   self.layerImportType)
                        if 'Labels' in targetLayerName:
                            if feat[labelField]:
                                targetFeature[attrs[2]] = feat[labelField]
                            else:
                                targetFeature[attrs[2]] = 'geen label'
                    if geom:
                        targetFeature.setGeometry(geom)
                        invalidCheck = write_layer(targetLayer, targetFeature,
                                                   True)
                        if invalidCheck == 'invalid':
                            invalidCount += 1
                targetLayer.commitChanges()
        if invalidCount > 0:
            message = (
                'Features zijn geimporteerd.\n'
                '{} features zijn niet geimporteerd vanwege ongeldige geometrie!'
                .format(invalidCount))
        else:
            message = 'Alle feature zijn succesvol geimporteerd!'
        QMessageBox.information(None, "INFO:", message)
        QgsProject.instance().removeMapLayers([self.importLayer.id()])

    def run_mapping(self):
        """get attribute mapping from the user"""
        targetTypes = self.read_types()
        importTypes = []
        importAttribute = self.type.currentText()
        for feat in self.importLayer.getFeatures():
            if feat[importAttribute] not in importTypes:
                importTypes.append(feat[importAttribute])
        if self.layerImportType == 'Point':
            MappingDialog.layerType = ['Point']
        else:
            MappingDialog.layerType = ['LineString', 'Polygon']
        MappingDialog.targetTypes = targetTypes
        MappingDialog.importTypes = importTypes
        self.mappingDict, ok = MappingDialog.getMapping()
        if ok:
            self.label7.setVisible(True)
            self.import_file.setVisible(True)

    def hide_all(self):
        """when the import start hide all on the UI"""
        self.bouwlaag_id.setVisible(False)
        self.label1.setVisible(True)
        self.label3.setVisible(False)
        self.label6.setVisible(False)
        self.label7.setVisible(False)
        self.mapping.setVisible(False)
        self.type.setVisible(False)
        self.select_file.setVisible(True)
        self.bestandsnaam.setVisible(True)
        self.import_file.setVisible(False)

    def close_import(self):
        """close feature form and save changes"""
        try:
            QgsProject.instance().removeMapLayers([self.importLayer.id()])
        except:  # pylint: disable=bare-except
            pass
        self.hide_all()
        self.close()
        try:
            self.parentWidget.show()
            del self.parentWidget
        except:  # pylint: disable=bare-except
            pass
        del self
Пример #21
0
    def newLULayer(self):

        if self.ludlg.LUincUFcheckBox.checkState(
        ) == 0 and self.ludlg.LUincLFcheckBox.checkState(
        ) == 0 and self.ludlg.LUincGFcheckBox.checkState() == 0:
            msgBar = self.iface.messageBar()
            msg = msgBar.createMessage(u'Select floors')
            msgBar.pushWidget(msg, Qgis.Info, 10)

        else:
            idcolumn = self.ludlg.getSelectedLULayerID()
            # if create from existing building layer
            if self.ludlg.createNewLUFileCheckBox.isChecked():
                print('aaaa')
                building_layer = self.getSelectedLULayer()
                crs = building_layer.crs()
                vl = QgsVectorLayer("Polygon?crs=" + crs.authid(),
                                    "memory:landuse", "memory")
            else:
                # create memory layer
                vl = QgsVectorLayer("Polygon?crs=", "memory:landuse", "memory")
            if vl.crs().toWkt() == "":
                vl.setCrs(QgsProject.instance().crs())
            provider = vl.dataProvider()
            # provider.addAttributes([])

            ground_floor_attributes = [
                QgsField(LanduseTool.lu_id_attribute, QVariant.Int),
                QgsField(LanduseTool.floors_attribute, QVariant.Int),
                QgsField(LanduseTool.area_attribute, QVariant.Double),
                QgsField(LanduseTool.gf_cat_attribute, QVariant.String),
                QgsField(LanduseTool.gf_subcat_attribute, QVariant.String),
                QgsField(LanduseTool.gf_ssx_attribute, QVariant.String),
                QgsField(LanduseTool.gf_nlud_attribute, QVariant.String),
                QgsField(LanduseTool.gf_tcpa_attribute, QVariant.String),
                QgsField(LanduseTool.gf_descrip_attribute, QVariant.String)
            ]

            lower_floor_attributes = [
                QgsField(LanduseTool.lf_cat_attribute, QVariant.String),
                QgsField(LanduseTool.lf_subcat_attribute, QVariant.String),
                QgsField(LanduseTool.lf_ssx_attribute, QVariant.String),
                QgsField(LanduseTool.lf_nlud_attribute, QVariant.String),
                QgsField(LanduseTool.lf_tcpa_attribute, QVariant.String),
                QgsField(LanduseTool.lf_descrip_attribute, QVariant.String)
            ]

            upper_floor_attributes = [
                QgsField(LanduseTool.uf_cat_attribute, QVariant.String),
                QgsField(LanduseTool.uf_subcat_attribute, QVariant.String),
                QgsField(LanduseTool.uf_ssx_attribute, QVariant.String),
                QgsField(LanduseTool.uf_nlud_attribute, QVariant.String),
                QgsField(LanduseTool.uf_ntcpa_attribute, QVariant.String),
                QgsField(LanduseTool.uf_descrip_attribute, QVariant.String)
            ]

            if self.ludlg.LUincGFcheckBox.checkState() == 2:
                provider.addAttributes(ground_floor_attributes)
                self.dockwidget.LUGroundfloorradioButton.setEnabled(1)

            if self.ludlg.LUincLFcheckBox.checkState() == 2:
                provider.addAttributes(lower_floor_attributes)
                self.dockwidget.LULowerfloorradioButton.setEnabled(1)

            if self.ludlg.LUincUFcheckBox.checkState() == 2:
                provider.addAttributes(upper_floor_attributes)
                self.dockwidget.LULowerfloorradioButton.setEnabled(1)

            vl.updateFields()
            # if create from existing building layer
            if self.ludlg.createNewLUFileCheckBox.isChecked():

                null_attr = []
                provider.addAttributes([QgsField('build_id', QVariant.String)])

                if self.ludlg.LUincGFcheckBox.checkState() == 2:
                    # TODO: has removed [QgsField("Build_ID", QVariant.Int)] +
                    provider.addAttributes(ground_floor_attributes)
                    self.dockwidget.LUGroundfloorradioButton.setEnabled(1)
                    null_attr += [
                        NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
                    ]

                if self.ludlg.LUincLFcheckBox.checkState() == 2:
                    provider.addAttributes(lower_floor_attributes)
                    self.dockwidget.LULowerfloorradioButton.setEnabled(1)
                    null_attr += [NULL, NULL, NULL, NULL, NULL, NULL]

                if self.ludlg.LUincUFcheckBox.checkState() == 2:
                    provider.addAttributes(upper_floor_attributes)
                    self.dockwidget.LULowerfloorradioButton.setEnabled(1)
                    null_attr += [NULL, NULL, NULL, NULL, NULL, NULL]

                new_feat_list = []
                i = 1
                for feat in building_layer.getFeatures():
                    new_feat = QgsFeature()
                    new_feat.setAttributes([i] + null_attr + [feat[idcolumn]])
                    i += 1
                    new_feat.setGeometry(feat.geometry())
                    new_feat_list.append(new_feat)

                vl.updateFields()
                provider.addFeatures(new_feat_list)
                vl.commitChanges()

            if self.ludlg.lu_shp_radioButton.isChecked(
            ):  # layer_type == 'shapefile':

                path = self.ludlg.lineEditLU.text()

                if path and path != '':

                    filename = os.path.basename(path)
                    location = os.path.abspath(path)

                    shph.createShapeFile(vl, path, vl.crs())
                    print('cri', vl.crs().authid())
                    input2 = self.iface.addVectorLayer(location, filename[:-4],
                                                       "ogr")
                else:
                    input2 = 'invalid data source'

            elif self.ludlg.lu_postgis_radioButton.isChecked():

                db_path = self.ludlg.lineEditLU.text()
                if db_path and db_path != '':
                    (database, schema, table_name) = db_path.split(':')
                    db_con_info = self.ludlg.dbsettings_dlg.available_dbs[
                        database]
                    uri = QgsDataSourceUri()
                    # passwords, usernames need to be empty if not provided or else connection will fail
                    if 'service' in list(db_con_info.keys()):
                        uri.setConnection(db_con_info['service'], '', '', '')
                    elif 'password' in list(db_con_info.keys()):
                        uri.setConnection(db_con_info['host'],
                                          db_con_info['port'],
                                          db_con_info['dbname'],
                                          db_con_info['user'],
                                          db_con_info['password'])
                    else:
                        print(db_con_info)  # db_con_info['host']
                        uri.setConnection('', db_con_info['port'],
                                          db_con_info['dbname'], '', '')
                    uri.setDataSource(schema, table_name, "geom")
                    error = QgsVectorLayerExporter.exportLayer(
                        vl, uri.uri(), "postgres", vl.crs())
                    if error[0] != QgsVectorLayerExporter.NoError:
                        print("Error when creating postgis layer: ", error[1])
                        input2 = 'duplicate'
                    else:
                        input2 = QgsVectorLayer(uri.uri(), table_name,
                                                "postgres")
                else:
                    input2 = 'invalid data source'

            else:
                input2 = vl

            if input2 == 'invalid data source':
                msgBar = self.iface.messageBar()
                msg = msgBar.createMessage(u'Specify output path!')
                msgBar.pushWidget(msg, Qgis.Info, 10)
            elif input2 == 'duplicate':
                msgBar = self.iface.messageBar()
                msg = msgBar.createMessage(u'Land use layer already exists!')
                msgBar.pushWidget(msg, Qgis.Info, 10)
            elif not input2:
                msgBar = self.iface.messageBar()
                msg = msgBar.createMessage(u'Land use layer failed to load!')
                msgBar.pushWidget(msg, Qgis.Info, 10)
            else:
                QgsProject.instance().addMapLayer(input2)
                msgBar = self.iface.messageBar()
                msg = msgBar.createMessage(u'Land use layer created!')
                msgBar.pushWidget(msg, Qgis.Info, 10)
                input2.startEditing()

        self.updateLULayer()
        self.ludlg.closePopUpLU()
        self.ludlg.lineEditLU.clear()
    def doMask(self, item):
        mapcrs = self.plugin.canvas.mapSettings().destinationCrs()

        ogrFeature = item.data(Qt.UserRole)
        layerName = "OSM "+ogrFeature.GetFieldAsString('id')
        geom = QgsGeometry.fromWkt(ogrFeature.GetGeometryRef().ExportToWkt())
        self.transform(geom)

        if (geom.type() == QgsWkbTypes.PolygonGeometry):
            try:
                try:
                    from mask import aeag_mask
                except:
                    from mask_plugin import aeag_mask

                aeag_mask.do(mapcrs, {geom}, "Mask "+layerName)

            except:
                geom = QgsGeometry.fromWkt(ogrFeature.GetGeometryRef().ExportToWkt())
                self.transform(geom)
                toCrs = self.plugin.canvas.mapSettings().destinationCrs()

                larg = max(geom.boundingBox().width(), geom.boundingBox().height())
                x = geom.boundingBox().center().x()
                y = geom.boundingBox().center().y()
                rect = QgsRectangle(x-larg, y-larg, x+larg, y+larg)  # geom.boundingBox()
                rect.scale(4)
                mask = QgsGeometry.fromRect(rect)

                mask = mask.difference(geom)

                maskLayer = QgsVectorLayer("MultiPolygon", "Mask "+layerName, "memory")
                maskLayer.setCrs(toCrs)
                QgsProject.instance().addMapLayer(maskLayer)
                pr = maskLayer.dataProvider()

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

                pr.addAttributes(fields.toList())

                maskLayer.startEditing()
                pr.addFeatures([fet])
                maskLayer.commitChanges()
                maskLayer.updateExtents()

                # transparence, epaisseur
                renderer = maskLayer.renderer()
                s = renderer.symbol()
                s.setOpacity(0.90)
                s.setColor(QColor(255, 255, 255))
                if isinstance(s, QgsLineSymbol):
                    s.setWidth(0)

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

            self.go(item)
    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)
Пример #24
0
class PRGModule(BaseModule):
    module_name = "PRG - granice administracyjne"

    def __init__(self, parent):
        super().__init__(parent)

        self.dockwidget = PRGDockWidget()
        iface.addDockWidget(Qt.RightDockWidgetArea, self.dockwidget)
        self.dockwidget.hide()

        self.action = self.parent.add_action(
            ':/plugins/gissupport_plugin/prg/prg.svg',
            self.module_name,
            callback=lambda state: self.dockwidget.setHidden(not state),
            parent=iface.mainWindow(),
            checkable=True,
            add_to_topmenu=True)

        self.populate_dockwidget_comboboxes()
        self.task = None
        self.manager = QgsApplication.taskManager()

        self.dockwidget.entity_type_combobox.currentTextChanged.connect(
            self.handle_entity_type_changed)
        self.dockwidget.entity_division_combobox.currentTextChanged.connect(
            self.handle_entity_division_changed)
        self.dockwidget.btn_download.clicked.connect(self.download_prg)
        self.dockwidget.filter_line_edit.textChanged.connect(
            self.filter_name_combobox)

    def filter_name_combobox(self, text: str):
        model = self.dockwidget.entity_name_combobox.model()
        view = self.dockwidget.entity_name_combobox.view()

        first_hit = 1
        for row in range(model.rowCount()):
            item_text = model.item(row, 0).text()

            if text.lower() not in item_text.lower():
                view.setRowHidden(row, True)
            else:
                if first_hit:
                    self.dockwidget.entity_name_combobox.setCurrentIndex(row)
                    first_hit = 0
                view.setRowHidden(row, False)

    def download_prg(self):
        entity_division = self.dockwidget.entity_division_combobox.currentText(
        )
        entity_teryt = self.dockwidget.entity_name_combobox.currentData()

        crs = QgsCoordinateReferenceSystem()
        crs.createFromSrid(2180)

        self.layer = QgsVectorLayer("MultiPolygon", "Obiekty PRG", "memory")
        self.layer.setCrs(crs)

        dp = self.layer.dataProvider()
        dp.addAttributes([QgsField("Nazwa", QVariant.String)])
        dp.addAttributes([QgsField("TERYT", QVariant.String)])
        self.layer.updateFields()

        self.task = PRGDownloadTask("Pobieranie danych PRG", 75, self.layer,
                                    entity_division, entity_teryt)
        self.manager.addTask(self.task)
        self.task.taskCompleted.connect(self.add_result_layer)

    def populate_dockwidget_comboboxes(self):
        self.dockwidget.entity_division_combobox.addItem(
            EntityOption.WOJEWODZTWO.value)
        self.dockwidget.entity_division_combobox.addItem(
            EntityOption.POWIAT.value)
        self.dockwidget.entity_division_combobox.addItem(
            EntityOption.GMINA.value)

        self.dockwidget.entity_type_combobox.addItem(EntityOption.BRAK.value)
        self.dockwidget.entity_type_combobox.addItem(
            EntityOption.WOJEWODZTWO.value)
        self.dockwidget.entity_type_combobox.addItem(EntityOption.POWIAT.value)
        self.dockwidget.entity_type_combobox.addItem(EntityOption.GMINA.value)

    def handle_entity_division_changed(self, entity_division_value: str):
        model = self.dockwidget.entity_type_combobox.model()
        item = model.item(0, 0)

        if entity_division_value == EntityOption.GMINA.value:
            item.setEnabled(False)
        else:
            item.setEnabled(True)

    def handle_entity_type_changed(self, entity_option_value: str):
        self.dockwidget.entity_name_combobox.clear()
        self.dockwidget.filter_line_edit.clear()

        if entity_option_value == EntityOption.WOJEWODZTWO.value:
            data = self.get_administratives("wojewodztwo")
        elif entity_option_value == EntityOption.POWIAT.value:
            data = self.get_administratives("powiat")
        elif entity_option_value == EntityOption.GMINA.value:
            data = self.get_administratives("gmina")
        else:
            self.dockwidget.filter_line_edit.setEnabled(False)
            return

        for item in data:
            display_name = f'{item[0]} | {item[1]}'
            self.dockwidget.entity_name_combobox.addItem(display_name, item[1])

    def add_result_layer(self):
        QgsProject.instance().addMapLayer(self.layer)
        self.zoom_to_layer()

    def zoom_to_layer(self):
        proj = QgsProject.instance()

        extent = self.layer.extent()
        if self.layer.crs().authid() != proj.crs().authid():
            transformation = QgsCoordinateTransform(self.layer.crs(),
                                                    proj.crs(), proj)
            extent = transformation.transform(extent)

        iface.mapCanvas().setExtent(extent)

    def get_administratives(self, level: str):
        self.dockwidget.filter_line_edit.setEnabled(True)

        search = ULDKSearchTeryt(level, ("nazwa", "teryt"))
        result = search.search("")
        result = [r.split("|") for r in result]

        return result
Пример #25
0
    def layer_to_QgsVectorLayer(
            source_layer,  # pylint: disable=too-many-locals,too-many-branches,too-many-statements
            input_file,
            context: Context,
            fallback_crs=QgsCoordinateReferenceSystem(),
            defer_layer_uri_set: bool = False):
        """
        Converts a vector layer
        """
        if source_layer.__class__.__name__ == 'CadFeatureLayer':
            layer = source_layer.layer
        else:
            layer = source_layer

        crs = CrsConverter.convert_crs(
            layer.layer_extent.crs,
            context) if layer.layer_extent else QgsCoordinateReferenceSystem()
        if not crs.isValid():
            crs = fallback_crs

        subset_string = ''
        if layer.selection_set:
            subset_string = 'fid in ({})'.format(','.join(
                [str(s) for s in layer.selection_set]))
        elif layer.definition_query:
            subset_string = ExpressionConverter.convert_esri_sql(
                layer.definition_query)

        base, _ = os.path.split(input_file)

        uri, wkb_type, provider, encoding, file_name = VectorLayerConverter.get_uri(
            source_layer=source_layer,
            obj=layer,
            base=base,
            crs=crs,
            subset=subset_string,
            context=context)

        if wkb_type is None or wkb_type == QgsWkbTypes.Unknown:
            wkb_type = VectorLayerConverter.layer_to_wkb_type(layer)
        context.layer_type_hint = wkb_type

        if Qgis.QGIS_VERSION_INT >= 31600:
            # try to get the layer name so that we can remove it from field references.
            # e.g. if layer name is polys then qgis won't support to arcgis style "polys.field" format
            parts = QgsProviderRegistry.instance().decodeUri(provider, uri)
            context.main_layer_name = parts.get('layerName')
            if not context.main_layer_name and provider == 'ogr':
                context.main_layer_name = Path(parts['path']).stem

            if context.main_layer_name:
                subset_string = subset_string.replace(
                    context.main_layer_name + '.', '')
        else:
            context.main_layer_name = None

        if provider == 'ogr' and (not file_name
                                  or not os.path.exists(file_name)
                                  ) and context.invalid_layer_resolver:
            res = context.invalid_layer_resolver(layer.name, uri, wkb_type)
            uri = res.uri
            provider = res.providerKey

        if Qgis.QGIS_VERSION_INT >= 31000:
            opts = QgsVectorLayer.LayerOptions()
            if wkb_type is not None:
                opts.fallbackWkbType = wkb_type

            if provider == 'ogr' and subset_string:
                uri += '|subset={}'.format(subset_string)

            original_uri = uri
            if defer_layer_uri_set:
                uri = 'xxxxxxxxx' + uri

            vl = QgsVectorLayer(uri, layer.name, provider, opts)
            if defer_layer_uri_set:
                vl.setCustomProperty('original_uri', original_uri)
        else:
            vl = QgsMemoryProviderUtils.createMemoryLayer(
                layer.name, QgsFields(), wkb_type, crs)

        # context.style_folder, _ = os.path.split(output_file)
        if layer.renderer:
            renderer = VectorRendererConverter.convert_renderer(
                layer.renderer, context)
            try:
                if not renderer.usingSymbolLevels():
                    renderer.setUsingSymbolLevels(
                        layer.use_advanced_symbol_levels)
            except AttributeError:
                pass

            if layer.use_page_definition_query:
                filter_expression = '"{}" {} @atlas_pagename'.format(
                    layer.page_name_field, layer.page_name_match_operator)
                root_rule = QgsRuleBasedRenderer.Rule(None)

                # special case -- convert a simple renderer
                if isinstance(renderer, QgsSingleSymbolRenderer):
                    filter_rule = QgsRuleBasedRenderer.Rule(
                        renderer.symbol().clone())
                    filter_rule.setFilterExpression(filter_expression)
                    filter_rule.setLabel(layer.name)
                    filter_rule.setDescription(layer.name)
                    root_rule.appendChild(filter_rule)
                else:
                    source_rule_renderer = QgsRuleBasedRenderer.convertFromRenderer(
                        renderer)
                    filter_rule = QgsRuleBasedRenderer.Rule(None)
                    filter_rule.setFilterExpression(filter_expression)
                    filter_rule.setLabel('Current Atlas Page')
                    filter_rule.setDescription('Current Atlas Page')
                    root_rule.appendChild(filter_rule)
                    for child in source_rule_renderer.rootRule().children():
                        filter_rule.appendChild(child.clone())

                renderer = QgsRuleBasedRenderer(root_rule)

            if renderer:
                vl.setRenderer(renderer)
                vl.triggerRepaint()
        else:
            vl.setRenderer(QgsNullSymbolRenderer())
            vl.triggerRepaint()

        metadata = vl.metadata()
        metadata.setAbstract(layer.description)
        vl.setMetadata(metadata)  #

        # layer.zoom_max = "don't show when zoomed out beyond"
        zoom_max = layer.zoom_max
        # layer.zoom_min = "don't show when zoomed in beyond"
        zoom_min = layer.zoom_min

        enabled_scale_range = bool(zoom_max or zoom_min)
        if zoom_max and zoom_min and zoom_min > zoom_max:
            # inconsistent scale range -- zoom_max should be bigger number than zoom_min
            zoom_min, zoom_max = zoom_max, zoom_min

        # qgis minimum scale = don't show when zoomed out beyond, i.e. ArcGIS zoom_max
        vl.setMinimumScale(
            zoom_max if enabled_scale_range else layer.stored_zoom_max)
        # qgis maximum scale = don't show when zoomed in beyond, i.e. ArcGIS zoom_min
        vl.setMaximumScale(
            zoom_min if enabled_scale_range else layer.stored_zoom_min)
        vl.setScaleBasedVisibility(enabled_scale_range)

        vl.setOpacity(1.0 - (layer.transparency or 0) / 100)

        if layer.display_expression_properties and layer.display_expression_properties.expression and layer.display_expression_properties.expression_parser is not None:
            vl.setDisplayExpression(
                ExpressionConverter.convert(
                    layer.display_expression_properties.expression,
                    layer.display_expression_properties.expression_parser,
                    layer.display_expression_properties.advanced, context))

        if Qgis.QGIS_VERSION_INT < 31000:
            vl.setDataSource(uri, layer.name, provider)

        if encoding:
            vl.dataProvider().setEncoding(encoding)

        if subset_string:
            vl.setSubsetString(subset_string)

        vl.setCrs(crs)

        for e in layer.extensions:
            if e.__class__.__name__ == 'ServerLayerExtension':
                if 'CopyrightText' in e.properties.properties:
                    layer_credits = e.properties.properties['CopyrightText']
                    metadata = vl.metadata()
                    rights = metadata.rights()
                    rights.append(layer_credits)
                    metadata.setRights(rights)
                    vl.setMetadata(metadata)

        LabelConverter.convert_annotation_collection(
            layer.annotation_collection, dest_layer=vl, context=context)
        vl.setLabelsEnabled(layer.labels_enabled)

        DiagramConverter.convert_diagrams(layer.renderer,
                                          dest_layer=vl,
                                          context=context)

        # setup joins
        join_layer = VectorLayerConverter.add_joined_layer(
            source_layer=layer,
            input_file=input_file,
            base_layer=vl,
            context=context)

        context.dataset_name = ''

        vl.setLegend(QgsMapLayerLegend.defaultVectorLegend(vl))

        if layer.hyperlinks:
            VectorLayerConverter.convert_hyperlinks(layer.hyperlinks, vl)

        vl.setDisplayExpression(
            QgsExpression.quotedColumnRef(layer.display_field))

        res = [vl]
        if join_layer:
            res.append(join_layer)

        context.main_layer_name = None
        return res
Пример #26
0
    def fetch(self):
        """
        Fetch Occurrence records for selected taxon.
        """
        QgsApplication.instance().setOverrideCursor(
            QtGui.QCursor(QtCore.Qt.WaitCursor))
        QgsMessageLog.logMessage('Fetching occurrences', 'SpeciesExplorer', 0)
        name = self.results_list.selectedItems()[0].text()

        end_of_records = False
        offset = 0
        layer = QgsVectorLayer('Point', name, 'memory')
        layer.setCrs(QgsCoordinateReferenceSystem('EPSG:4326'))
        provider = layer.dataProvider()
        counter = 0

        while not end_of_records:

            url = ('https://api.gbif.org/v1/occurrence/search?'
                   'scientificName=%s&offset=%i' % (name, offset))
            offset += 100
            result = gbif_GET(url, None)
            count = int(result['count'])
            end_of_records = result['endOfRecords']
            records = result['results']

            QgsMessageLog.logMessage(
                'Fetching record %s of %s occurrences' % (offset, count),
                'SpeciesExplorer', 0)
            # Will populate this in create_fields call
            if len(records) == 0:
                QgsMessageLog.logMessage('No records found', 'SpeciesExplorer',
                                         0)
                QMessageBox.information(self, 'Species Explorer',
                                        'No records found for %s' % name)
                return
            field_lookups = self.create_fields(layer, records[0])
            QgsMessageLog.logMessage('Field lookup: %s' % field_lookups,
                                     'SpeciesExplorer', 0)
            for record in records:
                QgsMessageLog.logMessage('Record: %s' % record,
                                         'SpeciesExplorer', 0)
                if ('decimalLongitude' not in record
                        or 'decimalLatitude' not in record):
                    continue

                feature = QgsFeature()
                feature.setGeometry(
                    QgsGeometry.fromPointXY(
                        QgsPointXY(record['decimalLongitude'],
                                   record['decimalLatitude'])))
                attributes = [counter]
                for key in field_lookups:
                    try:
                        attributes.append(record[key])
                    except KeyError:
                        # just append an empty item to make sure the list
                        # size is correct
                        attributes.append('')

                feature.setAttributes(attributes)
                provider.addFeatures([feature])
                counter += 1

            if offset > count:
                end_of_records = True

            QgsMessageLog.logMessage('End of records: %s' % end_of_records,
                                     'SpeciesExplorer', 0)

        layer.commitChanges()
        QgsProject.instance().addMapLayer(layer)

        # recursively walk back the cursor to a pointer
        while QgsApplication.instance().overrideCursor() is not None and \
            QgsApplication.instance().overrideCursor().shape() == \
            QtCore.Qt.WaitCursor:
            QgsApplication.instance().restoreOverrideCursor()
Пример #27
0
class Layer(object):

    def __init__(self, provider, uri, name, srid, extent, geometry_column=None, wkb_type=QgsWkbTypes.Unknown, alias=None, is_domain=False, is_structure=False, is_nmrel=False, display_expression=None):
        self.provider = provider
        self.uri = uri
        self.name = name
        if extent is not None:
            extent_coords = extent.split(';')
            extent = QgsRectangle(
                        float(extent_coords[0]),
                        float(extent_coords[1]),
                        float(extent_coords[2]),
                        float(extent_coords[3]))
        self.extent = extent
        self.geometry_column = geometry_column
        self.wkb_type = wkb_type
        self.alias = alias
        self.__layer = None
        self.fields = list()
        self.is_domain = is_domain
        self.is_structure = is_structure

        self.is_nmrel = is_nmrel
        self.srid = srid
        """ If is_nmrel is set to true it is a junction table in a N:M relation.
        Or in ili2db terms, the table is marked as ASSOCIATION in t_ili2db_table_prop.settings. """

        self.display_expression = display_expression

        self.__form = Form()

    def dump(self):
        definition = dict()
        definition['provider'] = self.provider
        definition['uri'] = self.uri
        definition['isdomain'] = self.is_domain
        definition['isstructure'] = self.is_structure
        definition['isnmrel'] = self.is_nmrel
        definition['displayexpression'] = self.display_expression
        definition['form'] = self.__form.dump()
        return definition

    def load(self, definition):
        self.provider = definition['provider']
        self.uri = definition['uri']
        self.is_domain = definition['isdomain']
        self.is_structure = definition['isstructure']
        self.is_nmrel = definition['isnmrel']
        self.display_expression = definition['displayexpression']
        self.__form.load(definition['form'])

    def create(self):
        if self.__layer is None:
            layer_name = self.alias or self.name

            settings = QSettings()
            # Take the "CRS for new layers" config, overwrite it while loading layers and...
            old_proj_value = settings.value("/Projections/defaultBehaviour", "prompt", type=str)
            settings.setValue("/Projections/defaultBehaviour", "useProject")
            self.__layer = QgsVectorLayer(self.uri, layer_name, self.provider)
            settings.setValue("/Projections/defaultBehavior", old_proj_value)

            if self.srid is not None and not self.__layer.crs().authid() == "EPSG:{}".format(self.srid):
                self.__layer.setCrs(QgsCoordinateReferenceSystem().fromEpsgId(self.srid))
            if self.is_domain:
                self.__layer.setReadOnly()
            if self.display_expression:
                self.__layer.setDisplayExpression(self.display_expression)
        for field in self.fields:
            field.create(self)

        return self.__layer

    def create_form(self, project):
        edit_form = self.__form.create(self, self.__layer, project)
        self.__layer.setEditFormConfig(edit_form)

    def post_generate(self, project):
        '''
        Will be called when the whole project has been generated and
        therefore all relations are available and the form
        can also be generated.
        '''
        has_tabs = False
        for relation in project.relations:
            if relation.referencing_layer == self:
                has_tabs = True
                break

        if has_tabs:
            tab = FormTab(QCoreApplication.translate('FormTab', 'General'), 2)
            for field in self.fields:
                if not field.hidden:
                    widget = FormFieldWidget(field.alias, field.name)
                    tab.addChild(widget)

            self.__form.add_element(tab)

            for relation in project.relations:
                if relation.referenced_layer == self:
                    tab = FormTab(relation.referencing_layer.name)
                    widget = FormRelationWidget(relation)
                    tab.addChild(widget)
                    self.__form.add_element(tab)
        else:
            for field in self.fields:
                if not field.hidden:
                    widget = FormFieldWidget(field.alias, field.name)
                    self.__form.add_element(widget)

    @property
    def layer(self):
        return self.__layer

    @property
    def real_id(self):
        '''
        The layer id. Only valid after creating the layer.
        '''
        if self.__layer:
            return self.__layer.id()
        else:
            return None
Пример #28
0
    def showResult(self):
        """
        Perform calculations and send them to display.
        """
        # Tuple[Tuple[str, str, int]]
        selected_rows = tuple(self.windowRow.tab)
        selected_columns = tuple(self.windowColumn.tab)
        selected_ValCalc = tuple(self.windowValue.tab)

        # Reading a field that has been selected for calculation.
        # Only one is allowed.
        # List[Tuple[str, str, int]]
        value = [x for x in selected_ValCalc if x[0] != 'calculation'][0]

        # Set the calculation function depending on the type of the selected
        # value.
        if value[0] == 'geometry':
            if value[2] == 1:
                fun = lambda feat: feat.geometry().length()
            elif value[2] == 2:
                fun = lambda feat: feat.geometry().area()
        elif value[0] == 'text':
            fun = lambda feat: None if not feat.attribute(value[1]) else \
                feat.attribute(value[1])
        elif value[0] == 'number':
            fun = lambda feat: None if not feat.attribute(value[1]) else \
                float(feat.attribute(value[1]))

        # Get selected layer
        index = self.ui.layer.currentIndex()
        layer_id = self.ui.layer.itemData(index)
        layer = QgsProject.instance().mapLayer(layer_id)

        selected_features_id = layer.selectedFeatureIds()
        only_selected = self.ui.onlySelected.isChecked()

        tmp_layer = QgsVectorLayer(layer.source(), layer.name(),
                                   layer.providerType())
        tmp_layer.setCrs(layer.crs())
        filter_str = self.ui.filter.toPlainText()
        layer_filter = layer.subsetString()
        if not layer_filter and filter_str:
            tmp_layer.setSubsetString(filter_str)
        elif layer_filter and filter_str:
            tmp_layer.setSubsetString('{} and {}'.format(
                layer_filter, filter_str))

        provider = tmp_layer.dataProvider()
        features = provider.getFeatures()

        # Dictionary on results {((row) (column)): [[values], [indexes]} ??
        results = {}

        # Compute percent_factor for progress monitoring
        n_features = provider.featureCount()
        if n_features:
            percent_factor = 100 / n_features
        else:
            percent_factor = 100

        progress = 0
        count_null = 0

        for f in features:
            if not only_selected or \
                    (only_selected and f.id() in selected_features_id):
                key_col = []
                key_row = []
                key = ()

                for k in selected_columns:
                    if k[0] == 'geometry':
                        if k[2] == 1:
                            key_col.append(f.geometr().length())
                        elif k[2] == 2:
                            key_col.append(f.geometry().area())
                    elif k[0] in ['text', 'number']:
                        if f.attribute(k[1]) is None:
                            new_key_kol = ''
                        else:
                            new_key_kol = f.attribute(k[1])
                        key_col.append(new_key_kol)

                for k in selected_rows:
                    if k[0] == 'geometry':
                        if k[2] == 1:
                            key_row.append(f.geometry().length())
                        elif k[2] == 2:
                            key_row.append(f.geometry().area())
                    elif k[0] in ['text', 'number']:
                        if f.attribute(k[1]) is None:
                            new_key_row = ''
                        else:
                            new_key_row = f.attribute(k[1])
                        key_row.append(new_key_row)

                key = (tuple(key_row), tuple(key_col))

                value_to_calculate = fun(f)
                if value_to_calculate is not None or \
                        self.ui.useNULL.isChecked():
                    if value_to_calculate is None:
                        count_null += 1
                        if value[0] == 'number':
                            value_to_calculate = 0

                    # If the key exists then a new value is added to the list.
                    if key in results:
                        results[key][0].append(value_to_calculate)
                    # If the key does not exist then a new list is created.
                    else:
                        results[key] = [[value_to_calculate], []]

                    results[key][1].append(f.id())

                else:
                    count_null += 1

                # Display progress
                progress += percent_factor
                self.statusBar().showMessage(
                    QCoreApplication.translate('GroupStats', 'Calculate...') +
                    '{:.2f}'.format(progress))
        self.statusBar().showMessage(
            self.statusBar().currentMessage() + ' |  ' +
            QCoreApplication.translate('GroupStats', 'generate view...'))

        # Find unique row and column keys (separately)
        keys = list(results.keys())
        row_set = set([])
        col_set = set([])
        for key in keys:
            # Add keys to the collection to reject repetition
            row_set.add(key[0])
            col_set.add(key[1])
        rows = list(row_set)
        cols = list(col_set)

        # Create dictionary for rows and columns for faster searching.
        row_dict = {}
        col_dict = {}
        for n, row in enumerate(rows):
            row_dict[row] = n
        for n, col in enumerate(cols):
            col_dict[col] = n

        calculations = [
            [x[2] for x in selected_ValCalc if x[0] == 'calculation'],
            [x[2] for x in selected_rows if x[0] == 'calculation'],
            [x[2] for x in selected_columns if x[0] == 'calculation'],
        ]

        # Take only a non-empty part of the list to calculate.
        if calculations[0]:
            calculation = calculations[0]
        elif calculations[1]:
            calculation = calculations[1]
        else:
            calculation = calculations[2]

        # Create empty array for data (rows x columns)
        data = []
        for x in range(max(len(rows), len(rows) * len(calculations[1]))):
            data.append(
                max(len(cols),
                    len(cols) * len(calculations[2])) * [('', ())])

        # Calculate of values ​​for all keys
        for x in keys:
            # row and column number in the data table for the selected key
            krow = row_dict[x[0]]
            kcol = col_dict[x[1]]
            # Perform all calculations for all keys.
            for n, y in enumerate(calculation):
                # At the right side of the equation is a list of 2:
                # 1. Resulting computation
                # 2. A list of feature ID's used in the computation
                if calculations[1]:
                    data[krow * len(calculations[1]) + n][kcol] = [
                        self.calculation.list[y][1](results[x][0]),
                        results[x][1]
                    ]
                elif calculations[2]:
                    data[krow][kcol * len(calculations[2]) + n] = [
                        self.calculation.list[y][1](results[x][0]),
                        results[x][1]
                    ]
                else:
                    data[krow][kcol] = [
                        self.calculation.list[y][1](results[x][0]),
                        results[x][1]
                    ]

        attributes = {}
        for i in range(provider.fields().count()):
            attributes[i] = provider.fields().at(i)

        row_names = []
        for x in selected_rows:
            if x[0] == 'geometry':
                row_names.append(x[1])
            elif x[0] != 'calculation':
                row_names.append(attributes[x[2]].name())
        col_names = []
        for x in selected_columns:
            if x[0] == 'geometry':
                col_names.append(x[1])
            elif x[0] != 'calculation':
                col_names.append(attributes[x[2]].name())

        # Insert names of rows and columns with calculations.
        calc_col_name = ()
        calc_row_name = ()
        if calculations[1]:
            calc = [self.calculation.list[x][0] for x in calculations[1]]
            _rows = [w + (o, ) for w in rows for o in calc]
            _cols = cols
            calc_row_name = (QCoreApplication.translate(
                'GroupStats', 'Function'), )
        elif calculations[2]:
            calc = [self.calculation.list[x][0] for x in calculations[2]]
            _cols = [w + (o, ) for w in cols for o in calc]
            _rows = rows
            calc_col_name = (QCoreApplication.translate(
                'GroupStats', 'Function'), )
        else:
            _cols = cols
            _rows = rows

        if _rows and _rows[0]:
            _rows.insert(0, tuple(row_names) + calc_row_name)
        if _cols and _cols[0]:
            _cols.insert(0, tuple(col_names) + calc_col_name)

        if _rows and _cols:
            self.ui.results.setUpdatesEnabled(False)
            self.windowResult = ResultsModel(data, _rows, _cols, layer)
            self.ui.results.setModel(self.windowResult)

            for i in range(len(_cols[0]), 0, -1):
                self.ui.results.verticalHeader() \
                    .setSortIndicator(i - 1, Qt.AscendingOrder)
            for i in range(len(_rows[0]), 0, -1):
                self.ui.results.horizontalHeader() \
                    .setSortIndicator(i - 1, Qt.AscendingOrder)

            message = self.statusBar().currentMessage()
            percent_factor = 100 / self.windowResult.columnCount()
            progress = 0

            for i in range(self.windowResult.columnCount()):
                self.ui.results.resizeColumnToContents(i)
                progress += percent_factor
                self.statusBar() \
                    .showMessage(message + '{:.2f}'.format(progress))
            self.ui.results.setUpdatesEnabled(True)

            record = 'records'
            if count_null == 1:
                record = 'record'

            if self.ui.useNULL.isChecked() and count_null:
                null_text = QCoreApplication.translate(
                    'GroupStats',
                    ' (used {} {} with null value in {} field)'.format(
                        count_null, record, value[1]))
            elif not self.ui.useNULL.isChecked() and count_null:
                null_text = QCoreApplication.translate(
                    'GroupStats',
                    ' (not used {} {} with null value in {} field)'.format(
                        count_null, record, value[1]))
            else:
                null_text = ''
            self.statusBar().showMessage(
                message + ' | ' +
                QCoreApplication.translate('GroupStats', 'done. ') + null_text,
                20000)
        else:
            try:
                del self.windowResult
            except AttributeError:
                pass

            self.statusBar().showMessage(
                QCoreApplication.translate('GroupStats', 'No data found.'),
                10000)
Пример #29
0
    def requestFlightPathLayer(self):
        # https://docs.qgis.org/testing/en/docs/pyqgis_developer_cookbook/vector.html#memory-provider
        filmsBySourceType = self.getSelection()
        epsg = 4326
        vectorCrs = QgsCoordinateReferenceSystem(
            epsg, QgsCoordinateReferenceSystem.EpsgCrsId)
        flightPathPointLayer = QgsVectorLayer(
            "MultiPoint?crs=epsg:{0}".format(epsg), "FlugwegePunkt", "memory")
        flightPathLineLayer = QgsVectorLayer(
            "MultiLineString?crs=epsg:{0}".format(epsg), "FlugwegeLinie",
            "memory")
        flightPathPointLayer.setCrs(vectorCrs)
        flightPathPointLayer.setCrs(vectorCrs)

        flightPathPointProvider = flightPathPointLayer.dataProvider()
        flightPathLineProvider = flightPathLineLayer.dataProvider()

        # add fields
        fields = [
            QgsField("filmnummer", QVariant.String),
            QgsField("flugweg_quelle", QVariant.String),
            QgsField("flugdatum", QVariant.String),
            QgsField("fotograf", QVariant.String),
            QgsField("pilot", QVariant.String),
            QgsField("flugzeug", QVariant.String),
            QgsField("abflug_zeit", QVariant.String),
            QgsField("ankunft_zeit", QVariant.String),
            QgsField("flugzeit", QVariant.String),
            QgsField("abflug_flughafen", QVariant.String),
            QgsField("ankunft_flughafen", QVariant.String),
            QgsField("wetter", QVariant.String),
            QgsField("target", QVariant.String),
            QgsField("orientation", QVariant.String)
        ]

        flightPathPointProvider.addAttributes(fields)
        flightPathLineProvider.addAttributes(fields)

        flightPathPointLayer.updateFields(
        )  # tell the vector layer to fetch changes from the provider
        flightPathLineLayer.updateFields()

        pointFeatureList = []
        lineFeatureList = []

        # Point: Flight GPS
        for filmNumber in filmsBySourceType[0]:
            # load .shp file, get geometries as multigeometry
            pointFeatureList.append(
                self.getFeatureWithMultiGeomFromOgrShp(filmNumber, ".shp",
                                                       ogr.wkbMultiPoint,
                                                       "flight_gps",
                                                       vectorCrs))

        # Point: Camera GPS
        for filmNumber in filmsBySourceType[2]:
            # load _gps.shp file, get geometries as multigeometry
            pointFeatureList.append(
                self.getFeatureWithMultiGeomFromOgrShp(filmNumber, "_gps.shp",
                                                       ogr.wkbMultiPoint,
                                                       "camera_gps",
                                                       vectorCrs))

        # Point: Image Mapping
        for filmNumber in filmsBySourceType[4]:
            # load image_cp based on orientation from APIS db
            pointFeatureList.append(
                self.getFeatureWithMultiGeomFromSpatialite(
                    filmNumber,
                    QgsWkbTypes.geometryType(QgsWkbTypes.MultiPoint),
                    "image_mapping"))

        # Line: Flight GPS
        for filmNumber in filmsBySourceType[1]:
            # load _lin.shp file, get geometries as multigeometry
            lineFeatureList.append(
                self.getFeatureWithMultiGeomFromOgrShp(filmNumber, "_lin.shp",
                                                       ogr.wkbMultiLineString,
                                                       "flight_gps",
                                                       vectorCrs))

        # Line: Camera GPS
        for filmNumber in filmsBySourceType[3]:
            # load _gps.shp file create line with Points2Path, get geometry as multigeometry
            lineFeatureList.append(
                self.multiPointToLineString(
                    self.getFeatureWithMultiGeomFromOgrShp(filmNumber,
                                                           "_gps.shp",
                                                           ogr.wkbMultiPoint,
                                                           "camera_gps",
                                                           vectorCrs,
                                                           sortBy='bildnr')))

        # Line: Image Mapping
        for filmNumber in filmsBySourceType[5]:
            # load image_cp based on orientation from APIS db create line with Points2Path, get geometry as multigeometry
            lineFeatureList.append(
                self.multiPointToLineString(
                    self.getFeatureWithMultiGeomFromSpatialite(
                        filmNumber,
                        QgsWkbTypes.geometryType(QgsWkbTypes.MultiPoint),
                        "image_mapping")))

        flightPathPointProvider.addFeatures(
            [pF for pF in pointFeatureList if pF is not None])
        flightPathLineProvider.addFeatures(
            [lF for lF in lineFeatureList if lF is not None])

        # update layer's extent when new features have been added
        # because change of extent in provider is not propagated to the layer
        flightPathPointLayer.updateExtents()
        flightPathLineLayer.updateExtents()

        return flightPathPointLayer, flightPathLineLayer
Пример #30
0
class Worker(QtCore.QObject):
    '''The worker that does the heavy lifting.
    /* QGIS offers spatial indexes to make spatial search more
     * effective.  QgsSpatialIndex will find the nearest index
     * (approximate) geometry (rectangle) for a supplied point.
     * QgsSpatialIndex will only give correct results when searching
     * for the nearest neighbour of a point in a point data set.
     * So something has to be done for non-point data sets
     *
     * Non-point join data set:
     * A two pass search is performed.  First the index is used to
     * find the nearest index geometry (approximation - rectangle),
     * and then compute the distance to the actual indexed geometry.
     * A rectangle is constructed from this (maximum minimum)
     * distance, and this rectangle is used to find all features in
     * the join data set that may be the closest feature to the given
     * point.
     * For all the features is this candidate set, the actual
     * distance to the given point is calculated, and the nearest
     * feature is returned.
     *
     * Non-point input data set:
     * First the centroid of the non-point input geometry is
     * calculated.  Then the index is used to find the nearest
     * neighbour to this point (using the approximate index
     * geometry).
     * The distance vector to this feature, combined with the
     * bounding rectangle of the input feature is used to create a
     * search rectangle to find the candidate join geometries.
     * For all the features is this candidate set, the actual
     * distance to the given feature is calculated, and the nearest
     * feature is returned.
     *
     * Joins involving multi-geometry datasets are not supported
     * by a spatial index.
     *
    */
    '''
    # Define the signals used to communicate back to the application
    progress = QtCore.pyqtSignal(float)  # For reporting progress
    status = QtCore.pyqtSignal(str)      # For reporting status
    error = QtCore.pyqtSignal(str)       # For reporting errors
    # Signal for sending over the result:
    finished = QtCore.pyqtSignal(bool, object)

    def __init__(self, inputvectorlayer, joinvectorlayer,
                 outputlayername, joinprefix,
                 distancefieldname="distance",
                 approximateinputgeom=False,
                 usejoinlayerapproximation=False,
                 usejoinlayerindex=True,
                 selectedinputonly=True,
                 selectedjoinonly=True,
                 excludecontaining=True):
        """Initialise.

        Arguments:
        inputvectorlayer -- (QgsVectorLayer) The base vector layer
                            for the join
        joinvectorlayer -- (QgsVectorLayer) the join layer
        outputlayername -- (string) the name of the output memory
                           layer
        joinprefix -- (string) the prefix to use for the join layer
                      attributes in the output layer
        distancefieldname -- name of the (new) field where neighbour
                             distance is stored
        approximateinputgeom -- (boolean) should the input geometry
                                be approximated?  Is only be set for
                                non-single-point layers
        usejoinlayerindexapproximation -- (boolean) should the index
                             geometry approximations be used for the
                             join?
        usejoinlayerindex -- (boolean) should an index for the join
                             layer be used.
        selectedinputonly -- Only selected features from the input
                             layer
        selectedjoinonly -- Only selected features from the join
                            layer
        excludecontaining -- exclude the containing polygon for points
        """

        QtCore.QObject.__init__(self)  # Essential!
        # Set a variable to control the use of indexes and exact
        # geometries for non-point input geometries
        self.nonpointexactindex = usejoinlayerindex
        # Creating instance variables from the parameters
        self.inpvl = inputvectorlayer
        self.joinvl = joinvectorlayer
        self.outputlayername = outputlayername
        self.joinprefix = joinprefix
        self.approximateinputgeom = approximateinputgeom
        self.usejoinlayerapprox = usejoinlayerapproximation
        self.selectedinonly = selectedinputonly
        self.selectedjoonly = selectedjoinonly
        self.excludecontaining = excludecontaining

        # Check if the layers are the same (self join)
        self.selfjoin = False
        if self.inpvl is self.joinvl:
            # This is a self join
            self.selfjoin = True
        # The name of the attribute for the calculated distance
        self.distancename = distancefieldname
        # Creating instance variables for the progress bar ++
        # Number of elements that have been processed - updated by
        # calculate_progress
        self.processed = 0
        # Current percentage of progress - updated by
        # calculate_progress
        self.percentage = 0
        # Flag set by kill(), checked in the loop
        self.abort = False
        # Number of features in the input layer - used by
        # calculate_progress (set when needed)
        self.feature_count = 1
        # The number of elements that is needed to increment the
        # progressbar (set when needed)
        self.increment = 0

    def run(self):
        try:
            # Check if the layers look OK
            if self.inpvl is None or self.joinvl is None:
                self.status.emit('Layer is missing!')
                self.finished.emit(False, None)
                return
            # Check if there are features in the layers
            incount = 0
            if self.selectedinonly:
                incount = self.inpvl.selectedFeatureCount()
            else:
                incount = self.inpvl.featureCount()
            if incount == 0:
                self.status.emit('Input layer has no features!')
                self.finished.emit(False, None)
                return
            joincount = 0
            if self.selectedjoonly:
                joincount = self.joinvl.selectedFeatureCount()
            else:
                joincount = self.joinvl.featureCount()
            if joincount == 0:
                self.status.emit('Join layer has no features!')
                self.finished.emit(False, None)
                return
            # Get the wkbtype of the layers
            self.inpWkbType = self.inpvl.wkbType()
            self.joinWkbType = self.joinvl.wkbType()

            # Check if the input layer does not have geometries
            if (self.inpvl.geometryType() == QgsWkbTypes.NullGeometry):
                self.status.emit('No geometries in the input layer!')
                self.finished.emit(False, None)
                return
            # Check if the join layer does not have geometries
            if (self.joinvl.geometryType() == QgsWkbTypes.NullGeometry):
                self.status.emit('No geometries in the join layer!')
                self.finished.emit(False, None)
                return
            # Set the geometry type and prepare the output layer
            inpWkbTypetext = QgsWkbTypes.displayString(int(self.inpWkbType))
            # self.inputmulti = QgsWkbTypes.isMultiType(self.inpWkbType)
            # self.status.emit('wkbtype: ' + inpWkbTypetext)
            # geometryType = self.inpvl.geometryType()
            # geometrytypetext = 'Point'
            # if geometryType == QgsWkbTypes.PointGeometry:
            #     geometrytypetext = 'Point'
            # elif geometryType == QgsWkbTypes.LineGeometry:
            #     geometrytypetext = 'LineString'
            # elif geometryType == QgsWkbTypes.PolygonGeometry:
            #     geometrytypetext = 'Polygon'
            # if self.inputmulti:
            #     geometrytypetext = 'Multi' + geometrytypetext
            # geomttext = geometrytypetext

            geomttext = inpWkbTypetext
            # Set the coordinate reference system to the input
            # layer's CRS using authid (proj4 may be more robust)
            if self.inpvl.crs() is not None:
                geomttext = (geomttext + "?crs=" +
                             str(self.inpvl.crs().authid()))
            # Retrieve the fields from the input layer
            outfields = self.inpvl.fields().toList()
            # Retrieve the fields from the join layer
            if self.joinvl.fields() is not None:
                jfields = self.joinvl.fields().toList()
                for joinfield in jfields:
                    outfields.append(QgsField(self.joinprefix +
                                     str(joinfield.name()),
                                     joinfield.type()))
            else:
                self.status.emit('Unable to get any join layer fields')
            # Add the nearest neighbour distance field
            # Check if there is already a "distance" field
            # (should be avoided in the user interface)
            # Try a new name if there is a collission
            collission = True
            trynumber = 1
            distnameorg = self.distancename
            while collission:   # Iterate until there are no collissions
                collission = False
                for field in outfields:
                    # This check should not be necessary - handled in the UI
                    if field.name() == self.distancename:
                        self.status.emit(
                              'Distance field already exists - renaming!')
                        # self.abort = True
                        # self.finished.emit(False, None)
                        # break
                        collission = True
                        self.distancename = distnameorg + str(trynumber)
                        trynumber = trynumber + 1
            outfields.append(QgsField(self.distancename, QVariant.Double))
            # Create a memory layer using a CRS description
            self.mem_joinl = QgsVectorLayer(geomttext,
                                            self.outputlayername,
                                            "memory")
            # Set the CRS to the inputlayer's CRS
            self.mem_joinl.setCrs(self.inpvl.crs())
            self.mem_joinl.startEditing()
            # Add the fields
            for field in outfields:
                self.mem_joinl.dataProvider().addAttributes([field])
            # For an index to be used, the input layer has to be a
            # point layer, or the input layer geometries have to be
            # approximated to centroids, or the user has to have
            # accepted that a join layer index is used (for
            # non-point input layers).
            # (Could be extended to multipoint)
            if (self.inpWkbType == QgsWkbTypes.Point or
                    self.inpWkbType == QgsWkbTypes.Point25D or
                    self.approximateinputgeom or
                    self.nonpointexactindex):
                # Number of features in the join layer - used by
                # calculate_progress for the index creation
                if self.selectedjoonly:
                    self.feature_count = self.joinvl.selectedFeatureCount()
                else:
                    self.feature_count = self.joinvl.featureCount()
                # Create a spatial index to speed up joining
                self.status.emit('Creating join layer index...')
                # The number of elements that is needed to increment the
                # progressbar - set early in run()
                self.increment = self.feature_count // 1000
                self.joinlind = QgsSpatialIndex()
                # Include geometries to enable exact distance calculations
                # self.joinlind = QgsSpatialIndex(flags=[QgsSpatialIndex.FlagStoreFeatureGeometries])

                if self.selectedjoonly:
                    for feat in self.joinvl.getSelectedFeatures():
                        # Allow user abort
                        if self.abort is True:
                            break
                        self.joinlind.insertFeature(feat)
                        self.calculate_progress()
                else:
                    for feat in self.joinvl.getFeatures():
                        # Allow user abort
                        if self.abort is True:
                            break
                        self.joinlind.insertFeature(feat)
                        self.calculate_progress()
                self.status.emit('Join layer index created!')
                self.processed = 0
                self.percentage = 0
                # self.calculate_progress()

            # Is the join layer a multi-geometry layer?
            # self.joinmulti = QgsWkbTypes.isMultiType(self.joinWkbType)
            # Does the join layer contain multi geometries?
            # Try to check the first feature
            # This is not used for anything yet
            self.joinmulti = False
            if self.selectedjoonly:
                feats = self.joinvl.getSelectedFeatures()
            else:
                feats = self.joinvl.getFeatures()
            if feats is not None:
                testfeature = next(feats)
                feats.rewind()
                feats.close()
                if testfeature is not None:
                    if testfeature.hasGeometry():
                        if testfeature.geometry().isMultipart():
                            self.joinmulti = True
            # Prepare for the join by fetching the layers into memory
            # Add the input features to a list
            self.inputf = []
            if self.selectedinonly:
                for f in self.inpvl.getSelectedFeatures():
                    self.inputf.append(f)
            else:
                for f in self.inpvl.getFeatures():
                    self.inputf.append(f)
            # Add the join features to a list (used in the join)
            self.joinf = []
            if self.selectedjoonly:
                for f in self.joinvl.getSelectedFeatures():
                    self.joinf.append(f)
            else:
                for f in self.joinvl.getFeatures():
                    self.joinf.append(f)
            # Initialise the global variable that will contain the
            # result of the nearest neighbour spatial join (list of
            # features)
            self.features = []
            # Do the join!
            # Number of features in the input layer - used by
            # calculate_progress for the join operation
            if self.selectedinonly:
                self.feature_count = self.inpvl.selectedFeatureCount()
            else:
                self.feature_count = self.inpvl.featureCount()
            # The number of elements that is needed to increment the
            # progressbar - set early in run()
            self.increment = self.feature_count // 1000
            # Using the original features from the input layer
            for feat in self.inputf:
                # Allow user abort
                if self.abort is True:
                    break
                self.do_indexjoin(feat)
                self.calculate_progress()
            self.mem_joinl.dataProvider().addFeatures(self.features)
            self.status.emit('Join finished')
        except:
            import traceback
            self.error.emit(traceback.format_exc())
            self.finished.emit(False, None)
            if self.mem_joinl is not None:
                self.mem_joinl.rollBack()
        else:
            self.mem_joinl.commitChanges()
            if self.abort:
                self.finished.emit(False, None)
            else:
                self.status.emit('Delivering the memory layer...')
                self.finished.emit(True, self.mem_joinl)

    def calculate_progress(self):
        '''Update progress and emit a signal with the percentage'''
        self.processed = self.processed + 1
        # update the progress bar at certain increments
        if (self.increment == 0 or
                self.processed % self.increment == 0):
            # Calculate percentage as integer
            perc_new = (self.processed * 100) / self.feature_count
            if perc_new > self.percentage:
                self.percentage = perc_new
                self.progress.emit(self.percentage)

    def kill(self):
        '''Kill the thread by setting the abort flag'''
        self.abort = True

    def do_indexjoin(self, feat):
        '''Find the nearest neigbour of a feature.  Using an index,
           if possible

        Parameter: feat -- The feature for which a neighbour is
                           sought
        '''
        infeature = feat
        # Get the feature ID
        infeatureid = infeature.id()
        # self.status.emit('**infeatureid: ' + str(infeatureid))
        # Get the feature geometry
        inputgeom = infeature.geometry()
        # Check for missing input geometry
        if inputgeom.isEmpty():
            # Prepare the result feature
            atMapA = infeature.attributes()
            atMapB = []
            for thefield in self.joinvl.fields():
                atMapB.extend([None])
            attrs = []
            attrs.extend(atMapA)
            attrs.extend(atMapB)
            attrs.append(0 - float("inf"))
            # Create the feature
            outFeat = QgsFeature()
            # Use the original input layer geometry!:
            outFeat.setGeometry(infeature.geometry())
            # Use the modified input layer geometry (could be
            # centroid)
            # outFeat.setGeometry(inputgeom)
            # Add the attributes
            outFeat.setAttributes(attrs)
            # self.calculate_progress()
            self.features.append(outFeat)
            # self.mem_joinl.dataProvider().addFeatures([outFeat])
            self.status.emit("Warning: Input feature with "
                                         "missing geometry: " +
                                         str(infeature.id()))
            return
        # Shall approximate input geometries be used?
        if self.approximateinputgeom:
            # Use the centroid as the input geometry
            inputgeom = infeature.geometry().centroid()
        # Check if the coordinate systems are equal, if not,
        # transform the input feature!
        if (self.inpvl.crs() != self.joinvl.crs()):
            try:
                # inputgeom.transform(QgsCoordinateTransform(
                #     self.inpvl.crs(), self.joinvl.crs(), None))
                # transcontext = QgsCoordinateTransformContext()
                # inputgeom.transform(QgsCoordinateTransform(
                #     self.inpvl.crs(), self.joinvl.crs(), transcontext))
                inputgeom.transform(QgsCoordinateTransform(
                    self.inpvl.crs(), self.joinvl.crs(),
                    QgsProject.instance()))
            except:
                import traceback
                self.error.emit(self.tr('CRS Transformation error!') +
                                ' - ' + traceback.format_exc())
                self.abort = True
                return
        # Find the closest feature!
        nnfeature = None
        minfound = False
        mindist = float("inf")

        # If the input layer's geometry type is point, or has been
        # approximated to point (centroid), then a join index will
        # be used.
        # if ((QgsWkbTypes.geometryType(self.inpWkbType) == QgsWkbTypes.PointGeometry and
        #     not QgsWkbTypes.isMultiType(self.inpWkbType)) or self.approximateinputgeom):
        if (self.approximateinputgeom or
                self.inpWkbType == QgsWkbTypes.Point or
                self.inpWkbType == QgsWkbTypes.Point25D):
            # Are there points on the join side?
            # Then the index nearest neighbour function is sufficient
            # if ((QgsWkbTypes.geometryType(self.joinWkbType) == QgsWkbTypes.PointGeometry and
            #     not QgsWkbTypes.isMultiType(self.joinWkbType)) or self.usejoinlayerapprox):
            if (self.usejoinlayerapprox or
                    self.joinWkbType == QgsWkbTypes.Point or
                    self.joinWkbType == QgsWkbTypes.Point25D):
                # Is it a self join?
                if self.selfjoin:
                    # Have to consider the two nearest neighbours
                    nearestids = self.joinlind.nearestNeighbor(
                                             inputgeom.asPoint(), 2)
                    fch = 0  # Which of the two features to choose
                    if (nearestids[0] == infeatureid and
                                               len(nearestids) > 1):
                        # The first feature is the same as the input
                        # feature, so choose the second one
                        fch = 1
                    # Get the feature!
                    if False:
                    #if self.selectedjoonly:
                        # This caused problems (wrong results) in QGIS 3.0.1
                        nnfeature = next(
                            self.joinvl.getSelectedFeatures(
                                QgsFeatureRequest(nearestids[fch])))
                    else:
                        nnfeature = next(self.joinvl.getFeatures(
                            QgsFeatureRequest(nearestids[fch])))
                # Not a self join
                else:
                    # Not a self join, so we search for only the
                    # nearest neighbour (1)
                    nearestids = self.joinlind.nearestNeighbor(
                                           inputgeom.asPoint(), 1)
                    # Get the feature!
                    if len(nearestids) > 0:
                        nearestid = nearestids[0]
                        nnfeature = next(self.joinvl.getFeatures(
                                 QgsFeatureRequest(nearestid)))
                    #else:
                    #if self.selectedjoonly:
                    #    nnfeature = next(self.joinvl.getSelectedFeatures(
                    #             QgsFeatureRequest(nearestid)))

                if nnfeature is not None:
                    mindist = inputgeom.distance(nnfeature.geometry())
                    minfound = True
            # Not points on the join side
            # Handle common (non multi) non-point geometries
            elif (self.joinWkbType == QgsWkbTypes.Polygon or
                  self.joinWkbType == QgsWkbTypes.Polygon25D or
                  self.joinWkbType == QgsWkbTypes.LineString or
                  self.joinWkbType == QgsWkbTypes.LineString25D):
                # Use the join layer index to speed up the join when
                # the join layer geometry type is polygon or line
                # and the input layer geometry type is point or a
                # point approximation
                nearestids = self.joinlind.nearestNeighbor(
                    inputgeom.asPoint(), 1)
                # Possibe index out of range!!! ???
                nearestindexid = nearestids[0]
                # Check for self join (possible if approx input)
                if self.selfjoin and nearestindexid == infeatureid:
                    # Self join and same feature, so get the
                    # first two neighbours
                    nearestindexes = self.joinlind.nearestNeighbor(
                                             inputgeom.asPoint(), 2)
                    # Possibe index out of range!!! ???
                    nearestindexid = nearestindexes[0]
                    if (nearestindexid == infeatureid and
                                  len(nearestindexes) > 1):
                        nearestindexid = nearestindexes[1]

                # If exclude containing, check for containment
                if self.excludecontaining:
                    contained = False
                    nearfeature = next(self.joinvl.getFeatures(
                                           QgsFeatureRequest(nearestindexid)))
                    # Check for containment
                    if nearfeature.geometry().contains(inputgeom):
                        contained = True
                    if inputgeom.contains(nearfeature.geometry()):
                        contained = True
                    numberofnn = 2
                    # Assumes that nearestNeighbor returns hits in the same
                    # sequence for all numbers of nearest neighbour
                    while contained:
                        if self.abort is True:
                            break
                        nearestindexes = self.joinlind.nearestNeighbor(
                                               inputgeom.asPoint(), numberofnn)
                        if len(nearestindexes) < numberofnn:
                            nearestindexid = nearestindexes[numberofnn - 2]
                            self.status.emit('No non-containing geometries!')
                            break
                        else:
                            nearestindexid = nearestindexes[numberofnn - 1]
                            # Seems to respect selection...?
                            nearfeature = next(self.joinvl.getFeatures(
                                QgsFeatureRequest(nearestindexid)))
                            # Check for containment  # Works!
                            if nearfeature.geometry().contains(
                                                         inputgeom):
                                contained = True
                            elif inputgeom.contains(
                                    nearfeature.geometry()):
                                contained = True
                            else:
                                contained = False
                        numberofnn = numberofnn + 1
                    # end while

                # Get the feature among the candidates from the index
                #if self.selectedjoonly:
                #    # Does not get the correct feature!
                #    nnfeature = next(self.joinvl.getSelectedFeatures(
                #        QgsFeatureRequest(nearestindexid)))
                # This seems to work also in the presence of selections
                nnfeature = next(self.joinvl.getFeatures(
                    QgsFeatureRequest(nearestindexid)))
                mindist = inputgeom.distance(nnfeature.geometry())
                if mindist == 0:
                    insidep = nnfeature.geometry().contains(
                                                          inputgeom.asPoint())
                    # self.status.emit('0 distance! - ' + str(nearestindexid))
                    # self.status.emit('Inside: ' + str(insidep))
                px = inputgeom.asPoint().x()
                py = inputgeom.asPoint().y()
                # Search the neighbourhood
                closefids = self.joinlind.intersects(QgsRectangle(
                    px - mindist,
                    py - mindist,
                    px + mindist,
                    py + mindist))
                for closefid in closefids:
                    if self.abort is True:
                        break
                    # Check for self join and same feature
                    if self.selfjoin and closefid == infeatureid:
                        continue
                    # If exclude containing, check for containment
                    if self.excludecontaining:
                        # Seems to respect selection...?
                        closefeature = next(self.joinvl.getFeatures(
                            QgsFeatureRequest(closefid)))
                        # Check for containment
                        if closefeature.geometry().contains(
                                                         inputgeom.asPoint()):
                            continue
                    if False:
                    #if self.selectedjoonly:
                        closef = next(self.joinvl.getSelectedFeatures(
                            QgsFeatureRequest(closefid)))
                    else:
                        closef = next(self.joinvl.getFeatures(
                            QgsFeatureRequest(closefid)))
                    thisdistance = inputgeom.distance(closef.geometry())
                    if thisdistance < mindist:
                        mindist = thisdistance
                        nnfeature = closef
                    if mindist == 0:
                        # self.status.emit('  Mindist = 0!')
                        break
            # Other geometry on the join side (multi and more)
            else:
                # Join with no index use
                # Go through all the features from the join layer!
                for inFeatJoin in self.joinf:
                    if self.abort is True:
                        break
                    joingeom = inFeatJoin.geometry()
                    thisdistance = inputgeom.distance(joingeom)
                    if thisdistance < 0:
                        self.status.emit("Warning: Join feature with "
                                         "missing geometry: " +
                                         str(inFeatJoin.id()))
                        continue
                    # If the distance is 0, check for equality of the
                    # features (in case it is a self join)
                    if (thisdistance == 0 and self.selfjoin and
                            infeatureid == inFeatJoin.id()):
                        continue
                    if thisdistance < mindist:
                        mindist = thisdistance
                        nnfeature = inFeatJoin
                    # For 0 distance, settle with the first feature
                    if mindist == 0:
                        break
        # non (simple) point input geometries (could be multipoint)
        else:
            if (self.nonpointexactindex):
                # Use the spatial index on the join layer (default).
                # First we do an approximate search
                # Get the input geometry centroid
                centroid = infeature.geometry().centroid()
                centroidgeom = centroid.asPoint()
                # Find the nearest neighbour (index geometries only)
                # Possibe index out of range!!! ???
                nearestid = self.joinlind.nearestNeighbor(centroidgeom, 1)[0]
                # Check for self join
                if self.selfjoin and nearestid == infeatureid:
                    # Self join and same feature, so get the two
                    # first two neighbours
                    nearestindexes = self.joinlind.nearestNeighbor(
                        centroidgeom, 2)
                    nearestid = nearestindexes[0]
                    if nearestid == infeatureid and len(nearestindexes) > 1:
                        nearestid = nearestindexes[1]
                # Get the feature!
                if False:
                #if self.selectedjoonly:
                    nnfeature = next(self.joinvl.getSelectedFeatures(
                        QgsFeatureRequest(nearestid)))
                else:
                    nnfeature = next(self.joinvl.getFeatures(
                        QgsFeatureRequest(nearestid)))
                mindist = inputgeom.distance(nnfeature.geometry())
                # Calculate the search rectangle (inputgeom BBOX
                inpbbox = infeature.geometry().boundingBox()
                minx = inpbbox.xMinimum() - mindist
                maxx = inpbbox.xMaximum() + mindist
                miny = inpbbox.yMinimum() - mindist
                maxy = inpbbox.yMaximum() + mindist
                # minx = min(inpbbox.xMinimum(), centroidgeom.x() - mindist)
                # maxx = max(inpbbox.xMaximum(), centroidgeom.x() + mindist)
                # miny = min(inpbbox.yMinimum(), centroidgeom.y() - mindist)
                # maxy = max(inpbbox.yMaximum(), centroidgeom.y() + mindist)
                searchrectangle = QgsRectangle(minx, miny, maxx, maxy)
                # Fetch the candidate join geometries
                closefids = self.joinlind.intersects(searchrectangle)
                # Loop through the geometries and choose the closest
                # one
                for closefid in closefids:
                    if self.abort is True:
                        break
                    # Check for self join and identical feature
                    if self.selfjoin and closefid == infeatureid:
                        continue
                    if False:
                    #if self.selectedjoonly:
                        closef = next(self.joinvl.getSelectedFeatures(
                            QgsFeatureRequest(closefid)))
                    else:
                        closef = next(self.joinvl.getFeatures(
                            QgsFeatureRequest(closefid)))
                    thisdistance = inputgeom.distance(closef.geometry())
                    if thisdistance < mindist:
                        mindist = thisdistance
                        nnfeature = closef
                    if mindist == 0:
                        break
            else:
                # Join with no index use
                # Check all the features of the join layer!
                mindist = float("inf")  # should not be necessary
                for inFeatJoin in self.joinf:
                    if self.abort is True:
                        break
                    joingeom = inFeatJoin.geometry()
                    thisdistance = inputgeom.distance(joingeom)
                    if thisdistance < 0:
                        self.status.emit("Warning: Join feature with "
                                         "missing geometry: " +
                                         str(inFeatJoin.id()))
                        continue
                    # If the distance is 0, check for equality of the
                    # features (in case it is a self join)
                    if (thisdistance == 0 and self.selfjoin and
                            infeatureid == inFeatJoin.id()):
                        continue
                    if thisdistance < mindist:
                        mindist = thisdistance
                        nnfeature = inFeatJoin
                    # For 0 distance, settle with the first feature
                    if mindist == 0:
                        break

        if not self.abort:
            # self.status.emit('Near feature - ' + str(nnfeature.id()))
            # Collect the attribute
            atMapA = infeature.attributes()
            if nnfeature is not None:
                atMapB = nnfeature.attributes()
            else:
                atMapB = []
                for thefield in self.joinvl.fields():
                    atMapB.extend([None])
            attrs = []
            attrs.extend(atMapA)
            attrs.extend(atMapB)
            attrs.append(mindist)
            # Create the feature
            outFeat = QgsFeature()
            # Use the original input layer geometry!:
            outFeat.setGeometry(infeature.geometry())
            # Use the modified input layer geometry (could be
            # centroid)
            # outFeat.setGeometry(inputgeom)
            # Add the attributes
            outFeat.setAttributes(attrs)
            # self.calculate_progress()
            self.features.append(outFeat)
            # self.mem_joinl.dataProvider().addFeatures([outFeat])
    # end of do_indexjoin

    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('NNJoinEngine', message)
    def processAlgorithm(self, parameters, context, feedback):
        
        # get inputs
        inputTab = self.parameterAsVectorLayer(parameters, self.inputTab, context)
        colApply = self.parameterAsFields(parameters, self.colApply, context)
        thresh = self.parameterAsString(parameters, self.thresh, context)
        maxIter = self.parameterAsString(parameters, self.maxIter, context)
        outPath = self.parameterAsString(parameters, self.OUTPUT, context)
        
        
        
        
        # create output layer from input data
        outTab = QgsVectorLayer('Polygon', 'outTab', 'memory')
        CRS = inputTab.crs()
        outTab.setCrs(CRS)
        outTab.dataProvider().addAttributes(inputTab.dataProvider().fields().toList())
        outTab.updateFields()
        feats = [feat for feat in inputTab.getFeatures()]
        outTab.dataProvider().addFeatures(feats)
        outTab.updateExtents()
        

        # redefine data types
        thresh = float(thresh)
        maxIter = int(maxIter)
        
        # generate temp folder
        QgsMessageLog.logMessage('Creating temporary output directory...', 'User notification', 0)
        tempDir = QgsProcessingUtils.tempFolder()
        if not os.path.exists(tempDir):
            os.makedirs(tempDir)
        
            
        
        # get field indices of interest
        QgsMessageLog.logMessage('Getting field names and indeces...', 'User notification', 0)
        fieldIdx = []
        fieldNames = outTab.fields().names()
        for f in list(range(0, len(fieldNames))):
            if fieldNames[f] in colApply:
                fieldIdx.append(fieldNames.index(fieldNames[f]))       
        
          
        
        def abideMinCases_func():
        
            # create container for information about processed features
            allProc = []
            
            # iterate over each feature
            feats = outTab.getFeatures()
            feat_iter_count = 0
            n_feats = outTab.featureCount()
            for feat in feats:
                
                feat_iter_count += 1
                QgsMessageLog.logMessage('Processing feature...(' + str(feat_iter_count) + '/' + str(n_feats) + ')', 'User notification', 0)
                
                # get attributes
                atts = feat.attributes()
                
                # iterate over fields of interest
                for a in list(range(0, len(atts))):
                    
                    QgsMessageLog.logMessage('Processing field...(' + str(a+1) + '/' + str(len(atts)) + ')', 'User notification', 0)
                    
                    # get active if current field is within the fields of interest
                    if a in fieldIdx:
                        
    
                        # extract value in question and area size for the respective features
                        to_val = atts[a]
                        
                        # get active if attribute value is lower than defined threshold
                        if atts[a] < thresh:
                            
                            # select current feature and create new layer
                            outTab.selectByIds([feat.id()])
                            temp_fileName = tempDir + '/temp_selected_' + str(feat_iter_count) + '_' + str(a) + '.gpkg'
                            QgsVectorFileWriter.writeAsVectorFormat(outTab, temp_fileName, 'ANSI', outTab.crs(), 'GPKG', 1)
            
                            
                            
                            # get adjacent features
                            params = {'INPUT' : outTab,
                                      'INTERSECT' : QgsProcessingFeatureSourceDefinition(temp_fileName, False),
                                      'METHOD' : 0,
                                      'PREDICATE' : [4] }
                            adjSel = processing.run('native:selectbylocation', params)['OUTPUT']
                            adj_feats = adjSel.selectedFeatures()
                            adjSel.removeSelection()
                            
                            
                            # get attribute values of adjacent features
                            adjIdx = []
                            adjAtts = []
                            for adj_feat in adj_feats:
                                adjIdx.append(adj_feat.id())
                                adjAtts.append(adj_feat[a])
                            
                            QgsMessageLog.logMessage('Feature comparison with ' + str(len(adjIdx)) + ' adjacent features...', 'User notification', 0)
                            
                            
                            # sort adjacent features by attribute values
                            adjIdx = [x for _, x in sorted(zip(adjAtts, adjIdx))]
                            adjAtts = sorted(adjAtts)
                                                        
                            
                            # iterate over each appropriate adjacent feature pair as long as the threshold is not reached
                            new_val = to_val
                            for p in list(range(0, len(adjIdx))):
                                 
                                 
                                # collect information about current feature pair
                                pair1 = str(feat.id()) + '_' + str(adjIdx[p])
                                pair2 = str(adjIdx[p]) + '_' + str(feat.id())
                                 
                                 
                                # get active if this feature pair has not been processed before
                                if (pair1 not in allProc) and (pair2 not in allProc) and (new_val < thresh):
                                       
                                    # get values of adjacent polygon 
                                    outTab.selectByIds([adjIdx[p]])
                                    comp_val = outTab.selectedFeatures()[0].attributes()[a]
                                    outTab.removeSelection()
       
                                    # calculate new value as mean
                                    new_val = (to_val + comp_val) / 2
                                        
                                                                        
                                    # update attribute values in respective features
                                    outTab.startEditing()
                                    outTab.changeAttributeValue(adjIdx[p], a, new_val)
                                    outTab.changeAttributeValue(feat.id(), a, new_val)
                                    outTab.commitChanges()
                                    
                                         
                                     
                                    # collect information about this processed feature pair
                                    allProc.append(pair1)
                                    
                                    # update value in question
                                    to_val = new_val
                                                                
                                
            return outTab
                
        # execute function
        for l in list(range(0, maxIter)):
            QgsMessageLog.logMessage('Start iterative processing...(' + str(l+1) + '/' + str(maxIter) + ')', 'User notification', 0)
            outTab = abideMinCases_func()
        
        # write to file
        QgsMessageLog.logMessage('Writing results to file...', 'User notification', 0)
        QgsVectorFileWriter.writeAsVectorFormat(outTab, outPath, 'ANSI', CRS, 'GPKG')
        
        
        # add the new layer to canvas
        QgsProject.instance().addMapLayer(outTab)
        QgsMapCanvas().setExtent(outTab.extent())
        QgsMapCanvas().setLayers([outTab])
        
        return {self.OUTPUT: outTab}
    def open_db(self):
        edb_filename = self.open_db_lineedit.text()
        edb_name, ext = os.path.splitext(os.path.basename(str(edb_filename)))
        QgsMessageLog.logMessage(
            "Loading edb %s" % edb_filename,
            'AirviroOfflineEdb',
            QgsMessageLog.INFO
        )

        self.db_uri.setDatabase(edb_filename)
        self.con, self.cur = connect(str(self.db_uri.database()))
        self.epsg = get_epsg(self.con)

        root = QgsProject.instance().layerTreeRoot()

        edb_increment = 1
        while root.findGroup(edb_name) is not None:
            edb_name = edb_name + unicode(edb_increment)
            edb_increment += 1

        QgsMessageLog.logMessage(
            "Adding edb layers in %s" % edb_name,
            'AirviroOfflineEdb',
            QgsMessageLog.INFO
        )
        edb_group = root.addGroup(edb_name)

        point_group = edb_group.addGroup('Point sources')
        area_group = edb_group.addGroup('Area sources')
        grid_group = edb_group.addGroup('Grid sources')
        road_group = edb_group.addGroup('Road sources')
        subtable_group = edb_group.addGroup('Subtables')
        company_group = edb_group.addGroup('Companies')
        facility_group = edb_group.addGroup('Facilities')
        emis_group = edb_group.addGroup('Emissions')

        point_support_group = point_group.addGroup('Support tables')
        area_support_group = area_group.addGroup('Support tables')
        grid_support_group = grid_group.addGroup('Support tables')
        road_support_group = road_group.addGroup('Support tables')
        facility_support_group = facility_group.addGroup('Support tables')
        company_support_group = company_group.addGroup('Support tables')

        unit_group = subtable_group.addGroup('Units')
        road_vehicle_group = subtable_group.addGroup('Road vehicles')
        road_vehicle_support_group = road_vehicle_group.addGroup(
            'Support tables'
        )
        roadtype_group = subtable_group.addGroup('Roadtypes')
        emis_func_group = subtable_group.addGroup('Emission functions')
        searchkey_group = subtable_group.addGroup('Searchkeys')
        timevar_group = subtable_group.addGroup('Time variations')
        subgrp_group = subtable_group.addGroup('Substance groups')
        
        self.layers = {}
        schema = ''
        geom_table_column_dict = dict(GEOMETRY_TABLES_COLUMNS)
        for table in TABLES:
            if not table_in_db(self.cur, table):
                iface.messageBar().pushMessage(
                    "Warning",
                    "Table %s not found in edb" % table,
                    level=QgsMessageBar.WARNING,
                    duration=3
                )
                continue
            geom_col = geom_table_column_dict.get(table, None)
            self.db_uri.setDataSource(
                schema,
                table,
                geom_col or ''
            )
            layer_uri = self.db_uri.uri()  # + "&crs=EPSG:4326"
            layer = QgsVectorLayer(layer_uri, table, 'spatialite')
            layer.setCrs(QgsCoordinateReferenceSystem(
                self.epsg,
                QgsCoordinateReferenceSystem.EpsgCrsId)
            )
            if not layer.isValid():
                raise ValueError(edb_filename)
            map_layer = QgsMapLayerRegistry.instance().addMapLayer(
                layer, False
            )
                        
            if 'timevar' in table:
                group = timevar_group
            elif 'emission_function' in table:
                group = emis_func_group
            elif 'searchkey' in table:
                group = searchkey_group
            elif 'unit' in table:
                group = unit_group
            elif 'subgrp' in table:
                group = subgrp_group
            elif table == 'substances':
                group = subtable_group
            elif table.endswith('_emis'):
                group = emis_group
            elif table == 'points':
                group = point_group
            elif 'point_' in table:
                group = point_support_group
            elif table == 'areas':
                group = area_group
            elif 'area_' in table:
                group = area_support_group
            elif table == 'roads':
                group = road_group
            elif table in ('road_vehicle_link', 'road_alobs'):
                group = road_support_group
            elif 'road_' in table:
                group = road_vehicle_group
            elif 'roadtype' in table:
                group = roadtype_group
            elif table == 'facilties':
                group = facility_group
            elif 'facility' in table:
                group = facility_support_group
            elif 'companies' == table:
                group = company_group
            elif 'company' in table:
                group = company_support_group
            elif 'traffic_situation' in table:
                group = road_vehicle_support_group

            group.setVisible(False)
            group.setExpanded(False)
            group.addLayer(map_layer)
            self.layers[table] = map_layer.id()

        for table in TABLES:
            foreign_keys = get_foreign_keys(self.con, table)
            referencing_layer = self.layers[table]
            for row in foreign_keys:
                referenced_layer = self.layers[row['table']]
                from_column = row['from']
                to_column = row['to']
                
                rel = QgsRelation()
                rel.setReferencingLayer(referencing_layer)
                rel.setReferencedLayer(referenced_layer)
                rel.addFieldPair(from_column, to_column)
                rel_name = 'fk_%s_%s-%s_%s' % (
                    table, from_column, row['table'], to_column
                )
                rel.setRelationId(rel_name)
                rel.setRelationName(
                    'fk_%s_%s-%s_%s' % (
                        table, from_column, row['table'], to_column)
                )
                
                if not rel.isValid():
                    raise ValueError(
                        'Reference %s is invalid' % rel_name
                    )
                QgsProject.instance().relationManager().addRelation(rel)
Пример #33
0
    def doMask(self, item):
        mapcrs = self.plugin.canvas.mapSettings().destinationCrs()

        ogrFeature = item.data(Qt.UserRole)
        layerName = "OSM "+ogrFeature.GetFieldAsString('id')
        geom = QgsGeometry.fromWkt(ogrFeature.GetGeometryRef().ExportToWkt())
        if (geom.type() == QgsWkbTypes.PolygonGeometry):
            try:
                try:
                    from mask import aeag_mask
                except:
                    from mask_plugin import aeag_mask

                aeag_mask.do(mapcrs, {geom}, "Mask "+layerName)

            except:
                geom = QgsGeometry.fromWkt(ogrFeature.GetGeometryRef().ExportToWkt())
                toCrs = self.plugin.canvas.mapSettings().destinationCrs()

                l = max(geom.boundingBox().width(), geom.boundingBox().height())
                x = geom.boundingBox().center().x()
                y = geom.boundingBox().center().y()
                rect = QgsRectangle(x-l, y-l, x+l, y+l)  # geom.boundingBox()
                rect.scale(4)
                mask = QgsGeometry.fromRect(rect)

                mask = mask.difference(geom)

                maskLayer = QgsVectorLayer("MultiPolygon", "Mask "+layerName, "memory")
                maskLayer.setCrs(toCrs)
                QgsProject.instance().addMapLayer(maskLayer)
                pr = maskLayer.dataProvider()

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

                pr.addAttributes(fields.toList())

                maskLayer.startEditing()
                pr.addFeatures([fet])
                maskLayer.commitChanges()
                maskLayer.updateExtents()

                # transparence, epaisseur
                renderer = maskLayer.renderer()
                s = renderer.symbol()
                s.setOpacity(0.90)
                s.setColor(QColor(255, 255, 255))
                if isinstance(s, QgsLineSymbol):
                    s.setWidth(0)

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

            self.go(item)
Пример #34
0
def nodeDuplicate(node,newname=None,position='bottom',target_node=None):
    import time
    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]
    #
    #print node.layer().name()
    #print newname
    layer = node.layer()
    # source of the layer
    provider = layer.dataProvider()
    #print "---------------------"
    #print provider.crs().authid()
    #print layer.crs().authid()
    #print "---------------------"
    # creation of the shapefiles:
    pathfile = os.path.join(oeq_global.OeQ_project_path(),newname+'.shp')
    ct_pathfile = os.path.join(oeq_global.OeQ_project_path(),newname+'.qml')
    writer = QgsVectorFileWriter(pathfile, "CP1250", provider.fields(), provider.geometryType(), layer.crs(), "ESRI Shapefile")
    #print writer
    outelem = QgsFeature()
    # iterating over the input layer
    for elem in layer.getFeatures():
             outelem.setGeometry(elem.geometry() )
             outelem.setAttributes(elem.attributes())
             writer.addFeature(outelem)
    del writer
    oeq_global.OeQ_wait_for_file(pathfile)
    #time.sleep(1)
    newlayer = QgsVectorLayer(pathfile, newname, "ogr")

    #print layer.isValid()
    QgsMapLayerRegistry.instance().addMapLayer(newlayer, True)
    newlayer.setCrs(layer.crs())
    #oeq_global.OeQ_wait_for_renderer(60000)
    #print newlayer.name()


    newnode = nodeByName(newlayer.name())
    if len(newnode) == 0:
        return None
    newnode = newnode[0]
   # oeq_global.OeQ_unlockQgis()
    #time.sleep(1)
    newlayer.loadNamedStyle(ct_pathfile)
    nodeCollapse(newnode)
    #time.sleep(1)
    #position = nodePosition(node,target_node)
    newnode=nodeMove(newnode,position,target_node)
    #time.sleep(1)
    #oeq_global.OeQ_unlockQgis()
    #oeq_global.OeQ_wait(0.5)
    #print "+++++++++++++++"
    return newnode
Пример #35
0
    def export_esu_line(self):
        """
        Export ESUs
        :return:
        """

        canvas = self.iface.mapCanvas()
        clayer = canvas.currentLayer()
        # will return 0 if none selected
        count = clayer.selectedFeatureCount()

        feature_count = clayer.featureCount()

        # Get list of selected features
        selected_esu_ids = list()
        if count > 0:
            selectedfeats = clayer.selectedFeatures()
            for feat in selectedfeats:
                selected_esu_ids.append(int(feat.attribute('esu_id')))
            feature_count = clayer.selectedFeatureCount()
            self.warn_about_selected_features(feature_count)

        # Prepare sql query
        if self.unassigned:
            nsgexportsql = self.sql_queries['export_all']
        else:
            nsgexportsql = self.sql_queries['export_assigned_only']

        # SQL to filter out selected records
        if count > 0:
            nsgexportsql += " WHERE esu.esu_id IN ({})".format(', '.join(
                map(str, selected_esu_ids)))

        # Setup database temporary tables
        for table in ['qryType12', 'qryType3', 'qryType4']:
            # Drop tables if left behind from last export
            args = {'table': table}
            query = self.run_sql('drop_table', args)
        query = self.run_sql('create_qryType12')
        query = self.run_sql('create_qryType3')
        query = self.run_sql('create_qryType4')

        # Run the main query
        if config.DEBUG_MODE:
            print(nsgexportsql)
        query = QSqlQuery(self.db)
        query.setForwardOnly(True)
        query.exec_(nsgexportsql)
        if query.isActive() is False:
            raise StandardError('Database query problem: {}'.format(
                query.lastError().text()))

        # create layer
        vlayer = QgsVectorLayer("multilinestring?crs=EPSG:27700", "temp",
                                "memory")
        vlayer.setCrs(
            QgsCoordinateReferenceSystem(
                27700, QgsCoordinateReferenceSystem.EpsgCrsId))
        provider = vlayer.dataProvider()

        # add fields
        self.fields = [
            QgsField("esu_id", QVariant.String),
            QgsField("USRN", QVariant.LongLong),
            QgsField("Rec_type", QVariant.Int),
            QgsField("DescTxt", QVariant.String),
            QgsField("Locality", QVariant.String),
            QgsField("Town", QVariant.String),
            QgsField("Entry_date", QVariant.Date),
            QgsField("Type_3_USRN", QVariant.LongLong),
            QgsField("Type_3_Desc", QVariant.String),
            QgsField("Type_4_USRN", QVariant.LongLong),
            QgsField("Type_4_Desc", QVariant.String)
        ]
        provider.addAttributes(self.fields)
        vlayer.updateFields()

        # Exit if output file path is invalid
        if len(str(self.export_path)) < 0:
            return False
        if self.check_if_export_file_in_use():
            return False

        # Run through SQL results creating features from rows
        self.progresswin.show()
        i = 0
        while query.next():
            if self.progresswin.wasCanceled():
                self.kill_export()
                break

            record = query.record()
            new_feature = self.create_feature_from_record(record)
            provider.addFeatures([new_feature])

            # Update progress bar
            i += 1
            diff = feature_count + (
                i - feature_count) if i > feature_count else feature_count
            percent_complete = (i / float(diff)) * 100
            self.progresswin.setValue(percent_complete)

        if self.killed:
            # Show message and exit if killed
            export_error_msg_box = QMessageBox(
                QMessageBox.Warning, " ",
                "An error occurred while exporting shapefile", QMessageBox.Ok,
                None)
            export_error_msg_box.setWindowFlags(Qt.CustomizeWindowHint
                                                | Qt.WindowTitleHint)
            export_error_msg_box.exec_()
            return False

        vlayer.updateExtents()
        result = QgsVectorFileWriter.writeAsVectorFormat(
            vlayer, self.export_path, "utf-8", None, "ESRI Shapefile")
        # checks for completed export
        if result == 0:
            self.progresswin.close()
            if config.DEBUG_MODE:
                print('DEBUG_MODE: {} features exported'.format(
                    vlayer.featureCount()))
            return True
Пример #36
0
class CatalogDialogTool(QObject):
    """
    Tool for managing the search and export functionality
    """

    def __init__(self, iface, dialog_ui, bbox_tool):
        """
        Constructor for the dialog tool
        :param iface: The QGIS Interface
        :param dialog_ui: The dialog GUI
        :param bbox_tool The bounding box tool
        :return: dialog tool
        """
        QObject.__init__(self, None)
        self.iface = iface
        self.dialog_ui = dialog_ui
        self.bbox_tool = bbox_tool

        self.progress_bar = None
        self.progress_message_bar = None
        self.progress_message_bar_widget = None
        self.search_thread_pool = QThreadPool()
        self.search_lock = Lock()
        self.export_thread_pool = QThreadPool()
        self.export_lock = Lock()
        self.query = None
        self.previous_credentials = None
        self.export_file = None
        self.footprint_layer = None

        self.filters = CatalogFilters(self.dialog_ui)

        self.dialog_ui.aoi_button.clicked.connect(self.aoi_button_clicked)
        self.dialog_ui.reset_button.clicked.connect(self.reset_button_clicked)
        self.dialog_ui.export_button.clicked.connect(self.export_button_clicked)
        self.bbox_tool.released.connect(self.search)
        self.model = None

    def init_progress_bar(self, progress_max):
        """
        Sets up the progress bar for search functionality
        :return: None
        """
        if not self.progress_message_bar:
            self.progress_message_bar = self.iface.messageBar().createMessage("Querying for data")
            self.progress_bar = QProgressBar()
            self.progress_bar.setMinimum(0)
            self.progress_bar.setMaximum(progress_max)
            self.progress_bar.setAlignment(Qt.AlignLeft | Qt.AlignCenter)
            self.progress_message_bar.layout().addWidget(self.progress_bar)
            self.progress_message_bar_widget = self.iface.messageBar().pushWidget(self.progress_message_bar, self.iface.messageBar().INFO)

    def init_layers(self):
        """
        Sets up the layers for rendering the items
        :return: None
        """
        if self.footprint_layer:
            QgsMapLayerRegistry.instance().removeMapLayer(self.footprint_layer.id())

        self.footprint_layer = QgsVectorLayer("Polygon?crs=EPSG:4326", "Catalog Footprints", "memory")
        self.footprint_layer.setCrs(QgsCoordinateReferenceSystem(4326), True)
        self.footprint_layer.dataProvider().addAttributes(CatalogAcquisitionFeature.get_fields())
        QgsMapLayerRegistry.instance().addMapLayer(self.footprint_layer)

    def clear_widgets(self):
        """
        Clears the progress bar
        :return: None
        """
        self.progress_bar = None
        self.progress_message_bar = None
        if self.progress_message_bar_widget:
            self.iface.messageBar().popWidget(self.progress_message_bar_widget)
        self.progress_message_bar_widget = None

    def is_searching(self):
        """
        Check to see if the system is still searching (checks if there's work in the search thread pool)
        :return: True if searching; False otherwise
        """
        return self.get_search_active_thread_count() > 0

    def is_exporting(self):
        """
        Check to see if the system is still exporting (checks if there's work in the export thread pool)
        :return: True if searching; False otherwise
        """
        return self.get_export_active_thread_count() > 0

    def get_search_active_thread_count(self):
        """
        Gets the number of active threads in the search thread pool
        :return:
        """
        with self.search_lock:
            return self.search_thread_pool.activeThreadCount()

    def get_export_active_thread_count(self):
        """
        Gets the number of active threads in the export thread pool
        :return:
        """
        with self.export_lock:
            return self.export_thread_pool.activeThreadCount()

    def aoi_button_clicked(self):
        """
        Validates and runs the search if validation successful
        :return: None
        """
        # can't run search during export
        if self.is_exporting():
            self.iface.messageBar().pushMessage("Error", "Cannot run search while export is running.", level=QgsMessageBar.CRITICAL)
        # can't run multiple search
        elif self.is_searching():
            self.iface.messageBar().pushMessage("Error", "Cannot run a new search while a search is running.", level=QgsMessageBar.CRITICAL)
        else:
            self.bbox_tool.reset()
            self.iface.mapCanvas().setMapTool(self.bbox_tool)

    def reset_button_clicked(self):
        """
        Resets filters.
        :return: None
        """
        self.reset()

    def export_button_clicked(self):
        """
        Validates and runs the export if validation successful
        :return: None
        """
        # can't run export during search
        if self.is_searching():
            self.iface.messageBar().pushMessage("Error", "Cannot run export while search is running.", level=QgsMessageBar.CRITICAL)
        # can't run multiple exports
        elif self.is_exporting():
            self.iface.messageBar().pushMessage("Error", "Cannot run a new export while a export is running.", level=QgsMessageBar.CRITICAL)
        else:
            self.export()

    def search(self, top, bottom, left, right):
        self.search_thread_pool.waitForDone(0)

        # validate credentials if they changed
        errors = []
        username, password, api_key, max_items_to_return = SettingsOps.get_settings()
        credentials = [username, password, api_key]
        if not self.previous_credentials or self.previous_credentials != credentials:
            SettingsOps.validate_stored_info(username, password, api_key, max_items_to_return, errors)
        self.previous_credentials = credentials

        # validate filters
        if not errors:
            self.filters.validate(errors)

        if errors:
            self.iface.messageBar().pushMessage("Error", "The following errors occurred: " + "<br />".join(errors), level=QgsMessageBar.CRITICAL)
        else:
            self.init_layers()

            self.dialog_ui.tab_widget.setCurrentIndex(RESULTS_TAB_INDEX)
            
            next_x_list = self.drange_list(float(left) + INCREMENTAL_INTERVAL, float(right), INCREMENTAL_INTERVAL)
            next_y_list = self.drange_list(float(bottom) + INCREMENTAL_INTERVAL, float(top), INCREMENTAL_INTERVAL)
            self.init_progress_bar(len(next_x_list) * len(next_y_list))

            self.model = CatalogTableModel(self.dialog_ui.table_view)
            self.dialog_ui.table_view.setModel(self.model)
            self.dialog_ui.table_view.selectionModel().selectionChanged.connect(self.selection_changed)

            if not self.query:
                self.query = GBDQuery(username=username, password=password, api_key=api_key)

            filters = self.filters.get_query_filters()
            time_begin = self.filters.get_datetime_begin()
            time_end = self.filters.get_datetime_end()

            current_x = float(left)
            current_y = float(bottom)
            for next_x in next_x_list:
                for next_y in next_y_list:
                    search_runnable = CatalogSearchRunnable(self.query, self.model, self, top=next_y, left=current_x, right=next_x, bottom=current_y, 
                                                            time_begin=time_begin, time_end=time_end, filters=filters)
                    search_runnable.task_object.task_complete.connect(self.on_search_complete)
                    self.search_thread_pool.start(search_runnable)
                    current_y = next_y
                current_y = bottom
                current_x = next_x

    def reset(self):
        self.filters.remove_all()

    def export(self):
        self.export_thread_pool.waitForDone(0)
        acquisitions = None
        if self.model is not None:
            acquisitions = self.model.data

        if not acquisitions:
            self.iface.messageBar().pushMessage("Error", "No data to export.", level=QgsMessageBar.CRITICAL)
        else:
            # open file ui
            select_file_ui = QFileDialog()
            starting_file = self.export_file or os.path.expanduser("~")
            export_file = select_file_ui.getSaveFileName(None, "Choose output file", starting_file, SELECT_FILTER)

            if export_file:
                self.export_file = export_file
                self.init_progress_bar(0)
                export_runnable = CatalogExportRunnable(acquisitions, self.export_file)
                export_runnable.task_object.task_complete.connect(self.on_export_complete)
                self.export_thread_pool.start(export_runnable)

    @pyqtSlot()
    def on_search_complete(self):
        thread_count = self.get_search_active_thread_count()
        if self.progress_message_bar:
            self.progress_bar.setValue(self.progress_bar.value() + 1)
        if thread_count == 0:
            self.clear_widgets()
            self.dialog_ui.table_view.resizeColumnsToContents()

    @pyqtSlot()
    def on_export_complete(self):
        thread_count = self.get_export_active_thread_count()
        if self.progress_message_bar:
            self.progress_bar.setValue(self.progress_bar.value() + 1)
        if thread_count == 0:
            self.clear_widgets()
            self.iface.messageBar().pushMessage("Info", 'File export has completed to "%s".' % self.export_file)

    def selection_changed(self, selected, deselected):
        self.footprint_layer.startEditing()

        # draw footprints for selected rows
        selected_rows = set()
        for index in selected.indexes():
            selected_rows.add(index.row())
        for row in selected_rows:
            acquisition = self.model.get(row)
            feature_id = self.model.generate_feature_id()
            self.model.set_feature_id(acquisition, feature_id)
            feature = CatalogAcquisitionFeature(feature_id, acquisition)
            self.footprint_layer.dataProvider().addFeatures([feature])

        # remove footprints for deselected rows
        deselected_rows = set()
        for index in deselected.indexes():
            deselected_rows.add(index.row())
        feature_ids_to_remove = []
        for row in deselected_rows:
            acquisition = self.model.get(row)
            feature_id = self.model.get_feature_id(acquisition)
            feature_ids_to_remove.append(feature_id)
            self.model.remove_feature_id(acquisition)
        if feature_ids_to_remove:
            self.footprint_layer.dataProvider().deleteFeatures(feature_ids_to_remove)

        self.footprint_layer.commitChanges()
        self.footprint_layer.updateExtents()
        self.footprint_layer.triggerRepaint()

    def drange_list(self, start, stop, step):
        drange_list = []
        r = start
        while r < stop:
            drange_list.append(r)
            r += step
        if not drange_list:
            drange_list.append(stop)
        return drange_list
Пример #37
0
def layer_empty_poly(tmp_dir, layer_simple_poly):
    dp: QgsVectorDataProvider = layer_simple_poly.dataProvider()
    layer = QgsVectorLayer('Polygon', 'test_poly', 'memory')
    layer.setCrs(dp.crs())
    assert layer.isValid()
    return layer
Пример #38
0
    def loadLayer(self,
                  inputParam,
                  parentNode,
                  useInheritance,
                  useQml,
                  uniqueLoad,
                  stylePath,
                  domainDict,
                  multiColumnsDict,
                  domLayerDict,
                  edgvVersion,
                  geomColumn=None,
                  isView=False,
                  editingDict=None,
                  customForm=False):
        """
        Loads a layer
        :param lyrName: Layer name
        :param idSubgrupo: sub group id
        :param uniqueLoad: boolean to mark if the layer should only be loaded once
        :param stylePath: path to the styles used
        :param domLayerDict: domain dictionary
        :return:
        """
        lyrName, schema, geomColumn, tableName, srid = self.getParams(
            inputParam)
        lyr = self.checkLoaded(tableName)
        if uniqueLoad and lyr is not None:
            return lyr
        fullName = '''"{0}"."{1}"'''.format(schema, tableName)
        pkColumn = self.abstractDb.getPrimaryKeyColumn(fullName)
        if useInheritance or self.abstractDb.getDatabaseVersion() in [
                '3.0', 'Non_EDGV', 'Non_Edgv', '2.1.3 Pro', '3.0 Pro'
        ]:
            sql = ''
        else:
            sql = self.abstractDb.gen.loadLayerFromDatabase(fullName,
                                                            pkColumn=pkColumn)
        self.setDataSource(schema,
                           tableName,
                           geomColumn,
                           sql,
                           pkColumn=pkColumn)

        vlayer = QgsVectorLayer(self.uri.uri(), tableName, self.provider)
        QgsProject.instance().addMapLayer(vlayer, addToLegend=False)
        crs = QgsCoordinateReferenceSystem(
            int(srid), QgsCoordinateReferenceSystem.EpsgCrsId)
        if vlayer is not None:
            vlayer.setCrs(crs)
            if useQml:
                vlayer = self.setDomainsAndRestrictionsWithQml(vlayer)
            else:
                vlayer = self.setDomainsAndRestrictions(
                    vlayer, tableName, domainDict, multiColumnsDict,
                    domLayerDict)
            if stylePath:
                fullPath = self.getStyle(stylePath, tableName)
                if fullPath:
                    vlayer.loadNamedStyle(fullPath, True)
                    # remove qml temporary file
                    self.utils.deleteQml(fullPath)
                    # clear fullPath variable
                    del fullPath
            if customForm:
                # vlayer = self.loadFormCustom(vlayer)
                pass
            if editingDict is not None:
                editLyr, joinLyrFieldName = self.loadEditLayer(
                    lyrName, editingDict)
                self.buildJoin(vlayer, pkColumn, editLyr, joinLyrFieldName)
            parentNode.addLayer(vlayer)
            if not vlayer.isValid():
                QgsMessageLog.logMessage(vlayer.error().summary(),
                                         "DSGTools Plugin", Qgis.Critical)
        vlayer = self.createMeasureColumn(vlayer)
        return vlayer
Пример #39
0
    def download_tiles(self, force=None):
        #calculate zoom_level con current canvas extents
        ex = self.iface.mapCanvas().extent()
        wgs84_minimum = self.transformToWGS84(
            QgsPointXY(ex.xMinimum(), ex.yMinimum()))
        wgs84_maximum = self.transformToWGS84(
            QgsPointXY(ex.xMaximum(), ex.yMaximum()))
        bounds = (wgs84_minimum.x(), wgs84_minimum.y(), wgs84_maximum.x(),
                  wgs84_maximum.y())
        map_units_per_pixel = (wgs84_maximum.x() - wgs84_minimum.x()
                               ) / self.iface.mapCanvas().width()
        zoom_level = ZoomForPixelSize(map_units_per_pixel)
        if zoom_level > 14:
            zoom_level = 14

        try:
            ranges = getTileRange(bounds, zoom_level)
        except ValueError:
            return

        if force or not self.actual_ranges or not (
                ranges[0][0] == self.actual_ranges[0][0]
                and ranges[0][1] == self.actual_ranges[0][1]
                and ranges[1][0] == self.actual_ranges[1][0]
                and ranges[1][1] == self.actual_ranges[1][1]):
            #print ("ZOOM_LEVEL", zoom_level, "NEW RANGES", ranges, "LAST RANGES", self.actual_ranges)
            self.actual_ranges = ranges
            x_range = ranges[0]
            y_range = ranges[1]

            overview_features = []
            sequences_features = []
            images_features = []

            progress = progressBar(self, 'go2mapillary')

            start_time = datetime.datetime.now()

            for y in range(y_range[0], y_range[1] + 1):
                for x in range(x_range[0], x_range[1] + 1):
                    folderPath = os.path.join(self.cache_dir, str(zoom_level),
                                              str(x))
                    filePathMvt = os.path.join(folderPath, str(y) + '.mvt')
                    #filePathJson = os.path.join(folderPath, str(y) + '.json')
                    if not os.path.exists(folderPath):
                        os.makedirs(folderPath)
                    res = None

                    if not os.path.exists(filePathMvt) or (
                            datetime.datetime.fromtimestamp(
                                os.path.getmtime(filePathMvt)) <
                        (datetime.datetime.now() - self.expire_time)):
                        # make the URL
                        url = getURL(x, y, zoom_level, SERVER_URL)
                        with open(filePathMvt, 'wb') as f:
                            response = requests.get(url,
                                                    proxies=getProxiesConf(),
                                                    stream=True)
                            total_length = response.headers.get(
                                'content-length')

                            if total_length is None:  # no content length header
                                f.write(response.content)
                            else:
                                dl = 0
                                total_length = int(total_length)
                                progress.start(
                                    total_length,
                                    'caching vector tile [%d,%d,%d]' %
                                    (x, y, zoom_level))
                                QgsMessageLog.logMessage("MISS [%d,%d,%d]" %
                                                         (x, y, zoom_level),
                                                         tag="go2mapillary",
                                                         level=Qgis.Info)
                                for data in response.iter_content(
                                        chunk_size=4096):
                                    dl += len(data)
                                    f.write(data)
                                    progress.setProgress(dl)

                    if os.path.exists(filePathMvt):
                        progress.start(
                            0, 'loading vector tile [%d,%d,%d]' %
                            (x, y, zoom_level))
                        if not res:
                            with open(filePathMvt, "rb") as f:
                                mvt = f.read()
                                QgsMessageLog.logMessage("CACHE [%d,%d,%d]" %
                                                         (x, y, zoom_level),
                                                         tag="go2mapillary",
                                                         level=Qgis.Info)
                        else:
                            mvt = res.content

                        bounds = mercantile.bounds(x, y, zoom_level)
                        tile_box = (bounds.west, bounds.south, bounds.east,
                                    bounds.north)
                        json_data = mapbox_vector_tile.decode(
                            mvt, quantize_bounds=tile_box)
                        if "mapillary-sequence-overview" in json_data:
                            overview_features = overview_features + json_data[
                                "mapillary-sequence-overview"]["features"]
                        elif "mapillary-sequences" in json_data:
                            sequences_features = sequences_features + json_data[
                                "mapillary-sequences"]["features"]
                        if "mapillary-images" in json_data and zoom_level == 14:
                            images_features = images_features + json_data[
                                "mapillary-images"]["features"]

            # print("loading time", datetime.datetime.now() - start_time)
            progress.stop('loading complete')

            for level in LAYER_LEVELS:
                geojson_file = os.path.join(self.cache_dir,
                                            "mapillary_%s.geojson" % level)
                try:
                    QgsProject.instance().removeMapLayer(
                        getattr(self, level + 'Layer').id())
                except:
                    pass
                if locals()[level + '_features']:
                    setattr(self, level, True)
                    geojson = {
                        "type": "FeatureCollection",
                        "features": locals()[level + '_features']
                    }

                    with open(geojson_file, 'w') as outfile:
                        json.dump(geojson, outfile)
                    defLyr = QgsVectorLayer(
                        os.path.join(self.cache_dir,
                                     'mapillary_%s.geojson' % level),
                        "Mapillary " + level, "ogr")
                    defLyr.loadNamedStyle(
                        os.path.join(os.path.dirname(__file__), "res",
                                     "mapillary_%s.qml" % level))
                    QgsExpressionContextUtils.setLayerVariable(
                        defLyr, "mapillaryCurrentKey",
                        self.module.viewer.locationKey)
                    defLyr.setCrs(QgsCoordinateReferenceSystem(4326))
                    QgsProject.instance().addMapLayer(defLyr)
                    self.iface.addCustomActionForLayerType(
                        getattr(self.module, 'filterAction_' + level),
                        None,
                        QgsMapLayer.VectorLayer,
                        allLayers=False)
                    self.module.filterDialog.applySqlFilter(layer=defLyr)
                    self.iface.addCustomActionForLayer(
                        getattr(self.module, 'filterAction_' + level), defLyr)
                    legendLayerNode = QgsProject.instance().layerTreeRoot(
                    ).findLayer(defLyr.id())
                    legendLayerNode.setExpanded(False)
                    defLyr.setDisplayExpression('"key"')
                    setattr(self, level + 'Layer', defLyr)
                else:
                    setattr(self, level, False)

        else:
            pass
Пример #40
0
    def renderer(self):
        qgis = QgsApplication([], False)
        qgis.setPrefixPath(self.settings.get('path'), True)
        qgis.setMaxThreads(1)
        qgis.initQgis()

        while True:
            try:
                fndata, srs, render_size, extended, \
                    target_box, result = self.queue.get()

                layer = QgsVectorLayer(fndata, 'layer', 'ogr')

                crs = QgsCoordinateReferenceSystem(srs.id)
                layer.setCrs(crs)

                settings = QgsMapSettings()
                settings.setLayers([layer.id()])
                settings.setFlag(QgsMapSettings.DrawLabeling)
                settings.setFlag(QgsMapSettings.Antialiasing)

                settings.setCrsTransformEnabled(True)
                settings.setDestinationCrs(crs)
                settings.setMapUnits(crs.mapUnits())
                settings.setOutputSize(QSize(*render_size))
                settings.setExtent(QgsRectangle(*extended))

                settings.setOutputImageFormat(QImage.Format_ARGB32)
                bgcolor = QColor.fromRgba(qRgba(255, 255, 255, 0))
                settings.setBackgroundColor(bgcolor)
                settings.setOutputDpi(96)

                QgsMapLayerRegistry.instance().addMapLayer(layer)
                settings.setLayers([layer.id()])

                # Создаем QImage руками чтобы можно было использовать
                # QgsMapRendererCustomPainterJob. Остальные не позволяют
                # обойти баг с рисованием поверх старого.
                img = QImage(settings.outputSize(), QImage.Format_ARGB32)

                # Эти костыли нужны для того, чтобы корректно рисовались
                # слои на прозрачном фоне, без этого получается каша.
                img.fill(QColor.fromRgba(qRgba(255, 255, 255, 255)))
                img.fill(QColor.fromRgba(qRgba(255, 255, 255, 0)))

                # DPI должно быть таким же как в settings, иначе ошибка. В QImage
                # разрешение указывается в точках на метр по каждой оси.
                dpm = settings.outputDpi() / 25.4 * 1000
                img.setDotsPerMeterX(dpm)
                img.setDotsPerMeterY(dpm)

                painter = QPainter(img)
                job = QgsMapRendererCustomPainterJob(settings, painter)
                job.renderSynchronously()
                painter.end()

                QgsMapLayerRegistry.instance().removeAllMapLayers()

                # Преобразование QImage в PIL
                ba = QByteArray()
                bf = QBuffer(ba)
                bf.open(QIODevice.WriteOnly)
                img.save(bf, 'PNG')
                bf.close()

                buf = StringIO()
                buf.write(bf.data())
                buf.seek(0)

                img = PIL.Image.open(buf)

                # Вырезаем нужный нам кусок изображения
                result.put(img.crop(target_box))

            except Exception as e:
                self.logger.error(e.message)

        qgis.exitQgis()
        def convertCoordinatesToPoints(inTable=joinTab):

            QgsMessageLog.logMessage(
                'Converting XY coordinates to spatial points.',
                'User notification', 0)

            # create temporary vector layer
            tempLyr = QgsVectorLayer('Point', 'temporary_points', 'memory')

            # define coordinate system
            CRS = tempLyr.crs()
            CRS.createFromId(4647)
            tempLyr.setCrs(CRS)

            # start editing
            tempLyr.startEditing()

            # create attribute fields
            for f in list(range(0, len(atts.columns))):
                tempLyr.dataProvider().addAttributes(
                    [QgsField(atts.columns[f], QVariant.String)])
            tempLyr.updateFields()

            # iterate over each address and add geometry
            for p in list(range(0, len(joinTab['11']))):

                QgsMessageLog.logMessage(
                    'Creating features...(' + str(p) + '/' +
                    str(len(joinTab['11'])) + ')', 'User notification', 0)

                # extract coordinates
                x = joinTab['11'].iloc[p]
                y = joinTab['12'].iloc[p]

                # convert coordinates to geometry
                pGeom = QgsGeometry.fromPointXY(QgsPointXY(x, y))

                # create feature
                feature = QgsFeature()

                # set coordinates for the new feature
                feature.setGeometry(pGeom)

                # add attributes
                feature.setAttributes(joinTab.values.tolist()[p])

                # add feature to temporary layer
                tempLyr.dataProvider().addFeature(feature)

                # update the extent of the layer
                tempLyr.updateExtents()

            # end editing
            tempLyr.commitChanges()

            # write temporary layer to file
            QgsMessageLog.logMessage('Wrting results to file.',
                                     'User notification', 0)
            outPath = outDir + '\\geocodierteAdressen_imAmtlichenAdressverzeichnis.gpkg'
            QgsVectorFileWriter.writeAsVectorFormat(tempLyr, outPath, 'ANSI',
                                                    tempLyr.crs(), 'GPKG')

            return tempLyr
    def transform_vector(self, out_file):
        log("Transforming file to: {}".format(out_file))
        layer = self.in_dataset

        source_crs = QgsCoordinateReferenceSystem()
        if self.SELECTED_TRANSFORM.source_proj:
            log("Source from proj")
            log(self.SELECTED_TRANSFORM.source_proj)
            source_crs.createFromProj4(self.SELECTED_TRANSFORM.source_proj)
        else:
            log("Source from id")
            source_crs.createFromId(self.SELECTED_TRANSFORM.source_code)

        log("Setting Source CRS")
        layer.setCrs(source_crs)

        if self.SELECTED_TRANSFORM.target_proj:
            log("Setting intermediate CRS from proj")
            log(self.SELECTED_TRANSFORM.target_proj)
            temp_crs = QgsCoordinateReferenceSystem()
            temp_crs.createFromProj4(self.SELECTED_TRANSFORM.target_proj)

            # We do an intermediate transform, so that the target gets a proper SRID
            temp_dir = tempfile.mkdtemp()
            temp_outfilename = os.path.join(temp_dir, 'temp_file.shp')
            log("Tempfile is: {}".format(temp_outfilename))
            error, message = QgsVectorFileWriter.writeAsVectorFormat(
                layer, temp_outfilename, 'utf-8', temp_crs, 'ESRI Shapefile')

            if error == QgsVectorFileWriter.NoError:
                log("Success on intermediate transform")
                # These overwrite the original target layer destination file.
                layer = QgsVectorLayer(temp_outfilename, 'in layer', 'ogr')
                # The next transform is from and to the destination transform, which is needed to define the CRS properly.
                intermediary_crs = QgsCoordinateReferenceSystem()
                intermediary_crs.createFromId(
                    self.SELECTED_TRANSFORM.target_code)
                layer.setCrs(intermediary_crs)
            else:
                log("Error writing temporary vector, code: {} and message: {}".
                    format(str(error), message))
                self.iface.messageBar().pushMessage(
                    "Error",
                    "Transformation failed, please check your configuration.",
                    level=Qgis.Critical,
                    duration=3)
                return

            log("Setting final target CRS from id")
            dest_crs = QgsCoordinateReferenceSystem()
            dest_crs.createFromId(self.SELECTED_TRANSFORM.target_code)

            error, message = QgsVectorFileWriter.writeAsVectorFormat(
                layer, out_file, 'utf-8', dest_crs, 'ESRI Shapefile')
            if error == QgsVectorFileWriter.NoError:
                log("Success")
                self.iface.messageBar().pushMessage("Success",
                                                    "Transformation complete.",
                                                    level=Qgis.Info,
                                                    duration=3)
                if self.dlg.TOCcheckBox.isChecked():
                    log("Opening file {}".format(out_file))
                    basename = QFileInfo(out_file).baseName()
                    vlayer = QgsVectorLayer(out_file, str(basename), "ogr")
                    if vlayer.isValid():
                        QgsProject.instance().addMapLayers([vlayer])
                    else:
                        log("vlayer invalid")
            else:
                log("Error writing vector, code: {} and message: {}".format(
                    str(error), message))
                self.iface.messageBar().pushMessage(
                    "Error",
                    "Transformation failed, please check your configuration.",
                    level=Qgis.Critical,
                    duration=3)
Пример #43
0
aparser.add_argument('--dpi', type=int, default=96)
aparser.add_argument('--width', type=int, default=1000)
args = aparser.parse_args(sys.argv[1:])

QgsApplication.setPrefixPath('/usr', True)
QgsApplication.initQgis()

layer = QgsVectorLayer(args.input, 'layer', 'ogr')
extent = layer.extent()
print("Layer extent: %s" % extent.toString())

QgsMapLayerRegistry.instance().removeAllMapLayers()
QgsMapLayerRegistry.instance().addMapLayer(layer)

crs = QgsCoordinateReferenceSystem(4326)
layer.setCrs(crs)

render = QgsMapRenderer()
render.setLayerSet([layer.id()])

iwidth = args.width
iheight = int(iwidth * (extent.height() / extent.width()))

print("Image size: %dx%d" % (iwidth, iheight))

dpi = args.dpi

img = QImage(iwidth, iheight, QImage.Format_RGB32)
img.setDotsPerMeterX(dpi / 25.4 * 1000)
img.setDotsPerMeterY(dpi / 25.4 * 1000)
img.fill(qRgb(255, 255, 255))
Пример #44
0
    def buildLayer(self):

        displayName = self.database.name + '_' + self.project.name + '_' + self.shapeName.replace(
            '/', '')
        vectorLayer = QgsVectorLayer("Point", displayName, "memory")
        provider = vectorLayer.dataProvider()
        vectorLayer.startEditing()

        # create field names for vector layer
        attributeList = [
            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),
            QgsField("EPSG", QVariant.Int)
        ]

        for key in self.objects[0].data.keys():
            try:
                value = float(self.objects[0].data[key])
                field = QgsField(key, QVariant.Double)
                attributeList.append(field)
            except:
                pass
            try:
                value = str(self.objects[0].data[key])
                field = QgsField(key, QVariant.String)
                attributeList.append(field)
            except:
                pass

        # add fields to attribute table
        provider.addAttributes(attributeList)
        epsg = 0

        for object in self.objects:
            epsg = object.epsg
            # add feature
            feat = QgsFeature()
            if object.coordinates[0] == None or object.coordinates[1] == None:
                continue
            #print object.coordinates[0], float(object.coordinates[0]), object.coordinates[1], float(object.coordinates[1])
            feat.setGeometry(
                QgsGeometry.fromPoint(
                    QgsPoint(object.coordinates[0], object.coordinates[1])))
            attribute = [
                object.invid, object.shortname, object.name,
                float(object.coordinates[0]),
                float(object.coordinates[1]),
                self.database.options["connection"], self.database.filepath,
                object.parent.name, object.parent.id, object.locname,
                object.epsg
            ]

            for key in object.data.keys():
                if isinstance(object.data[key], decimal.Decimal):
                    attribute.append(float(object.data[key]))
                else:
                    attribute.append(object.data[key])
            feat.setAttributes(attribute)
            provider.addFeatures([feat])

            # Commit changes
            vectorLayer.commitChanges()
        #http://qgis.org/api/2.18/classQgsVectorFileWriter.html#ab566ed2016352c37d9a4a6900614eac2
        error = ""
        #fileName = displayName.replace('\\','').replace(':','').replace('*','').replace('?','').replace('"','').replace('<','').replace('>','').replace('|','').replace('/','').strip().replace(' ','_')
        #generating random string for filename
        fileName = ''.join(
            random.choice(string.ascii_uppercase + string.digits)
            for _ in range(20))

        CoordinateReferenceSystem = QgsCoordinateReferenceSystem(
            4326, QgsCoordinateReferenceSystem.EpsgCrsId)

        if epsg:
            CoordinateReferenceSystem = QgsCoordinateReferenceSystem(
                epsg, QgsCoordinateReferenceSystem.EpsgCrsId)

        if self.main.config.get("Options", "savelayer") == "True":
            fileName = os.path.join(self.main.tmpDirectory,
                                    fileName + '.sqlite')
            error = QgsVectorFileWriter.writeAsVectorFormat(
                vectorLayer, fileName, 'CP1250', CoordinateReferenceSystem,
                'SpatiaLite', False, None, ['SPATIALITE=YES'])
            layer = QgsVectorLayer(fileName, displayName, "ogr")
            layer.setCrs(CoordinateReferenceSystem)
        else:
            fileName = os.path.join(self.main.tmpDirectory, fileName + '.shp')
            #error = QgsVectorFileWriter.writeAsVectorFormat(vectorLayer, fileName, 'utf-8', CoordinateReferenceSystem, 'ESRI Shapefile')
            error = QgsVectorFileWriter.writeAsVectorFormat(
                vectorLayer, fileName, 'CP1250', CoordinateReferenceSystem,
                'ESRI Shapefile')
            layer = QgsVectorLayer(fileName, displayName, "ogr")
            layer.setCrs(CoordinateReferenceSystem)

        if error == QgsVectorFileWriter.NoError:
            print("NoError ")
            QgsProject.instance().addMapLayer(layer)
        elif error == QgsVectorFileWriter.ErrDriverNotFound:
            print("ErrDriverNotFound ")
        elif error == QgsVectorFileWriter.ErrCreateDataSource:
            QApplication.restoreOverrideCursor()
            QMessageBox.critical(QWidget(), "Error", "ErrCreateDataSource")
            print("ErrCreateDataSource ")
        elif error == QgsVectorFileWriter.ErrCreateLayer:
            print("ErrCreateLayer ")
        elif error == QgsVectorFileWriter.ErrAttributeTypeUnsupported:
            print("ErrAttributeTypeUnsupported ")
        elif error == QgsVectorFileWriter.ErrAttributeCreationFailed:
            print("ErrAttributeCreationFailed ")
        elif error == QgsVectorFileWriter.ErrProjection:
            print("ErrProjection ")
        elif error == QgsVectorFileWriter.ErrFeatureWriteFailed:
            print("ErrFeatureWriteFailed ")
        elif error == QgsVectorFileWriter.ErrInvalidLayer:
            print("ErrInvalidLayer ")
        elif error == QgsVectorFileWriter.Canceled:
            QApplication.restoreOverrideCursor()
            QMessageBox.critical(
                QWidget(), "Error",
                "Writing was interrupted by manual cancelation.")
            print("Canceled ")
Пример #45
0
def passPointSeek(crete_layer, ID_crete, dem_layer, PassagePoint):
    """Seeks passage points (peak, col) along ridge

    Extract all points of interest (start of line, end of line, peak, pass) from polyline layer
    """

    # Load ridge line layer
    inCRS = crete_layer.crs().authid()
    crs = QgsCoordinateReferenceSystem(inCRS)

    # Load dem_layer layer
    x_res = dem_layer.rasterUnitsPerPixelX()
    y_res = dem_layer.rasterUnitsPerPixelY()

    # Create memory layer to store result
    pointPassage = QgsVectorLayer("Point", "point", 'memory')
    pointPassage.setCrs(crs)
    name_T_id = "T_id"
    name_L_id = "L_id"
    name_P_id = "P_id"
    name_nat = "nature"
    provider = pointPassage.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)
        ])
        pointPassage.updateFields()

    pointPassage.startEditing()

    # Loop over features
    for feature in crete_layer.getFeatures():
        feat_L_id = feature.attribute(ID_crete)
        geomType = feature.geometry().wkbType()
        if geomType == 2:
            geom = feature.geometry().asPolyline()
            nb = len(geom)
            geom_clean = feature.geometry().asPolyline()
            ind = 0
            for i in range(0, nb - 1):
                pt1 = geom[i]
                x1 = pt1.x()
                if x1 % 10 == 2:
                    x1 += 0.5
                elif x1 % 10 == 8:
                    x1 += -0.5
                y1 = pt1.y()
                if y1 % 10 == 2:
                    y1 += 0.5
                elif y1 % 10 == 8:
                    y1 += -0.5
                pt2 = geom[i + 1]
                x2 = pt2.x()
                if x2 % 10 == 2:
                    x2 += 0.5
                elif x2 % 10 == 8:
                    x2 += -0.5
                y2 = pt2.y()
                if y2 % 10 == 2:
                    y2 += 0.5
                elif y2 % 10 == 8:
                    y2 += -0.5
                pt1 = QgsPoint(x1, y1)
                pt2 = QgsPoint(x2, y2)
                dist = math.sqrt(pt1.sqrDist(pt2))
                if dist > math.sqrt(x_res * x_res + y_res * y_res) + 1:
                    azimuth = pt1.azimuth(pt2)
                    if azimuth % 10 != 0:
                        decoup_dist = math.sqrt(x_res * x_res + y_res * y_res)
                    else:
                        decoup_dist = x_res

                    tot_distance = 0
                    pts = []
                    while tot_distance / x_res < dist / x_res:
                        tot_distance += decoup_dist
                        xv = round(tot_distance *
                                   math.sin(math.radians(azimuth)))
                        yv = round(tot_distance *
                                   math.cos(math.radians(azimuth)))
                        # print xv, yv, tot_distance, azimuth, x1, y1, x2, y2
                        pt = QgsPoint(pt1.x() + xv, pt1.y() + yv)
                        pts.append(pt)
                    pt1_elev = dem_layer.dataProvider().identify(
                        pt1, QgsRaster.IdentifyFormatValue)
                    pt2_elev = dem_layer.dataProvider().identify(
                        pt2, QgsRaster.IdentifyFormatValue)
                    min_elev = min(pt1_elev, pt2_elev)
                    max_elev = max(pt1_elev, pt2_elev)
                    points_elev = []
                    min_list = None
                    max_list = None
                    max_id = None
                    min_id = None
                    for j, point in enumerate(pts):
                        elev = dem_layer.dataProvider().identify(
                            point, QgsRaster.IdentifyFormatValue)
                        if elev < min_elev:
                            if min_list == None or elev < min_list:
                                min_list = elev
                                min_id = j
                        if elev > max_elev:
                            if max_list == None or elev < max_list:
                                max_list = elev
                                max_id = j
                    if max_id != None and min_id != None:
                        if max_id < min_id:
                            geom_clean.insert(i + 1 + ind, pts[max_id])
                            geom_clean.insert(i + 2 + ind, pts[min_id])
                            ind += 2
                        else:
                            geom_clean.insert(i + 2 + ind, pts[min_id])
                            geom_clean.insert(i + 1 + ind, pts[max_id])
                            ind += 2
                    elif max_id != None and min_id == None:
                        geom_clean.insert(i + 1 + ind, pts[max_id])
                        ind += 1
                    elif min_id != None and max_id == None:
                        geom_clean.insert(i + 1 + ind, pts[min_id])
                        ind += 1
            nb = len(geom_clean)
            elev_list = []
            for point in geom_clean:
                elev = dem_layer.dataProvider().identify(
                    point, QgsRaster.IdentifyFormatValue)
                elev_list.append(elev.results()[1])
            count = 0
            for i in range(0, nb):
                feat_point = QgsFeature()
                try:
                    if i == 0:
                        feat_point.setGeometry(QgsGeometry.fromPoint(geom[0]))
                        nat = 's'
                        t_id = 'l' + str(feat_L_id) + 'p' + str(count) + nat
                        feat_point.setAttributes(
                            [t_id, feat_L_id, count, 'start'])
                        count += 1
                        pointPassage.dataProvider().addFeatures([feat_point])
                    elif i == nb - 1:
                        feat_point.setGeometry(QgsGeometry.fromPoint(geom[-1]))
                        nat = 'e'
                        t_id = 'l' + str(feat_L_id) + 'p' + str(count) + nat
                        feat_point.setAttributes(
                            [t_id, feat_L_id, count, 'end'])
                        count += 1
                        pointPassage.dataProvider().addFeatures([feat_point])
                    elif i < 3:
                        pass
                    elif i > nb - 3:
                        pass
                    else:
                        feat_point.setGeometry(
                            QgsGeometry.fromPoint(geom_clean[i]))
                        min_elev1 = min(elev_list[i - 3], elev_list[i - 2],
                                        elev_list[i - 1])
                        min_elev2 = min(elev_list[i + 3], elev_list[i + 2],
                                        elev_list[i + 1])
                        max_elev1 = max(elev_list[i - 3], elev_list[i - 2],
                                        elev_list[i - 1])
                        max_elev2 = max(elev_list[i + 3], elev_list[i + 2],
                                        elev_list[i + 1])
                        if elev_list[i] < min_elev1 and elev_list[
                                i] <= min_elev2:
                            nat = 'd'
                            t_id = 'l' + str(feat_L_id) + 'p' + str(
                                count) + nat
                            feat_point.setAttributes(
                                [t_id, feat_L_id, count, 'col'])
                            count += 1
                            pointPassage.dataProvider().addFeatures(
                                [feat_point])
                        if elev_list[i] >= max_elev1 and elev_list[
                                i] > max_elev2:
                            nat = 't'
                            t_id = 'l' + str(feat_L_id) + 'p' + str(
                                count) + nat
                            feat_point.setAttributes(
                                [t_id, feat_L_id, count, 'pic'])
                            count += 1
                            pointPassage.dataProvider().addFeatures(
                                [feat_point])
                    pointPassage.commitChanges()
                    pointPassage.updateExtents()
                except:
                    pass
        else:
            print 'PPS: no multiline'

    return pointPassage, crs, dem_layer
Пример #46
0
    def get_transformed_layers(self):
        transformed_layers = []
        for background_layer in self.layers_to_transform:
            _t = QgsWkbTypes.displayString(background_layer.wkbType())

            result_layer = QgsVectorLayer(
                "{}?crs={}".format(_t,
                                   background_layer.crs().authid()),
                "result_cartogram", "memory")
            features_to_add = []
            result_layer.setCrs(background_layer.crs())
            pr_result_layer = result_layer.dataProvider()
            pr_result_layer.addAttributes(background_layer.fields().toList())
            result_layer.updateFields()

            for ix, ft in enumerate(background_layer.getFeatures()):
                ref_geom = ft.geometry()
                ref_coords = ref_geom.__geo_interface__['coordinates']
                if ref_geom.__geo_interface__['type'] == 'LineString':
                    new_geom = QgsGeometry.fromPolyLineXY([
                        QgsPointXY(*self.g._interp_point(
                            *ref_coords[ix_coords]))
                        for ix_coords in range(len(ref_coords))
                    ])
                elif ref_geom.__geo_interface__['type'] == 'MultiLineString':
                    lines = []
                    for ix_line in range(len(ref_coords)):
                        lines.append([
                            QgsPointXY(*self.g._interp_point(
                                *ref_coords[ix_line][ix_coords]))
                            for ix_coords in range(len(ref_coords[ix_line]))
                        ])
                    new_geom = QgsGeometry.fromMultiPolylineXY(lines)
                elif ref_geom.__geo_interface__['type'] == 'Polygon':
                    rings = []
                    for ix_ring in range(len(ref_coords)):
                        rings.append([
                            QgsPointXY(*self.g._interp_point(
                                *ref_coords[ix_ring][ix_coords]))
                            for ix_coords in range(len(ref_coords[ix_ring]))
                        ])
                    new_geom = QgsGeometry.fromPolygonXY(rings)

                elif ref_geom.__geo_interface__['type'] == 'MultiPolygon':
                    polys = []
                    for ix_poly in range(len(ref_coords)):
                        rings = []
                        for ix_ring in range(len(ref_coords[ix_poly])):
                            rings.append([
                                QgsPointXY(*self.g._interp_point(
                                    *ref_coords[ix_poly][ix_ring][ix_coords]))
                                for ix_coords in range(
                                    len(ref_coords[ix_poly][ix_ring]))
                            ])
                        polys.append(rings)
                    new_geom = QgsGeometry.fromMultiPolygonXY(polys)
                else:
                    self.status.emit('Geometry type error')
                    continue
                feature = QgsFeature()
                feature.setGeometry(new_geom)
                feature.setAttributes(ft.attributes())
                features_to_add.append(feature)
                self.progress.emit(1)
            pr_result_layer.addFeatures(features_to_add)
            result_layer.updateExtents()
            transformed_layers.append(result_layer)
        return transformed_layers
Пример #47
0
    def kpIteratePts(self, linetoMeasurekp4p, ptLayer):
        """will iterate over all points in a layer, finding distance to and along line.
        Outputs a new layer."""
        new_pt_layer = QgsVectorLayer(
            'Point', 'KPed_' + str(ptLayer.name()),
            'memory')  # define new layer we will return
        new_pt_layer.setCrs(ptLayer.crs())  # get crs from input layer
        prov_old = ptLayer.dataProvider(
        )  # provider to get the attribute field names and type
        provider_ptLayer = new_pt_layer.dataProvider(
        )  # provider for new layer to add the features to
        fields_ptLayer = prov_old.fields()
        for f in fields_ptLayer:
            # iterate over all field names and add to new provider
            znameField = f.name()
            type_field = str(f.typeName())
            if type_field == 'Integer':
                provider_ptLayer.addAttributes(
                    [QgsField(znameField, QVariant.Int)])
            if type_field == 'Real':
                provider_ptLayer.addAttributes(
                    [QgsField(znameField, QVariant.Double)])
            if type_field == 'String':
                provider_ptLayer.addAttributes(
                    [QgsField(znameField, QVariant.String)])
            else:
                provider_ptLayer.addAttributes(
                    [QgsField(znameField, QVariant.String)])

        iterate_names_list = ["KP", "DOL", "Latitude", "Longitude"]
        new_attr_names = self.name_collision_checker(
            iterate_names_list,
            ptLayer)  # check if the new names we add already exist
        provider_ptLayer.addAttributes([
            QgsField(new_attr_names[0], QVariant.Double),
            QgsField(new_attr_names[1], QVariant.Double),
            QgsField(new_attr_names[2], QVariant.String),
            QgsField(new_attr_names[3], QVariant.String)
        ])  # four new fields we are calculating
        new_pt_layer.startEditing()
        for old_feat in ptLayer.getFeatures():
            # iterate over all point features
            geom_of = old_feat.geometry()
            point_of = geom_of.asPoint()  # get point object
            new_feat = QgsFeature()
            new_feat.setGeometry(
                geom_of)  # create and set geometry from old feature
            attributes_nf = old_feat.attributes(
            )  # copy of old feat attributes

            if self.geodetic_usekp4p == 0:
                # we measure Cartesian coords
                line_length = self.measureLine(self.linelayer, point_of,
                                               False) + self.offsetkp4p
                whole_line_length = self.measureWholeLine(
                    self.linelayer, False)
                dcc_dist = self.closestPt(
                    linetoMeasurekp4p, point_of, True,
                    False)[1]  # second False means we use Cartesian distance
            elif self.geodetic_usekp4p == 2:
                # we measure geodetic coords
                line_length = self.measureLine(linetoMeasurekp4p, point_of,
                                               True) + self.offsetkp4p
                whole_line_length = self.measureWholeLine(self.linelayer, True)
                dcc_dist = self.closestPt(linetoMeasurekp4p, point_of, True,
                                          True)[1]
            if self.reversekp_statuskp4p == 0:
                kp_dist = line_length
            elif self.reversekp_statuskp4p == 2:
                kp_dist = whole_line_length - line_length

            attributes_nf.append(round(
                kp_dist, self.kpdeckp4p))  # round with precision values
            attributes_nf.append(round(
                dcc_dist, self.dccdeckp4p))  # round with precision values
            attributes_nf.append(
                self.formatCoord(point_of)[0])  # insert latitude
            attributes_nf.append(
                self.formatCoord(point_of)[1])  # insert longitude
            new_feat.setAttributes(
                attributes_nf)  # set new attributes to new feat
            provider_ptLayer.addFeatures([new_feat
                                          ])  # add new feature to provider

        new_pt_layer.commitChanges()  # finish editing layer
        return new_pt_layer  # return the new layer with new features with new attributes
Пример #48
0
    def putKPPointsAlongLine(self, source, maxseglen):
        "We travel along the line and test if each consecutive segment should contain KPs and how many"
        layercrs = source.sourceCrs()
        if layercrs != KPTool.epsg4326:
            transto4326 = QgsCoordinateTransform(layercrs, KPTool.epsg4326,
                                                 QgsProject.instance())
            transfrom4326 = QgsCoordinateTransform(KPTool.epsg4326, layercrs,
                                                   QgsProject.instance())

        new_pt_layer = QgsVectorLayer(
            'Point', 'KP_points_' + str(source.name()),
            'memory')  # define new layer we will return
        new_pt_layer.setCrs(source.crs())  # get crs from input layer
        new_pt_layer.startEditing()
        provider_ptLayer = new_pt_layer.dataProvider(
        )  # provider for new layer to add the features to
        provider_ptLayer.addAttributes([QgsField('KP', QVariant.Double)])
        iterator = source.getFeatures()
        KP_label_count = 0

        for cnt, feature in enumerate(iterator):
            if feature.geometry().isMultipart():
                seg = feature.geometry().asMultiPolyline()
            else:
                seg = [feature.geometry().asPolyline()]
            numseg = len(seg)
            if numseg < 1 or len(seg[0]) < 2:
                self.iface.messageBar().pushMessage(
                    'Less than one segment in line layer',
                    level=Qgis.Critical,
                    duration=2)
                continue
            for line in seg:
                numpoints = len(line)
                if self.Reverse_KP_points == 2:  #reverse point order for reverse KP
                    _ = line.reverse()
                ptStart = QgsPointXY(line[0][0], line[0][1])
                new_kp_point = self.createFeatureFromPoint(
                    ptStart, KP_label_count)
                provider_ptLayer.addFeatures([new_kp_point])
                remaining_dist = 0.0  #remaining distance to next point
                if layercrs != KPTool.epsg4326:  # Convert to 4326
                    ptStart = transto4326.transform(ptStart)
                for x in range(1, numpoints):
                    ptEnd = QgsPointXY(line[x][0], line[x][1])
                    if layercrs != KPTool.epsg4326:  # Convert to 4326
                        ptEnd = transto4326.transform(ptEnd)
                    gline = KPTool.geod.InverseLine(ptStart.y(), ptStart.x(),
                                                    ptEnd.y(), ptEnd.x())
                    if remaining_dist + gline.s13 > maxseglen:  #we have to place at least one KP
                        s = maxseglen - remaining_dist
                        g = gline.Position(
                            s, Geodesic.LATITUDE | Geodesic.LONGITUDE
                            | Geodesic.LONG_UNROLL)
                        ptKP = QgsPointXY(g['lon2'], g['lat2'])
                        if layercrs != KPTool.epsg4326:
                            ptKP = transfrom4326.transform(ptKP)
                        KP_label_count = KP_label_count + maxseglen
                        remaining_dist = remaining_dist + gline.s13 - maxseglen
                        new_kp_point = self.createFeatureFromPoint(
                            ptKP, KP_label_count)
                        provider_ptLayer.addFeatures([new_kp_point])
                        if remaining_dist > maxseglen:  #we need to place more KP pts
                            extra_from_start = s
                            n = int(remaining_dist / maxseglen)
                            for i in range(0, n):
                                s = maxseglen * (i + 1) + extra_from_start
                                g = gline.Position(
                                    s, Geodesic.LATITUDE | Geodesic.LONGITUDE
                                    | Geodesic.LONG_UNROLL)
                                ptKP = QgsPointXY(g['lon2'], g['lat2'])
                                if layercrs != KPTool.epsg4326:  # Convert each point back to the output CRS
                                    ptKP = transfrom4326.transform(ptKP)
                                KP_label_count = KP_label_count + maxseglen
                                remaining_dist = remaining_dist - maxseglen
                                new_kp_point = self.createFeatureFromPoint(
                                    ptKP, KP_label_count)
                                provider_ptLayer.addFeatures([new_kp_point])
                    else:  #no KPs placed in this segment, keep the cumulative distance
                        remaining_dist = remaining_dist + gline.s13
                    ptStart = ptEnd
        new_pt_layer.commitChanges()
        return new_pt_layer
 def drawEllipse(self):
     # self.showInfo('Result: ' + str(self.result))
     meanx = self.result[0]
     meany = self.result[1]
     angle1 = self.result[2]
     angle2 = self.result[3]
     SD1 = self.result[4]
     SD2 = self.result[5]
     if self.method == 2:  # CrimeStat
         SD1 = SD1 * (sqrt(2) *
                      sqrt(self.featureCount) /
                      sqrt(self.featureCount - 2))
         SD2 = SD2 * (sqrt(2) *
                      sqrt(self.featureCount) /
                      sqrt(self.featureCount - 2))
     if self.crimestatCorr and self.method != 2:
         SD1 = SD1 * sqrt(2)
         SD2 = SD2 * sqrt(2)
     if self.degfreedCorr and self.method != 2:
         SD1 = SD1 * sqrt(self.featureCount) / sqrt(self.featureCount - 2)
         SD2 = SD2 * sqrt(self.featureCount) / sqrt(self.featureCount - 2)
         # SD1 = SD1 * sqrt(self.featureCount) / sqrt(self.featureCount - 1)
         # SD2 = SD2 * sqrt(self.featureCount) / sqrt(self.featureCount - 1)
     # Find the major and minor axis
     majoraxisangle = angle1
     minoraxisangle = angle2
     majorSD = SD2
     minorSD = SD1
     if SD2 < SD1:
         majoraxisangle = angle2
         minoraxisangle = angle1
         majorSD = SD1
         minorSD = SD2
     # Calculate the "compass" direction angle (clockwise from north)
     direction = 90.0 - majoraxisangle * 180 / pi
     # Calculte the eccentricity
     eccentricity = sqrt(1 - pow(minorSD, 2) / pow(majorSD, 2))
     # Create the memory layer for the ellipse
     sdefields = []
     sdefields.append(QgsField("meanx", QVariant.Double))
     sdefields.append(QgsField("meany", QVariant.Double))
     sdefields.append(QgsField("majoranglerad", QVariant.Double))
     # sdefields.append(QgsField("minoranglerad", QVariant.Double))
     sdefields.append(QgsField("directiondeg", QVariant.Double))
     sdefields.append(QgsField("majorsd", QVariant.Double))
     sdefields.append(QgsField("minorsd", QVariant.Double))
     sdefields.append(QgsField("eccentricity", QVariant.Double))
     layeruri = 'Polygon?'
     layeruri = (layeruri + 'crs=' +
                 str(self.SDLayer.dataProvider().crs().authid()))
     memSDlayer = QgsVectorLayer(layeruri, self.OutputLayerName.text(),
                                 "memory")
     # Set the CRS to the original CRS object
     memSDlayer.setCrs(self.SDLayer.dataProvider().crs())
     memSDlayer.startEditing()  # ?
     for field in sdefields:
         memSDlayer.dataProvider().addAttributes([field])
     sdfeature = QgsFeature()
     theta1 = majoraxisangle
     points = []
     step = pi / 180    # 360 points to draw the ellipse
     t = 0.0
     while t < 2 * pi:
         p1 = QPointF(meanx + majorSD * cos(t) * cos(majoraxisangle) -
                      minorSD * sin(t) * sin(majoraxisangle),
                      meany + majorSD * cos(t) * sin(majoraxisangle) +
                      minorSD * sin(t) * cos(majoraxisangle))
         points.append(QgsPointXY(p1))
         t = t + step
     # Close the polygon
     p1 = QPointF(meanx + majorSD * cos(majoraxisangle),
                  meany + majorSD * sin(majoraxisangle))
     points.append(QgsPointXY(p1))
     sdfeature.setGeometry(QgsGeometry.fromPolygonXY([points]))
     attrs = [meanx, meany, majoraxisangle, direction,
              majorSD, minorSD, eccentricity]
     sdfeature.setAttributes(attrs)
     memSDlayer.dataProvider().addFeatures([sdfeature])
     memSDlayer.commitChanges()  # ?
     memSDlayer.updateExtents()
     QgsProject.instance().addMapLayers([memSDlayer])
Пример #50
0
class islh_parser:
    """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',
            'islh_parser_{}.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'&LHPO data viewer')
        # TODO: We are going to let the user set this up in a future iteration
        self.toolbar = self.iface.addToolBar(u'islh_parser')
        self.toolbar.setObjectName(u'islh_parser')

        #print "** INITIALIZING islh_parser"

        self.pluginIsActive = False
        self.dockwidget = None
        self.hk_widget = None



    # 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('islh_parser', 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:
            self.toolbar.addAction(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/islh_parser/icon.png'
        self.add_action(
            icon_path,
            text=self.tr(u'ISLH'),
            callback=self.run,
            parent=self.iface.mainWindow())

    #--------------------------------------------------------------------------

    def onClosePlugin(self):
        """Cleanup necessary items here when plugin dockwidget is closed"""

        #print "** CLOSING islh_parser"

        # disconnects
        self.dockwidget.closingPlugin.disconnect(self.onClosePlugin)

        # remove this statement if dockwidget is to remain
        # for reuse if plugin is reopened
        # Commented next statement since it causes QGIS crashe
        # when closing the docked window:

        self.dockwidget = None

        self.pluginIsActive = False

        del(self.psk_layer)
        del(self.klo_layer)
        del(self.kto_layer)
        del(self.kpo_layer)
        del(self.kbo_layer)
        del(self.bzl_layer)
        del(self.jp_layer)
        del(self.op_layer)

        del(self.doc)
        del(self.root)

        del(barva)
        del(znacka)

        self = None


    def unload(self):
        """Removes the plugin menu item and icon from QGIS GUI."""

        #print "** UNLOAD islh_parser"

        for action in self.actions:
            self.iface.removePluginMenu(
                self.tr(u'&LHPO data viewer'),
                action)
            self.iface.removeToolBarIcon(action)
        # remove the toolbar
        del self.toolbar

        #smaze fci znacka
        #del islh_parser.znacka

    #--------------------------------------------------------------------------


    #widget functions
    #--------------------------------------------------------------------------

    def select_input_xml(self):
        filename = QFileDialog.getOpenFileName(self.dockwidget, "Select ISLH XML file ","", '*.xml')
        self.dockwidget.input_file.setText(filename)

    def read_islh(self):

        os.chdir(self.plugin_dir) #musim do plugin diru, abysem nacet svg

        if not self.dockwidget.input_file.text():
            QMessageBox.critical(QDialog()
                    ,u"Missing file",u"Není vybrán žádný soubor")
        else:
            self.f = open(self.dockwidget.input_file.text())
            try:
                #nachroustam xml
                self.dockwidget.output_working_on.setText(u"načítám XML")
                self.load_xml()

            except:
                QMessageBox.critical(QDialog()
                        ,u"vadný soubor",u"soubor se nepodařilo načíst")

            #pridam skupinu
            self.layerTreeRoot = QgsProject.instance().layerTreeRoot()
            self.por_mapa_group = self.layerTreeRoot.insertGroup(0, u'Porostní mapa')


            #self.psk_layer = self.iface.addVectorLayer('MultiPolygon'
            self.psk_layer = QgsVectorLayer('MultiPolygon'
                    , 'PSK', 'memory')

            self.psk_layer.loadNamedStyle('styles/por_mapa.qml')

            #self.crs = self.psk_layer.crs()
            #self.crs.createFromId(5514)
            #self.psk_layer.setCrs(self.crs)
            self.crs = QgsCoordinateReferenceSystem()
            self.crs.createFromId(5514)
            self.psk_layer.setCrs(self.crs)

            self.dockwidget.output_working_on.setText(u"generuji vrstvu PSK")

            try:

                self.populate_layer('ODD/DIL/POR/PSK', self.psk_layer)

                #pridam index

                self.psk_index = QgsSpatialIndex()
                for f in self.psk_layer.getFeatures():
                    self.psk_index.insertFeature(f)

                
                QgsMapLayerRegistry.instance().addMapLayer(self.psk_layer, False)
                self.por_mapa_group.addLayer(self.psk_layer)

            except:
                QMessageBox.critical(QDialog()
                        ,u"Nevhodný formát dat",u"nepodařilo se vytvořit vrstvu PSK")


            #kpo
            self.kpo_layer = QgsVectorLayer('Multipolygon'
                    , 'KPO', 'memory')

            self.kpo_layer.loadNamedStyle('styles/por_mapa_kpo.qml')

            self.kpo_layer.setCrs(self.crs)

            self.dockwidget.output_working_on.setText(u"generuji vrstvu KPO")

            try:

                self.populate_layer('KPO', self.kpo_layer)

                #index nepridam, je to jen kartoska

                QgsMapLayerRegistry.instance().addMapLayer(self.kpo_layer, False)
                #self.por_mapa_group.addLayer(self.kpo_layer)
                self.por_mapa_group.insertLayer(0, self.kpo_layer)

            except:
                QMessageBox.critical(QDialog()
                        ,u"Chyba vytváření KPO",u"nepodařilo se vytvořit vrstvu KPO")

            #-----

            #klo
            self.klo_layer = QgsVectorLayer('Linestring'
                    , 'KLO', 'memory')

            self.klo_layer.loadNamedStyle('styles/porostni_mapa_linie.qml')

            self.klo_layer.setCrs(self.crs)

            self.dockwidget.output_working_on.setText(u"generuji vrstvu KLO")

            try:

                self.populate_layer('KLO', self.klo_layer)

                #index nepridam, je to jen kartoska

                QgsMapLayerRegistry.instance().addMapLayer(self.klo_layer, False)
                #self.por_mapa_group.addLayer(self.klo_layer)
                self.por_mapa_group.insertLayer(0, self.klo_layer)

            except:
                QMessageBox.critical(QDialog()
                        ,u"Chyba vytváření KLO",u"nepodařilo se vytvořit vrstvu KLO")

            #-----

            #kbo
            self.kbo_layer = QgsVectorLayer('MultiPoint'
                    , 'KBO', 'memory')

            self.kbo_layer.loadNamedStyle('styles/styly_body.qml')

            self.kbo_layer.setCrs(self.crs)

            self.dockwidget.output_working_on.setText(u"generuji vrstvu KBO")

            try:

                self.populate_layer('KBO', self.kbo_layer)

                #index nepridam, je to jen kartoska

                QgsMapLayerRegistry.instance().addMapLayer(self.kbo_layer, False)
                #self.por_mapa_group.addLayer(self.kbo_layer)
                self.por_mapa_group.insertLayer(0, self.kbo_layer)

            except:
                QMessageBox.critical(QDialog()
                        ,u"Chyba vytváření KBO",u"nepodařilo se vytvořit vrstvu KBO")

            #-----

            #kto
            self.kto_layer = QgsVectorLayer('Point'
                    , 'KTO', 'memory')

            self.kto_layer.loadNamedStyle('styles/styly_txt.qml')

            self.kto_layer.setCrs(self.crs)

            self.dockwidget.output_working_on.setText(u"generuji vrstvu KTO")

            try:

                self.populate_layer('KTO', self.kto_layer)

                #index nepridam, je to jen kartoska

                QgsMapLayerRegistry.instance().addMapLayer(self.kto_layer, False)
                #self.por_mapa_group.addLayer(self.kto_layer)
                self.por_mapa_group.insertLayer(0, self.kto_layer)

            except:
                QMessageBox.critical(QDialog()
                        ,u"Chyba vytváření KTO",u"nepodařilo se vytvořit vrstvu KTO")

            #-----
            #BZL JP OP
            #skupina
            self.bzl_jp_op_mapa_group = self.layerTreeRoot.insertGroup(1, u'BZL, JP, OP')

            #-----

            #bzl
            self.bzl_layer = QgsVectorLayer('Multipolygon'
                    , 'BZL', 'memory')

            #self.psk_layer.loadNamedStyle('styles/por_mapa.qml')

            self.bzl_layer.setCrs(self.crs)

            self.dockwidget.output_working_on.setText(u"generuji vrstvu BZL")


            try:
                self.populate_layer('ODD/DIL/POR/BZL', self.bzl_layer)

                #index nepridam, je to jen kartoska

                QgsMapLayerRegistry.instance().addMapLayer(self.bzl_layer, False)
                #self.por_mapa_group.addLayer(self.bzl_layer)
                self.bzl_jp_op_mapa_group.insertLayer(0, self.bzl_layer)

            except:
                QMessageBox.critical(QDialog()
                        ,u"Chyba vytváření BZL",u"nepodařilo se vytvořit vrstvu BZL")


            #------

            #jp
            self.jp_layer = QgsVectorLayer('Multipolygon'
                    , 'JP', 'memory')

            #self.psk_layer.loadNamedStyle('styles/por_mapa.qml')

            self.jp_layer.setCrs(self.crs)

            self.dockwidget.output_working_on.setText(u"generuji vrstvu JP")


            self.populate_layer('ODD/DIL/POR/JP', self.jp_layer)

            #index nepridam, je to jen kartoska

            QgsMapLayerRegistry.instance().addMapLayer(self.jp_layer, False)
            #self.por_mapa_group.addLayer(self.jp_layer)
            self.bzl_jp_op_mapa_group.insertLayer(0, self.jp_layer)
            try:
                a=1

            except:
                QMessageBox.critical(QDialog()
                        ,u"Chyba vytváření JP",u"nepodařilo se vytvořit vrstvu JP")


            #------

            #op
            self.op_layer = QgsVectorLayer('Multipolygon'
                    , 'OP', 'memory')

            #self.psk_layer.loadNamedStyle('styles/por_mapa.qml')

            self.op_layer.setCrs(self.crs)

            self.dockwidget.output_working_on.setText(u"generuji vrstvu OP")

            #try:

            self.populate_layer('ODD/DIL/POR/OP', self.op_layer)

            #index nepridam, je to jen kartoska

            QgsMapLayerRegistry.instance().addMapLayer(self.op_layer, False)
            #self.por_mapa_group.addLayer(self.op_layer)
            self.bzl_jp_op_mapa_group.insertLayer(0, self.op_layer)

            try:
                a=1

            except:
                QMessageBox.critical(QDialog()
                        ,u"Chyba vytváření OP",u"nepodařilo se vytvořit vrstvu OP")


            #------
            self.bzl_jp_op_mapa_group.setVisible(Qt.Unchecked)



            lhc_list = [self.lhc.get('LHC_KOD')]
            self.dockwidget.input_lhc.clear()
            self.dockwidget.input_lhc.addItems(lhc_list)

            #nastavit komba na zacatek
            self.select_lhc()
            self.select_odd()
            self.select_dil()
            self.select_por()
            self.select_psk()

    def select_lhc(self):
        self.dockwidget.input_odd.clear()
        self.dockwidget.input_dil.clear()
        self.dockwidget.input_por.clear()
        self.dockwidget.input_psk.clear()

        self.dockwidget.input_odd.addItems(
                [ odd.get('ODD') for odd in self.lhc.xpath('ODD')]
                )

    def select_odd(self):
        self.odd = self.lhc.find("ODD[@ODD='%s']"%self.dockwidget.input_odd.currentText())

        self.dockwidget.input_dil.clear()
        self.dockwidget.input_por.clear()
        self.dockwidget.input_psk.clear()
        self.dockwidget.input_dil.addItems(
                [ dil.get('DIL') for dil in self.odd.xpath('DIL')]
                )

        self.jprl = (
                self.lhc.get('LHC_KOD')
                , self.odd.get('ODD'))

        #zrus vybrane graficky
        self.psk_layer.setSelectedFeatures([])

        #vyber
        request = QgsFeatureRequest().setFilterExpression( 
                "lhc_kod = '%s' AND odd = '%s'"%
                self.jprl)

        it = self.psk_layer.getFeatures( request )
        self.psk_layer.setSelectedFeatures([f.id() for f in it])

        box = self.psk_layer.boundingBoxOfSelected()
        self.iface.mapCanvas().setExtent(box)
        self.iface.mapCanvas().refresh()

    def select_dil(self):
        self.dil = self.odd.find("DIL[@DIL='%s']"%self.dockwidget.input_dil.currentText())

        self.dockwidget.input_por.clear()
        self.dockwidget.input_psk.clear()
        self.dockwidget.input_por.addItems(
                [ por.get('POR') for por in self.dil.xpath('POR')]
                )


        self.jprl = (
                self.lhc.get('LHC_KOD')
                , self.odd.get('ODD')
                , self.dil.get('DIL'))

        #zrus vybrane graficky
        self.psk_layer.setSelectedFeatures([])

        #vyber
        request = QgsFeatureRequest().setFilterExpression( 
                "lhc_kod = '%s' AND odd = '%s' AND dil ='%s'"%
                self.jprl)

        it = self.psk_layer.getFeatures( request )
        self.psk_layer.setSelectedFeatures([f.id() for f in it])

        box = self.psk_layer.boundingBoxOfSelected()
        self.iface.mapCanvas().setExtent(box)
        self.iface.mapCanvas().refresh()

    def select_por(self):
        self.por = self.dil.find("POR[@POR='%s']"%self.dockwidget.input_por.currentText())

        self.dockwidget.input_psk.clear()
        self.dockwidget.input_psk.addItems(
                [ psk.get('PSK') for psk in self.por.xpath('PSK')]
                )


        self.jprl = (
                self.lhc.get('LHC_KOD')
                , self.odd.get('ODD')
                , self.dil.get('DIL')
                , self.por.get('POR'))

        #zrus vybrane graficky
        self.psk_layer.setSelectedFeatures([])

        #vyber
        request = QgsFeatureRequest().setFilterExpression( 
                "lhc_kod = '%s' AND odd = '%s' AND dil ='%s' AND por = '%s'"%
                self.jprl)

        it = self.psk_layer.getFeatures( request )
        self.psk_layer.setSelectedFeatures([f.id() for f in it])

        box = self.psk_layer.boundingBoxOfSelected()
        self.iface.mapCanvas().setExtent(box)
        self.iface.mapCanvas().refresh()

        #self.select_psk() #workaround kvuli 


    def select_psk(self):

        self.psk = self.por.find("PSK[@PSK='%s']"%self.dockwidget.input_psk.currentText())

        self.jprl = (
                self.lhc.get('LHC_KOD')
                , self.odd.get('ODD')
                , self.dil.get('DIL')
                , self.por.get('POR')
                , self.psk.get('PSK'))

        #zrus vybrane graficky
        self.psk_layer.setSelectedFeatures([])

        #vyber
        request = QgsFeatureRequest().setFilterExpression( 
                "lhc_kod = '%s' AND odd = '%s' AND dil ='%s' AND por = '%s' AND psk = '%s'"%
                self.jprl)

        it = self.psk_layer.getFeatures( request )
        self.psk_layer.setSelectedFeatures([f.id() for f in it])

        box = self.psk_layer.boundingBoxOfSelected()
        self.iface.mapCanvas().setExtent(box)
        self.iface.mapCanvas().refresh()

    def show_hk(self):
        #nejdriv zjistim, jestli je vybrany nejaky prvek graficky
        #pak musim u vyberu pomoci roletek dat odselektovani vseho

        if len(self.psk_layer.selectedFeatures()) == 0 and len(self.jprl) < 5:
            QMessageBox.critical(QDialog()
                    ,u"Chyba výběru",u"Není vybrána žádná porostní skupina")

            return(None)

        if len(self.psk_layer.selectedFeatures()) > 0: #musi bejt prave jeden
            #kdyz je jich vic, vem prvni
            selected_psk = self.psk_layer.selectedFeatures()[0]
            self.jprl = (selected_psk['lhc_kod']
                    , selected_psk['odd']
                    , selected_psk['dil']
                    , selected_psk['por']
                    , selected_psk['psk'])

            #nastavim comba
            index = self.dockwidget.input_lhc.findText(selected_psk['lhc_kod'])
            if index >= 0:
                self.dockwidget.input_lhc.setCurrentIndex(index)

            self.select_lhc()

            index = self.dockwidget.input_odd.findText(selected_psk['odd'])
            if index >= 0:
                self.dockwidget.input_odd.setCurrentIndex(index)

            self.select_odd()

            index = self.dockwidget.input_dil.findText(selected_psk['dil'])
            if index >= 0:
                self.dockwidget.input_dil.setCurrentIndex(index)

            self.select_dil()

            index = self.dockwidget.input_por.findText(selected_psk['por'])
            if index >= 0:
                self.dockwidget.input_por.setCurrentIndex(index)

            self.select_por()

            index = self.dockwidget.input_psk.findText(selected_psk['psk'])
            if index >= 0:
                self.dockwidget.input_psk.setCurrentIndex(index)

            self.select_psk()

            #self.psk_layer.setSelectedFeatures([])



        if self.hk_widget == None:
            self.hk_widget = hk_displayDockWidget()

        self.iface.addDockWidget(Qt.TopDockWidgetArea, self.hk_widget)

        self.result = self.transform(self.root
                , ODD="'%s'"%self.jprl[1]
                , DIL="'%s'"%self.jprl[2]
                , POR="'%s'"%self.jprl[3]
                , PSK="'%s'"%self.jprl[4])

        self.hk_widget.webView.setHtml(
                etree.tostring(self.result)
                )

        self.hk_widget.show()



    

    #--------------------------------------------------------------------------
    def run(self):
        """Run method that loads and starts the plugin"""

        if not self.pluginIsActive:
            self.pluginIsActive = True

            #print "** STARTING islh_parser"

            # dockwidget may not exist if:
            #    first run of plugin
            #    removed on close (see self.onClosePlugin method)
            if self.dockwidget == None:
                # Create the dockwidget (after translation) and keep reference
                self.dockwidget = islh_parserDockWidget()

            # connect to provide cleanup on closing of dockwidget
            self.dockwidget.closingPlugin.connect(self.onClosePlugin)

            # show the dockwidget
            # TODO: fix to allow choice of dock location
            self.iface.addDockWidget(Qt.LeftDockWidgetArea, self.dockwidget)
            self.dockwidget.show()


            #buttons actions
            self.dockwidget.input_file.clear()
            self.dockwidget.input_file_button.clicked.connect(self.select_input_xml)

            self.dockwidget.input_read.clicked.connect(self.read_islh)

            self.dockwidget.input_lhc.activated.connect(self.select_lhc)
            self.dockwidget.input_odd.activated.connect(self.select_odd)
            self.dockwidget.input_dil.activated.connect(self.select_dil)
            self.dockwidget.input_por.activated.connect(self.select_por)
            self.dockwidget.input_psk.activated.connect(self.select_psk)


            self.dockwidget.input_hk_button.clicked.connect(self.show_hk)

            #load xslt stuff

            self.ns = etree.FunctionNamespace("http://ciselniky")
            self.ns.prefix = "cis"
            self.ns['lesni_oblast'] = ciselniky.lesni_oblast
            self.ns['slt'] = ciselniky.slt
            self.ns['katuze'] = ciselniky.katuze
            self.ns['lvs'] = ciselniky.lvs
            self.ns['zvl_statut'] = ciselniky.zvl_statut

            self.xslt_root = etree.XML(open('%s/xslt/hk.xsl'%self.plugin_dir,'r').read())
            self.transform = etree.XSLT(self.xslt_root)

            #nastavim barvu na neco, co neni v por mape
            self.iface.mapCanvas().setSelectionColor(QColor('#f40'))

            from karto_fce import *


    #----------------------------------------------------
    #plugin logic
    def load_xml(self):
        """:param f: file with islh xml data"""
        self.doc = etree.parse(self.f)
        self.root = self.doc.getroot()
        self.lhc = self.root.find("./LHC")

    def populate_layer(self, PATH, layer):
        """return layer with psk as geoJSON"""

        layer_data = self.lhc.xpath(PATH)

        if not layer_data:
            return(None)

        featureCount = len(layer_data)
        self.dockwidget.progressBar.setRange(0, featureCount)
        self.progres = iter(range(0, featureCount))

        pr = layer.dataProvider()

        attnames = [k for k in layer_data[0].attrib.keys()]

        tag = layer_data[0].tag

        if tag in ['PSK', 'BZL', 'JP', 'OP']:
            attnames = ['lhc_kod','odd','dil','por'] + attnames
            
        if tag == 'PSK':
            attnames.append('etz')

        pr.addAttributes(
            [QgsField(k
                , QVariant.String
                ) for k in attnames]
            )
                

                
        layer.updateFields()

        geom_tag = {
                'PSK':'PSK_OBRAZ'
                , 'BZL':'BZL_OBRAZ'
                , 'JP':'JP_OBRAZ'
                , 'OP':'OP_OBRAZ'
                , 'KLO':'LIN_OBRAZ'
                , 'KTO':'TXT_OBRAZ'
                , 'KBO':'BOD_OBRAZ'
                , 'KPO':'PLO_OBRAZ'
                }[tag]

        for feature_data in layer_data:
            feature = QgsFeature()
            
            if tag in ['BZL', 'JP', 'OP']:
                feature.setAttributes([
                        feature_data.find('../../../..').get('LHC_KOD')
                        , feature_data.find('../../..').get('ODD')
                        , feature_data.find('../..').get('DIL')
                        , feature_data.find('..').get('POR')]
                    +[feature_data.get(a) for a in attnames if a not in [
                        'lhc_kod', 'odd', 'dil', 'por']
                    ])
            elif tag == 'PSK':
                feature.setAttributes([
                        feature_data.find('../../../..').get('LHC_KOD')
                        , feature_data.find('../../..').get('ODD')
                        , feature_data.find('../..').get('DIL')
                        , feature_data.find('..').get('POR')]
                    +[feature_data.get(a) for a in attnames if a not in [
                        'lhc_kod', 'odd', 'dil', 'por','etz']]
                    #+ [ json.dumps(dict(etz.attrib)) for etz in feature_data.xpath('ETZ')]
                    + [json.dumps([dict(etz.attrib) for etz in feature_data.xpath('ETZ')])]
                    )
            else:
                feature.setAttributes([feature_data.get(a) for a in attnames])

            try:
                feature.setGeometry(
                    islh_parser.parse_geometry(feature_data.find(geom_tag))
                    )
            except TypeError:
                QMessageBox.critical(QDialog()
                        ,u"Prvek se nepodařilo vytvořit",u"%s"%etree.tostring(feature_data))


            pr.addFeatures([feature])

            #posunu progres bar
            self.dockwidget.progressBar.setValue(self.progres.next())

        #nakonec se mrknu, esli je PSK ZNACKA
        if tag == 'PSK' and not 'PSK_ZNACKA' in attnames:
            layer.addExpressionField('znacka(etz)', QgsField('PSK_ZNACKA',QVariant.Int))

            
    #------------------------------------
    ##geometry
    @staticmethod
    def parse_geometry(gr):
        """node s ISLH grafikou"""

        g = gr[0] #obraz ma jen jeden prvek

        geom = (
                QgsGeometry.fromPoint(islh_parser.parse_point(g)) if g.tag == 'B'
                else QgsGeometry.fromPolyline(islh_parser.parse_line(g)) if g.tag == 'L'
                else QgsGeometry.fromMultiPoint(islh_parser.parse_multipoint(g)) if g.tag == 'MB'
                else QgsGeometry.fromMultiPolyline(islh_parser.parse_multiline(g)) if g.tag == 'ML'
                else QgsGeometry.fromPolygon(islh_parser.parse_polygon(g)) if g.tag == 'P'
                else QgsGeometry.fromMultiPolygon(islh_parser.parse_multipolygon(g)) if g.tag == 'MP' 
                else None) 

        return(geom)

    @staticmethod
    def parse_point(p):
        """udělá z bodu ogr bod"""

        (y,x) = map(lambda x: -float(x), p.get('S').split('$'))
        return(
                QgsPoint(x,y)
                )

    @staticmethod
    def parse_line(l):
        """udělá z bodu ogr bod"""

        return(
                [islh_parser.parse_point(point) for point in l.xpath('B')]
                )

    @staticmethod
    def parse_multipoint(l):

        return(
                [islh_parser.parse_point(point) for point in l.xpath('B')]
                )

    @staticmethod
    def parse_multiline(p):

        return(
                [islh_parser.parse_line(line) for line in p.xpath('L')]
                )

    @staticmethod
    def parse_polygon(p):

        return(
                [islh_parser.parse_line(line) for line in p.xpath('L')]
                )


    @staticmethod
    def parse_multipolygon(p):
        return(
                [islh_parser.parse_polygon(polygon) for polygon in p.xpath('P')]
                )