ArcGIS Python Geometry from Shapely
The ArcGIS Python API Geometry object includes the capability to export the geometry to a Shapely Geometry object, but not the capability to create a new ArcGIS Geometry object from a Shapely object. Thankfully, it is not difficult to add this capability to every ArcGIS Geometry object in a namespace.
Periodically I am working in an environment without
arcpy available. Typically this is when using Docker containers, but also can simply be due to working natively in a Mac environment as well. In these environments, if I need to perform geometry manipulation operations, I need to convert ArcGIS Geometry objects to Shapely Geometry objects, perform the spatial operations, and convert the Shapely Geometry objects back to ArcGIS Geometry objects.
Converting from ArcGIS Geometry to Shapely Geometry is easy enough using the
as_shapely method. Going the other way is not as easy since there is not a native method. Simply add the following code at the top, and you will have the
from_shapely method available on any type of Geometry object in the same namespace.
from arcgis.geometry import BaseGeometry @classmethod def from_shapely(cls, shapely_geometry): return cls(shapely_geometry.__geo_interface__) BaseGeometry.from_shapely = from_shapely
Then, doing something like snapping a point to a line, and then trimming the line at the point can be performed using Shapely with the results being converted back to ArcGIS Python geometry objects.
from shapely import ops from arcgis.geometry import Geometry # convert from ArcGIS to Shapely shapely_linestring = arcgis_polyline.as_shapely shapely_point = arcgis_point.as_shapely # snap using Shapely snap_point = shapely_linestring.interpolate( shapely_linestring.project(shapely_point) ) # trim using Shapely (split and only keep the first LineString) trim_linestring = ops.split(shapely_linestring, snap_point) # convert back to ArcGIS and replace original variable values arcgis_polyline = Geometry.from_shapely(trim_linestring) arcgis_point = Geometry.from_shapely(snap_point)