Conversion de JSON ArcGIS Server en GeoJSON?

47

Je crée une carte Web à l'aide de Leaflet et je veux pouvoir récupérer des couches d'entités à partir de notre ArcServer. J'ai réussi à récupérer une classe d'entités au format JSON, mais les objets JSON d'Esri ne sont pas conformes aux normes GeoJSON et ne peuvent donc pas être affichés.

Est-ce que quelqu'un connaît un script de conversion ou un outil qui gère cela?

Sinon, je prévois de créer un script pour convertir les objets JSON ArcServer en GeoJSON.

Tanneur
la source
J'avais du mal à faire en sorte qu'ogr2ogr mange ESRI json à partir d'une requête de fonctionnalité MapServer. (L'exemple de @ SasaIvetic utilise une requête FeatureServer, et le résultat MapServer que je dois consommer ne doit pas avoir été interchangeable.) Quoi qu'il en soit, ce site a totalement fait l'affaire: http://ogre.adc4gis.com/
elrobis

Réponses:

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

Cette commande lira le résultat de la requête directement à partir de l'URL. Vous pouvez également lui fournir un fichier texte contenant votre JSON ou directement un JSON codé sur la ligne de commande. Vous pouvez bien sûr utiliser les liaisons ORG Python pour l’automatiser dans un script si nécessaire, ou la bibliothèque pour le faire en code.

Pour ceux qui aiment les services Web, voir Ogre, un client Web ogr2ogr capable de convertir json en géojson, puis de geojson au fichier de formes.

Référence: http://www.gdal.org/drv_geojson.html

Sasa Ivetic
la source
J'ai téléchargé FWTools. Lorsque j'exécute cette commande, le message d'erreur «Impossible d'ouvrir le source de données« Mon URL ici »avec les pilotes suivants. -> ESRI Shapefile -> Fichier MapInfo -> UK .NTF -> SDTS -> TIGER -> S57 -> DGN -> VRT -> REC -> Mémoires -> 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 Je ne vois pas quelque chose comme "ESRI JSON" dans la liste des pilotes.
Tanner
1
@Tanner: FWTools est livré avec OGR v1.7 où le support GeoJSON a été ajouté avec v1.8.0. J'utilise GDAL / OGR 1.9dev ici, mais pas via FWTools. Je pense que je les ai obtenues de gisinternals.com/sdk
Sasa Ivetic
Merci. Je dois que cela fonctionne sur la ligne de commande. Je travaille toujours à le faire fonctionner en javascript. Tous les conseils seraient appréciés.
Tanner
@Tanner, comment avez-vous passé l'erreur? Ce n'est pas un problème de version pour moi mais
j'obtiens
@ kflaw Désolé, mais je ne me souviens pas exactement. Je pense que je viens d'utiliser ogr2ogr sur la ligne de commande et que je n'ai ni besoin ni utilisé FWTools.
Tanner
7

Vous pouvez également voir les geojson-utils d’ Esri sur Github qui "contient des utilitaires [javascript] permettant de convertir GeoJSON en formats json géographiques et inversement. Actuellement, seul GeoJSON vers JSON Esri a été développé. Notez également que seules les géométries du système de coordonnées WGS84 ont été développées. sont pris en charge. "

nicogis
la source
2
Mise à jour 12/2017: geojson-utilsest obsolète. Voir arcgis-to-geojson-utils or terraformer
GavinR
5

ESRI JSON à GeoJSON (pour OpenLayers) * susceptible d'être modifié pour 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

Mapperz
la source
Si vous comptez vous convertir, vous devriez utiliser ogr2ogr
Evan Carroll le
5

ArcGIS prend désormais en charge GeoJSON

Désormais, ArcGIS Online utilise GeoJSON via l'URL de l'API ArcGIS Rest. Tout ce que vous avez à faire est de définir f=geojsonl'URL et de configurer le service. Sachez que, par défaut, ArcGIS Online n'autorise pas l' exportation GeoJSON tant que vous n'autorisez pas explicitement d'autres formats de sortie.

Voici comment activer l'exportation:

  1. Connectez-vous à arcgis en ligne
  2. cliquez sur les couches d'entités,
  3. cliquez sur l'onglet de réglage
  4. cochez cette case qui dit

    Exporter des données

    Autoriser les autres à exporter vers différents formats.

  5. Enregistrez et attendez quelques minutes.

Dans la page de requête, vous devriez voir la liste déroulante de format de sortie avec l'option GeoJSON. Le vieux s'appelait json.

Hoogw
la source
Un service de repos Agol est-il différent d'un service de repos de serveur ArcGIS? Agol peut-il seulement fournir geoJSON en tant que service de repos et non pas serveur?
jeudi
4

Couche Leaflet et vecteur ArGIS.

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

Démo de travail. http://geojason.info/leaflet-vector-layers/demos/arcgis-server/

Plus d'informations sur Leaflet et ArcGIS.

  • Couches Leaflet et ArcGIS Server, à savoir AgsDynamicLayer et AgsFeatureLayer.

Vous pouvez obtenir ce fork qui prend en charge le serveur 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/

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

ns-1m
la source
3

J'ai créé une extension d'objet serveur pour générer GeoJSON à partir des services de carte ArcGIS Server. Il a été testé avec 10.1 et 10.2 mais pas plus tôt. https://github.com/geobabbler/AGSOpenFormats

Bill Dollins
la source
3

Pour une conversion ponctuelle, j'aurais utilisé la réponse acceptée de @Sasa Ivetic, mais j'avais besoin de quelque chose en temps réel et Terraformer a travaillé correctement pour cela. Malheureusement, il s’agit uniquement de fonctionnalités uniques par défaut. Vous devez donc parcourir en boucle la matrice et ajouter un ID à chaque fonctionnalité:

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

Cela a bien fonctionné pour moi, sauf pour les polygones en plusieurs parties (c'est-à-dire l'Alaska et ses îles), mais je suis novice dans ce domaine et il est donc possible que j'ai mal codé quelque chose!

abettermap
la source
3

Conversion d'ArcGIS JSON en GeoJSONThere dans un navigateur pur

il y a 2 façons de faire

1) TERRAFORMER

Note: utilisation dans node.js et utilisation dans le navigateur sont différentes , détails voir lien

2) Esri / arcgis-to-geojson-utils

utiliser dans le navigateur, ArcgisToGeojsonUtils est une référence var globale du point d’entrée de ce 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
}

});

Toutefois, si vous souhaitez regrouper par vous-même, juste pour apprendre, suivez les étapes

a) Vous devez compiler tout le fichier source du module dans un seul bundle.js

rollup.js installer par

npm install --global rollup

puis allez dans votre dossier racine js lib, recherchez le fichier js du point d’entrée, dans ce cas c’est index.js

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

Vous devriez trouver un nouveau fichier bundle.js dans votre répertoire racine.

Maintenant, dans le fichier html de votre navigateur, incluez ce fichier bundle.js

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

Vous pouvez l'utiliser maintenant par

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

Rappelez-vous que esri_arcgis_to_geojson est le nom que vous avez appelé la lib

Cela devient le nom de la variable globale, disponible dans le navigateur.

Le truc, c’est que le processus de groupement ajoute une fonction d’implémentation instantanée comme (fonction xx {}), voici la partie supérieure 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

Hoogw
la source
2

C'est généralement * très facile à convertir.

J'ai créé un script https://github.com/calvinmetcalf/esri2geo et d'autres fonctionnent également.

* L'exception concerne les polygones en plusieurs parties avec des trous qui ne sont pas convertis 1 à 1 sans géotraitement.

Calvin
la source
1

Si c'est une requête unique et que vous n'avez pas plus de 1000 fonctionnalités, essayez de la coller dans qgis en utilisant le calque add vector - choisissez le protocole et remplacez cette URL de repos arcgis par la vôtre: http://geodata.epa.gov/arcgis / rest / services / OAR / USEPA_NEI_2005 / MapServer / 1 / query? où = objectid +% 3D + objectid & outfields = * & f = json ... Cela suppose que gdal 1.10 est installé

utilisateur33290
la source
1

Peut-être même plus facilement, vous pouvez utiliser la bibliothèque Esri- Leaflet pour l'ajouter de manière native en tant que couche dans Leaflet.

Andrew Turner
la source
2
Pourriez-vous incorporer un exemple dans votre message décrivant comment cette réponse est la question du PO?
Paul le
0

Si tout ce dont vous avez besoin est de renvoyer le service ArcServer en tant que GeoJSON à utiliser dans la technologie de cartographie de votre choix, je vous recommande vivement de consulter ce dialogue relatif au problème GitHub .

Je ne vais pas reproduire le dialogue ici car cela ferait perdre du temps. Vos options sont clairement définies directement depuis Esri.

Shawn Goulet
la source
-1

serveur arcgis rest api, service d'entités,

si vous interrogez la couche, avec une URL telle que celle-ci, ... / 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}}

Vous ne pouvez pas définir le format geojson, f = pgeojson sera une mauvaise requête, f = json, car les informations de retour ne sont pas des fonctionnalités, les couches que json a renvoyées.

Essayez cette page de requête html, vous pouvez voir, pas d’option geojson,

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

Si vous souhaitez renvoyer geojson (fonctionnalité), vous devez utiliser cette URL ... / FeatureServer / 0 / query ...

/ 0 / signifie que layerID, s'il est sur 1 couche, alors layerID = 0 .....

Essayez cette page de requête html, vous pouvez voir, geojson est une option, car vous couchez une couche spécifique avec layerID = 0

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

Remarque: n'oubliez pas de définir ces 2 paramètres: outSR = 4326 & f = geojson dans l'ID de référence spatiale de l'URL, srid = 4326, car la carte Web utilise tous ce format, le format f signifie, f = pgeojson et f = geojson fonctionnent. Si vous ne définissez pas outSR = 4326, l'API restante du serveur Arcgis, par défaut, n'utilisera PAS 4326, mais une autre méthode. Seul 4326 a un degré unitaire, qui est utilisé dans la plupart des cartes Web. Les autres formats ne fonctionneraient pas avec les cartes Web.

À propos, pour ceux qui veulent utiliser l’application de repos de serveur d’arcgis avec le service de tuiles,

tilestream et autres

/zoom(z)/x/y.png

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

Service de tuiles de serveur Arcgis: pas de png, x et y dans un ordre différent

     /zoom(z)/y/x

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

Hoogw
la source