Select to view content in your preferred language

Select Layer by Location not providing correct result.

3676
28
Jump to solution
02-12-2013 09:45 AM
SusanWhitney
Occasional Contributor
I sought assistance with a portion of this code earlier. I have added an additional step, which to me would seem pretty simple, but I am still learning the ups & downs of Python.

My script creates data driven pages. I use a list to populate a layer definition query to run a specific township. Now I am trying to do a selection (SelectLayerByLocation) to only find the townships where there is data. I first just added the SelectLayerByLocation command. Did not work. With further reading, it looked like I needed to run a MakeFeatureLayer on the two sets of data involved in the selection. Still did not work. Do I need to use cursors or is the answer much simpler?

I do not have any error messages. I have added try/except to see if I can find additional information on what is happening with my script. The data exports just fine, but there are maps that do not have any data.
Thank you for any guidance.

# PoleDDpages.py # Author: slw # Date: XXXXX # Revisions: XXXXX # Description: Create Pole map book series using Data Driven Pages and #           insert a cover page  # Import ArcPy import os,arcpy  try:          # Set up variables     # Location of pole map .mxd document     mxdDoc = r"G:\GEOSPATIAL\Publishing\Pole\Pole_QtrSec.mxd"      # Create the MapDocument object     mxd = arcpy.mapping.MapDocument(mxdDoc)     df = arcpy.mapping.ListDataFrames(mxd)[0]     layer = arcpy.mapping.ListLayers (mxd, "SURVEY_GRID_BNDRY",df)[0]     poleLyr = arcpy.mapping.ListLayers (mxd, "Pole",df)[0]      # Overwrite existing file     arcpy.env.overwriteOutput = True      # Output directory for the pole maps     outDir = r"G:\GEOSPATIAL\Publishing\Pole"      # Set the workspace     arcpy.env.workspace = outDir      # List of map grids     twpList = ['\"TOWNSHIP_C\" = \'D5\' AND \"RANGE_CD\" = \'5\'',\                '\"TOWNSHIP_C\" = \'D6\' AND \"RANGE_CD\" = \'4\'']       i=1     for twpName in twpList:         layer.definitionQuery = twpName          # refresh() after changing the layer def query to 'redefine' the DDP index limits         mxd.dataDrivenPages.refresh()                 # Create temporary layers to work with the Selection         arcpy.MakeFeatureLayer_management(layer, "surveyLyr")         arcpy.MakeFeatureLayer_management(poleLyr, "poleLyr_new")          # Clear the Selection before starting         #arcpy.SelectLayerByAttribute_management("surveyLyr", "CLEAR_SELECTION", "")         #print "The selection has been cleared"                  # Select Layer By Location to limit to just maps with data         arcpy.SelectLayerByLocation_management("surveyLyr", "INTERSECT", "poleLyr_new", "", "NEW_SELECTION")          # refresh() after changing the layer def query to 'redefine' the DDP index limits         mxd.dataDrivenPages.refresh()          mxd.saveACopy(os.path.splitext(mxdDoc) [0] + str(i) + os.path.splitext(mxdDoc)[1])         i += 1                   # The final mapbook name taken from the list         finalPDFfn = outDir + "\\" + twpName [16:18] + twpName [38:39] + "Pole.pdf"                  # Create the final PDF -- which is just an empty shell right now         finalPDF = arcpy.mapping.PDFDocumentCreate(finalPDFfn)          # A temporary pdf file for processing         tmpPDF = outDir + "\\PoleMapPages.pdf"          # Let the user know what is happening!         print "Exporting " + twpName [16:18] + twpName [38:39]                  # Export the data driven pages in the mxd to a temporary PDF         print "Exporting map pages to the temporary PDF"         ddp = mxd.dataDrivenPages.exportToPDF(tmpPDF)          # Append the temporary pdf to the final pdf         # Cover, map pages, back cover         print "Appending Map Pages"         finalPDF.appendPages (r"G:\GEOSPATIAL\Publishing\Pole\PoleCovers\Covers_"\                               + twpName [16:18] + twpName [38:39] + ".pdf")         finalPDF.appendPages(tmpPDF)         finalPDF.appendPages(r"G:\GEOSPATIAL\Publishing\TwpGrid_Color8x11.pdf")          # Set properties for Adobe Reader and save PDF.         finalPDF.updateDocProperties(pdf_open_view = "USE_THUMBS", pdf_layout = "SINGLE_PAGE")         finalPDF.saveAndClose()          # Deleting temporary layers         arcpy.Delete_management("surveyLyr")         arcpy.Delete_management("poleLyr_new")      except Exception as e:     print e.message     print arcpy.GetMessages(2)      # Clean up print "Cleaning up" # Delete the temporary PDF using the ArcPy function if arcpy.Exists(tmpPDF):                  arcpy.Delete_management(tmpPDF)   # Delete objects del mxd, tmpPDF, ddp               # Finished message print "Map compilation completed. Please review the final output."
Tags (2)
0 Kudos
28 Replies
SusanWhitney
Occasional Contributor
First you are correct in your statement "To be specific, the code I last posted runs without error and the exported map sheets reflect some index pages without pole data?"

I ran the script again with the str modification you noted in the definition query and received the same result.

I tried to open the mxd files G:\GEOSPATIAL\Publishing\Pole\Pole_QtrSec1.mxd and Pole_QtrSec2.mxd. The files would not open. Got a large ArcMap error  ...

Opening the selected Arcmap document failed.
The standard document information of the map document could not be read.
The data frames of the map document could not be read due to the following error:
0x80040111 (Class factory cannot supply requested class)
The last successfully loaded component was:
esriDisplay.RgbColor ({7EE9C496-D123-11D0-8383-080009b996cc})
the specified file does not contain a valid ArcMap document

... so I was not able to check the definition query. I did try to open on more than one machine.

Before I started trying to add the select by location, the definition query was working and providing only the township/range I was asking for. I still get the correct township/range in the resulting file, it's just that I also have pages (sections) that do not have any data.

Looks like I had better research on better error trapping. I guess the beginning class was not enough!
Thank you,
Susan
0 Kudos
T__WayneWhitley
Honored Contributor
hmmm, that's very interesting.  Not entirely informative, but interesting nevertheless.

I am not saying this is your problem, but it could be you are dealing with an 'older' mxd document, do you know if that is the case?

What you can try is altering the version mxd to saveACopy to - this is the syntax:

saveACopy (file_name, {version})

...where 'version' is the optional parameter -- unfortunately I don't think you can test for the original mxd version, but if you think it is an earlier version causing this save corruption to a more recent version, you can test saving it to one of the earlier versions by specifying that optional param (I forgot the current software version you are currently using?):

Directly from the 10.1 webhelp:

MapDocument (arcpy.mapping)
Desktop » Geoprocessing » ArcPy » Mapping module
http://resources.arcgis.com/en/help/main/10.1/index.html#//00s30000000n000000
******************************
A string that sets the output version number. The default value will use the current version.

�?�10.1 �??Version 10.1
�?�10.0 �??Version 10.0
�?�8.3 �??Version 8.3
�?�9.0 �??Version 9.0/9.1
�?�9.2 �??Version 9.2
�?�9.3 �??Version 9.3

(The default value is None)
******************************

So, you can try changing the relevant line in your code to (I have entered the string in bold letters - try an earlier version as necessary):
mxd.saveACopy(os.path.splitext(mxdDoc) [0] + str(i) + os.path.splitext(mxdDoc)[1], '10.0')

And if this is not your problem, I'll try to test the the code segment related to setting the def query later today.

Enjoy,
Wayne

EDIT:  Better yet, if you can open your py script in IDLE, and enter a print command to print the def query just before you set it for the layer:

print twpName + " AND \"OBJECTID\" NOT IN " + str(subquery)

...then, instead of trying to fix how the test mxds are being saved, you may directly test the def query to see if it is working properly (I could tell you if you pasted it here).  Test it 'manually' by copying the result of the print statement from the IDLE window, open your orig mxd and paste it in the def query window, hit OK, then go to your DDP toolbar and refresh your index...

Check your map results...are the index pages correctly 'refined' to the extent of your pole layer?  If not, then the def query process needs work.  If so, the remaining pdf export component of your code needs work.
0 Kudos
SusanWhitney
Occasional Contributor
The .mxd was created in version 10.1, so I don't know if that would be the problem.

I added the print statement to the script and this was the result (I stripped out the extra statements):

"TOWNSHIP_C" = 'D5' AND "RANGE_CD" = '5'AND"OBJECTID"NOT IN(186,226,227,248,271,272,274,275,297,322,347,348)
Exporting D55

"TOWNSHIP_C" = 'D6' AND "RANGE_CD" = '4'AND"OBJECTID"NOT IN(186,226,227,248,271,272,274,275,297,322,347,348)
Exporting D64

When adding this to the definition query in the original .mxd, it still results in pages without data for both instances.
Thank you,
Susan
0 Kudos
T__WayneWhitley
Honored Contributor
Great now we are getting somewhere, Susan - now what I want you to do as part of the troubleshooting process, if you have not already done so, paste one of those queries in the index layer's def query window (of your original mxd) - but click the query button to bring up the query builder dialog, then enter and click 'Verify'....if the query can be evaluated, you should get the msg in a pop-up, "The expression was successfully verified."  If so, go refresh the DDP index layer and check out the data in your view - do you still get pages where there is 'no data'.  If so, then either something is wrong with the construction of the query or you are looking for something other than what is defined in the problem - the result should be only pages containing pole data.

Hope that helps.

-Wayne
0 Kudos
SusanWhitney
Occasional Contributor
Did all of that exactly. Still get pages with no data.
0 Kudos
T__WayneWhitley
Honored Contributor
Could be something silly - the problem here is I'm 'flying blind', cannot see the same thing you are looking at.
You are limited here as to the size of what you can attach, but can you save a copy of your mxd in 10.0 with only the pole and index  (township/range) layers making sure to retain the DDP setup, make it 'relative-pathed' with just the relevant layers in a ver 10.0 gdb (or shapefile format is fine), and attach here?

Quicker to troubleshoot that way - I can pick apart your code way faster and tell you what I have done after having completed it.

Sorry for your trouble!  Also, when you're checking your sheets, you are checking the pages in the mxd itself, correct?


-Wayne
0 Kudos
SusanWhitney
Occasional Contributor
Yes, I checked the sheets in the mxd itself.
We are working in 10.1, so I need to make everything version 10.0.
I'll try to get that out today or tomorrow.
Thank you for all of your help, Wayne.
Susan
0 Kudos
T__WayneWhitley
Honored Contributor
...one more I guess parting thought for the day on this matter -- the thing about Make Feature Layer is that it 'stamps' whatever may be selected on a given layer into memory.  I have assumed nothing is selected and that when we preprocessed layers for the next step, Select by Location, I intended to then 'stamp' one full layer with the other full layer.  So that being said, this operation only works as I intended if there are no selections 1st.

Tell me that isn't the problem, lol!  Could be the select processing is a little off...but no worries, I am looking at another tool I wrote here that at one point had a similar problem - a user was running a script tool where initially I assumed there were no preselected features --- the tool inadvertently returned no results when that should not have been the case...all due to starting with a subset 'stamped' by Make Feature Layer.  (no prior selections results in the whole compliment of features included in the layer).

Anyway, there it is...have to consider it.


Enjoy,
Wayne
0 Kudos
T__WayneWhitley
Honored Contributor
Test this (it is untested, didn't even look at your PDF section, so you have to give it a try):
# PoleDDpages.py
# Author: slw
# Date: XXXXX
# Revisions: XXXXX
# Description: Create Pole map book series using Data Driven Pages and
#           insert a cover page

# Import ArcPy
import os,arcpy

# Overwrite existing file
arcpy.env.overwriteOutput = True

try:
    
    # Set up variables
    # Location of pole map .mxd document
    mxdDoc = r"G:\GEOSPATIAL\Publishing\Pole\Pole_QtrSec.mxd"

    # Create the MapDocument object
    mxd = arcpy.mapping.MapDocument(mxdDoc)
    df = arcpy.mapping.ListDataFrames(mxd)[0]
    layer = arcpy.mapping.ListLayers (mxd, "SURVEY_GRID_BNDRY",df)[0]
    poleLyr = arcpy.mapping.ListLayers (mxd, "Pole",df)[0]

    ################
    # moved part of code to select grids (layer) intersecting 'Pole' features (poleLyr)
    # Create temporary layers to work with the Selection,
    # 1st need to assure no prior selections...the sel by loc syntax:
    # SelectLayerByLocation_management (in_layer, {overlap_type}, {select_features}, {search_distance}, {selection_type})
    # in_layer is the index layer; select_features is the pole layer
    
    SelectBy = [layer, poleLyr]
    for lyr in SelectBy:
          iniCount = int(arcpy.GetCount_management(lyr).getOutput(0))
          if iniCount != 0:
               arcpy.SelectLayerByAttribute_management(lyr, 'CLEAR_SELECTION')

    # should now be properly 'initialized' with no prior selections, i.e., full complement datasets      
    arcpy.MakeFeatureLayer_management(layer, "surveyLyr")
    arcpy.MakeFeatureLayer_management(poleLyr, "poleLyr_new")
        
    # Select Layer By Location to limit to just maps with data
    arcpy.SelectLayerByLocation_management("surveyLyr", "INTERSECT", "poleLyr_new", "", "NEW_SELECTION")

    # Susan, check that this works, switching the selection...
    # SelectLayerByAttribute_management (in_layer_or_view, {selection_type}, {where_clause})
    arcpy.SelectLayerByAttribute_management("surveyLyr", "SWITCH_SELECTION")

    # new code to get at OBJECTIDs to modify def query
    IDs = []
    rows = arcpy.SearchCursor("surveyLyr")
    for row in rows:
          IDs.append(row.OBJECTID)

    del row, rows

    subquery = '('
    for each in IDs:
         subquery = subquery + str(each) + ','

    subquery = subquery[0:-1] + ')'
    ################

    # Output directory for the pole maps
    outDir = r"G:\GEOSPATIAL\Publishing\Pole"

    # Set the workspace
    arcpy.env.workspace = outDir

    # List of map grids
    twpList = ['\"TOWNSHIP_C\" = \'D5\' AND \"RANGE_CD\" = \'5\'',\
               '\"TOWNSHIP_C\" = \'D6\' AND \"RANGE_CD\" = \'4\'']

    for twpName in twpList:
        # modified the definitionQuery to include the subquery exclusion clause
        layer.definitionQuery = twpName + " AND \"OBJECTID\" NOT IN " + str(subquery)

        # refresh() after changing the layer def query to 'redefine' the DDP index limits
        mxd.dataDrivenPages.refresh()
         
        # The final mapbook name taken from the list
        finalPDFfn = outDir + "\\" + twpName [16:18] + twpName [38:39] + "Pole.pdf"
        
        # Create the final PDF -- which is just an empty shell right now
        finalPDF = arcpy.mapping.PDFDocumentCreate(finalPDFfn)

        # A temporary pdf file for processing
        tmpPDF = outDir + "\\PoleMapPages.pdf"

        # Let the user know what is happening!
        print "Exporting " + twpName [16:18] + twpName [38:39]
        
        # Export the data driven pages in the mxd to a temporary PDF
        print "Exporting map pages to the temporary PDF"
        ddp = mxd.dataDrivenPages.exportToPDF(tmpPDF)

        # Append the temporary pdf to the final pdf
        # Cover, map pages, back cover
        print "Appending Map Pages"
        finalPDF.appendPages (r"G:\GEOSPATIAL\Publishing\Pole\PoleCovers\Covers_"\
                              + twpName [16:18] + twpName [38:39] + ".pdf")
        finalPDF.appendPages(tmpPDF)
        finalPDF.appendPages(r"G:\GEOSPATIAL\Publishing\TwpGrid_Color8x11.pdf")

        # Set properties for Adobe Reader and save PDF.
        finalPDF.updateDocProperties(pdf_open_view = "USE_THUMBS", pdf_layout = "SINGLE_PAGE")
        finalPDF.saveAndClose()

        # Deleting temporary layers
        arcpy.Delete_management("surveyLyr")
        arcpy.Delete_management("poleLyr_new")    

except Exception as e:
    print e.message
    print arcpy.GetMessages(2)
    
# Clean up
print "Cleaning up"
# Delete the temporary PDF using the ArcPy function
if arcpy.Exists(tmpPDF):         
        arcpy.Delete_management(tmpPDF)  
# Delete objects
del mxd, tmpPDF, ddp             

# Finished message
print "Map compilation completed. Please review the final output."


This time, if it does not work, I just need better or more feedback from you - more details about what you see...such as perhaps pages with 'no data' - exactly what you mean by that, because just maybe you actually do have pole data on the very edge of the index page so that by the strictest definition you do have intersecting pole data.  Make sure too that what is defined in the index layer DDP is what is actually exported...you know the drill, eliminate by parts or steps all possibilities where things may go awry...

Enjoy,
Wayne
0 Kudos
SusanWhitney
Occasional Contributor
It's working! The only issue is, if there is a map (twp/range) where there are no sheets selected, the
mxd.dataDrivenPages.refresh() fails and no other maps are output. Is there a way we can handle this?

As an additional note to your last post. The pages that do not have data, really do not have any pole data at all. Nothing on the edges trying to peek through!

Thank you,
Susan
0 Kudos