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
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
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
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
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)
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
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
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())
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
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
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)
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
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
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)
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
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)
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
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
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()
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
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)
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
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)
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)
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
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
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
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
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
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
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)
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))
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 ")
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
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
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
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])
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')] )