แปลง ArcGIS Server JSON เป็น GeoJSON หรือไม่


47

ฉันกำลังสร้างแผนที่เว็บโดยใช้Leafletและฉันต้องการที่จะสามารถดึงเลเยอร์คุณลักษณะจาก ArcServer ของเรา ฉันสามารถดึงคลาสคุณลักษณะเป็น JSON ได้สำเร็จ แต่วัตถุ JSON ของ Esri ไม่เป็นไปตามมาตรฐาน GeoJSON ดังนั้นจึงไม่สามารถแสดงได้

ไม่มีใครรู้สคริปต์แปลงหรือเครื่องมือที่จัดการสิ่งนี้หรือไม่

ถ้าไม่ใช่ฉันวางแผนที่จะสร้างสคริปต์เพื่อแปลงวัตถุ ArcServer JSON เป็น GeoJSON


ฉันมีปัญหาในการรับ ogr2ogr เพื่อกิน ESRI json ที่มาจากแบบสอบถามคุณลักษณะ MapServer (ตัวอย่างของ @ SasaIvetic ใช้การร้องขอ FeatureServer และผลลัพธ์ MapServer ที่ฉันต้องใช้จะต้องไม่สามารถใช้แทนกันได้) อย่างไรก็ตามไซต์นี้ใช้เคล็ดลับทั้งหมด: http://ogre.adc4gis.com/
elrobis

คำตอบ:


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

คำสั่งนั้นจะอ่านผลลัพธ์ของแบบสอบถามโดยตรงจาก URL คุณสามารถจัดหาไฟล์ข้อความที่มี JSON ของคุณหรือคุณสามารถจัดหา JSON ที่เข้ารหัสโดยตรงในบรรทัดคำสั่ง แน่นอนว่าคุณสามารถใช้ ORG Python ในการผูกให้เป็นแบบอัตโนมัติภายในสคริปต์ถ้าจำเป็นหรือไลบรารีเพื่อทำมันในโค้ด

สำหรับผู้ที่ชอบบริการเว็บดูOgreลูกค้าเว็บ ogr2ogr ซึ่งสามารถแปลง json เป็น geojson ไปและกลับเช่นเดียวกับ geojson เพื่อ shapefile

การอ้างอิง: http://www.gdal.org/drv_geojson.html


ฉันดาวน์โหลด FWTools เมื่อฉันเรียกใช้คำสั่งนั้นฉันได้รับข้อผิดพลาด 'ไม่สามารถเปิดแหล่งข้อมูล' My URL ที่นี่ 'พร้อมไดรเวอร์ต่อไปนี้ -> ESRI Shapefile -> ไฟล์ MapInfo -> UK .NTF -> SDTS -> TIGER -> S57 -> DGN -> VRT -> REC -> หน่วยความจำ -> BNA -> CSV -> NAS -> GML -> GPX - > KML -> GeoJSON -> Interlis 1 -> Interlis 2 -> GMT -> SQLite -> ODBC -> PGeo -> OGDI -> OGDI -> PostgreSQL -> MySQL -> XPlane -> AVCBin -> AVCE00 -> DXF -> Geoconcept - > GeoRSS -> GPSTrackMaker -> VFK ฉันไม่เห็นอะไรอย่าง 'ESRI JSON' ในรายการไดรเวอร์
แทนเนอร์

1
@Tanner: FWTools มาพร้อมกับ OGR v1.7 ซึ่งมีการเพิ่มการสนับสนุน GeoJSON ด้วย v1.8.0 ฉันกำลังเรียกใช้ GDAL / OGR 1.9dev ที่นี่ แต่ไม่ใช่ผ่าน FWTools ฉันคิดว่าฉันได้รับมาจากgisinternals.com/sdk
Sasa Ivetic

ขอบคุณ ฉันได้สิ่งนี้เพื่อทำงานบนบรรทัดคำสั่ง ฉันยังคงทำงานเพื่อให้มันทำงานใน Javascript ของฉัน - เคล็ดลับใด ๆ ที่จะได้รับการชื่นชม
แทนเนอร์

@ เครื่องมือคุณทราบข้อผิดพลาดนั้นได้อย่างไร มันไม่ได้เป็นปัญหารุ่นสำหรับฉัน แต่ฉันได้รับข้อผิดพลาดเดียวกันบนเครื่องหน้าต่างของฉัน
kflaw

@kflaw ขออภัย แต่ฉันจำไม่ได้ว่าแน่นอน ฉันคิดว่าฉันเพิ่งใช้ ogr2ogr ในบรรทัดคำสั่งและไม่ต้องการหรือใช้ FWTools
แทนเนอร์

7

คุณสามารถเห็นgeojson-utilsของ Esri บน Github ว่า"มี [javascript] ยูทิลิตี้สำหรับการแปลง GeoJSON ไปเป็นรูปแบบ json ทางภูมิศาสตร์อื่น ๆ และในทางกลับกันปัจจุบัน GeoJSON เป็น Esri JSON ได้รับการพัฒนาเท่านั้น ได้รับการสนับสนุน "


2
อัปเดต 12/2017: geojson-utilsเลิกใช้แล้ว ดูarcgis-to-geojson-utilsหรือTerraformer
GavinR

5

ESRI JSON เป็น GeoJSON (สำหรับ OpenLayers) * มีแนวโน้มที่จะได้รับการแก้ไขสำหรับ 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;>

แหล่งที่มา: http://mapbutcher.com/blog/?p=62


หากคุณกำลังจะแปลงคุณควรใช้ ogr2ogr
Evan Carroll

5

ขณะนี้ ArcGIS รองรับ GeoJSON

ตอนนี้ ArcGIS Online มี GeoJSON ผ่าน URL ของ API สำหรับ ArcGIS Rest สิ่งที่คุณต้องทำคือตั้งค่าf=geojsonใน URL และกำหนดค่าบริการ ระวังโดยค่าเริ่มต้น ArcGIS ออนไลน์จะไม่อนุญาตให้ส่งออก GeoJSON จนกว่าคุณจะอนุญาตรูปแบบผลลัพธ์อื่น ๆ อย่างชัดเจน

นี่คือวิธีการเปิดใช้งานการส่งออก:

  1. เข้าสู่ระบบ arcgis ออนไลน์
  2. คลิกเลเยอร์คุณลักษณะ
  3. คลิกที่แท็บการตั้งค่า
  4. ทำเครื่องหมายในช่องที่ระบุว่า

    ส่งออกข้อมูล

    อนุญาตให้ผู้อื่นส่งออกเป็นรูปแบบที่แตกต่างกัน

  5. บันทึกและรอสักครู่

ในหน้าแบบสอบถามคุณจะเห็นรายการแบบหล่นลงของรูปแบบผลลัพธ์ด้วยตัวเลือก GeoJSON jsonเก่าที่ถูกเรียกว่า


เซอร์วิส agol rest แตกต่างจากบริการ Rest Server ArcGIS หรือไม่? agol สามารถให้บริการ geoJSON เป็นที่พักเท่านั้นไม่ใช่เซิร์ฟเวอร์ได้หรือไม่
jotamon

4

เลเยอร์ของ Leaflet และ ArGIS

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

สาธิตการทำงาน http://geojason.info/leaflet-vector-layers/demos/arcgis-server/

เพิ่มเติมเกี่ยวกับแผ่นพับและ ArcGIS

  • เลเยอร์ของ Leaflet และ ArcGIS Server เช่น AgsDynamicLayer และ AgsFeatureLayer

คุณสามารถรับทางแยกนี้ซึ่งรองรับเซิร์ฟเวอร์ 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 และแผ่นพับ http://blog.geomusings.com/2012/04/17/arcgis-image-services-and-leaflet/



3

สำหรับการแปลงครั้งเดียวฉันจะใช้คำตอบที่ได้รับการยอมรับจาก @Sasa Ivetic แต่ต้องการบางสิ่งแบบเรียลไทม์และTerraformerทำงานได้อย่างเหมาะสม น่าเสียดายที่มันมีไว้สำหรับฟีเจอร์เดียวเท่านั้นโดยค่าเริ่มต้นดังนั้นสำหรับฟีเจอร์หลายอย่างที่คุณต้องใช้ในการวนรอบอาร์เรย์และเพิ่ม ID ให้กับแต่ละฟีเจอร์:

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

มันใช้งานได้ดีสำหรับฉันยกเว้นรูปหลายเหลี่ยม (เช่น Alaska และหมู่เกาะ) แต่ฉันใหม่สำหรับสิ่งนี้ดังนั้นจึงเป็นไปได้ที่ฉันจะเขียนรหัสบางอย่างไม่ถูกต้อง!


3

แปลง ArcGIS JSON เป็น GeoJSON ในเบราว์เซอร์แท้ๆ

มี 2 ​​วิธีที่คุณสามารถทำได้

1) TERRAFORMER

หมายเหตุ: ใช้ใน node.js และใช้ในเบราว์เซอร์แตกต่างกันดูรายละเอียดที่ลิงค์

2) Esri / arcgis-to-geojson-utils

ใช้ในเบราว์เซอร์ ArcgisToGeojsonUtils เป็น global var reference จุดเริ่มต้นของโมดูลนี้

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

});

อย่างไรก็ตามหากคุณต้องการมัดด้วยตัวเองเพียงเพื่อการเรียนรู้ให้ทำตามขั้นตอน

a) คุณจำเป็นต้องรวบรวมไฟล์ซอร์สโมดูลทั้งหมดไว้ใน bundle.js เดียว

ติดตั้งrollup.js

npm install --global rollup

จากนั้นไปที่โฟลเดอร์รูท js lib ของคุณค้นหาไฟล์ entry point js ในกรณีนี้คือindex.js

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

คุณควรค้นหาไฟล์ใหม่ bundle.js ในรูทไดเร็กทอรีของคุณ

ในไฟล์ html ของเบราว์เซอร์ของคุณให้รวมไฟล์ bundle.js นี้

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

คุณสามารถใช้งานได้ทันทีโดย

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

จำesri_arcgis_to_geojsonเป็นชื่อที่คุณตั้งชื่อ lib

นี่เป็นชื่อตัวแปรส่วนกลางที่มีอยู่ในเบราว์เซอร์

เคล็ดลับคือกระบวนการมัดเพิ่มฟังก์ชั่นการใช้งานทันทีเช่น (ฟังก์ชั่น xx {}) นี่คือส่วนบนจาก 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 เพื่อ GeoJSON-utils


2

มันมักจะแปลงง่ายสวย

ฉันสร้างสคริปต์https://github.com/calvinmetcalf/esri2geoและมีคนอื่นที่ทำงานได้ดีเช่นกัน

* ข้อยกเว้นคือรูปหลายเหลี่ยมหลายส่วนที่มีรูซึ่งไม่แปลง 1 ต่อ 1 โดยไม่มีการประมวลผลทางภูมิศาสตร์


1

หากเป็นการค้นหาครั้งเดียวและคุณไม่มีฟีเจอร์มากกว่า 1,000 รายการให้ลองวางสิ่งนี้ลงใน qgis โดยใช้เพิ่มเลเยอร์เวกเตอร์ - เลือกโปรโตคอลและแทนที่ URL ส่วนที่เหลือของ arcgis นี้ด้วย: http://geodata.epa.gov/arcgis / rest / services / OAR / USEPA_NEI_2005 / MapServer / 1 / query? โดยที่ = objectid +% 3D + objectid & outfields = * & f = json ... ถือว่าคุณติดตั้ง gdal 1.10 แล้ว


1

บางทียิ่งง่ายขึ้นคุณสามารถใช้ไลบรารี่ Esriเพื่อเพิ่มเป็นเลเยอร์ในแผ่นพับ


2
คุณสามารถรวมตัวอย่างในการโพสต์ของคุณโดยสรุปว่าคำตอบของคำถาม OP นี้ได้อย่างไร
เปาโล

0

หากสิ่งที่คุณต้องการก็คือการกลับมาบริการ ArcServer เป็น GeoJSON กับการใช้งานใดในเทคโนโลยีการทำแผนที่ที่คุณต้องการผมขอแนะนำให้คุณดูที่นี้ GitHub ปัญหาการเจรจา

ฉันจะไม่ทำซ้ำบทสนทนาที่นี่เพราะมันจะเสียเวลา ตัวเลือกของคุณถูกจัดวางอย่างชัดเจนจาก Esri โดยตรง


-1

ส่วนที่เหลือของเซิร์ฟเวอร์ arcgis, บริการคุณลักษณะ,

ถ้าคุณสอบถามเลเยอร์ด้วย URL เช่นนี้ ... / 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}}

คุณไม่สามารถตั้งค่ารูปแบบ geojson, f = pgeojson จะเป็นคำขอที่ไม่ดี, f = json, เพราะสิ่งที่ส่งคืนไม่ได้มีคุณสมบัติ, เลเยอร์ json ถูกส่งคืน

ลองใช้หน้าแบบสอบถาม html นี้คุณจะเห็นว่าไม่มีตัวเลือก geojson

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

หากคุณต้องการกลับ geojson (คุณสมบัติ) คุณต้องใช้ URL นี้ ... / FeatureServer / 0 / แบบสอบถาม ...

/ 0 / หมายถึง layerID ถ้าเปิดมีเพียง 1 เลเยอร์ดังนั้น layerID = 0 .....

ลองใช้หน้าแบบสอบถาม html นี้คุณสามารถเห็นได้ว่า geojson เป็นตัวเลือกเนื่องจากคุณเป็นชั้นค้นหาเฉพาะที่มี layerID = 0

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

หมายเหตุ: อย่าลืมตั้งค่าพารามิเตอร์เหล่านั้น 2: outSR = 4326 & f = geojson ใน ID อ้างอิงเชิงพื้นที่ URL, srid = 4326 เนื่องจากเว็บแผนที่ทั้งหมดใช้สิ่งนี้ f หมายถึงรูปแบบทั้ง f = pgeojson และ f = geojson หากคุณไม่ได้ตั้งค่า outSR = 4326, arcgis ส่วนที่เหลือเซิร์ฟเวอร์ api โดยค่าเริ่มต้นจะไม่ใช้ 4326 แทนที่จะใช้อย่างอื่นเพียง 4326 เท่านั้นมีหน่วยระดับซึ่งใช้ในแผนที่เว็บส่วนใหญ่ รูปแบบอื่นจะไม่ทำงานกับแผนที่เว็บ

โดยวิธีการสำหรับผู้ที่ต้องการใช้ ArcGIS เซิร์ฟเวอร์ส่วนที่เหลือ API กับบริการกระเบื้อง

tilestream และอื่น ๆ

/zoom(z)/x/y.png

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

เซอร์วิสไทล์เซิร์ฟเวอร์ arcgis: ไม่มี png, x และ y ตามลำดับที่ต่างกัน

     /zoom(z)/y/x

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

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.