Field Calculator is one of the most frequently used tools within ArcMap: taught as part of nearly every introductory GIS course, it offers spreadsheet-like features to the normally static attribute table. Starting in ArcGIS 10.0, the attribute table also exposes the raw Geometry
object of each feature to Field Calculator. This underutilized feature allows for rapid access to data that normally requires running a separate geoprocessing tool and joining the result to the attribute table. Building on my previous post about geodesic areas, I’ve compiled some of the more useful one-line geometry field calculations.
These examples assume that the name of the shape field is SHAPE
. Also, don’t forget that the Python parser must be used. If you immediately see an ERROR 999999
message, then it is likely that the parser is inadvertently set to VB Script
.
Centroids and Midpoints
!SHAPE!.trueCentroid.X
and!SHAPE!.trueCentroid.Y
return the longitude and latitude coordinates of the true centroid of the feature as floating point numbers. For concave shapes (e.g. a horseshoe) this point can lie outside of the feature.!SHAPE!.labelPoint.X
and!SHAPE!.labelPoint.Y
return the longitude and latitude coordinates of the label point of the feature as floating point numbers. The label point always lies within the feature, even when concave.!SHAPE!.centroid.X
and!SHAPE!.centroid.Y
return the longitude and latitude coordinates of the centroid of the feature as floating point numbers. This is identical to the true centroid above, unless that point is outside of the feature in which case the label point is returned.!SHAPE!.positionAlongLine(0.5,True).firstPoint.X
and!SHAPE!.positionAlongLine(0.5,True).firstPoint.Y
return the longitude and latitude coordinates of the midpoint of the feature as floating point numbers. To get the coordinates for the point at another fraction along the line, replace0.5
with a value between0.0
and1.0
. For example,!SHAPE!.positionAlongLine(0.2, True)
returns the point one-fifth of the length from the start of the feature to the end of the feature. Passing inFalse
for the boolean parameter will return the point at a horizontal distance along the line rather than a fraction of the line.
Length, Perimieter, and Area
!SHAPE!.length
returns the planar length of a line feature or the planar perimeter of a polygon feature. The units are the feature’s coordinate system’s linear units. This is identical to theSHAPE_Length
field automatically added in geodatabase feature classes.!SHAPE!.getLength("PLANAR","KILOMETERS")
returns the planar length of a line feature or the planar perimieter of a polygon feature in kilometers. The area can be calculated in other units, identical to the Calculate Geometry tool in the attribute table.!SHAPE!.getLength("GEODESIC","KILOMETERS")
returns the geodesic length of a line feature or the geodesic perimeter of a polygon feature in kilometers. This accurate length calculation can be performed on feature classes in geographic coordinate systems (i.e. “unprojected”). The length can be calculated in other units and with other measurement types, as discussed in my detailed post about geodesic areas.!SHAPE!.area
returns the planar area of a polygon feature in the feature’s coordinate system as a floating point number. The units are the square of the feature’s coordinate system’s linear units. This is identical to theSHAPE_Area
field automatically added in geodatabase feature classes.!SHAPE!.getArea("PLANAR","SQUAREKILOMETERS")
returns the area of a polygon feature projected onto a two-dimensional plane in square kilometers. The area can be calculated in other units, identical to the Calculate Geometry tool in the attribute table.!SHAPE!.getArea("GEODESIC","SQUAREKILOMETERS")
returns the geodesic area of a polygon feature in square kilometers. This accurate area calculation can be performed on feature classes in geographic coordinate systems (i.e. “unprojected”). The area can be calculated in other units and with other measurement types, as discussed in the in my detailed post about geodesic areas.sorted([arcpy.Polygon(!SHAPE!.getPart(i), !SHAPE!.spatialReference).area for i in range( !SHAPE!.partCount)])[-1]
returns the area of the largest part within a polygon. If the polygon has only one part, it returns the area of that part. This complex expression gets the individual parts of a multipart polygon, retrieves their areas, stores them in a Python list via a list comprehension, sorts the list, then takes the last (i.e. largest) value.
Extents, Convex Hulls, and Compactness
!SHAPE!.extent.YMax
,!SHAPE!.extent.XMax
,!SHAPE!.extent.YMin
, and!SHAPE!.extent.XMin
return the coordinate for the north, east, south, and western bounds of the feature, respectively.!SHAPE!.extent.polygon
returns a polygonal representation of the extent that can then be the target of other operations, e.g.!SHAPE!.extent.polygon.centroid
for the centroid of the extent,!SHAPE!.extent.polygon.area
for the area of the extent,!SHAPE!.extent.polygon.length
, for the perimeter of the extent.!SHAPE!.convexHull()
returns a polygonal convex hull of an input point or line feature. This polygon can then be the target of other operations, e.g.!SHAPE!.convexHull().centroid
for the centroid of the convex hull,!SHAPE!.convexHull().extent
for the extent of the convex hull,!SHAPE!.convexHull().area
for the area of the convex hull,!SHAPE!.convexHull().length
, for the perimeter of the convex hull-.!SHAPE!.area/!SHAPE!.convexHull().area
returns the area of the feature divided by the area of the convex hull. This is a useful quick measure of compactness of concave polygons, where values closer to 1 denote more compact polygons without large concavities.
Part and Vertex Counts
!SHAPE!.partCount
returns the number of parts in the feature as an integer number. Features with more than one part as considered multipart, and consist of distinct, non-contiguous polygons linked to a single row in the attribute table.!Shape!.pointCount
returns the number of vertices in a line or polygon feature feature as an integer number. Remember that there is an additional last vertex in a polygon that is a duplicate of the first vertex to “close” the shape, so a square will return a value of 5, a hexagon will return a value of 7, etc.!Shape!.pointCount-!Shape!.partCount
returns the number of unique vertices in a valid polygon feature as an integer number. The subtraction of!Shape!.partCount
is necessary to avoid double counting the first vertex (of each part), which is repeated in order to “close” the part.
Densified and Simplified Geometry
!SHAPE!.densify("DISTANCE",1000,100)
returns a densified line or polygon with additional vertices every 1000 horizontal units and a maximum deviation from the original line of 100 horizontal units. Outputting this value to theSHAPE
field itself is equivalent to the Densify tool, except that it can be performed with only an ArcGIS for Desktop Basic license rather than a Standard license.!SHAPE!.generalize(150)
returns a simplified line with vertices removed within a tolerance of 150 horizontal units using the Douglas-Peucker algorithm. Outputting this value to theSHAPE
field itself is equivalent to the Simplify Line tool/Simplify Polygon tool, except that it can be performed with only an ArcGIS for Desktop Basic license rather than a Standard license.
Projected Geometries
- It is possible to project geometries to a new coordinate system defined by a
SpatialReference
object. The constructor for this object uses the “well-known identifier” (WKID) for different coordinate systems, as listed in this PDF of geographic coordinate systems and this PDF of projected coordinate systems. arcpy.PointGeometry(!SHAPE!.centroid, !SHAPE!.spatialReference ).projectAs(arcpy.SpatialReference(26986)).firstPoint.X
returns the longitude of the centroid projected from its native coordinate system to the NAD83 Massachusetts State Plane coordinate system (WKID 26986). To get the latitude, replace the finalX
withY
; to use different centroid types, replacecentroid
withlabelPoint
ortrueCentroid
; to output a different coordinate system, replace26986
with the output coordinate system’s WKID.!SHAPE!.projectAs(arcpy.SpatialReference(26986).exportToString()).area
returns the area of a polygon projected from its native coordinate system to the NAD83 Massachusetts State Plane coordinate system (WKID 26986). To output a different coordinate system, replace26986
with the output coordinate system’s WKID.- The previous example converts the
SpatialReference
object to a string using theexportToString()
method, while the preceding example does not. This is necessary because!SHAPE!
returns a<type 'geoprocessing describe geometry object'>
rather than a true<class 'arcpy.arcobjects.geometries.PointGeometry'>
or <class 'arcpy.arcobjects.geometries.Polyline'>
or<class 'arcpy.arcobjects.geometries.Polygon'>
object. As such, all method parameters are converted to strings viagp_fixargs()
. This works fine for thegetLength()
,getArea()
,conexHull()
,densify()
, andsimplify()
methods whose parameters are all easily stringifiedstr
,int
, andfloat
primitives. However, this stringification does not handleSpatialReference
objects. So if you encounterRuntimeError: Object: CreateObject error creating spatial reference
, try using theexportToString()
method on theSpatialReference
object.
Thanks Dan,
Very useful blog. Keep up the good work!
Really helpful summary. I especially like the simple approach to measuring “compactness”