Converting geometries between GeoJSON, esri JSON, and esri Python

17903
4
Jump to solution
03-31-2014 05:53 AM
FilipKrál
Occasional Contributor III
Hi,
I want to be able to convert geometries between GeoJSON [1], esri JSON [2, 3], and esri Python objects [4] using ArcGIS 10.1 SP1.

[1] http://geojson.org/geojson-spec.html
[2] http://resources.arcgis.com/en/help/main/10.1/index.html#//018v0000004m000000
[3] https://developers.arcgis.com/javascript/jsapi/geometry-amd.html etc.
[4] http://resources.arcgis.com/en/help/main/10.1/index.html#/Geometry/018z00000070000000/

Converting GeoJSON to esri Python using arcpy.AsShape as described in [2] works.

However, converting esri JSON to esri Python described in example 6 on the same help page [2] raises an error.
I understand the error but none of my experiments worked and this example is from the official help.
esri_json = {"paths" : [[[-97.08, 32.8], [-97.05, 32.6], [-97.06, 32.7], [-97.07, 32.6]], [[-97.4, 32.5], [-97.2, 32.75]]], "spatialReference" : {"wkid" : 4326}} polyline = arcpy.AsShape(esri_json, True) >>> # returns Traceback (most recent call last):   File "<editor selection>", line 1, in <module> TypeError: AsShape() takes exactly 1 argument (2 given)


I believed it was possible to get esri JSON from esri Python using the JSON property on geometry objects [4], but this consistently fails with errors like:
Traceback (most recent call last):   File "<editor selection>", line 6, in <module> AttributeError: 'PointGeometry' object has no attribute 'JSON'


Do you know about a reliable way of converting esri geometries to GeoJSON in Python?

I would be grateful for any comments.
Filip.
Tags (2)
0 Kudos
1 Solution

Accepted Solutions
JasonScheirer
Occasional Contributor III
The AsShape() takes exactly 1 argument (2 given) and AttributeError: 'PointGeometry' object has no attribute 'JSON' errors imply that you're on an version of ArcGIS before the JSON stuff was added. I thought I got all of that in at 10.1 SP1, maybe your install is messed up? Try replacing geometries.py and arcobjects.py in arcpy from a fresh install of 10.1 SP1 and see if that helps.

You can try the esri2open toolbox or the geojson-madness toolbox and see if either of those work for you. If you're willing to experiment in the browser or on your local computer with node.js then Terraformer is also an option.

If you go the geojson-madness route, there are two simple functions you could lift for your own purposes. One will reliably convert an arcpy geometry into GeoJSON and the other will turn GeoJSON into an arcpy geometry (via WKT).

View solution in original post

0 Kudos
4 Replies
JasonScheirer
Occasional Contributor III
The AsShape() takes exactly 1 argument (2 given) and AttributeError: 'PointGeometry' object has no attribute 'JSON' errors imply that you're on an version of ArcGIS before the JSON stuff was added. I thought I got all of that in at 10.1 SP1, maybe your install is messed up? Try replacing geometries.py and arcobjects.py in arcpy from a fresh install of 10.1 SP1 and see if that helps.

You can try the esri2open toolbox or the geojson-madness toolbox and see if either of those work for you. If you're willing to experiment in the browser or on your local computer with node.js then Terraformer is also an option.

If you go the geojson-madness route, there are two simple functions you could lift for your own purposes. One will reliably convert an arcpy geometry into GeoJSON and the other will turn GeoJSON into an arcpy geometry (via WKT).
0 Kudos
FilipKrál
Occasional Contributor III
Many thanks for your reply, Jason, and apologies for not checking my setup. The machine I was using yesterday did not have Service Pack 1 installed. Today I am with SP1 and the JSON property on geometries works as a charm.

I couldn't find out-of-the-box arcpy conversion to GeoJSON but the functions you pointed out in your geojson-madness library do the job.

Below I am adding my notes on this topic in context of Python/JavaScript in case anyone is interested. Corrections and additions are more than welcome.

Filip.

Converting geometries between esri JSON, GeoJSON, and arcpy objects
In Python with arcpy:

# GeoJSON     --> esri Python : arcpy.AsShape(x)
# GeoJSON     --> esri JSON   : arcpy.AsShape(x).JSON
# esri Python --> GeoJSON     : geojson-madness.geometry_to_struct(x)
# esri Python --> esri JSON   : x.JSON
# esri JSON   --> esri Python : arcpy.AsShape(x, True)
# esri JSON   --> GeoJSON     : geojson-madness.geometry_to_struct(arcpy.AsShape(x, True))


In JavaScript with esri js api and Terraformer:
// esri JSON  --> esri JSAPI   : esri.geometry.jsonUtils.fromJson(json)
// GeoJSON    --> esri JSAPI   : Terraformer.ArcGIS.convert(...)
// esri JSON  --> GeoJSON      : Terraformer.ArcGIS.parse(...)
// esri JSAPI --> GeoJSON      : Terraformer.ArcGIS.parse(...)
// esri JSAPI --> esri JSON    : esri JSON is representation of esri JSAPI
// GeoJSON    --> esri JSON    : Terraformer.ArcGIS.convert(...)


Support for spatial reference in json is generally poor. Information about coordinate system is often lost in translation to different format. Often WGS84 is the only officially supported coordinate system. Therefore, extra care must be taken to handle coordinate systems properly on both server and client side.

Spatial reference in GeoJSON can be defined on any object by the 'crs' member, which is inherited and should not be overridden on children. For example:
crs_wgs84 = {'type': 'EPSG', 'properties': {'code': 4326}}
crs_osgb = {'type': 'EPSG', 'properties': {'code': 27700}}


Spatial reference is esri JSON can be defined as WKT or WKID. For example:
//{"wkid" : <wkid>, "latestWkid" : <wkid>, "vcsWkid" : <wkid>,"latestVcsWkid" : <wkid>}
var web_mercator = {"wkid" : 102100, "latestWkid" : 3857 }
var osgb = {"wkid": 27700}


Notable Python libraries
import arcpy
import json
from osgeo import gdal
from osgeo import ogr
import shapely         # https://pypi.python.org/pypi/Shapely
import pysal           # http://pysal.readthedocs.org/en/latest/index.html
import geojson-madness # https://github.com/jasonbot/geojson-madness


Notable JavaScript libraries
Terraformer https://github.com/Esri/Terraformer
proj4js http://trac.osgeo.org/proj4js/
geojson-utils https://github.com/Esri/geojson-utils
koop (js server) https://github.com/Esri/koop

Other notes
ArcGIS 10.2 has tools 'JSON to Features' and 'Features to JSON' tools.

ogr2ogr should be able to convert formats to OGRGeoJSON.
http://www.gdal.org/ogr/drv_geojson.html
ogr2ogr -f GeoJSON test.json "http://sampleserver3.arcgisonline.com/ArcGIS/rest/services/Hydrography...

There is an ArcGIS Server Object Extension that adds support for GeoJSON (didn't try it personally)
https://github.com/geobabbler/AGSOpenFormats

Somebody already had an ArcGIS Idea

RESOURCES
GeoJSON Specification:http://geojson.org/geojson-spec.html
esri JavaScript geometries:
https://developers.arcgis.com/javascript/jsapi/geometry-amd.html
http://www.esri.com/industries/landing-pages/geoservices/~/media/Files/Pdfs/library/whitepapers/pdfs...
http://resources.arcgis.com/en/help/arcgis-rest-api/#/Geometry_Objects/02r3000000n1000000/
JoshuaBixby
MVP Esteemed Contributor

A couple of comments since this is an older thread.  Since 2014, Esri started support GeoJSON with Features To JSON—Help | ArcGIS Desktop at ArcGIS 10.5, which is handy for exporting sets of geometry objects to GeoJSON.  Unfortunately, sadly, JSON To Features—Help | ArcGIS Desktop  still does not support GeoJSON at ArcGIS 10.6.

Also, since 2014, the GeoJSON has been formally adopted as RFC 7946 - The GeoJSON Format .  Although what the IETF adopted was mostly the same, there are some important differences in the standard, most notably with the removal of alternative coordinate reference systems.  GeoJSON is now all ESPG: 4326.

JasonScheirer
Occasional Contributor III
Also, arcpy geometry objects have the __geo_interface__ attribute which does GeoJSON in most cases. It was unreliable with Polygons with rings until 10.2.1.
0 Kudos