Select to view content in your preferred language

How to set layer definition query equal to data driven page number?

4982
19
Jump to solution
12-20-2013 07:32 AM
MatthewBaker2
Deactivated User
All,

I'd like to make maps of students based on the school they're attending, what otherwise might be called a 'scatter-plot map'.

Is it possible to set a definition query on the student and school point layers to only display what is set as the data driven page number (in this case, the school number?)

The definition query would use the data driven page number, which is the school number, to display on the map the current school, and all students attending that school.

I hope I'm explaining myself correctly! Any ideas or pointers on how to better describe this problem are all welcome.

Thanks!

-m
0 Kudos
19 Replies
MatthewBaker2
Deactivated User
Thanks for your help, Wayne.

I am running the script in the python window with the MXD open:


>>> import arcpy
... mxd = arcpy.mapping.MapDocument("CURRENT")
... lyr1 = arcpy.mapping.ListLayers(mxd, "students")[0]
... lyr2 = arcpy.mapping.ListLayers(mxd, "schools")[0] 
... for pageNum in range(1, mxd.dataDrivenPages.pageCount + 1):
...     mxd.dataDrivenPages.currentPageID = pageNum
...     defQry = "SCHOOL_NUM = {0}".format(pageNum)
...     lyr1.definitionQuery = defQry
...     lyr2.definitionQuery = defQry
...     print "Exporting page {0} of {1}".format(str(mxd.dataDrivenPages.currentPageID), str(mxd.dataDrivenPages.pageCount))
...     arcpy.mapping.ExportToPNG(mxd, r"C:\scatterplots\outputs" + str(pageNum) + ".png") 
...     del mxd


This currently produces no error, but no results either.

However, from the python window changing the MapDocument property to:

mxd = arcpy.mapping.MapDocument(r"C:\scatterplots\mxd\scatterplotsdenver.mxd")


I get the following error:

Exporting page 1 of 11
Runtime error 
Traceback (most recent call last):
  File "<string>", line 6, in <module>
NameError: name 'mxd' is not defined


Running the file in Aptana, pointing to the MXD by its path, I get no error, but no result either...

-m
0 Kudos
MatthewBaker2
Deactivated User
One thing I just noticed:

A single PNG is being created at c:\scatterplots called outputs1.png

Strange!
0 Kudos
T__WayneWhitley
Honored Contributor
OK, I don't know what Aptana is, probably some sort of add-on extension...but no matter, I think you are messing things up trying to define the 'mxd' variable twice.

I think you said you were troubleshooting within the current ArcMap session's Python window?  If that's the case and the DDP mxd is the one loaded, then certainly use the 'CURRENT' keyword.  How many pages are in your index layer?  And check the field you're setting up the query on, is it text or numeric??


EDIT:
Oh, looks like you've got the 'del mxd' line indented - you cannot do that....that is why it is only printing a single page.  Put the del mxd line outside the loop, like so:
import arcpy
mxd = arcpy.mapping.MapDocument("CURRENT")
lyr1 = arcpy.mapping.ListLayers(mxd, "students")[0]
lyr2 = arcpy.mapping.ListLayers(mxd, "schools")[0] 
for pageNum in range(1, mxd.dataDrivenPages.pageCount + 1):
    mxd.dataDrivenPages.currentPageID = pageNum
    defQry = "SCHOOL_NUM = {0}".format(pageNum)
    lyr1.definitionQuery = defQry
    lyr2.definitionQuery = defQry
    print "Exporting page {0} of {1}".format(str(mxd.dataDrivenPages.currentPageID), str(mxd.dataDrivenPages.pageCount))
    arcpy.mapping.ExportToPNG(mxd, r"C:\scatterplots\outputs" + str(pageNum) + ".png") 
del mxd
0 Kudos
T__WayneWhitley
Honored Contributor
For testing purposes, simply delete the 'del mxd' line - then check your output directory for the separate png page exports.
0 Kudos
MatthewBaker2
Deactivated User
Ok now we're getting somewhere:

Un-indenting the del mxd line enables me to create 11 output PNG files... but... they're all blank

One note here is the SCHOOL_NUM values don't start at 1, they are all in the 200-400 range, and they aren't sequential.

An example of a def query would be:

"SCHOOL_NUM" = 397


I can't tell if this script will allow for that, but since there are 11 (blank) outputs, seems something is going correctly...

Thanks again, Wayne!

-m
0 Kudos
MatthewBaker2
Deactivated User
OK, I don't know what Aptana is, probably some sort of add-on extension...


Aptana is an open-source IDE for javascript, CSS, python, etc.
0 Kudos
T__WayneWhitley
Honored Contributor
Ah, good to know...

So about your school numbers -- you're currently defining the query based on the page number, so you've determined you don't want to do that!  So what you need (or one way to fulfill your need - if I remember correctly) in those layers you're setting the definition on is to code a field for what you want to display per page...think I've done this before.  Only use a page definition query if you need it, i.e., to limit what is shown per page.  A very simple scenario is when you have overlapping pages for whatever reason - basically to 'make focus' for the features pertaining to the current page when there's no need to 'clutter' the map with other features (which will of course have their own exclusive focus on a different page).

Hope that helps!

Wayne
0 Kudos
MatthewBaker2
Deactivated User
I think that makes sense.

I do want to limit the display of schools (based on the SCHOOL_NUM def. query) as well as the students (SCHOOL_NUM is the school they're attending). By doing this, I show a single school and all the kids that attend the school.

The schools layer I've got down to a subset of 11 schools, but the student point file is 86,000+ points, where each school is a few thousand of those points.

So what besides the SCHOOL_NUM field would I need? If I could simply use that as the page # and the def query, I'd be all set...
0 Kudos
T__WayneWhitley
Honored Contributor
So are the points that has school numbers that which you are trying to apply the page definition query to?

Ordinarily, the best way is to set up your point attribute table based on some relation you know based on your pages...so what I mean is how are your points related to the way your pages are defined?  You may have to more or less code a new field 'manually' or maybe it's as simple or almost as simple as a spatial join, say polys to points.

pagenum is the grid index number, correct?  Then, if you had subsets of records in the point fc coded by the pagenum value corresponding to the grid index number, then when you set up and have the page def execute per page, the appropriate set of features will be 'filtered'.  Does that make sense now?  If not, maybe you can explain further with explicit examples of what you want to display and attach a sample of the data (both polys and points).

Hope that helps,
Wayne

EDIT:
Oh I see, you have 2 layers (schools and students) you want to apply def queries to.  Are they both point layers?  It would help immensely to at least show a pic of your data.  Also I want to see your index layer.
I don't know how complex this has become but did you know (if this isn't oversimplifying) you could make an index layer out of the schools to then display per page the students attending that school?  So, with that, it's relatively easy to see that you need to have attribute data somewhere coded for what student belongs to which school.  ....or, as I said before do some sort of spatial join, attribute join, etc., in order to 'inherit' the necessary info upon which to base a query that makes sense.

Basically, with your png export, you've proved your code processing is working - you just need to correct your queries in order to show something meaningful on your pages.  So with the number of post responses growing large (this one's #19), why don't we move this conversation to private messaging.  If your private msg for this forum is enabled, I'll send you my email, you can post data to me (or post it here if you like).  I'll get to it after lunch, explain the technique, talk it over with you should I have questions or am missing data...etc etc.
0 Kudos
MatthewBaker2
Deactivated User
The solution proved to be page definitions, rather than python scripting (but see below for how I used python).

Page Definitions, in combination with data driven pages, were all I needed to ensure that other layers in the map were displaying the same SCHOOL_ID as the index layer of the data driven pages.

With the Index layer set to a copy of the schools layer, the layer turned off, and the SORT and NAME fields of DDP set to SCHOOL_ID.

Then enable page definitions of a 2nd schools layer (used for display) and set the page name field to SCHOOL_ID.

Do the same thing with the students layer, page name field set to SCHOOL_ID

Now when you toggle between data driven pages (on the hidden schools index layer), the 2nd schools layer displays the school being referenced by the index layer, the students show those that match the index layer as well, and we're all set.

Many thanks to Wayne Whitley for all the help!!!

Python: Many of our output maps are for powerpoint, rather than print, so the simple python script found here made it easy to export the data driven pages to PNG!

Thanks, Jeff for getting me started on this problem!
0 Kudos