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!
Solved! Go to Solution.
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!
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!