[GIS] How to figure out the length of polyline features in a feature class with a WGS 1984 coordinate system

arcgis-desktoparcpycoordinate systemwgs84

I'm trying to figure out lengths of polyline features in a feature class with a WGS 1984 coordinate system.

Here's code to list lengths:

>>> import arcpy
>>> inFc = r"C:\Users\e1b8\Desktop\E1B8\GIS_Stackexchange\data.gdb\test"
>>> sr = arcpy.Describe (inFc).spatialReference
>>> sr.name
u'GCS_WGS_1984'
>>> with arcpy.da.SearchCursor (inFc, "SHAPE@") as cursor:
    for geom, in cursor:
        print geom.length

0.000785568606752
0.000784558202405
0.00117166138222
0.000816779544786

I'm not sure what units these lengths are in. I know it's generally in the coordinate system's linear units, but WGS 1984 has no linear units.

>>> sr.linearUnitName
u''

Ultimately I'd like to be able to write code that works with distances and is compatible with both projected and geographic coordinate systems. Usually I use the spatial reference's metersPerUnit property to get to a common unit regardless of the coordinate system's unit, but this throws an error for WGS 1984:

>>> sr.metersPerUnit

Traceback (most recent call last):
  File "<pyshell#13>", line 1, in <module>
    sr.metersPerUnit
AttributeError: SpatialReference: Get attribute metersPerUnit does not exist

So again, how can I get the length of features? And preferably, how do I figure out their lengths in meters?

Best Answer

I thought at first the arcpy.Polyline.getLength() method would work, as you can specify a measurement type and units but it did not because it is GCS. As you can see here, we are still in Decimal Degrees:

>>> with arcpy.da.SearchCursor("line_wgs", 'SHAPE@') as rows:
...     for row in rows:
...         print row[0].getLength('PLANAR', 'METERS')
...         
0.00193201661559
>>> desc = arcpy.Describe("line_wgs")
>>> desc.spatialReference.factoryCode
4326

What you can do is add a spatial reference to your search cursor (such as the Web Mercator):

>>> with arcpy.da.SearchCursor("line_wgs", 'SHAPE@', spatial_reference=arcpy.SpatialReference(102100)) as rows:
...     for row in rows:
...         print row[0].getLength('PLANAR', 'METERS')
...         
215.071313581
>>> 

Note, since WGS Web Mercator is in meters you can just use the length property as you did in your first one:

>>> with arcpy.da.SearchCursor("line_wgs", 'SHAPE@', spatial_reference=arcpy.SpatialReference(102100)) as rows:
...     for row in rows:
...         print row[0].length
...         
215.071313581
>>>