¿Convertir ArcGIS Server JSON a GeoJSON?


47

Estoy creando un mapa web con Leaflet , y quiero poder tomar capas de entidades de nuestro ArcServer. He podido recuperar con éxito una clase de entidad como JSON, pero los objetos JSON de Esri no siguen los estándares GeoJSON, por lo que no se pueden mostrar.

¿Alguien sabe de una secuencia de comandos de conversión o herramienta que maneja esto?

Si no, planeo crear un script para convertir objetos JSON de ArcServer a GeoJSON.


Estaba teniendo problemas para que ogr2ogr comiera ESRI json proveniente de una consulta de características de MapServer. (El ejemplo de @ SasaIvetic utiliza una solicitud de FeatureServer, y el resultado de MapServer que necesito consumir no debe haber sido intercambiable.) De todos modos, este sitio hizo el truco: http://ogre.adc4gis.com/
elrobis

Respuestas:


40

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

Ese comando leerá el resultado de la consulta directamente desde la URL. También puede proporcionarle un archivo de texto que contenga su JSON o puede proporcionar directamente JSON codificado en la línea de comando. Por supuesto, puede usar enlaces ORG Python para automatizarlo dentro de un script si es necesario, o la biblioteca para hacerlo en código.

Para aquellos a los que les gustan los servicios web, vea Ogre, un cliente web ogr2ogr que puede convertir json a geojson y viceversa, así como geojson a shapefile.

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


Descargué FWTools. Cuando ejecuto ese comando, aparece el error 'No se puede abrir el origen de datos' Mi URL aquí 'con los siguientes controladores. -> 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 No veo algo como 'ESRI JSON' en la lista de controladores.
Tanner

1
@Tanner: FWTools viene con OGR v1.7 donde se agregó el soporte GeoJSON con v1.8.0. Estoy ejecutando GDAL / OGR 1.9dev aquí, aunque no a través de FWTools. Creo que los obtuve de gisinternals.com/sdk
Sasa Ivetic

Gracias. Tengo esto para trabajar en la línea de comando. Todavía estoy trabajando para que funcione en mi Javascript; cualquier consejo sería apreciado.
Tanner

@ Tanner, ¿cómo superaste ese error? No es un problema de versión para mí, pero recibo el mismo error en mi máquina Windows
kflaw

@kflaw Lo siento, pero no recuerdo exactamente. Creo que acabo de usar ogr2ogr en la línea de comandos, y no necesité ni usé FWTools.
Tanner

7

También puede ver las utilidades geojson de Esri en Github que "contienen utilidades [javascript] para convertir GeoJSON a otros formatos geográficos json y viceversa. Actualmente solo se ha desarrollado GeoJSON a Esri JSON. Además, tenga en cuenta que solo las geometrías en el sistema de coordenadas WGS84 son compatibles."


2
Actualización 12/2017: geojson-utilsestá en desuso. Ver arcgis-to-geojson-utils o terraformer
GavinR

5

ESRI JSON a GeoJSON (para OpenLayers) * Probable de ser modificado para JavaScript de folleto

        //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;>

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


Si vas a convertir deberías usar ogr2ogr
Evan Carroll

5

ArcGIS ahora es compatible con GeoJSON

Ahora ArcGIS Online tiene GeoJSON a través de ArcGIS Rest API URL. Todo lo que necesita hacer es establecer f=geojsonen la URL y configurar el servicio. Tenga en cuenta que, de forma predeterminada, ArcGIS en línea no permitirá la exportación de GeoJSON hasta que explícitamente permita otros formatos de salida.

Aquí se explica cómo habilitar la exportación:

  1. Inicie sesión en arcgis en línea
  2. haga clic en las capas de entidades,
  3. haga clic en la pestaña de configuración
  4. marque esta casilla que dice

    Exportar datos

    Permitir que otros exporten a diferentes formatos.

  5. Ahorra y espera unos minutos.

En la página de consulta, debería ver la lista desplegable del formato de salida con la opción GeoJSON. El viejo fue llamado json.


¿Es un servicio de descanso agol diferente de un servicio de descanso del servidor ArcGIS? ¿Agol solo puede proporcionar geoJSON como un servicio de descanso y no como servidor?
jotamon

4

Folleto y capa vectorial ArGIS.

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

Demo de trabajo. http://geojason.info/leaflet-vector-layers/demos/arcgis-server/

Más sobre Folleto y ArcGIS.

  • Folleto y capas de ArcGIS Server, es decir, AgsDynamicLayer y AgsFeatureLayer.

Puede obtener esta bifurcación que tiene soporte para el servidor ArcGIS.

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/

Servicios de ArcGIS Image y folleto http://blog.geomusings.com/2012/04/17/arcgis-image-services-and-leaflet/



3

Para una conversión de una sola vez, hubiera utilizado la respuesta aceptada de @Sasa Ivetic pero necesitaba algo en tiempo real, y Terraformer trabajó decentemente para eso. Desafortunadamente, solo es para funciones únicas de forma predeterminada, por lo que para múltiples funciones debe recorrer la matriz y agregar una ID a cada función:

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)
};

Esto funcionó bien para mí, excepto en polígonos de varias partes (es decir, Alaska y sus islas), pero soy nuevo en esto, ¡así que es posible que haya codificado algo incorrectamente!


3

Convertir ArcGIS JSON a GeoJSONThere en puro navegador

hay 2 formas de hacerlo

1) TERRAFORMADOR

Nota: el uso en node.js y el uso en el navegador son diferentes , ver detalles en el enlace

2) Esri / arcgis-to-geojson-utils

uso en el navegador, ArcgisToGeojsonUtils es una referencia global var el punto de entrada de este módulo

<script src="https://unpkg.com/@esri/arcgis-to-geojson-utils@1.2.0/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
}

});

Sin embargo, si desea agruparlo solo, solo para aprender, siga los pasos

a) Necesita compilar todo el archivo fuente del módulo en un solo paquete.js

rollup.js instalar por

npm install --global rollup

luego vaya a su carpeta raíz js lib, busque el archivo js del punto de entrada, en este caso es index.js

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

Debería encontrar un nuevo archivo bundle.js en su directorio raíz.

Ahora en el archivo html de su navegador, incluya este archivo bundle.js

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

Puedes usarlo ahora por

  // 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

Recuerda que esri_arcgis_to_geojson es el nombre que llamaste lib

Este se convierte en el nombre de la variable global, disponible en el navegador.

El truco es que el proceso de paquete agrega una función de implementación instantánea como (function xx {}) aquí está la parte superior de 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


2

Por lo general, es * una conversión bastante fácil.

Hice un script https://github.com/calvinmetcalf/esri2geo y hay otros que también funcionan bien.

* La excepción son los polígonos de varias partes con agujeros que no convierten 1 a 1 sin un poco de geoprocesamiento.



1

Quizás aún más fácil puede usar la biblioteca de Esri-leaflet para agregarlo de forma nativa como una capa en Leaflet.


2
¿Podría incorporar un ejemplo en su publicación que describa cómo esta respuesta es la pregunta del OP?
Paul

0

Si todo lo que necesita es devolver el servicio ArcServer como GeoJSON para usar en la tecnología de mapeo que desee, le recomiendo que mire este diálogo de problema de GitHub .

No voy a replicar el diálogo aquí porque eso perdería tiempo. Sus opciones están claramente establecidas directamente desde Esri.


-1

API de resto de servidores de ArcGIS, servicio de funciones,

si consulta la capa, con una URL como esta, ... / 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}}

No puede establecer el formato geojson, f = pgeojson será una mala solicitud, f = json, porque el material de retorno no es una característica, las capas json fueron devueltas.

Pruebe esta página de consulta html, puede ver, no hay opción de geojson,

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

Si desea devolver geojson (característica), debe usar esta URL ... / FeatureServer / 0 / query ...

/ 0 / significa layerID, si on solo tiene 1 capa, entonces layerID = 0 .....

Pruebe esta página de consulta html, puede ver, geojson es una opción, porque es una capa específica de consulta con layerID = 0

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

Nota: recuerde establecer esos 2 parámetros: outSR = 4326 & f = geojson en el ID de referencia espacial de URL, srid = 4326, porque todos los mapas web usan esto, f significa formato, tanto f = pgeojson como f = geojson funciona. Si no establece SR = 4326, la API de resto del servidor arcgis por defecto NO usará 4326, en su lugar usará otra cosa, solo 4326 tiene un grado de unidad, que se usa en la mayoría de los mapas web. Otro formato no funcionaría con los mapas web.

Por cierto, para aquellos que quieran usar la API de rest del servidor arcgis con el servicio de mosaico,

tiletream y otros

/zoom(z)/x/y.png

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

servicio de mosaico del servidor arcgis: no png, x e y en orden diferente

     /zoom(z)/y/x

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

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.