Looping through a definition query in data driven pages

7451
12
03-20-2012 03:09 PM
KarlaMayne
New Contributor II
I'm hoping someone can help me with this one; I've read every post I could find and I'm still stuck. I've got a series of data driven pages that I can get to export with no problem, but I also need to update a mask layer while I'm exporting each page. The ddp name is based on state names and the mask layer is also based on state name. I've got a simple definition query that I use to turn the mask layer on and off for each state. For example, the current ddp is Arizona so the definition query on the mask layer would be "STATE_NAME" <> 'Arizona'. This turns the mask layer off for Arizona while leaving the surrounding states grayed out.

Here's the script that I have so far:

import arcpy, sys, os
arcpy.OverWriteOutput = 1
mxd = arcpy.mapping.MapDocument("CURRENT")

print "Enter save as pdf location:"
pdfDir = arcpy.GetParameterAsText(0)
outputFolder = pdfDir + r"\PDFs"

df = arcpy.mapping.ListDataFrames(mxd, "Layers")[0]
maskLayer = arcpy.mapping.ListLayers(mxd, "state_bnd110", df)[0]
maskField = "STATE_NAME"

for pageNum in range(1, mxd.dataDrivenPages.pageCount + 1):
    mxd.dataDrivenPages.currentPageID = pageNum
    pageName = mxd.dataDrivenPages.pageRow.STATE_NAME
    for lyr in arcpy.mapping.ListLayers(mxd):
        if lyr.name == maskLayer:
            lyr.definitionQuery = '"STATE_NAME" <> pageName'
        arcpy.mapping.ExportToPDF(mxd, os.path.dirname(outputFolder)+ os.sep + pageName + ".pdf")
        lyr.definitionQuery = ""
        arcpy.RefreshActiveView()

del mxd
arcpy.GetMessages()

If I take out the layer loop the script will export all the ddp with no trouble (and with no mask symbology). As the script is now, it will export the first state (Arizona) with all the states grayed out (for this page, Arizona should not be) then it will export Arizona again and again.

Any help would be greatly appreciated!
Karla
Tags (2)
12 Replies
MathewCoyle
Frequent Contributor
Your loops and indentation are important in this case, read this.

http://forums.arcgis.com/threads/48475-Please-read-How-to-post-Python-code
0 Kudos
KarlaMayne
New Contributor II
Thank you for replying with that information!  I couldn't figure out how to get my script to post with the indentations intact. 

Here it is again, complete with indentations:

import arcpy, sys, os
arcpy.OverWriteOutput = 1
mxd = arcpy.mapping.MapDocument("CURRENT")

print "Enter save as pdf location:"
pdfDir = arcpy.GetParameterAsText(0)
outputFolder = pdfDir + r"\PDFs"

df = arcpy.mapping.ListDataFrames(mxd, "Layers")[0]
maskLayer = arcpy.mapping.ListLayers(mxd, "state_bnd110", df)[0]
maskField = "STATE_NAME"

for pageNum in range(1, mxd.dataDrivenPages.pageCount + 1):
    mxd.dataDrivenPages.currentPageID = pageNum
    pageName = mxd.dataDrivenPages.pageRow.STATE_NAME
    for lyr in arcpy.mapping.ListLayers(mxd):
        if lyr.name == maskLayer:
            lyr.definitionQuery = '"STATE_NAME" <> pageName'
        arcpy.mapping.ExportToPDF(mxd, os.path.dirname(outputFolder)+ os.sep + pageName + ".pdf")
        lyr.definitionQuery = ""
        arcpy.RefreshActiveView()

del mxd
arcpy.GetMessages()
0 Kudos
MathewCoyle
Frequent Contributor
Your main problem is most likely your query. Try this.
'"STATE_NAME" <> %s' % pageName

Also, that is the wrong format for the overwrite ouput. Use this.
arcpy.env.overwriteOutput = True
0 Kudos
KarlaMayne
New Contributor II
Thanks for the suggestion, that solved the problem of exporting the ddp with the mask symbology.  Unfortunately, it's still looping through the same state (the first one, Arizona) over and over again without moving on to the next page in the ddp.
0 Kudos
MathewCoyle
Frequent Contributor
Try moving your export back one, so it is under the pageNum loop instead of the layer loop. You may want the activeview refresh before the export as well.

for pageNum in range(1, mxd.dataDrivenPages.pageCount + 1):
    mxd.dataDrivenPages.currentPageID = pageNum
    pageName = mxd.dataDrivenPages.pageRow.STATE_NAME
    for lyr in arcpy.mapping.ListLayers(mxd):
        if lyr.name == maskLayer:
            lyr.definitionQuery = '"STATE_NAME" <> %s' % pageName
    arcpy.RefreshActiveView()
    arcpy.mapping.ExportToPDF(mxd, os.path.dirname(outputFolder)+ os.sep + pageName + ".pdf")
    lyr.definitionQuery = ""
0 Kudos
KarlaMayne
New Contributor II
Okay, I gave that a try and now I'm getting a Runtime Error after it exports the first ddp.

type 'exceptions.RuntimeError'>: LayerObject: Set attribute definitionQuery does not exist
Failed to execute
0 Kudos
MathewCoyle
Frequent Contributor
Delete the last lyr definition query in your script after the pdf export.
0 Kudos
LynnFrederico
New Contributor II
This is clearly very late:  but when you have DDP enabled, you then get a special definition query button.  In properties where you would normally got to set your query builder, there is now a "page definition" button.  you can specify that a lyr match or don't match the index layer name.  if i understand correctly this is what you were trying to get your code to do.
0 Kudos
by Anonymous User
Not applicable
I just had great success with the following edits to this code. Thanks for sharing it. I also was able to change it to export JPEGs.

I'm attaching my Python script.

#DDP: Set Definition Query on a secondary index 
 #Variables that need to be set by user:
 #mxdpath = r'C:\Users\Test.mxd' # string
 #outputfolder = 'PDFFolder' # string
 #namefield = 'THE FIELD CONTAINING THE NAME OF THE RESULTING PDF FILE' #string
 #queryfield = 'THE FIELD CONTAINING THE VALUE FOR THE DESIRED QUERY' #string
 #layers = ['LIST','OF','LAYERS'] # list ('Layer1_UpdateQuery', 'Layer2_UpdateQuery', 'etc')

#Import Modules
import arcpy, os

# Set Variables
mxdpath = r'D:\arcgis\Samples\DDP_Index2.mxd' # string
outputfolder = 'D:\PDF' # string
namefield = 'FIPS' # string
queryfield = 'STATE_NAME' # string
layers = ['CountySel_FIPS'] # list

mxd = arcpy.mapping.MapDocument(mxdpath)
# Start Loop through Data Driven Pages

for pageNum in range(1, mxd.dataDrivenPages.pageCount + 1):
    mxd.dataDrivenPages.currentPageID = pageNum # set the current page
    pageName = mxd.dataDrivenPages.pageRow.getValue(namefield) # get the pageName
    pageName += '.pdf' # add '.pdf' extension for file name
    pdf = os.path.join(outputfolder, pageName) # add pageName to output folder to get full output path
    # Start Loop through all layers of mxd file

    for lyr in arcpy.mapping.ListLayers(mxd): # for every layer in mxd's Layer List
            if lyr.name in layers: # if layer name in user input list above
                #value = mxd.DataDrivenPages.pageRow.getValue(queryfield) # get value of query field
                value = mxd.dataDrivenPages.pageRow.getValue(queryfield)
                print value
                if lyr.definitionQuery == True: # if a definitionQuery Exsts...
                    query = lyr.definitionQuery + "AND" + queryfield + "=" + "\"" + value + "\"" # Add new to old
                else:
                    query = queryfield + "=" + "\"" + value + "\"" # else create a new query
                    lyr.definitionQuery = query # set the layers defintionQuery
            else:
                print 'Next' # else print next, this isn't necassary, but its a good place holder

    print pageName
    arcpy.mapping.ExportToPDF(mxd, pdf) # export the current Page to pdf
del mxd, lyr, pageName, pageNum, query, value