0

I have the following code to ouput all of my layers to pdfs. I'm trying to update the code from ArcMap to work in ArcGIS Pro. I'm not understanding the correct syntax to use for the curLayer line after the for loop starts. Please advise.

import sys
import arcpy
import os
import arcpy.mp as Map

# Set control parameters for map production
xDate = "April - 2024"  # Current data set being displayed (above legend on layout)
xPrint = "no"           # "yes"/"no" for print control
xFormat = "pdf"         # can be either pdf or png
xRes = 300              # resolution
pdfBook = "Viewer_MapBook_April_2024"  # Name of mapbook; disabled when format set to png
xDir = r"C:\Projects\Well Water Quality Viewer\make_web\Display_Maps\Display_Maps"  # Output directory
aprxFile = r"C:\Projects\Well Water Quality Viewer\make_web\Display_Maps\Display_Maps\Display_Maps.aprx"  # aprx document

# List of desired maps (in the order requested for mapbook)
maps = [
    'Alkalinity-Co', 'Arsenic-Co', 'Arsenic-Max-Co', 'Atrazine Family-Co', 'Bacteria-Co', 
    'Chloride-Co', 'Conductivity-Co', 'Copper-Co', 'Iron-Co', 'Lead-Co', 
    'Manganese-Co', 'Nitrate-Co', 'Nitrate Exceedence-Co', 'pH-Co', 'Saturation Index-Co', 
    'Sulfate-Co', 'Total Hardness-Co',
    'Alkalinity-TR', 'Arsenic-TR', 'Arsenic-Max-TR', 'Atrazine Family-TR', 'Bacteria-TR', 
    'Chloride-TR', 'Conductivity-TR', 'Copper-TR', 'Iron-TR', 'Lead-TR', 
    'Manganese-TR', 'Nitrate-TR', 'Nitrate Exceedence-TR', 'pH-TR', 'Saturation Index-TR', 
    'Sulfate-TR', 'Total Hardness-TR',
    'Alkalinity-S', 'Arsenic-S', 'Arsenic-Max-S', 'Atrazine Family-S', 'Bacteria-S', 
    'Chloride-S', 'Conductivity-S', 'Copper-S', 'Iron-S', 'Lead-S', 
    'Manganese-S', 'Nitrate-S', 'Nitrate Exceedence-S', 'pH-S', 'Saturation Index-S', 
    'Sulfate-S', 'Total Hardness-S',
]

# Set environment
arcpy.env.overwriteOutput = True
aprx = Map.ArcGISProject(aprxFile)
layout = aprx.listLayouts('PW_WEB_MAPPER')[0]
ms = layout.mapSeries
noteSet = layout.listElements("TEXT_ELEMENT", "Data_Set")[0]
noteSet.text = xDate

# Determine printing and PDF settings
dfList = aprx.listMaps("Layers")[0]

if xFormat != "pdf":
    xPrint = "no"
if xPrint == "no":
    mapPrint = "N"
else:
    mapPrint = "P"
if xFormat != "pdf":
    pdfBook = "no"
if pdfBook != "no":
    pdfDoc = Map.PDFDocumentCreate(os.path.join(xDir, pdfBook)+".pdf")

# Main loop
for xmap in maps:  
    curLayer = dfList.listLayers(dfList)[xmap]
    curLayer.visible = True
    Xport = os.path.join(xDir, xmap)
    if xFormat == "pdf":
        layout.exportToPDF(aprx, Xport, resolution=xRes)
        if pdfBook != "no":
            pdfDoc.appendPages(Xport + ".pdf")
    else:
        Map.ExportToPNG(aprx, Xport, resolution=xRes)

    if mapPrint == "P":
        Map.PrintMap(aprx)

    print("Exported: ", xmap)
    curLayer.visible = False

if pdfDoc != "no":
    pdfDoc.saveAndClose()
    del pdfDoc
del aprx
print("Script Complete")

1 Answer 1

1

dfList.listLayers(dfList) returns a python list, but xmap is a string. Lists can only be indexed using integers.

Before the loop, you could build a dict of layers then use that for the lookup instead:

layers = {layer.name: layer for layer in dfList.listLayers(dfList)}

for xmap in maps:
    try:
        curLayer = layers[xmap]
    except KeyError:
        print(f'layer "{xmap}" not found')
        continue
3
  • maps is a list of my layers so I'm not sure why I need to build another dictionary of layers? Commented Oct 16 at 14:38
  • maps is just a list of strings that could potentially be the names of layers. dfList.listLayers(dfList) returns a list of layer objects that actually exist in the dataframe. You need a way to search through that list of layer objects to find the one that matches the layer name you're looping over. Dictionaries provide a straightforward way to create "lookup table" of layer objects that can be searched by name, which is what my example shows.
    – mikewatt
    Commented Oct 16 at 20:41
  • May be helpful to read up on lists and dicts
    – mikewatt
    Commented Oct 16 at 20:43

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.