4

I am using the following code in a script tool to import a set of shapefiles from a folder specified by the user, duplicate two of the layers, style all of them and re-order them in the layers panel.

The last piece of code - the bit that re-orders my layers does not work.

I get the following error:

name 'alayer' is not defined See log for more details

What I don't understand is if I split the code into two separate scripts, load/duplicate/style the layers and then run the re-order layers section separately, the code executes perfectly.

Where am I going wrong?

I'm running 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()
2
  • Can you identify which line the error occurs in?
    – Joseph
    Nov 22, 2016 at 12:30
  • File "<string>", line 83, in <module> NameError: name 'alayer' is not defined
    – Stuart
    Nov 22, 2016 at 12:35

1 Answer 1

4

I've edited your code a bit to contain a couple of functions to call these instead of repeating similar lines of code for each layer. I only tested the functions which loads the style and reorders the layers which seems to work. Assume this code is untested but hopefully this will help avoid the 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()
4
  • @Stuart - Most welcome, glad it works ;)
    – Joseph
    Nov 22, 2016 at 14:41
  • @Stuart - Edited post to include a slightly cleaner version, let me know if it doesn't work so that I can rollback the edit ;)
    – Joseph
    Nov 22, 2016 at 15:35
  • Hi Joseph, unfortunately this throws up an error message: List index out of range - line 30.
    – Stuart
    Nov 23, 2016 at 9:29
  • @Stuart - Thanks for checking, removed the edit. Didn't have time to test it =)
    – Joseph
    Nov 23, 2016 at 11:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.