23

In ArcGIS 10 and Python I want to get the extent (xmax, ymax, xmin, ymin) info of each of the polygons in a shapefile.

I can get the extent of the whole shapefile using

file=r"D:\SCRATCH\ARCGIS\100k_trc_tiles_TVM.shp"
desc=arcpy.Describe(file)
print desc.extent.Xmax

394551.52085039532

But I can't seem to figure out how to get the same info for each row in the dataset.

rows = arcpy.SearchCursor("100k_trc_tiles_TVM")
for row in rows:
 print row

prints the 31 rows in the dataset but

for row in rows:
 desc=arcpy.Describe(row)
 print desc.extent.Xmax

gives an error.

Runtime error : Object: Describe input value is not valid type

I was thinking of adding the extent values to the table using "calculate geometry" but this only gives the centroid. Then I guess we can use something like row.GetValue("xmax").

That being said I know that we can create the X/Y, max/min using the function from http://www.ian-ko.com/free/free_arcgis.htm but it would be best if we can avoid having to add fields, especially if ArcPy can get these values.

Basically I need to get the extents to feed into the clip tool to clip out 30 areas of data (according to the 1:100,000 map sheets) for geoprocessing since the Split tool fails due to the large size of the dataset (see Why Intersect gives ERROR 999999: Error executing function Invalid Topology [Too many lineseg endpoints]?). I want to automate this as it is repeated on a number of datasets.

=== working script ===

# Emulates Arc Info SPLIT tool by using Clip but
# Requires a FC from which each row is used as the input clip feature.
# Each row must be rectangular.
# Used on 12GB FGDB with 100 million records.


#Licence: Creative Commons
#Created by: George Corea; [email protected], [email protected]
import arcpy, string

#inFrame=arcpy.GetParameterAsText(0) # Input dataframe FC
#inFile=arcpy.GetParameterAsText(1) # Input FC for splitting
#outDir=arcpy.GetParameterAsText(2) # Output FGDB

inFrame=r"D:\SCRATCH\ARCGIS\100k_trc_tiles_TVM.shp"
inFile=r"c:\junk\106\data\7_Merge.gdb\FullRez_m2b"
outDir=r"D:\SCRATCH\Projects\206\datasplit\test_slaasp.gdb"
#NameField="Name_1"

#arcpy.env.workspace = r"C:/Workspace"
arcpy.env.overwriteOutput = True

rows = arcpy.SearchCursor(inFrame)
shapeName = arcpy.Describe(inFrame).shapeFieldName
for row in rows:
    feat = row.getValue(shapeName)
    Name = row.Name_1
    print "Executing clip on: "+str(Name)
    extent = feat.extent
    #print extent.XMin,extent.YMin,extent.XMax,extent.YMax
# Create an in_memory polygon
    XMAX = extent.XMax
    XMIN = extent.XMin
    YMAX = extent.YMax
    YMIN = extent.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)
    ShapeFile = outDir+"\\temp_poly"
    arcpy.CopyFeatures_management(polygon, ShapeFile)

    #print Name
### Set local variables
    in_features = inFile
    clip_features = ShapeFile
    out_feature_class = outDir+"\\"+Name
    xy_tolerance = "0.22"

    # Execute Clip

    try:
        arcpy.Clip_analysis(in_features, clip_features, out_feature_class, xy_tolerance)
        print "Completed: "+str(Name)
    except:
        error = arcpy.GetMessages()
        print "Failed on: "+str(Name)+" due to "+str(error)
0

5 Answers 5

29

Get the shape object in your cursor and access its extent property. See ArcGIS Help Working with geometry in Python:

rows = arcpy.SearchCursor(inFeatures)

shapeName = arcpy.Describe(inFeatures).shapeFieldName
for row in rows:
    feat = row.getValue(shapeName)
    extent = feat.extent
    print extent.XMin,extent.YMin,extent.XMax,extent.YMax

While the above works it is better to use the newer, more performant arcpy.da cursor syntax which was introduced in ArcGIS Desktop 10.1:

with arcpy.da.SearchCursor(inFeatures, ['SHAPE@']) as rows:
    for row in rows:
        extent = row[0].extent
        print(extent.XMin,extent.YMin,extent.XMax,extent.YMax)
0
2

Another way would be to do a SearchCursor() on the shapefile, then you can use row.shape.extent:

rows = arcpy.SearchCursor(shapefileName)

for row in rows:
   extent = row.shape.extent
   ...
   ...
2

I just tried the Minimum Bounding Geometry (Envelope) (in Data Management) in ArcGIS 10 and it seems to do exactly the same, for all the fields.

1

Try capitalizing the "M" in "XMax". I think it's supposed to be:

print desc.extent.XMax

instead of

print desc.extent.Xmax

according to the documentation. Of course that makes me wonder how your first code snippet worked.

0

As covered in Extracting coordinates of polygon vertices in ArcMap? you can get get the vertices of a polygon and then add the x and y coordinates of each vertex as fields in the attribute table. This has the limitation of not attaching the max/min coordinates directly to each polygon but this can be achieved in a few ways.

The method I am most familiar with is to read the x and y fields into python lists using the pyshp module, which can then be sorted to find maximum and minimum values for each polygon. Pyshp can then be used to open a writer class to add new fields to the original polygons and write these max and min values to the correct polygon.

I believe this can be done using the arcpy, but I had a lot of problems with writing to shapefiles in 9.3 using the geoprocessor, so I prefer the pyshp method, however I am unsure if the arcpy module has solved these issues.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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