50

I'm creating a web map using Leaflet, and I want to be able to grab feature layers from our ArcServer. I have successfully been able to retrieve a feature class as JSON, but Esri's JSON objects don't follow the GeoJSON standards so they cannot be displayed.

Does anyone know of a conversion script or tool that handles this?

If not, I plan on creating a script to convert ArcServer JSON objects to GeoJSON.

PolyGeo
65.5k29 gold badges115 silver badges350 bronze badges
asked Aug 3, 2011 at 17:23
1
  • I was having trouble getting ogr2ogr to eat ESRI json coming from a MapServer feature query. (@SasaIvetic's example uses a FeatureServer request, and the MapServer result I need to consume must not have been interchangeable.) Anyway, this site totally did the trick: http://ogre.adc4gis.com/ Commented Oct 12, 2015 at 16:08

14 Answers 14

42

OGR:

ogr2ogr -f GeoJSON test.json "http://sampleserver3.arcgisonline.com/ArcGIS/rest/services/Hydrography/Watershed173811/FeatureServer/0/query?where=objectid+%3D+objectid&outfields=*&f=json" OGRGeoJSON

That command will read the query result directly from the URL. You can also supply it with a text file containing your JSON or you can directly supply encoded JSON on the command line. You can of course use ORG Python bindings to automate it within a script if necessary, or the library to do it in code.

For those that like web services, see Ogre an ogr2ogr web client which can convert json to geojson to and back, as well as geojson to shapefile.

Reference: http://www.gdal.org/drv_geojson.html

jbchurchill
4,49924 silver badges41 bronze badges
answered Aug 3, 2011 at 17:46
5
  • I downloaded FWTools. When I run that command, I get the error 'Unable to open datasource 'My URL here' with the following drivers. -> ESRI Shapefile -> MapInfo File -> UK .NTF -> SDTS -> TIGER -> S57 -> DGN -> VRT -> REC -> Memory -> BNA -> CSV -> NAS -> GML -> GPX -> KML -> GeoJSON -> Interlis 1 -> Interlis 2 -> GMT -> SQLite -> ODBC -> PGeo -> OGDI -> PostgreSQL -> MySQL -> XPlane -> AVCBin -> AVCE00 -> DXF -> Geoconcept -> GeoRSS -> GPSTrackMaker -> VFK I don't see something like 'ESRI JSON' in the list of drivers. Commented Aug 3, 2011 at 20:15
  • 1
    @Tanner: FWTools comes with OGR v1.7 where GeoJSON support was added with v1.8.0. I'm running GDAL/OGR 1.9dev here, though not through FWTools. I think I got them from gisinternals.com/sdk Commented Aug 3, 2011 at 20:33
  • Thanks. I got this to work on the command line. I'm still working on getting it to work in my Javascript - any tips would be appreciated. Commented Aug 4, 2011 at 18:03
  • @Tanner how did you get past that error? It's not a version issue for me but I'm getting the same error on my windows machine Commented Jun 22, 2016 at 19:45
  • @kflaw Sorry, but I don't recall exactly. I think I just used ogr2ogr on the command line, and didn't need or use FWTools. Commented Jun 23, 2016 at 17:19
9

You can also see Esri's geojson-utils on Github that "contains [javascript] utilities for converting GeoJSON to other geographic json formats and vice versa. Currently only GeoJSON to Esri JSON has been developed. Also, note that only geometries in the WGS84 coordinate system are supported."

matt wilkie
28.3k35 gold badges150 silver badges286 bronze badges
answered Mar 22, 2013 at 14:12
1
9

ArcGIS now supports GeoJSON

Now ArcGIS Server (since 10.4) and ArcGIS Online has GeoJSON through ArcGIS Rest API URL. All you need to do is set f=geojson in the URL and configure the service. Be aware, by default, ArcGIS Online will not allow GeoJSON export until you explicit permit other output formats.

Here is how to enable the export:

  1. Log into ArcGIS Online
  2. Click the feature layers,
  3. Click the setting tab
  4. Check this box that says

Export Data

Allow others to export to different formats. 5. Save and wait a few minutes.

In the query page, you should see the output format dropdown list with the GeoJSON option. The old was called json.

Vince
20.5k16 gold badges49 silver badges65 bronze badges
answered Oct 17, 2016 at 23:00
3
  • 1
    Is a agol rest service different from an ArcGIS server rest service? Can only agol provide geoJSON as a rest service and not server? Commented Mar 29, 2018 at 23:57
  • I just edited the asnwer, hopefully will be shown soon, this is also supported in ArcGIS Server as of 10.4 Commented Jul 9, 2020 at 1:36
  • While AGOL/ArcGIS Server do "support" GeoJSON, attempting to export data using this format can lead to timeouts. Try downloading data from the USGS "National Map" endpoints. The JSON endpoints do not appear to suffer from this timeout issue. Commented Dec 18, 2021 at 11:42
7

ESRI JSON to GeoJSON (for OpenLayers) *Likely to be modified for Leaflet javascript

 //create esri JSON object
 var myReturn = "esriObj = "+xmlHttpGet(restCall, false);
 eval(myReturn);
I can now work with esriObj as a JSON object i.e. esriObj.geometryType. What happens in the xmlHttpGet method? Basically I create a XMLHttpRequest and pass in my REST URL – your can see this code here
3. OK i have my ‘ESRI query’ JSON object now I need to parse the features in this object and essentially create GeoJSON strings which the OpenLayers sample will be happy with – cue the code butchery...
function esriDeserialize(geojson)
{
 var element = document.getElementById('text');
 var type = document.getElementById("formatType").value;
 var features = formats['in'][type].read(geojson);
 var bounds;
 if(features)
 {
 if(features.constructor != Array) {
 features = [features];
 }
 for(var i=0; i<features.length;>
 if (!bounds) {
 bounds = features[i].geometry.getBounds();
 } else {
 bounds.extend(features[i].geometry.getBounds());
 }
 }
 vectors.addFeatures(features);
 //map.zoomToExtent(bounds);
 var plural = (features.length &gt; 1) ? 's' : '';
 //element.value = features.length + ' feature' + plural + ' added'
 } else {
 element.value = 'Bad input ' + type;
 }
}
function getEsriGeom(restCall){
 //call ESRI Rest API
 //"http://pc302926/ArcGIS/rest/services/worldadmin/MapServer/0/query?text=&amp;geometry=&amp;geometryType=esriGeometryEnvelope&amp;inSR=&amp;spatialRel=esriSpatialRelIntersects&amp;where=%22FIPS_CNTRY%22+%3D+%27AS%27&amp;returnGeometry=true&amp;outSR=4326&amp;outFields=&amp;f=json"
 var element = document.getElementById('text'); 
 //create esri JSON object
 var myReturn = "esriObj = "+xmlHttpGet(restCall, false);
 eval(myReturn);
 element.value = "";
 var coordPairsPerFeature = 0;
 //for each feature
 for (var i=0; i &lt; esriObj.features.length; i++)
 {
 //get the geometry
 var o = esriObj.features[i].geometry;
 element.value = element.value + esriObj.features[i].attributes.ADMIN_NAME;
 //loop through all the rings
 for (var s=0; s &lt; o.rings.length; s++)
 {
 //create geojson start &amp; end - i know i'm getting polygons
 var geojsonstart = '{"type":"Feature", "id":"OpenLayers.Feature.Vector_124", "properties":{}, "geometry":{"type":"Polygon", "coordinates":[['
 var geojsonend = ']]}, "crs":{"type":"OGC", "properties":{"urn":"urn:ogc:def:crs:OGC:1.3:CRS84"}}}';
 //the coordinates for this ring
 var coords = o.rings[s];
 //loop through each coordinate
 var coordPair="";
 for (var g=0; g &lt; coords.length; g++)
 {
 coordPairsPerFeature = coordPairsPerFeature+1;
 //alert(coords[g]);
 if(g==coords.length-1){
 coordPair = coordPair+"["+coords[g]+"]";
 }else{
 coordPair=coordPair+"["+coords[g]+"],";
 }
 }
 //combine to create geojson string
 esriDeserialize(geojsonstart+coordPair+geojsonend);
 }
 element.value = element.value + "," + coordPairsPerFeature +"n";
 }
}
</features.length;>

source: http://mapbutcher.com/blog/?p=62

answered Aug 3, 2011 at 17:52
2
  • If you're going to convert you should use ogr2ogr Commented Jan 12, 2017 at 7:36
  • "*Likely to be modified for Leaflet javascript" - is there an update? (also, the Map Butcher URL is 404 :-( Commented Nov 10, 2020 at 21:09
6

Converting ArcGIS JSON to GeoJSONThere in pure Browser

there are 2 ways you can do

1) @terraformer/arcgis

Note: use in node.js and use in browser are different, details see link

2) Esri/arcgis-to-geojson-utils

use in browser, ArcgisToGeojsonUtils is global var reference the entry point of this module

<script src="https://unpkg.com/@esri/[email protected]/dist/arcgis-to-geojson.js"></script>
// parse ArcGIS JSON, convert it to GeoJSON
const geojson = ArcgisToGeojsonUtils.arcgisToGeoJSON({
"x":-122.6764,
"y":45.5165,
"spatialReference": {
 "wkid": 4326
}

});

However, if you want to bundle by yourself, just for learning, follow steps

a) You need to compile all the module source file into a single bundle.js

rollup.js install by

npm install --global rollup

then go to your js lib root folder, find the entry point js file, in this case it is index.js

$ rollup index.js --format umd --name "esri_arcgis_to_geojson" --file bundle.js

You should find a new file bundle.js in your root directory.

Now in your browser html file, include this bundle.js file

<script src='.../.../.../bundle.js'>

You can use it now by

 // parse ArcGIS JSON, convert it to GeoJSON
 var geojson = esri_arcgis_to_geojson.arcgisToGeoJSON({
 "x":-122.6764,
 "y":45.5165,
 "spatialReference": {
 "wkid": 4326
 }
 });
 
 // take GeoJSON and convert it to ArcGIS JSON
 var arcgis = esri_arcgis_to_geojson.geojsonToArcGIS({
 "type": "Point",
 "coordinates": [45.5165, -122.6764]
 });enter code here

Remember esri_arcgis_to_geojson is the name you named the lib

This becomes the global variable name, available in browser.

The trick is, bundle process add instant implement function like (function xx {}) here is the top part from bundle.js

 (function (global, factory) {
 typeof exports === 'object' && typeof module !== 'undefined' ? 
 factory(exports) :
 typeof define === 'function' && define.amd ? define(['exports'], 
 factory) :
 (factory((global.arcgis_to_geojson = {})));
 }(this, (function (exports) { 'use strict';
 ***ORIGINAL SOURCE CODE OF JS MODULE***
 })));
 

arcgis-to-geojson-utils

answered Oct 14, 2016 at 17:31
1
  • This webpage: ArcGIS JSON to GeoJSON uses Terraformer and you can see an example of how it's used here Commented Jul 24, 2024 at 14:13
4

Leaflet and ArGIS vector layer.

https://github.com/JasonSanford/leaflet-vector-layers

Working demo. http://geojason.info/leaflet-vector-layers/demos/arcgis-server/

More on Leaflet and ArcGIS.

  • Leaflet and ArcGIS Server layers i.e. AgsDynamicLayer and AgsFeatureLayer.

You can get this fork which has support for ArcGIS server.

https://github.com/dtsagile/Leaflet/

 var sitesLayer = new L.AgsDynamicLayer(
 'http://ags2.dtsagile.com/ArcGIS/rest/services/LiveFeeds/WxMappr/MapServer',
 { maxZoom: 19,
 attribution: "NOAA",
 opacity: 1,
 layers: 'show:2' });
_map.addLayer(sitesLayer);

http://blog.davebouwman.com/2011/08/04/leaflet-lean-mean-javascript-maps/

ArcGIS Image Services and Leaflet http://blog.geomusings.com/2012/04/17/arcgis-image-services-and-leaflet/

answered Apr 21, 2012 at 3:58
3

Its usually* pretty easy converting.

I made a script https://github.com/calvinmetcalf/esri2geo and there are others that work well too.

*The exception is multi-part polygons with holes which don't convert 1-to-1 without some geoprocessing.

answered Dec 31, 2012 at 20:54
3

I've built a server object extension to generate GeoJSON from ArcGIS Server map services. It's been tested with 10.1 and 10.2 but not earlier. https://github.com/geobabbler/AGSOpenFormats

answered Sep 11, 2013 at 2:40
3

For a one-time conversion I would have used the accepted answer from @Sasa Ivetic but needed something real-time, and Terraformer worked decently for that. Unfortunately it's only for single features by default, so for multiple features you need to loop through the array and add an ID to each feature:

var FeatureCollection = {
 type: "FeatureCollection",
 features: []
}
for (var i = 0; i < arcgis.features.length; i++) {
 var feature = Terraformer.ArcGIS.parse(arcgis.features[i]);
 feature.id = i;
 FeatureCollection.features.push(feature)
};

This worked fine for me except on multi-part polygons (i.e. Alaska and its islands), but I'm new to this so it's possible I coded something incorrectly!

answered Jul 18, 2014 at 13:13
1

If its a one time query and you don't have more than 1000 features try pasting this into qgis by using the add vector layer - choose protocol and replace this arcgis rest URL with yours: http://geodata.epa.gov/arcgis/rest/services/OAR/USEPA_NEI_2005/MapServer/1/query?where=objectid+%3D+objectid&outfields=*&f=json ... This assumes you have gdal 1.10 installed

answered Jul 18, 2014 at 23:21
1

I made a web version of ESRI's Terraformer tool for ESRI JSON -> GeoJSON conversion in the browser at https://observablehq.com/@thadk/arcgis-json-parser-to-geojson which can be customized as needed when the ArcGIS server does not allow you to export it as GeoJSON directly.

answered Nov 29, 2019 at 8:55
0

Perhaps even easier you can use the Esri-leaflet library to add it natively as a layer in Leaflet.

PolyGeo
65.5k29 gold badges115 silver badges350 bronze badges
answered Sep 26, 2013 at 17:29
1
  • 3
    Could you incorporate an example in your post outlining how this answer's the OP's question? Commented Sep 26, 2013 at 18:00
0

If all you need is to return the ArcServer Service as a GeoJSON to use in whichever mapping tech you want, I highly recommend you look at this GitHub issue dialogue.

I am not going to replicate the dialogue here because that would waste time. Your options are clearly laid out there directly from Esri.

mgri
16.4k6 gold badges48 silver badges80 bronze badges
answered Jan 27, 2017 at 17:46
-1

arcgis server rest api, feature service,

if you query the layer, with URL like this, .../FeatureServer/query?layerDefs=...

http://services3.arcgis.com/your_token/arcgis/rest/services/Parcels/FeatureServer/query?layerDefs={"0":""}&returnGeometry=true&f=pgeojson&geometryType=esriGeometryEnvelope&geometry={"xmin" : -117.923158, "ymin" : 33.644081, "xmax" : -117.921436, "ymax" : 33.645157,"spatialReference" : {"wkid" : 4326}}

You can not set geojson format, f=pgeojson will be bad request, f=json, because the return stuff is not feature, the layers json was return.

Try this html query page, you can see, no geojson option,

 http://services3.arcgis.com/you_token/arcgis/rest/services/Parcels/FeatureServer/query

If you want to return geojson (feature), you must use this URL .../FeatureServer/0/query...

/0/ means layerID, if on has only 1 layer, then layerID = 0.....

Try this html query page, you can see, geojson is option, because you are query specific layer with layerID = 0

http://services3.arcgis.com/your_token/arcgis/rest/services/Parcels/FeatureServer/0/query

Note: remember to set those 2 parameters: outSR=4326&f=geojson in the URL spatial reference ID, srid = 4326, because web map all use this, f means format, both f=pgeojson and f=geojson works. If you don't set outSR=4326, arcgis server rest api by default will NOT use 4326, instead use something else, only 4326 has unit degree, which is used in most web map. Other format would not work with web maps.

By the way, for those want to use arcgis server rest api with tile service,

tilestream and others

/zoom(z)/x/y.png

http://localhost/v2/city_parcels/12/706/1641.png

arcgis server tile service: no png, x and y in different order

 /zoom(z)/y/x

http://services3.arcgis.com/your_token/ArcGIS/rest/services/Parcels/MapServer/tile/12/1641/706

answered Oct 18, 2016 at 16:24

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.