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.

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

Upto 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")
    #env.workspace = path + '\extents' # Directory as files being processed

    print 'Working in ' + path
    #os.remove(path2 + r'\*.*')
    #os.rmdir(path2)
    os.mkdir(path2)
    env.workspace = path2
    #print env.workspace

    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 x, y, z
         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"
         #open (dfStore, 'w')
         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
         #print arcpy.GetMessages()

    # code to add ExtentID value to shp file
         #rows = arcpy.InsertCursor(dfStore)
         #print 'Filling in ', rows
         #row = rows.newRow()
         #row.strField = str(x)
         #rows.insertRow(row)
         #print arcpy.GetMessages()

      #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'

  #for item in list:
  #arcpy.Delete_management(item)

In response to the answer by Nathan.

Yes extentID=name of Dataframe.

I am still having problems with writing to the shape file. 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 shape file. What am I not understanding here?

best,

---- 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.

Thanks for any advice.

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'

#for item in list:
# arcpy.Delete_management(item)
share|improve this question
2  
Could you elaborate on what you are doing? –  Dan Patterson May 11 '11 at 3:19
1  
It is not clear if you want to use a datafame extent to insert a value into a field attribute. or possibly insert a dynamically generated shape file into a dataframe. I would say either way you need to make it clearer what you are looking for. –  Brad Nesom May 11 '11 at 4:20
    
sorry... I am capturing the extents of multiple mxd's into a single shape file (working) and now I want to write the dataframe ID into the shape file. It should also add in the name of the mxd and the scale. For some reason the following ... 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 ... Thanks for your help. –  GeorgeC May 11 '11 at 7:09
2  
@geoge - it is ok to edit your question and add, clarify, or post images to help. The formatting is much easier to read in the question as opposed to the comments. –  Brad Nesom May 11 '11 at 13:11
1  
Thanks Dan and Brad. I have updated the post and included the whole code. I really appreciate your help. Cheers, –  GeorgeC May 12 '11 at 0:28
show 1 more comment

1 Answer

up vote 0 down vote accepted

I'm a bit lost here, so excuse me if my answer is off base. George, when you say you want the ExtentID, isn't that just 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. :

 for el in arcpy.mapping.ListLayoutElements(mxd2, "DATAFRAME_ELEMENT"):
     ExtentIDStore = str(el.name)
     #print x, y, z <--- You don't need to print x y and z. They are unrelated at this point.
     print ExtentIDStore #used to see which item to add to the shape file

     print ExtentIDStore[x] # <- This will just print an indexed character in the string

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:

row.strField = str(x)

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:

row.ExtentID = ExtentIDStore

File name you can get via the filePath property of the MapDocument class and the os.path.basename method, i.e.:

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

If you don't want the extension, use filename.strip(".mxd") to remove it.

Scale would be:

scale = el.scale # Scale of the dataframe referenced in the loop
row.Scale = scale

And that should fill in the rows you're looking for.

Update: 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:

rows.insertRow(row)

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.

P.S. 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.

share|improve this answer
    
Thanks N. Please see my edited Q above. I couldn't figure out how to include code etc in the comments. –  GeorgeC Jun 7 '11 at 4:02
    
Editing your question is the right option to add code and update it as your needs change. Updated my answer for you. Give it a shot! –  Nathanus Jun 7 '11 at 15:22
    
Thanks. This works great. The only issue is with scale - "el.scale" is el meant to be the current dataframe/extent? and scale a value extracted automatically by python from it? What document lists all the values that Python can extract from a mxd...? Sorry I am learning python without any formal course... –  GeorgeC Jun 9 '11 at 3:46
    
Added a post script for you with some references. –  Nathanus Jun 9 '11 at 12:26
    
What am I doing wrong? the script seems to be adding the extent, scale etc into a new row and overwriting the polygon attributes of the row. I've updated the question with the new code and output. Thanks for your help so far... –  GeorgeC Jun 9 '11 at 23:43
show 1 more comment

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.