4 votos

Reordenar capas en el índice de QGIS usando python

Estoy utilizando el siguiente código en una herramienta de script para importar un conjunto de shapefiles desde una carpeta especificada por el usuario, duplicar dos de las capas, aplicarles estilo a todas ellas y reordenarlas en el panel de capas.

El último fragmento de código, el que reordena las capas, no funciona.

Me aparece el siguiente error:

el nombre 'alayer' no está definido Ver log para más detalles

Lo que no entiendo es si divido el código en dos scripts separados, cargo/duplico/estilo las capas y luego ejecuto la sección de reordenar capas por separado, el código se ejecuta perfectamente.

¿En qué me equivoco?

Estoy ejecutando QGIS 2.14.8

    ##Select_MasterMap_Folder=folder

    import os,sys
    from qgis.core import*
    from PyQt4.QtCore import*
    from qgis.utils import*
    from qgis.gui import *
    import qgis

    source_dir=(Select_MasterMap_Folder)

    for files in os.listdir(source_dir):

            # load only the shapefiles
            if files.endswith("Area.shp"):
                vlayer = QgsVectorLayer(source_dir + "/" + files, files[0:11]+" "+files[11:15],  "ogr")

                # add layer to the registry
                QgsMapLayerRegistry.instance().addMapLayer(vlayer)

            if files.endswith("cLine.shp"):
                vlayer = QgsVectorLayer(source_dir + "/" + files, files[0:11]+" "+files[11:15], "ogr")

                # add layer to the registry
                QgsMapLayerRegistry.instance().addMapLayer(vlayer)

            if files.endswith("Point.shp"):
                vlayer = QgsVectorLayer(source_dir + "/" + files, files[0:11]+" "+files[11:16], "ogr")

                # add layer to the registry
                QgsMapLayerRegistry.instance().addMapLayer(vlayer)

            if files.endswith("Text.shp"):
                vlayer = QgsVectorLayer(source_dir + "/" + files, files[0:12]+" "+files[12:16], "ogr")

                # add layer to the registry
                QgsMapLayerRegistry.instance().addMapLayer(vlayer)

    canvas = qgis.utils.iface.mapCanvas()
    layers = canvas.layers()

    vl = QgsMapLayerRegistry.instance().mapLayersByName('Topographic Line')[0]
    iface.setActiveLayer(vl)
    iface = qgis.utils.iface; vl = iface.activeLayer(); iface.addVectorLayer(vl.source(), vl.name() + " copy", vl.providerType())

    vl = QgsMapLayerRegistry.instance().mapLayersByName('Topographic Area')[0]
    iface.setActiveLayer(vl)
    iface = qgis.utils.iface; vl = iface.activeLayer(); iface.addVectorLayer(vl.source(), vl.name() + " copy", vl.providerType())

    layer= QgsMapLayerRegistry.instance().mapLayersByName('Topographic Point')[0]
    iface.setActiveLayer(vl)
    layer.loadNamedStyle('P:/Office Admin/GIS/Templates/MasterMap styles for QGIS/Emapsite NEW MasterMap styles/1TopographicPoint.qml')
    layer= QgsMapLayerRegistry.instance().mapLayersByName('Cartographic Text')[0]
    iface.setActiveLayer(vl)
    layer.loadNamedStyle('P:/Office Admin/GIS/Templates/MasterMap styles for QGIS/Emapsite NEW MasterMap styles/2CartographicText.qml')
    layer= QgsMapLayerRegistry.instance().mapLayersByName('Topographic Line')[0]
    iface.setActiveLayer(vl)
    layer.loadNamedStyle('P:/Office Admin/GIS/Templates/MasterMap styles for QGIS/Emapsite NEW MasterMap styles/3TopographicLine.qml')
    layer= QgsMapLayerRegistry.instance().mapLayersByName('Topographic Line copy')[0]
    iface.setActiveLayer(vl)
    layer.loadNamedStyle('P:/Office Admin/GIS/Templates/MasterMap styles for QGIS/Emapsite NEW MasterMap styles/4TopographicLineCopy.qml')
    layer= QgsMapLayerRegistry.instance().mapLayersByName('Topographic Area')[0]
    iface.setActiveLayer(vl)
    layer.loadNamedStyle('P:/Office Admin/GIS/Templates/MasterMap styles for QGIS/Emapsite NEW MasterMap styles/5TopographicArea.qml')
    layer= QgsMapLayerRegistry.instance().mapLayersByName('Topographic Area copy')[0]
    iface.setActiveLayer(vl)
    layer.loadNamedStyle('P:/Office Admin/GIS/Templates/MasterMap styles for QGIS/Emapsite NEW MasterMap styles/6TopographicAreaCopy.qml')

    qgis.utils.iface.mapCanvas().refresh()

    canvas = qgis.utils.iface.mapCanvas()
    layers = canvas.layers()

    for i in layers:
      if i.name() == "Topographic Area":
        alayer = i
      elif i.name() == "Topographic Area copy":
        blayer = i

    root = QgsProject.instance().layerTreeRoot()

    # Move alayer
    myalayer = root.findLayer(alayer.id())
    myClone = myalayer.clone()
    parent = myalayer.parent()
    parent.insertChildNode(5, myClone)
    parent.removeChildNode(myalayer)

    # Move blayer
    myblayer = root.findLayer(blayer.id())
    myClone = myblayer.clone()
    parent = myblayer.parent()
    parent.insertChildNode(5, myClone)
    parent.removeChildNode(myblayer)

    canvas = qgis.utils.iface.mapCanvas()
    layers = canvas.layers()

    for i in layers:
      if i.name() == "Topographic Line":
        alayer = i
      elif i.name() == "Topographic Line copy":
        blayer = i

    root = QgsProject.instance().layerTreeRoot()

    # Move alayer
    myalayer = root.findLayer(alayer.id())
    myClone = myalayer.clone()
    parent = myalayer.parent()
    parent.insertChildNode(2, myClone)
    parent.removeChildNode(myalayer)

    # Move blayer
    myblayer = root.findLayer(blayer.id())
    myClone = myblayer.clone()
    parent = myblayer.parent()
    parent.insertChildNode(3, myClone)
    parent.removeChildNode(myblayer)

    for i in layers:
      if i.name() == "Cartographic Text":
        alayer = i
      elif i.name() == "Topographic Point":
        blayer = i

    root = QgsProject.instance().layerTreeRoot()

    # Move alayer
    myalayer = root.findLayer(alayer.id())
    myClone = myalayer.clone()
    parent = myalayer.parent()
    parent.insertChildNode(1, myClone)
    parent.removeChildNode(myalayer)

    # Move blayer
    myblayer = root.findLayer(blayer.id())
    myClone = myblayer.clone()
    parent = myblayer.parent()
    parent.insertChildNode(0, myClone)
    parent.removeChildNode(myblayer)

qgis.utils.iface.mapCanvas().refresh()

0 votos

¿Puede identificar en qué línea se produce el error?

0 votos

File "<string>", line 83, in <module> NameError: el nombre 'alayer' no está definido.

4voto

Mue Puntos 2469

He editado un poco tu código para que contenga un par de funciones que llamen a éstas en lugar de repetir líneas de código similares para cada capa. Sólo he probado las funciones que carga el estilo y reordena las capas que parece funcionar. Asumo que este código no está probado pero espero que esto ayude a evitar el error:

##Select_MasterMap_Folder=folder

import os,sys
from qgis.core import*
from PyQt4.QtCore import*
from qgis.utils import*
from qgis.gui import *
import qgis

source_dir=(Select_MasterMap_Folder)
for files in os.listdir(source_dir):
    # load only the shapefiles
    if files.endswith("Area.shp"):
        vlayer = QgsVectorLayer(source_dir + "/" + files, files[0:11]+" "+files[11:15],  "ogr")
        # add layer to the registry
        QgsMapLayerRegistry.instance().addMapLayer(vlayer)
    if files.endswith("cLine.shp"):
        vlayer = QgsVectorLayer(source_dir + "/" + files, files[0:11]+" "+files[11:15], "ogr")
        QgsMapLayerRegistry.instance().addMapLayer(vlayer)
    if files.endswith("Point.shp"):
        vlayer = QgsVectorLayer(source_dir + "/" + files, files[0:11]+" "+files[11:16], "ogr")
        QgsMapLayerRegistry.instance().addMapLayer(vlayer)
    if files.endswith("Text.shp"):
        vlayer = QgsVectorLayer(source_dir + "/" + files, files[0:12]+" "+files[12:16], "ogr")
        QgsMapLayerRegistry.instance().addMapLayer(vlayer)

vl = QgsMapLayerRegistry.instance().mapLayersByName('Topographic Line')[0]
iface.setActiveLayer(vl)
iface = qgis.utils.iface; vl = iface.activeLayer(); iface.addVectorLayer(vl.source(), vl.name() + " copy", vl.providerType())

vl = QgsMapLayerRegistry.instance().mapLayersByName('Topographic Area')[0]
iface.setActiveLayer(vl)
iface = qgis.utils.iface; vl = iface.activeLayer(); iface.addVectorLayer(vl.source(), vl.name() + " copy", vl.providerType())

qgis.utils.iface.mapCanvas().refresh()
root = QgsProject.instance().layerTreeRoot()
layers = QgsMapLayerRegistry.instance().mapLayers().values()
style_path = 'P:/Office Admin/GIS/Templates/MasterMap styles for QGIS/Emapsite NEW MasterMap styles/'

def load_style(layer, qml):
    layer.loadNamedStyle(style_path + qml)

def reorder_layers(layer, node):
    myalayer = root.findLayer(layer.id())
    myClone = myalayer.clone()
    parent = myalayer.parent()
    parent.insertChildNode(node, myClone)
    parent.removeChildNode(myalayer)

for i in layers:
  if i.name() == "Topographic Point":
    load_style(i, '1TopographicPoint.qml')
    reorder_layers(i, 0)
  if i.name() == "Cartographic Text":
    load_style(i, '2CartographicText.qml')
    reorder_layers(i, 1)
  if i.name() == "Topographic Line":
    load_style(i, '3TopographicLine.qml')
    reorder_layers(i, 2)
  if i.name() == "Topographic Line copy":
    load_style(i, '4TopographicLineCopy.qml')
    reorder_layers(i, 3)
  if i.name() == "Topographic Area":
    load_style(i, '5TopographicArea.qml')
    reorder_layers(i, 4)
  if i.name() == "Topographic Area copy":
    load_style(i, '6TopographicAreaCopy.qml')
    reorder_layers(i, 5)
  else:
    pass

qgis.utils.iface.mapCanvas().refresh()

0 votos

@Stuart - De nada, me alegro de que funcione ;)

0 votos

@Stuart - Editado post para incluir una versión ligeramente más limpia, hágamelo saber si no funciona para que pueda deshacer la edición ;)

0 votos

Hola Joseph, lamentablemente esto arroja un mensaje de error: Índice de lista fuera de rango - línea 30.

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X