def testRepack(self): vl = QgsVectorLayer(u'{}|layerid=0'.format(self.repackfile), u'test', u'ogr') ids = [f.id() for f in vl.getFeatures(QgsFeatureRequest().setFilterExpression('pk=1'))] vl.setSelectedFeatures(ids) assert vl.selectedFeaturesIds() == ids, vl.selectedFeaturesIds() assert vl.pendingFeatureCount() == 5, vl.pendingFeatureCount() assert vl.startEditing() assert vl.deleteFeature(3) assert vl.commitChanges() assert vl.selectedFeatureCount() == 0 or vl.selectedFeatures()[0]['pk'] == 1
def testRepack(self): vl = QgsVectorLayer('{}|layerid=0'.format(self.repackfile), 'test', 'ogr') ids = [f.id() for f in vl.getFeatures(QgsFeatureRequest().setFilterExpression('pk=1'))] vl.selectByIds(ids) self.assertEqual(vl.selectedFeatureIds(), ids) self.assertEqual(vl.featureCount(), 5) self.assertTrue(vl.startEditing()) self.assertTrue(vl.deleteFeature(3)) self.assertTrue(vl.commitChanges()) self.assertTrue(vl.selectedFeatureCount() == 0 or vl.selectedFeatures()[0]['pk'] == 1)
def testRepack(self): vl = QgsVectorLayer("{}|layerid=0".format(self.repackfile), "test", "ogr") ids = [f.id() for f in vl.getFeatures(QgsFeatureRequest().setFilterExpression("pk=1"))] vl.selectByIds(ids) self.assertEqual(vl.selectedFeaturesIds(), ids) self.assertEqual(vl.pendingFeatureCount(), 5) self.assertTrue(vl.startEditing()) self.assertTrue(vl.deleteFeature(3)) self.assertTrue(vl.commitChanges()) self.assertTrue(vl.selectedFeatureCount() == 0 or vl.selectedFeatures()[0]["pk"] == 1)
def seleccionaelementosigpac(datosfila): rutacarpetarecintos=r"O:/sigmena/carto/SIGPAC/Sigpac_2020/Recintos/" rutacapadesalida="c:/work/micapatierra.shp" layersalida = QgsVectorLayer(rutacapadesalida, "CapaTierra", 'ogr') pr = layersalida.dataProvider() mun=str(datosfila[0]*1000+datosfila[1]) agr=str(datosfila[2]) zon=str(datosfila[3]) pol=str(datosfila[4]) par=str(datosfila[5]) rec=str(datosfila[6]) caparecintos=os.path.join(rutacarpetarecintos,"RECFE20_"+mun+".shp") print(caparecintos) layer = QgsVectorLayer(caparecintos, mun, 'ogr') #QgsProject.instance().addMapLayers([layer]) layer.selectByExpression("\"C_POLIGONO\" = '{}' ".format(pol)+" AND \"C_PARCELA\" = '{}'".format(par),QgsVectorLayer.SetSelection) #selection = layer.selectByExpression("\"C_POLIGONO\" = {} ".format(pol)+" AND \"C_PARCELA\" = {}".format(par),QgsVectorLayer.SetSelection) print("\"C_POLIGONO\" = '{}' ".format(pol)+" AND \"C_PARCELA\" = '{}'".format(par)) selection = layer.selectedFeatures() #creo la nueva capa con la seleccion #QgsVectorFileWriter.writeAsVectorFormat(layer, output_path, "CP120", layer.crs(), "ESRI Shapefile", onlySelected=True) para guardar los seleccionados como shape #lyr9=QgsVectorLayer(output_path,"Sigpac_"+str(mun)+"_"+str(pol)+"_"+str(par),"ogr") para crear un shape si despues queremos guardarlo en el #lyr9=processing.run('native:saveselectedfeatures', { "INPUT": layer, "OUTPUT": "memory:"+"Sigpac_"+str(mun)+"_"+str(pol)+"_"+str(par) })['OUTPUT'] para guardalo en una capa temporal. #deberia copiar lo seleccionado y guardarlo en la capa de destino. de momento supongo que tienen la misma estructura #primero copiar los atributos de la capa de origen, todos #despues copiar el feature de la capa de origen #ultimo pegar la feature a la capa de destino y finalmente los atributos. for feature in selection: attrs = feature.attributes() #si no quisiera todos puedo hacerlo asipor indice #idx = layer.fieldNameIndex('name') #print(feature.attributes()[idx]) #o por nombre #name = f.attribute('NAME') geom = feature.geometry() newfet = QgsFeature() newfet.setGeometry(geom) layersalida.updateExtents() newfet.setAttributes(attrs) layersalida.updateFields() pr.addFeatures([newfet])
def testRepack(self): vl = QgsVectorLayer('{}|layerid=0'.format(self.repackfile), 'test', 'ogr') ids = [ f.id() for f in vl.getFeatures( QgsFeatureRequest().setFilterExpression('pk=1')) ] vl.selectByIds(ids) self.assertEqual(vl.selectedFeatureIds(), ids) self.assertEqual(vl.featureCount(), 5) self.assertTrue(vl.startEditing()) self.assertTrue(vl.deleteFeature(3)) self.assertTrue(vl.commitChanges()) self.assertTrue(vl.selectedFeatureCount() == 0 or vl.selectedFeatures()[0]['pk'] == 1)
def testRepack(self): vl = QgsVectorLayer(u'{}|layerid=0'.format(self.repackfile), u'test', u'ogr') ids = [ f.id() for f in vl.getFeatures( QgsFeatureRequest().setFilterExpression('pk=1')) ] vl.setSelectedFeatures(ids) assert vl.selectedFeaturesIds() == ids, vl.selectedFeaturesIds() assert vl.pendingFeatureCount() == 5, vl.pendingFeatureCount() assert vl.startEditing() assert vl.deleteFeature(3) assert vl.commitChanges() assert vl.selectedFeatureCount() == 0 or vl.selectedFeatures( )[0]['pk'] == 1
def returnSelectedPUIDDict(setupObject): selectedPUIDDict = dict() puLayer = QgsVectorLayer(setupObject.puPath, 'Planning units', 'ogr') iface.setActiveLayer(puLayer) puLayer = iface.activeLayer() provider = puLayer.dataProvider() idFieldIndex = provider.fieldNameIndex('Unit_ID') statusFieldIndex = provider.fieldNameIndex('Status') selectedPUs = puLayer.selectedFeatures() for aPU in selectedPUs: puID = int(aPU.attributes()[idFieldIndex]) puStatus = str(aPU.attributes()[statusFieldIndex]) selectedPUIDDict[puID] = puStatus return selectedPUIDDict
def is_valid_polygon_selection(layer: QgsVectorLayer) -> bool: """"Checks if the layer type is polygon and if anything is selected.""" if layer.geometryType() != QgsWkbTypes.PolygonGeometry: msg = QMessageBox() msg.setIcon(QMessageBox.Information) msg.setText("Unsupported layer type!") msg.setInformativeText("Please select polygon layer.") msg.setWindowTitle("Info") msg.setStandardButtons(QMessageBox.Ok) msg.exec_() return False if not layer.selectedFeatures(): msg = QMessageBox() msg.setIcon(QMessageBox.Information) msg.setText("Please select at least one feature!") msg.setWindowTitle("Info") msg.setStandardButtons(QMessageBox.Ok) msg.exec_() return False return True
def unionespacial(self, event): # Datos de viviendas de catastro bu = self.input_gml.filePath() # Datos de perímetros de núcleos de población EIEL nucleo = self.input_shp.filePath() # Unir aributos por localización: Viviendas y núcleos bu_output = 'C:/V_EIEL/viviendasclasificadas.shp' processing.run( "qgis:joinattributesbylocation", { 'INPUT': bu, 'JOIN': nucleo, 'PREDICATE': 0, 'JOIN_FIELDS': ['CODIGO', 'DENOMINACI'], 'METHOD': 0, 'PREFIX': 'NU_', 'OUTPUT': bu_output }) joinat = QgsVectorLayer(bu_output, "Viviendas clasificadas nucleo", "ogr") QgsProject.instance().addMapLayers([joinat]) # Selecciono registros sin clasificar de la capa de viviendas clasificadas utilizando la capa núcleos expresion = "NU_CODIGO is NULL" joinat.selectByExpression(expresion, QgsVectorLayer.SetSelection) #Genero el buffer de la capa núcleos nucleo = self.input_shp.filePath() file_output = 'C:/V_EIEL/buffernucleo.shp' processing.run( "native:buffer", { 'INPUT': nucleo, 'DISTANCE': 200, 'SEGMENTS': 10, 'DISSOLVE': False, 'END_CAP_STYLE': 0, 'JOIN_STYLE': 0, 'MITER_LIMIT': 1, 'OUTPUT': file_output }) lyrBuffer = QgsVectorLayer(file_output, "Buffer nucleo", "ogr") QgsProject.instance().addMapLayers([lyrBuffer]) # Unión espacial de los registros seleccionados de joinat con buffer bu_output_2 = 'C:/V_EIEL/viviendasclasificadas_2.shp' processing.run( "qgis:joinattributesbylocation", { 'INPUT': QgsProcessingFeatureSourceDefinition( 'Viviendas clasificadas nucleo', True), 'JOIN': lyrBuffer, 'PREDICATE': 0, 'JOIN_FIELDS': ['CODIGO', 'DENOMINACI'], 'METHOD': 0, 'PREFIX': 'NU_', 'OUTPUT': bu_output_2 }) joinat_2 = QgsVectorLayer(bu_output_2, "Viviendas clasificadas buffer", "ogr") QgsProject.instance().addMapLayers([joinat_2]) joinat.removeSelection() joinat.commitChanges() # El resto de viviendas no clasificadas mediante la union con capa buffer pasan a estar en diseminado joinat_2 = iface.activeLayer() expresion_2 = "NU_CODIGO_ is NULL" joinat_2.selectByExpression(expresion_2, QgsVectorLayer.SetSelection) joinat_2.startEditing() n = joinat_2.selectedFeatureCount() for i in range(0, n): diseminado = joinat_2.selectedFeatures() viv_diseminado = diseminado[i] viv_diseminado.setAttribute("NU_CODIGO_", "99") viv_diseminado["NU_CODIGO_"] = "99" joinat_2.updateFeature(viv_diseminado) viv_diseminado.setAttribute("NU_DENOM_1", "DISEMINADO") viv_diseminado["NU_DENOM_1"] = "DISEMINADO" joinat_2.updateFeature(viv_diseminado) joinat_2.commitChanges() joinat_2.removeSelection() joinat_2.startEditing() features = joinat_2.getFeatures() for feature in features: feature.setAttribute(feature.fieldNameIndex('NU_CODIGO'), feature['NU_CODIGO_']) feature.setAttribute(feature.fieldNameIndex('NU_DENOMIN'), feature['NU_DENOM_1']) joinat_2.updateFeature(feature) joinat_2.commitChanges() joinat_2.removeSelection() # Elimino los campos NU_CODIGO_ y NU_DENOM_1 para conservar la misma estructura en las dos capas joint attributes joinat_2.startEditing() joinat_2.deleteAttributes([27, 28]) joinat_2.updateFields() joinat_2.commitChanges() # Creo la capa union de Viviendas clasificadas nucleo(solo la selección) y viviendas clasificadas buffer # En primer lugar extraigo las viviendas clasificadas en la union con la capa nucleos expresion_3 = "NU_CODIGO is not NULL" joinat.selectByExpression(expresion_3, QgsVectorLayer.SetSelection) joinat.startEditing() seleccion = 'C:/V_EIEL/viviendasclasificadas_seleccion.shp' processing.run("native:saveselectedfeatures", { 'INPUT': joinat, 'OUTPUT': seleccion }) nucleo_seleccion = QgsVectorLayer( seleccion, "Viviendas clasificadas nucleo seleccion", "ogr") QgsProject.instance().addMapLayers([nucleo_seleccion]) joinat.removeSelection() resultado = 'C:/V_EIEL/viviendasclasificadas_resultado.shp' processing.run("native:mergevectorlayers", { 'LAYERS': [nucleo_seleccion, joinat_2], 'OUTPUT': resultado }) resultado_merge = QgsVectorLayer(resultado, "Viviendas clasificadas", "ogr") QgsProject.instance().addMapLayers([resultado_merge]) # Suprimo del proyecto todas las capas intermedias generadas en el proceso QgsProject.instance().removeMapLayer(nucleo_seleccion) QgsProject.instance().removeMapLayer(joinat_2) QgsProject.instance().removeMapLayer(joinat) QgsProject.instance().removeMapLayer(lyrBuffer) #Representación categorizada de la capa resultado #Valores únicos resultado_merge = iface.activeLayer() valoresnucleo = [] unico = resultado_merge.dataProvider() campos = unico.fields() id = campos.indexFromName('NU_DENOMIN') valoresnucleo = unico.uniqueValues(id) #Creación de categorías categorias = [] for valornucleo in valoresnucleo: # inicio el valor de símbolo por defecto para la geometría tipo symbol = QgsSymbol.defaultSymbol(resultado_merge.geometryType()) # configuración de capa de simbología layer_style = {} layer_style['color'] = '%d, %d, %d' % (random.randint( 0, 256), random.randint(0, 256), random.randint(0, 256)) layer_style['outline'] = '#000000' symbol_layer = QgsSimpleFillSymbolLayer.create(layer_style) # sustitución de simbología por defecto por simbología configurada if symbol_layer is not None: symbol.changeSymbolLayer(0, symbol_layer) # creación de objeto renderer categoria = QgsRendererCategory(valornucleo, symbol, str(valornucleo)) # generación de entrada para la lista de categorías categorias.append(categoria) renderer = QgsCategorizedSymbolRenderer('NU_DENOMIN', categorias) # asignación del renderer a la capa if renderer is not None: resultado_merge.setRenderer(renderer) resultado_merge.triggerRepaint() # Cálculo de estadísticas resultado = iface.activeLayer() estadisticas = 'C:/V_EIEL/estadisticas.csv' processing.run( "qgis:statisticsbycategories", { 'CATEGORIES_FIELD_NAME': ['NU_DENOMIN', 'NU_CODIGO'], 'INPUT': 'Viviendas clasificadas', 'OUTPUT': 'C:/V_EIEL/estadisticas.csv', 'VALUES_FIELD_NAME': 'numberOfDw', }) # Cargo datos calculados de estadísticas de distribución de viviendas en QTableWidget tbl_resultados with open(estadisticas, 'r') as leer_estadisticas: registros = leer_estadisticas.read().splitlines() contar = 0 #Descarto la primera linea del archivo por contener las cabeceras de los campos for registro in registros: r = 0 if contar > 0: campos = registro.split(',') #Puesto que el campo codigo se almacena con "" las elimino para que no aparezcan en la tabla sc = campos[1].lstrip('"').rstrip('"') #Cargo datos del csv en Qtable widget self.tbl_resultados.insertRow(r) self.tbl_resultados.setItem(r, 0, QTableWidgetItem(str(sc))) self.tbl_resultados.setItem( r, 1, QTableWidgetItem(str(campos[0]))) self.tbl_resultados.setItem( r, 2, QTableWidgetItem(str(campos[7]))) r = r + 1 contar = contar + 1 # Rastreo de registros duplicados en capa resultado por intersectar con dos buffer o dos núcleos features = resultado_merge.getFeatures() referencias = [] referencias_dup = [] for f in features: idr = f.fieldNameIndex('reference') referencia = f.attribute(idr) if referencia not in referencias: referencias.append(referencia) else: referencias_dup.append(referencia) self.lst_duplicados.addItems(referencias_dup) total_duplicados = self.lst_duplicados.count() self.text_duplicados.append(str(total_duplicados))
def run(self): """ global almacen #coloco el puntero arriba del todo QgsProject.instance().layerTreeRegistryBridge().setLayerInsertionPoint( QgsProject.instance().layerTreeRoot(), 0 ) #genero una lista con los sistemas de referencia misdatos=[["Etrs89 Zona30 (25830)","25830"],["Etrs89 Zona29 (25829)","25829"],["ED50 Zona30 (23030)","23030"],["ED50_Zona29 (23029)","23029"],["WGS84 geograficas sexagesimales(4326)","4326"], ["WGS84 geograficas centesimales(4326)","4258"]] #self.dlg.comboBox_src.clear() for element in misdatos: self.dlg.comboBox_src.addItem( element[0]) # Create the dialog with elements (after translation) and keep reference # Only create GUI ONCE in callback, so that it will only load when the plugin is started if self.first_start == True: self.first_start = False #leo la cache rutacache=os.path.join(QgsApplication.qgisSettingsDirPath(),r"python\plugins\zoomSigmena\cache.txt") if os.path.isfile(rutacache) ==True: filecache = open(rutacache, "r") filecacheleido=filecache.readlines() try: import ast almacen= ast.literal_eval((filecacheleido[0].replace('\n','')).replace(" [[","[[").replace("]] ","]]"))#.split(',')) cache_utm=int(almacen[0]) cache_geo=int(almacen[1]) cache_escala=almacen[2] print(cache_escala) print (almacen) #miscomarcas=(filecacheleido[3].replace('\n','')).strip('][').split(',') #convierto una str en una list #mismunicipios=ast.literal_eval((filecacheleido[4].replace('\n','')).replace(" [[","[[").replace("]] ","]]"))#.split(',')) #convierto una str en una list filecache.close() except: print("esta no encuentra el file cache") self.dlg.lineEdit_escala.setText(str(cache_escala)) self.dlg.checkBox_utm.setChecked(cache_utm) self.dlg.checkBox_geo.setChecked(cache_geo)""" # show the dialog #self.dlg.show() # Run the dialog event loop result = self.dlg.exec_() # See if OK was pressed if result: print("empezamos") #habria que hacer un repair antes de cada una de ellas por si acaso. #filtrar las manchas que se van a matar en la proxima semana. OK #lo primero seria ver la interseccion de la capa de las manchas con la capa de montes. almacenar los resultados en una variable OK #lo siguiente leer la tabla de los que si han pagado #finalmente para cada mancha en las proximas fechas ver cuales no han pagado. #definovariables rutacapademanchas = r"O:/sigmena/usuarios/caza_y_pesca/manchas 2020-2021/Manchas_2020-2021.shp" #r"R:/SIGMENA/prueba/2021/01/15/manchas.shp" columnafecha = 'Fecha_caz' columnamatricula = 'P_Matricul' rutacapademontes = r"O:/sigmena/carto/PROPIEDA/MONTES/PERTENEN/catalogo/42_mup_catalogo_ex_etrs89.shp" rutatablalicencias = r"R:\SIGMENA\prueba\2020\11\20\mitablalicencias.xlsx" hojalicencias = 'hojacaza' columnamontes = 'columnaetiqueta' diasaconsiderar = 7 #supongo que querran hacerlo variable #leo la tabla excel PARA VER que montes han pagado___________________________________________________________________________________ listado_montes_pagado = [] #Abrimos el fichero excel documento_excel = xlrd.open_workbook(rutatablalicencias) hoja_de_interes = documento_excel.sheet_by_index(0) #Leemos el numero de filas y columnas de la hoja de libros filas = hoja_de_interes.nrows columnas = hoja_de_interes.ncols print("el excel tiene " + str(filas) + " filas y " + str(columnas) + " columnas") for i in range( 1, hoja_de_interes.nrows ): #Ignoramos la primera fila, que indica los campos #for j in range(libros.ncols): linea = float( repr(hoja_de_interes.cell_value(i, 1)) ) #columna que tiene la etiqueta de los montes, con indice cero listado_montes_pagado.append(linea) print("listado_montes_pagado") print(listado_montes_pagado) #leo la capa de manchas vlmanchas = QgsVectorLayer(rutacapademanchas, "Manchas", "ogr") #y la reparo proceso1 = processing.run("native:fixgeometries", { 'INPUT': rutacapademanchas, 'OUTPUT': 'TEMPORARY_OUTPUT' }) vlmanchas = proceso1['OUTPUT'] #y la de montes vlmontes = QgsVectorLayer(rutacapademontes, "Montes", "ogr") #miro las fechas from datetime import date import datetime today = date.today() hoy = today.strftime("%Y-%m-%d") # YY-mm-dd print("hoy=", hoy) fechalimite = today + datetime.timedelta(days=diasaconsiderar) print("fecha limite=", fechalimite) #selecciono las manchas que tengo que estudiar por fecha vlmanchas.selectByExpression( "\"{}\"".format(columnafecha) + " >= '{}' ".format(hoy) + " AND \"{}\"".format(columnafecha) + " <= '{}' ".format(fechalimite), QgsVectorLayer.SetSelection) selection = vlmanchas.selectedFeatures() QgsProject.instance().addMapLayer(vlmanchas) listadecotosaestudiar = [] #seleciono los montes que tocan con todas las manchas processing.run( 'qgis:selectbylocation', { 'INPUT': vlmontes, 'INTERSECT': vlmanchas, 'METHOD': 0, 'PREDICATE': [0] }) selection_montes = vlmontes.selectedFeatures() listademontesaestudiar = [] for feature in selection: #attrs = feature.attributes() #si no quisiera todos puedo hacerlo asipor indice idx = feature.fieldNameIndex('P_Matricul') #print(feature.attributes()[idx]) #o por nombre geom_1 = feature.geometry() for fea in selection_montes: geom_montes = fea.geometry() #tengo que ver cuales de esas manchas interseccionan con montes de up. if geom_1.intersects(geom_montes) is True: geom3 = geom_1.intersection( geom_montes ) #deberia calcular esta superficie de geom3 para ver si es despreciable area_ratio = 100.0 * geom3.area() / geom_1.area() #saco las columnas n_mon = fea[ "Etiqueta"] #etiqueta es la columna de la capa de montes con el nombre de los montes matricula = feature.attribute(columnamatricula) #veo si esta en la lista de los que han pagado if float(n_mon) not in listado_montes_pagado: print(" El " + str(round(area_ratio, 2)) + " % de la mancha del Coto " + feature.attributes()[idx] + " se encuentra en el MUP " + str(n_mon) + " que no ha pagado") listadecotosaestudiar.append(matricula) listademontesaestudiar.append(n_mon) #geom = feature.geometry() #podia sacar la superficie de interseccion para descartar los muy despreciables. de momento paso. print(listadecotosaestudiar) print(listademontesaestudiar) #for element in listademontesaestudiar: # if element not in listado_montes_pagado: """for registro in tabla.getFeatures(): print registro['Field1']""" """
def splitSelectedByNumber(self, layerName, div, method="h", tilt=90, checkNewShape=False, shpPath="result", checkExitingShape=False, checkResultToMap=True): global recurs recurs = 0 if layerName == "": QMessageBox.warning(iface.mainWindow(), "error", "At least a polygon layer must be selected.") return maplist = QgsMapLayerRegistry.instance().mapLayersByName(layerName) layer = maplist[0] if layer: #Gets layer CRS for new layer crs = layer.crs().description() if self.debug: print "Starting, Layer crs: " + crs # Create a new memory layer and add an area attribute polName = "%s_%s_%i" % (layerName, method, div) polyLayer = QgsVectorLayer("MultiPolygon?crs=" + crs, polName, "memory") polyLayer.dataProvider().addAttributes( [QgsField("strataArea", QVariant.Double)]) #QgsMapLayerRegistry.instance().addMapLayer(polyLayer) allFeatures = False if not layer.selectedFeatures(): layer.invertSelection() allFeatures = True #save original target area # origTargetArea=targetArea # Loop though all the selected features progressMessageBar = iface.messageBar().createMessage( "splitting...") self.progress = QProgressBar() self.progress.setAlignment(Qt.AlignLeft | Qt.AlignVCenter) self.progress.setMaximum(div * layer.selectedFeatureCount()) progressMessageBar.layout().addWidget(self.progress) iface.messageBar().pushWidget(progressMessageBar, iface.messageBar().INFO) self.progress.setValue(1) for feature in layer.selectedFeatures(): geom = feature.geometry() targetArea = geom.area() / div granularity = div * 2 if self.debug: print "Starting Number of original geoms: ", str( len(geom.asGeometryCollection())) if self.debug: print "Starting Number of part to split into: ", str( geom.area() / div) # div=round(geom.area()/origTargetArea) if div < 1: div = 1 if div > 1: # granularity=round(granulFactor*geom.area()/targetArea) # if self.debug: print "Granularity: ",granularity #Figure out direction to start with from cutting method #If alternating, start horizontally if tilt == 0 or tilt == 90: self.alternatingSlice(geom, polyLayer, targetArea, granularity, method, method) else: if method == "h": self.alternatingSliceTilt(geom, polyLayer, targetArea, granularity, tilt + 90) else: self.alternatingSliceTilt(geom, polyLayer, targetArea, granularity, tilt) else: self.addGeomToLayer(geom, polyLayer) polyLayer.commitChanges() self.progress.setValue(div * layer.selectedFeatureCount()) polyLayer.updateExtents() #if self.debug: print recurs if checkResultToMap: QgsMapLayerRegistry.instance().addMapLayer(polyLayer) if checkNewShape: QgsVectorFileWriter.writeAsVectorFormat( polyLayer, shpPath, 'utf-8', polyLayer.crs()) if checkExitingShape: polyLayer.selectAll() layer.dataProvider().addFeatures(polyLayer.selectedFeatures()) layer.updateExtents() layer.selectAll() layer.invertSelection() if allFeatures: layer.invertSelection() iface.messageBar().hide()
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')] )