Convertendo JSON do ArcGIS Server em GeoJSON?

47

Estou criando um mapa da web usando o Leaflet e quero poder capturar camadas de recursos do nosso ArcServer. Consegui recuperar com êxito uma classe de recurso como JSON, mas os objetos JSON da Esri não seguem os padrões GeoJSON e, portanto, não podem ser exibidos.

Alguém sabe de um script ou ferramenta de conversão que lida com isso?

Caso contrário, planejo criar um script para converter objetos ArcServer JSON em GeoJSON.

Curtidor
fonte
Eu estava tendo problemas para fazer com que ogr2ogr comesse o ESRI json vindo de uma consulta de recurso do MapServer. (@ Exemplo de SasaIvetic utiliza um pedido FeatureServer, eo MapServer resultar I precisa consumir não deve ter sido intercambiáveis.) De qualquer forma, este site fez totalmente o truque: http://ogre.adc4gis.com/
elrobis

Respostas:

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

Esse comando lerá o resultado da consulta diretamente do URL. Você também pode fornecê-lo com um arquivo de texto contendo seu JSON ou pode fornecer diretamente JSON codificado na linha de comandos. Obviamente, é possível usar as ligações do ORG Python para automatizá-lo em um script, se necessário, ou a biblioteca para fazê-lo em código.

Para aqueles que gostam de serviços da web, consulte Ogre, um cliente da web ogr2ogr que pode converter json em geojson para e para trás, bem como geojson em shapefile.

Referência: http://www.gdal.org/drv_geojson.html

Sasa Ivetic
fonte
Eu baixei o FWTools. Quando executo esse comando, recebo o erro 'Não é possível abrir a fonte de dados' Minha URL aqui '' com os seguintes drivers. -> ESRI Shapefile -> Arquivo MapInfo -> Reino Unido .NTF -> SDTS -> TIGER -> S57 -> DGN -> VRT -> REC -> Memória -> 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 Não vejo algo como 'ESRI JSON' na lista de drivers.
Tanner
1
@ Tanner: O FWTools vem com o OGR v1.7, onde o suporte GeoJSON foi adicionado com a v1.8.0. Estou executando o GDAL / OGR 1.9dev aqui, embora não através do FWTools. Eu acho que os obteve gisinternals.com/sdk
Sasa Ivetic
Obrigado. Eu fiz isso funcionar na linha de comando. Ainda estou trabalhando para que ele funcione no meu Javascript - todas as dicas serão apreciadas.
Tanner
@ Tanner, como você passou por esse erro? Não é um problema de versão para mim, mas eu estou recebendo o mesmo erro na minha máquina Windows
kflaw
@kflaw Desculpe, mas não me lembro exatamente. Acho que usei ogr2ogr na linha de comando e não precisei nem usei o FWTools.
Tanner
7

Você também pode ver os geojson-utils da Esri no Github que "contêm utilitários [javascript] para converter o GeoJSON em outros formatos geográficos json e vice-versa. Atualmente, apenas o GeoJSON para Esri JSON foi desenvolvido. Além disso, observe que apenas as geometrias no sistema de coordenadas WGS84 são suportados ".

nicogis
fonte
2
Atualização 12/2017: geojson-utilsestá obsoleta. Veja arcgis-to-geojson-utils ou terraformer
GavinR:
5

ESRI JSON para GeoJSON (para OpenLayers) * Probabilidade de ser modificado para 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;>

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

Mapperz
fonte
Se você estiver indo para converter você deve usar ogr2ogr
Evan Carroll
5

ArcGIS agora suporta GeoJSON

Agora o ArcGIS Online possui o GeoJSON através do URL da ArcGIS Rest API. Tudo o que você precisa fazer é definir f=geojsona URL e configurar o serviço. Esteja ciente de que, por padrão, o ArcGIS online não permitirá a exportação do GeoJSON até que você permita explicitamente outros formatos de saída.

Aqui está como habilitar a exportação:

  1. Entre no arcgis online
  2. clique nas camadas do recurso,
  3. clique na guia de configuração
  4. marque esta caixa que diz

    Exportar dados

    Permita que outros exportem para diferentes formatos.

  5. Salve e aguarde alguns minutos.

Na página de consulta, você deve ver a lista suspensa do formato de saída com a opção GeoJSON. O antigo foi chamado json.

hoogw
fonte
Um serviço de descanso agol é diferente de um serviço de descanso do servidor ArcGIS? A agol pode apenas fornecer o geoJSON como um serviço de descanso e não como servidor?
jotamon
4

Camada de vetor de folheto e ArGIS.

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

Demonstração de trabalho. http://geojason.info/leaflet-vector-layers/demos/arcgis-server/

Mais sobre Leaflet e ArcGIS.

  • Camadas de folheto e servidor ArcGIS, ou seja, AgsDynamicLayer e AgsFeatureLayer.

Você pode obter este fork que suporta o 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/

Folheto e serviços de imagem do ArcGIS http://blog.geomusings.com/2012/04/17/arcgis-image-services-and-leaflet/

ns-1m
fonte
3

Eu construí uma extensão de objeto de servidor para gerar GeoJSON a partir dos serviços de mapa do ArcGIS Server. Foi testado com 10.1 e 10.2, mas não antes. https://github.com/geobabbler/AGSOpenFormats

Bill Dollins
fonte
3

Para uma conversão única, eu usaria a resposta aceita da @Sasa Ivetic, mas precisava de algo em tempo real, e o Terraformer trabalhou decentemente para isso. Infelizmente, é apenas para recursos únicos por padrão; portanto, para vários recursos, você precisa percorrer a matriz e adicionar um ID a cada recurso:

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

Isso funcionou bem para mim, exceto em polígonos de várias partes (por exemplo, Alasca e suas ilhas), mas sou novo nisso, portanto é possível que codifiquei algo incorretamente!

abettermap
fonte
3

Convertendo ArcGIS JSON para GeoJSONThere no navegador puro

existem 2 maneiras de fazer

1) TERRAFORMADOR

Nota: use no node.js e use no navegador são diferentes , detalhes consulte o link

2) Esri / arcgis-to-geojson-utils

usar no navegador, ArcgisToGeojsonUtils é uma referência global de var o ponto de entrada deste módulo

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

});

No entanto, se você deseja agrupar sozinho, apenas para aprender, siga as etapas

a) Você precisa compilar todo o arquivo de origem do módulo em um único bundle.js

instalação do rollup.js por

npm install --global rollup

em seguida, vá para a pasta raiz js lib, localize o arquivo js do ponto de entrada; nesse caso, é index.js

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

Você deve encontrar um novo arquivo bundle.js no diretório raiz.

Agora no arquivo html do navegador, inclua este arquivo bundle.js

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

Você pode usá-lo agora

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

Lembre-se de esri_arcgis_to_geojson é o nome que você chamou de lib

Este se torna o nome da variável global, disponível no navegador.

O truque é que o processo de bundle adiciona uma função instantânea de implementação como (function xx {}) aqui é a parte superior do 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-para-geojson-utils

hoogw
fonte
2

É geralmente * muito fácil converter.

Eu criei um script https://github.com/calvinmetcalf/esri2geo e há outros que também funcionam bem.

* A exceção são polígonos de várias partes com orifícios que não convertem 1 para 1 sem algum geoprocessamento.

Calvin
fonte
1

Talvez ainda mais fácil você possa usar a biblioteca do Esri-leaflet para adicioná-la nativamente como uma camada no Leaflet.

Andrew Turner
fonte
2
Você poderia incorporar um exemplo em sua postagem descrevendo como essa resposta é a pergunta do OP?
Paul
0

Se tudo o que você precisa é retornar o ArcServer Service como um GeoJSON para usar em qualquer tecnologia de mapeamento que você desejar, eu recomendo que você veja este diálogo de problemas do GitHub .

Não vou replicar o diálogo aqui, porque isso perderia tempo. Suas opções estão claramente definidas diretamente na Esri.

Shawn Goulet
fonte
-1

api do resto do servidor arcgis, serviço de recursos,

se você consultar a camada, com URL como este, ... / 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}}

Você não pode definir o formato geojson, f = pgeojson será uma solicitação incorreta, f = json, porque o material de retorno não é recurso, as camadas json foram retornadas.

Experimente esta página de consulta html, você pode ver, sem opção de geojson,

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

Se você deseja retornar geojson (recurso), deve usar este URL ... / FeatureServer / 0 / query ...

/ 0 / significa layerID, se tiver apenas 1 camada, layerID = 0 .....

Experimente esta página de consulta html, como você pode ver, geojson é uma opção, porque você é uma camada específica de consulta com layerID = 0

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

Nota: lembre-se de definir esses 2 parâmetros: outSR = 4326 & f = geojson no ID de referência espacial da URL, srid = 4326, porque todos os mapas da web usam isso, f significa formato, ambos os trabalhos f = pgeojson ef = geojson. Se você não definir SR = 4326, a API de descanso do servidor arcgis por padrão NÃO usará 4326; em vez disso, usará outra coisa, apenas 4326 possui grau de unidade, o que é usado na maioria dos mapas da web. Outro formato não funcionaria com mapas da web.

A propósito, para aqueles que desejam usar o Arcgis Server Rest API com serviço de tile,

tilestream e outros

/zoom(z)/x/y.png

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

serviço de mosaico do servidor arcgis: sem png, x e y em ordem diferente

     /zoom(z)/y/x

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

hoogw
fonte