This is for ArcGIS 10, Python 2.65.
I have code which captures the extent of dataframes within all mxd's in a directory. I also want it to add the dataframe name, scale and the name of the MXD it extracted the extent polygon from.
The current code that I have give the following errors.
P:\2011\Job_031_TownPlanning_SeriesProduction\Working\mxd\1
P:\2011\Job_031_TownPlanning_SeriesProduction\Working\mxd\1\temp_extents
Created…Polygon_Extent_1 Irvinebank
I
Up to here the code is fine.
Executing: AddField
P:\2011\Job_031_TownPlanning_SeriesProduction\Working\mxd\1\temp_extents\Polygon_Extent_1.shp ExtentID TEXT # # # # NON_NULLABLE NON_REQUIRED # Start Time: Thu May 12 08:49:57 2011 Adding ExtentID to P:\2011\Job_031_TownPlanning_SeriesProduction\Working\mxd\1\temp_extents\Polygon_Extent_1.shp…
Succeeded at Thu May 12 08:49:57 2011
(Elapsed Time: 0.00 seconds)
It creates the column but I want it to put in the x'th value from the array of dataframe names and the test print statement only produces either the full list or the x'th character in the list.
Filling
in Traceback (most
recent call last): File
"P:\2011\Job_031_TownPlanning_SeriesProduction\Working\mxd\1\extent_creation4.py",
line 64, in
row.strField = str(x) File "C:\Program
Files\ArcGIS\Desktop10.0\arcpy\arcpy\arcobjects_base.py", line 35, in setattr
return setattr(self._arc_object, attr, ao) RuntimeError: ERROR 999999:
Error executing function.
These are errors in writing to the row. I also want it to capture the MXD file name
The updated code is below.
import arcpy, glob, os
from arcpy import env
from arcpy import mapping
env.overwriteOutput = True
path = os.getcwd() # Script in same directory as files being processed
path2 = path + r'\temp_extents'
mxdList = glob.glob(path + "\*.mxd")
print 'Working in ' + path
os.mkdir(path2)
env.workspace = path2
x = 0
y = 1
z = 1
while y < 7:
print 'Processing ' + mxd
for mxd in mxdList:
mxd2 = mapping.MapDocument(mxd)
try:
dataframe = mapping.ListDataFrames(mxd2, "*")[x]
frameExtent = dataframe.extent
print frameExtent
XMAX = frameExtent.XMax
XMIN = frameExtent.XMin
YMAX = frameExtent.YMax
YMIN = frameExtent.YMin
pnt1 = arcpy.Point(XMIN, YMIN)
pnt2 = arcpy.Point(XMIN, YMAX)
pnt3 = arcpy.Point(XMAX, YMAX)
pnt4 = arcpy.Point(XMAX, YMIN)
array = arcpy.Array()
array.add(pnt1)
array.add(pnt2)
array.add(pnt3)
array.add(pnt4)
array.add(pnt1)
polygon = arcpy.Polygon(array)
#Create Polygon Shapefile
arcpy.CreateFeatureclass_management(path2, "Polygon_Extent" + "_" + str(z), "POLYGON")
arcpy.CopyFeatures_management(polygon, "Polygon_Extent" + "_" + str(z))
print 'Created...' "Polygon_Extent" + "_" + str(z)
#Capture and Enter ExtentID, File Name and other info
for el in arcpy.mapping.ListLayoutElements(mxd2, "DATAFRAME_ELEMENT"):
ExtentIDStore = str(el.name)
print ExtentIDStore #used to see which item to add to the shape file
print ExtentIDStore[x] # should show the full entry at storage x but instead shows the character at x
dfStore = path2 + "\Polygon_Extent" + "_" + str(z) + ".shp"
arcpy.AddField_management(dfStore,'ExtentID','TEXT') #should only be done once per shp
arcpy.AddField_management(dfStore,'FileRef','TEXT') #should only be done once per shp
arcpy.AddField_management(dfStore,'Scale','SHORT') #should only be done once per shp
#END - Capture and Enter ExtentID, File Name and other info
z = z + 1
except IndexError:
pass
x = x + 1
y = y + 1
list = []
lstFCs = arcpy.ListFeatureClasses("Polygon_Extent*")
print 'Merging Polygon_Extents* to Extent.shp'
for fc in lstFCs:
list.append(fc)
arcpy.Merge_management(list, "Extent")
print 'Created Extent.shp and exiting'
In response to the answer by Nathan.
Yes extentID=name of Dataframe.
I am still having problems with writing to the shapefile. I thought
rows = arcpy.InsertCursor(dfStore, mxd2)
row = rows.newRow()
print 'Filling in ', rows
row.ExtentID = ExtentIDStore
filepath = mxd2.filePath # Gets full path of MXD used in your dataframe loop
filename = os.path.basename(filepath) # Extracts the file name and extension
row.FileRef = filename
scale = el.scale
row.Scale = scale
would work but the values aren't inputed into the shapefile. What am I not understanding here?
—- UPDATED ISSUE
The code is now creating the desired output (of file name, extent, scale etc) but it seems to be overwriting the row which holds the polygon attribute -rather than appending the scale, extent etc values into the appropriate columns in the row.
I've tried placing the code for this in different loops but it makes no difference.
Output
Reading 2 mxd files from Q:\Software\GIS\ESRI\ArcGIS10\CustomScripts\temp\Extents
Processing
Q:\Software\GIS\ESRI\ArcGIS10\CustomScripts\temp\Extents\10_TownPlanning_B&L_Overlay_Ver2b_Kuranda.mxd
Created…Q:\Software\GIS\ESRI\ArcGIS10\CustomScripts\temp\Extents\t10\Polygon_Extent_1.shp
desc = Name:
Shape Type : True Scale
: False Number of fields: 1 Filled in
Koah
10_TownPlanning_B&L_Overlay_Ver2b_Kuranda.mxd
40000.0 into Q:\Software\GIS\ESRI\ArcGIS10\CustomScripts\temp\Extents\t10\Polygon_Extent_1.shp
desc = Name:
Shape Type : True Scale
: False Number of fields: 1 Filled in
Overview
10_TownPlanning_B&L_Overlay_Ver2b_Kuranda.mxd
750000.0 into Q:\Software\GIS\ESRI\ArcGIS10\CustomScripts\temp\Extents\t10\Polygon_Extent_1.shp
desc = Name:
Shape Type : True Scale
: False Number of fields: 1 Filled in
Kuranda
10_TownPlanning_B&L_Overlay_Ver2b_Kuranda.mxd
40000.0 into Q:\Software\GIS\ESRI\ArcGIS10\CustomScripts\temp\Extents\t10\Polygon_Extent_1.shp
Processing
Q:\Software\GIS\ESRI\ArcGIS10\CustomScripts\temp\Extents\9_TownPlanning_B&L_Overlay_Ver2b_MtMalloy.mxd
… Merging Polygon_Extents* to
Extent.shp Deleting identical entries
Created Extent.shp and exiting
import arcpy, glob, os
from arcpy import env
from arcpy import mapping
env.overwriteOutput = True
path = os.getcwd() # Script in same directory as files being processed
path2 = path + r'\t6'
mxdList = glob.glob(path + "\*.mxd")
count_Mapdocs = len(mxdList)
#env.workspace = path + '\extents' # Directory as files being processed
print 'Reading '+str(count_Mapdocs)+ ' mxd files from ' + path
os.mkdir(path2)
env.workspace = path2
x = 0
y = 1
z = 1
while y < 7:
for mxd in mxdList:
print 'Processing ' + mxd
mxd2 = mapping.MapDocument(mxd)
try:
dataframe = mapping.ListDataFrames(mxd2, "*")[x]
frameExtent = dataframe.extent
XMAX = frameExtent.XMax
XMIN = frameExtent.XMin
YMAX = frameExtent.YMax
YMIN = frameExtent.YMin
pnt1 = arcpy.Point(XMIN, YMIN)
pnt2 = arcpy.Point(XMIN, YMAX)
pnt3 = arcpy.Point(XMAX, YMAX)
pnt4 = arcpy.Point(XMAX, YMIN)
array = arcpy.Array()
array.add(pnt1)
array.add(pnt2)
array.add(pnt3)
array.add(pnt4)
array.add(pnt1)
polygon = arcpy.Polygon(array)
#Create Polygon Shapefile
arcpy.CreateFeatureclass_management(path2, "Polygon_Extent" + "_" + str(z), "POLYGON")
arcpy.CopyFeatures_management(polygon, "Polygon_Extent" + "_" + str(z))
dfStore = path2 + "\Polygon_Extent" + "_" + str(z) + ".shp"
print 'Created...' + dfStore
arcpy.AddField_management(dfStore,'ExtentID','TEXT') #should only be done once per shp
arcpy.AddField_management(dfStore,'FileRef','TEXT') #should only be done once per shp
arcpy.AddField_management(dfStore,'Scale','FLOAT') #should only be done once per shp
#Capture and Enter ExtentID, File Name and other info
for el in arcpy.mapping.ListLayoutElements(mxd2, "DATAFRAME_ELEMENT"):
desc = arcpy.Describe(dfStore)
print "desc =" + str(desc)
indexList = arcpy.ListIndexes(dfStore)
# Iterate through the list of indexes
# This is just to check on whats going on.
for index in indexList:
# Print index properties
#
print "Name: " + index.name
print "\tType : " + str(index.isAscending)
print "\tScale : " + str (index.isUnique)
print "\tNumber of fields: " + str(len(index.fields))
rows = arcpy.InsertCursor(dfStore, desc)
row = rows.newRow()
ExtentIDStore = el.name
row.ExtentID = ExtentIDStore
filepath = mxd2.filePath # Gets full path of MXD used in your dataframe loop
filename = os.path.basename(filepath) # Extracts the file name and extension
row.FileRef = filename
scale = el.scale
row.Scale = float(scale)
# This is just to check on whats going on.
print 'Filled in ', str(ExtentIDStore), str(filename), str(scale) + " into " + dfStore
rows.insertRow(row) # insert value into the row (should be the same row as
z = z + 1
except IndexError:
pass
x = x + 1
y = y + 1
list = []
lstFCs = arcpy.ListFeatureClasses("Polygon_Extent*")
print 'Merging Polygon_Extents* to Extent.shp'
for fc in lstFCs:
list.append(fc)
arcpy.Merge_management(list, "Extent")
print 'Deleting identical entries'
arcpy.DeleteIdentical_management("Extent.shp", ["SHAPE"])
print 'Created Extent.shp and exiting'
Best Answer
I'm a bit lost here, so my answer may be off base. When you say you want the
ExtentID
, that appears to be the name of the Dataframe you're exporting the extent of. If this is the case (which is what your code is doing to my best guess), you don't need the [x] index when printing it. :By the time you reach the loop above, your code is only concerned with the Dataframe Element in question, so there is no need to do any indexing for storage.
ExtendIDStore
should be what you add to the shapefile row.Your error which results at this line:
Is probably because you are not referencing a field that exists. What comes after the row reference is the name of the Field. In this case, it should be:
File name you can get via the
filePath
property of the MapDocument class and theos.path.basename
method, i.e.:If you don't want the extension, use
filename.strip(".mxd")
to remove it.Scale would be:
And that should fill in the rows you're looking for.
For the new problem, I think you are misusing the insert cursor. The second argument should be a spatial reference, which cannot be gleaned via an MXD. I would recommend creating the cursor with only one argument (the output file or dfStore). You also forgot the last (and most important) line:
Without that your data never gets put into the table. Put that down at the end of the row loop so that the data is actually inserted after all the variables are set.
For more information about accessing Dataframe, layer, and map properties (scale, name, current position), check out the mapping module. The scale property of the Dataframe class can be seen on the classes page of the same name.