Take the 2-minute tour ×
Geographic Information Systems Stack Exchange is a question and answer site for cartographers, geographers and GIS professionals. It's 100% free, no registration required.

I am trying to use ESRIs generated python code to move around my Extent Data Frame based on location of my Main Line shapefile, as to not have the Data Frame over top of the main line when developing a data driven page set up.

When attempting I receive this error:

<class 'arcgisscripting.ExecuteError'>: Failed to execute. Parameters are not valid.
ERROR 000725: Output Feature Class: Dataset in_memory\tempFC already exists.
Failed to execute (CopyFeatures).

Failed to execute (MoveLocatorMap).

ESRI's Code below:

import arcpy, os, sys

#Python function
def findLocation(corner, mainDF, locatorDF, polyLayer):

#The following funtion creates a polygon feature for each of the 4 corners of the
#main data frame.  The X,Y coordinates are calculated using the main data frame's
#extent as well as the proportional distances along the main data frame's extent. For
#example, in the figure below, the X value is simply the data frame's XMax value.  But
#the Y value is the YMax value minus the proportional distance of the locator data
#frames height compared to the main data frame's height. We know the total Y distance
#(YMax - YMin) and we know the height of each data frame (elementHeight) so we can
#multiply the Y delta by the percent of the locator data frame to the main dataframe
#to get:

# Y = mainDF.extent.YMax - ((mainDF.extent.YMax - mainDF.extent.YMin) * (locatorDF.elementHeight / mainDF.elementHeight))

#   +----+----------+----+
#   |    |          |    |
#   +----+          +----+  <-- X, Y value example
#   |                    |
#   |                    |
#   |                    |
#   |                    |
#   |                    |
#   +----+          +----+
#   |    |          |    |
#   +----+----------+----+

if corner =="SW":
    neX = mainDF.extent.XMin + ((mainDF.extent.XMax - mainDF.extent.XMin) * (locatorDF.elementWidth / mainDF.elementWidth))
    neY = mainDF.extent.YMin + ((mainDF.extent.YMax - mainDF.extent.YMin) * (locatorDF.elementHeight / mainDF.elementHeight))
    nwX = mainDF.extent.XMin
    nwY = mainDF.extent.YMin + ((mainDF.extent.YMax - mainDF.extent.YMin) * (locatorDF.elementHeight / mainDF.elementHeight))
    swX = mainDF.extent.XMin
    swY = mainDF.extent.YMin
    seX = mainDF.extent.XMin + ((mainDF.extent.XMax - mainDF.extent.XMin) * (locatorDF.elementWidth / mainDF.elementWidth))
    seY = mainDF.extent.YMin

if corner == "SE":
    neX = mainDF.extent.XMax
    neY = mainDF.extent.YMin + ((mainDF.extent.YMax - mainDF.extent.YMin) * (locatorDF.elementHeight / mainDF.elementHeight))
    nwX = mainDF.extent.XMax - ((mainDF.extent.XMax - mainDF.extent.XMin) * (locatorDF.elementWidth / mainDF.elementWidth)) 
    nwY = mainDF.extent.YMin + ((mainDF.extent.YMax - mainDF.extent.YMin) * (locatorDF.elementHeight / mainDF.elementHeight))
    swX = mainDF.extent.XMax - ((mainDF.extent.XMax - mainDF.extent.XMin) * (locatorDF.elementWidth / mainDF.elementWidth))
    swY = mainDF.extent.YMin
    seX = mainDF.extent.XMax
    seY = mainDF.extent.YMin

if corner =="NW":
    neX = mainDF.extent.XMin + ((mainDF.extent.XMax - mainDF.extent.XMin) * (locatorDF.elementWidth / mainDF.elementWidth))
    neY = mainDF.extent.YMax
    nwX = mainDF.extent.XMin
    nwY = mainDF.extent.YMax
    swX = mainDF.extent.XMin
    swY = mainDF.extent.YMax - ((mainDF.extent.YMax - mainDF.extent.YMin) * (locatorDF.elementHeight / mainDF.elementHeight))
    seX = mainDF.extent.XMin + ((mainDF.extent.XMax - mainDF.extent.XMin) * (locatorDF.elementWidth / mainDF.elementWidth))
    seY = mainDF.extent.YMax - ((mainDF.extent.YMax - mainDF.extent.YMin) * (locatorDF.elementHeight / mainDF.elementHeight))

if corner == "NE":
    neX = mainDF.extent.XMax
    neY = mainDF.extent.YMax
    nwX = mainDF.extent.XMax - ((mainDF.extent.XMax - mainDF.extent.XMin) * (locatorDF.elementWidth / mainDF.elementWidth))
    nwY = mainDF.extent.YMax
    swX = mainDF.extent.XMax - ((mainDF.extent.XMax - mainDF.extent.XMin) * (locatorDF.elementWidth / mainDF.elementWidth))
    swY = mainDF.extent.YMax - ((mainDF.extent.YMax - mainDF.extent.YMin) * (locatorDF.elementHeight / mainDF.elementHeight))
    seX = mainDF.extent.XMax
    seY = mainDF.extent.YMax - ((mainDF.extent.YMax - mainDF.extent.YMin) * (locatorDF.elementHeight / mainDF.elementHeight))

#After the coordinates are calculated, they are used to create a polygon feature and saved to a temporary shapefile.  The
#code below is nearly identical to the Polygon Class code sample found in help.     
coordList = [[[neX,neY],[nwX,nwY],[swX,swY],[seX,seY]]]
point = arcpy.Point()
array = arcpy.Array()
featureList = []
for feature in coordList:
    for coordPair in feature:
        point.X = coordPair[0]
        point.Y = coordPair[1]
        array.add(point)
    array.add(array.getObject(0))
    polygon = arcpy.Polygon(array)
    array.removeAll()
    featureList.append(polygon)

arcpy.CreateFeatureclass_management(r"in_memory", "tempFC", "POLYGON")
arcpy.CopyFeatures_management(featureList, r"in_memory\tempFC")

#The temporary shapefile is used to perform a select by location to see if it intersects with features in the index layer.
arcpy.SelectLayerByLocation_management(polyLayer, "INTERSECT", r"in_memory\tempFC", "", "NEW_SELECTION")

#Using a cursor, it checks for selected features.  If 0, then there is no intersection and the locator map can be placed there
#without conflict. If >= 1, then there is a conflict and the next location will be tested.
polyCursor = arcpy.SearchCursor(polyLayer)
polyRow = polyCursor.next()
count = 0
while polyRow:
    count = count + 1
    polyRow = polyCursor.next()

#Clear the selection
arcpy.SelectLayerByAttribute_management(polyLayer, "CLEAR_SELECTION")    

#Delete the temporary shapefile.
arcpy.Delete_management(r"in_memory\tempFC")

#Return the count value to main part of script to determine placement of locator map.
return count


#*******************************
#MAIN SCRIPT STARTS HERE
#*******************************

#read input parameter
mxdPath = os.path.join(sys.path[0], "LigSWIndex.mxd")

#Reference map document
mxd = arcpy.mapping.MapDocument(mxdPath)

#reference data frames
mainDF = arcpy.mapping.ListDataFrames(mxd, "MainDF")[0]
locatorDF = arcpy.mapping.ListDataFrames(mxd, "LocatorDF")[0]

#create PDF and check to see if it already exists
finalPDF = os.path.join(sys.path[0], "ligonier_stormwater.pdf")
if os.path.exists(finalPDF):
    os.remove(finalPDF)

outPDF = arcpy.mapping.PDFDocumentCreate(finalPDF)


#Loop through each Data Driven Page
#for pageNum in range(1, 10): # Loop through just 10 records for faster testing
for pageNum in range(1, mxd.dataDrivenPages.pageCount + 1):
    mxd.dataDrivenPages.currentPageID = pageNum
    print "Page " + str(pageNum) + " of " + str(mxd.dataDrivenPages.pageCount)
    arcpy.AddMessage("Page " + str(pageNum) + " of " + str   (mxd.dataDrivenPages.pageCount))


#Reference the index layer that uses DDP query definition
for layer in arcpy.mapping.ListLayers(mxd, "", mainDF):
    if layer.name == "Main Line":
        polyLayer = layer

#Place locator data frame - priority location is: SW, SE, NW, NE. If all conflict,
#the default is the SW corner.
if findLocation("SW", mainDF, locatorDF, polyLayer) == 0:
    locatorDF.elementPositionX = 1
    locatorDF.elementPositionY = 1
    txtSW.text = "SW = True"
elif findLocation("SE", mainDF, locatorDF, polyLayer) == 0:
    locatorDF.elementPositionX = 5.5
    locatorDF.elementPositionY = 1
    txtSE.text = "SE = True"
elif findLocation("NW", mainDF, locatorDF, polyLayer) == 0:
    locatorDF.elementPositionX = 1
    locatorDF.elementPositionY = 6
    txtNW.text = "NW = True"
elif findLocation("NE", mainDF, locatorDF, polyLayer) == 0:
    locatorDF.elementPositionX = 5.5
    locatorDF.elementPositionY = 6
    txtNE.text = "NE = TRUE"
else:
    locatorDF.elementPositionX = 1
    locatorDF.elementPositionY = 1
    txtSW.text = "NW - DEFAULT"

tempPDF = os.path.join(sys.path[0], "temp.pdf")
arcpy.mapping.ExportToPDF(mxd, tempPDF)
outPDF.appendPages(tempPDF)
os.remove(tempPDF)

outPDF.saveAndClose()
os.startfile(finalPDF)

del mxd
share|improve this question
    
As a quick fix you could try setting arcpy.env.overwriteOutput = True before the line giving the error (or earlier): help.arcgis.com/en/arcgisdesktop/10.0/help/index.html#//… –  PolyGeo Oct 20 '11 at 22:44
    
It appears this does make it successfully run, yet the data frame location appears to only be generating once, and that location appears to be synonymous with the rest of the following pages. –  Justin Zimmerman Oct 26 '11 at 12:21
    
I'm getting a very similar error using this script. Locator map position is generated once, and is used for all maps. In addition to this, temporary shapefiles are printed to PDF. Has anyone successfully executed this script? –  Czed Aug 16 '12 at 11:44

1 Answer 1

up vote 0 down vote accepted

After some tinkering around I finally got it to work for my MXD.

A lot of things should be changed for this code to be properly working. The location on the locator map position is hard coded in to the code. The name of the mxd, pdf, and the feature class should also be changed. Also make sure you are using the correct data frame names (or change them in the code.)

Hope this helps!

# Author:  
# Date:    October 24, 2011
# Version: ArcGIS 10.0
# Purpose: Move a locator data frame into a page position based on underlying
#          data.  It will test 4 corner locations and place the locator in the
#          first position there is not a conflict.  If all locations conflict,
#          it gets placed into the default position.        

import arcpy, os, sys
arcpy.env.overwriteOutput=1

#Python function
 def findLocation(corner, mainDF, locatorDF, polyLayer):

#The following funtion creates a polygon feature for each of the 4 corners of the
#main data frame.  The X,Y coordinates are calculated using the main data frame's
#extent as well as the proportional distances along the main data frame's extent. For
#example, in the figure below, the X value is simply the data frame's XMax value.  But
#the Y value is the YMax value minus the proportional distance of the locator data
#frames height compared to the main data frame's height. We know the total Y distance
#(YMax - YMin) and we know the height of each data frame (elementHeight) so we can
#multiply the Y delta by the percent of the locator data frame to the main dataframe
#to get:

# Y = mainDF.extent.YMax - ((mainDF.extent.YMax - mainDF.extent.YMin) * (locatorDF.elementHeight / mainDF.elementHeight))

#   +----+----------+----+
#   |    |          |    |
#   +----+          +----+  <-- X, Y value example
#   |                    |
#   |                    |
#   |                    |
#   |                    |
#   |                    |
#   +----+          +----+
#   |    |          |    |
#   +----+----------+----+

if corner =="SW":
    neX = mainDF.extent.XMin + ((mainDF.extent.XMax - mainDF.extent.XMin) * (locatorDF.elementWidth / mainDF.elementWidth))
    neY = mainDF.extent.YMin + ((mainDF.extent.YMax - mainDF.extent.YMin) * (locatorDF.elementHeight / mainDF.elementHeight))
    nwX = mainDF.extent.XMin
    nwY = mainDF.extent.YMin + ((mainDF.extent.YMax - mainDF.extent.YMin) * (locatorDF.elementHeight / mainDF.elementHeight))
    swX = mainDF.extent.XMin
    swY = mainDF.extent.YMin
    seX = mainDF.extent.XMin + ((mainDF.extent.XMax - mainDF.extent.XMin) * (locatorDF.elementWidth / mainDF.elementWidth))
    seY = mainDF.extent.YMin

if corner == "SE":
    neX = mainDF.extent.XMax
    neY = mainDF.extent.YMin + ((mainDF.extent.YMax - mainDF.extent.YMin) * (locatorDF.elementHeight / mainDF.elementHeight))
    nwX = mainDF.extent.XMax - ((mainDF.extent.XMax - mainDF.extent.XMin) * (locatorDF.elementWidth / mainDF.elementWidth)) 
    nwY = mainDF.extent.YMin + ((mainDF.extent.YMax - mainDF.extent.YMin) * (locatorDF.elementHeight / mainDF.elementHeight))
    swX = mainDF.extent.XMax - ((mainDF.extent.XMax - mainDF.extent.XMin) * (locatorDF.elementWidth / mainDF.elementWidth))
    swY = mainDF.extent.YMin
    seX = mainDF.extent.XMax
    seY = mainDF.extent.YMin

if corner =="NW":
    neX = mainDF.extent.XMin + ((mainDF.extent.XMax - mainDF.extent.XMin) * (locatorDF.elementWidth / mainDF.elementWidth))
    neY = mainDF.extent.YMax
    nwX = mainDF.extent.XMin
    nwY = mainDF.extent.YMax
    swX = mainDF.extent.XMin
    swY = mainDF.extent.YMax - ((mainDF.extent.YMax - mainDF.extent.YMin) * (locatorDF.elementHeight / mainDF.elementHeight))
    seX = mainDF.extent.XMin + ((mainDF.extent.XMax - mainDF.extent.XMin) * (locatorDF.elementWidth / mainDF.elementWidth))
    seY = mainDF.extent.YMax - ((mainDF.extent.YMax - mainDF.extent.YMin) * (locatorDF.elementHeight / mainDF.elementHeight))

if corner == "NE":
    neX = mainDF.extent.XMax
    neY = mainDF.extent.YMax
    nwX = mainDF.extent.XMax - ((mainDF.extent.XMax - mainDF.extent.XMin) * (locatorDF.elementWidth / mainDF.elementWidth))
    nwY = mainDF.extent.YMax
    swX = mainDF.extent.XMax - ((mainDF.extent.XMax - mainDF.extent.XMin) * (locatorDF.elementWidth / mainDF.elementWidth))
    swY = mainDF.extent.YMax - ((mainDF.extent.YMax - mainDF.extent.YMin) * (locatorDF.elementHeight / mainDF.elementHeight))
    seX = mainDF.extent.XMax
    seY = mainDF.extent.YMax - ((mainDF.extent.YMax - mainDF.extent.YMin) * (locatorDF.elementHeight / mainDF.elementHeight))

#After the coordinates are calculated, they are used to create a polygon feature and saved to a temporary shapefile.  The
#code below is nearly identical to the Polygon Class code sample found in help.     
coordList = [[[neX,neY],[nwX,nwY],[swX,swY],[seX,seY]]]
point = arcpy.Point()
array = arcpy.Array()
featureList = []
for feature in coordList:
    for coordPair in feature:
        point.X = coordPair[0]
        point.Y = coordPair[1]
        array.add(point)
    array.add(array.getObject(0))
    polygon = arcpy.Polygon(array)
    array.removeAll()
    featureList.append(polygon)


arcpy.CreateFeatureclass_management(r"in_memory", "tempFC1", "POLYGON")
arcpy.CopyFeatures_management(featureList, r"in_memory\tempFC1")

#The temporary shapefile is used to perform a select by location to see if it intersects with features in the index layer.
arcpy.SelectLayerByLocation_management(polyLayer, "INTERSECT", r"in_memory\tempFC1", "", "NEW_SELECTION")

#Using a cursor, it checks for selected features.  If 0, then there is no intersection and the locator map can be placed there
#without conflict. If >= 1, then there is a conflict and the next location will be     tested.
polyCursor = arcpy.SearchCursor(polyLayer)
polyRow = polyCursor.next()
count = 0
while polyRow:
    count = count + 1
    polyRow = polyCursor.next()

#Clear the selection
arcpy.SelectLayerByAttribute_management(polyLayer, "CLEAR_SELECTION")    

#Delete the temporary shapefile.
arcpy.Delete_management(r"in_memory\tempFC1")

#Return the count value to main part of script to determine placement of locator map.
        return count


#*******************************
#MAIN SCRIPT STARTS HERE
#*******************************

#read input parameter
mxdPath = os.path.join(sys.path[0], "LigSewerIndex.mxd")

#Reference map document
mxd = arcpy.mapping.MapDocument(mxdPath)

#reference data frames
mainDF = arcpy.mapping.ListDataFrames(mxd, "MainDF")[0]
locatorDF = arcpy.mapping.ListDataFrames(mxd, "LocatorDF")[0]

#create PDF and check to see if it already exists
finalPDF = os.path.join(sys.path[0], "ligonier_sewer.pdf")
if os.path.exists(finalPDF):
    os.remove(finalPDF)

outPDF = arcpy.mapping.PDFDocumentCreate(finalPDF)


#Loop through each Data Driven Page
#for pageNum in range(1, 10): # Loop through just 10 records for faster testing
for pageNum in range(1, mxd.dataDrivenPages.pageCount + 1):
    mxd.dataDrivenPages.currentPageID = pageNum
    print "Page " + str(pageNum) + " of " + str(mxd.dataDrivenPages.pageCount)
        arcpy.AddMessage("Page " + str(pageNum) + " of " +    str(mxd.dataDrivenPages.pageCount))


    #Reference the index layer that uses DDP query definition
    for layer in arcpy.mapping.ListLayers(mxd, "", mainDF):
        if layer.name == "Main Line":
            polyLayer = layer     

    #Place locator data frame - priority location is: SW, SE, NW, NE. If all conflict,
    #the default is the SW corner.
    if findLocation("SW", mainDF, locatorDF, polyLayer) == 0:
        locatorDF.elementPositionX = 2.2
        locatorDF.elementPositionY = 0.61

    elif findLocation("SE", mainDF, locatorDF, polyLayer) == 0:
        locatorDF.elementPositionX = 26.4
        locatorDF.elementPositionY = 0.61

    elif findLocation("NW", mainDF, locatorDF, polyLayer) == 0:
        locatorDF.elementPositionX = 2.2
        locatorDF.elementPositionY = 18.12

    elif findLocation("NE", mainDF, locatorDF, polyLayer) == 0:
        locatorDF.elementPositionX = 26.4
        locatorDF.elementPositionY = 18.12

    else:
        locatorDF.elementPositionX = 2.2
        locatorDF.elementPositionY = 0.61


    tempPDF = os.path.join(sys.path[0], "temp.pdf")
    arcpy.mapping.ExportToPDF(mxd, tempPDF)
    outPDF.appendPages(tempPDF)
    os.remove(tempPDF)

outPDF.saveAndClose()
os.startfile(finalPDF)

del mxd
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.