2

I am trying to find the area of a particular polygon (OriginalPolygon, below), and I can do that... But, I'd like it in acres regardless of the original units of the polygon.(Data is coming into this script in a range of projections, but we're always interested in "acreage.")

If I was calculating geometry to store in a field, then I could use feat.area@acres -- but I don't need this stored as an attribute, I just need it as a temporary variable to tell the user. This question implies that unless I'm actually calculating geometry, the units of the shape area measurement are tied to the projection and therefore fixed.

So: Is there any way to calculate geometry in such a way that the value is only a numerical output that I can display as the script runs, or am I stuck with making an attribute field, calculating geometry, reading the field value to tell the user, and then deleting the field?

rows = arcpy.SearchCursor(OriginalPolygon)
shapeName = arcpy.Describe(OriginalPolygon).shapeFieldName
for row in rows:
    feat = row.getValue(shapeName)
    PolygonArea = feat.area
Erica
  • 8,974
  • 4
  • 34
  • 79

3 Answers3

4

I've never been able to accomplish this directly. In the past what I've done instead is to retrieve the area information the same way you have and then I access the SpatialReference of the Feature Class to determine what the linear units are.

Assuming that the majority of spatial reference systems use either meters or feet, I just write a simple conditional to determine my conversion factor and use that factor to calculate the area in my desired units.

Being able to do it directly certainly would be a nice feature.

Brian
  • 4,209
  • 4
  • 33
  • 53
3

As @Brian stated, in lieu of an ESRI provided solution, it's pretty easy to just write a function that will calculate acres for units of your datasource. And if you find that you need to add another conversion, you just add one more conversion line to it.

So you could just add the following into your code (amending your code from above).

def getAcres(area,units):
    if units.lower() == "foot":
        return area * 0.0000229568411
    elif units.lower() == "meter":
        return area * 0.00024711

shapeName = arcpy.Describe(OriginalPolygon).shapeFieldName
units = arcpy.Describe(OriginalPolygon).spatialReference.linearUnitName ## Get the units

rows = arcpy.SearchCursor(OriginalPolygon)
for row in rows:
    feat = row.getValue(shapeName)
    PolygonArea = getAcres(feat.area,units)

If you really wanted to get fancy (and have one-size-fits-all reusable code), you could even write the function to accept an option for output units, and then have a whole bunch of conversion routines that could be called for various input/output formats.

UPDATE: If you want a quick-and-dirty solution, you can also use the arcpy Geometry object, and get the Area using the getArea method of the Geometry object within the ArcGIS Python window. For example, you can write the following:

Single feature selected:

geometries = arcpy.CopyFeatures_management("YOUR_LAYER",arcpy.Geometry())
print geometries[0].getArea("GEODESIC","ACRES")

Multiple features selected:

geometries = arcpy.CopyFeatures_management("YOUR_LAYER",arcpy.Geometry())
for geom in geometries:
  print geom.getArea("GEODESIC","ACRES")

I feel like there's probably a better way to create/access the geometries object rather than CopyFeatures, but that's for another day.

RyanKDalton
  • 23,068
  • 17
  • 110
  • 178
  • 1
    +1 Re the last idea: with n input units possible and m output units, that would require mn conversion routines, which can be huge. Instead, just pick a standard unit once and for all (such as a square meter) and assign to each unit--whether input or output--its size in square meters, the "conversion factor." That requires at most m* + n numbers (and usually just max(m,n) because both lists contain common units). Then you need only one simple conversion routine which merely multiplies the answer by the input factor and divides it by the output factor. – whuber Nov 15 '13 at 17:24
1

As of ArcGIS 10.2.2 you can use the geometry getArea method (see doc)

def shedarea(in_poly, atype="GEODESIC", aunits="SQUAREMILES"):
    sumarea = 0
    with arcpy.da.SearchCursor(in_poly, "SHAPE@") as rows:
        for row in rows:
            sumarea += row[0].getArea(atype, aunits)
    return sumarea
Curtis Price
  • 1,560
  • 13
  • 12
  • +1 For people looking for Square US Foot calculations, you can use row[0].getArea('PLANAR', 'SQUAREFEET') / 1.0000040000120005 – Barbarossa Feb 16 '23 at 15:52