[GIS] Using Python to field calculate Lat/Long with decimal degrees rather than meters

arcpyfield-calculatorlatitude longitude

The below is a snippet of a python script that I am writing that basically adds two fields – Latitude and Longitude, then calculates them. I could use the Add XY Tool which gets me to the same point. The way that I did it with the expression3 and expression4 variables should work but doesn't. The projection is WGS 84 the script works fully from start to finish. The columns are calculated in meters rather than decimal degrees which is what is needed for the project.

Any thoughts?

... 
... 
... 

## Add Lat/Long Fields 
inFeature = "Point_Feature_Class" 
fieldName1 = "Latitude" 
fieldName2 = "Longitude" 
fieldType = "DOUBLE" 
arcpy.AddField_management(inFeature, fieldName1, fieldType) 
arcpy.AddField_management(inFeature, fieldName2, fieldType) 

## Execute CalculateField of Lat/Long Fields 
expression1 = "{0}".format("!SHAPE.extent.XMax!") 
expression2 = "{0}".format("!SHAPE.extent.YMax!") 
#expression3 = "{0}".format("!SHAPE.extent@decimaldegrees!") 
#expression4 = "{0}".format("!SHAPE.extent@decimaldegrees!") 

arcpy.CalculateField_management(inFeature, fieldName1, expression1, "PYTHON_9.3") 
arcpy.CalculateField_management(inFeature, fieldName2, expression2, "PYTHON_9.3") 
#arcpy.CalculateField_management(inFeature, fieldName1, expression3, "PYTHON_9.3") 
#arcpy.CalculateField_management(inFeature, fieldName2, expression4, "PYTHON_9.3")

... 
... 
...

Best Answer

As stated in the tool documentation for Calculate Field:

Python expressions can use the geometry area and length properties with an areal or linear unit to convert the value to a different unit of measure (for example, !shape.length@kilometers!)

These expressions are not usable with points or individual coordinates. Fortunately, you can use other properties and methods of the pointGeometry and point classes to get your desired result.

Since your data is already in a geographic coordinate system, the following will return latitude and longitude values of your points. (Technically this returns the coordinates of the first part of each point, but that's only relevant if you are using MultiPoint geometry).

!SHAPE!.firstPoint.X #Longitude
!SHAPE!.firstPoint.Y #Latitude

If your data were in a different coordinate system, the following field calculator expressions convert each point to a PointGeometry object and then use the projectAs to project each point to the WGS84 geographic coordinate system before getting the coordinates. If your data has a datum other than WGS84, you should use the appropriate SpatialReference object constructed using the name or well-known ID of the datum.

arcpy.PointGeometry(!Shape!.firstPoint,!Shape!.spatialReference).projectAs(arcpy.SpatialReference(4326)).firstPoint.X
arcpy.PointGeometry(!Shape!.firstPoint,!Shape!.spatialReference).projectAs(arcpy.SpatialReference(4326)).firstPoint.X

I don't know why it's necessary to create the PointGeometry object instead of just running projectAs on !SHAPE!. On ArcMap 10.3 the !SHAPE! object is <type 'geoprocessing describe geometry object'> while the PointGeometry is <class 'arcpy.arcobjects.geometries.PointGeometry'> in ArcMap 10.3. This is not necessary when using cursors in Python.

Related Question