Select to view content in your preferred language

How to combine loops or reuse variables

849
1
Jump to solution
04-21-2020 01:45 PM
JeffThomasILM
Frequent Contributor

I have a project with multiple layouts and corresponding maps (1-to-1). The maps/layouts are very similar (to get around Pro's inability to set layer visibility per view) and I want to automate setting up the common layers in each map/layout. It's two basic steps: 1) adjust the def query on one of two layer and 2) center the map frame on the queried feature. I've created a loop that successfully changes the def query on all maps:

maps = proj.listMaps()
for m in maps:
    zhLyr = m.listLayers("Zoning History")[0]
    suLyr = m.listLayers("Special Use Permit")[0]
    if caseType == "C" or caseType == "Z":
        zhLyr.definitionQuery = "CaseNumber = '" + case + "'"
        zhLyr.visible = True
        suLyr.visible = False
    elif caseType == "S":
        suLyr.definitionQuery = "CaseNumber = '" + case + "'"
        suLyr.visible = True
        zhLyr.visible = False

I conceptually know how to loop through the layouts and center them on the feature:

layouts = proj.listLayouts()      
for l in layouts:
    mf = l.listElements("MAPFRAME_ELEMENT")
    if caseType == "C" or caseType == "Z":
        zhExt = mf.getLayerExtent(zhLyr)
        mf.camera.setExtent(zhExt)
        mf.camera.scale = 1500
    elif caseType == "S":
        suExt = mf.getLayerExtent(suLyr)
        mf.camera.setExtent(suExt)
        mf.camera.scale = 1500‍‍‍‍‍‍‍‍‍‍‍

The problem is the layer variable. It's defined in the first loop and I don't know if there's a way to recall it in the second loop. Maybe the loops have to be nested, but I'm having trouble figuring out how to do that properly. Thank you for any help!

Tags (2)
0 Kudos
1 Solution

Accepted Solutions
JeffThomasILM
Frequent Contributor

I figured out how to combine the loops, using the map property from the MapFrame object instead of the listMaps function of the ArcGISProject object. 

import arcpy

proj = arcpy.mp.ArcGISProject("CURRENT")
path = proj.filePath
case = path.split("\\")[-1][:-5] # project file name is the case number
caseType = path.split("\\")[-1][0:1] # first character of case number indicates type
layouts = proj.listLayouts()

for l in layouts:
    mf = l.listElements("MAPFRAME_ELEMENT","Map Frame")[0]
    zhLyr = mf.map.listLayers("Zoning History")[0]
    suLyr = mf.map.listLayers("Special Use Permit")[0]
    if caseType == "C" or caseType == "Z":
        zhLyr.definitionQuery = "CaseNumber = '" + case + "'"
        zhLyr.visible = True
        suLyr.visible = False
        zhExt = mf.getLayerExtent(zhLyr)
        mf.camera.setExtent(zhExt)
        mf.camera.scale = 1500
    elif caseType == "S":
        suLyr.definitionQuery = "CaseNumber = '" + case + "'"
        suLyr.visible = True
        zhLyr.visible = False
        suExt = mf.getLayerExtent(suLyr)
        mf.camera.setExtent(suExt)
        mf.camera.scale = 1500

Still a few details to work out, such as I don't actually want every map scale to be 1:1500. But it works!

View solution in original post

0 Kudos
1 Reply
JeffThomasILM
Frequent Contributor

I figured out how to combine the loops, using the map property from the MapFrame object instead of the listMaps function of the ArcGISProject object. 

import arcpy

proj = arcpy.mp.ArcGISProject("CURRENT")
path = proj.filePath
case = path.split("\\")[-1][:-5] # project file name is the case number
caseType = path.split("\\")[-1][0:1] # first character of case number indicates type
layouts = proj.listLayouts()

for l in layouts:
    mf = l.listElements("MAPFRAME_ELEMENT","Map Frame")[0]
    zhLyr = mf.map.listLayers("Zoning History")[0]
    suLyr = mf.map.listLayers("Special Use Permit")[0]
    if caseType == "C" or caseType == "Z":
        zhLyr.definitionQuery = "CaseNumber = '" + case + "'"
        zhLyr.visible = True
        suLyr.visible = False
        zhExt = mf.getLayerExtent(zhLyr)
        mf.camera.setExtent(zhExt)
        mf.camera.scale = 1500
    elif caseType == "S":
        suLyr.definitionQuery = "CaseNumber = '" + case + "'"
        suLyr.visible = True
        zhLyr.visible = False
        suExt = mf.getLayerExtent(suLyr)
        mf.camera.setExtent(suExt)
        mf.camera.scale = 1500

Still a few details to work out, such as I don't actually want every map scale to be 1:1500. But it works!

0 Kudos