Take the 2-minute tour ×
Geographic Information Systems Stack Exchange is a question and answer site for cartographers, geographers and GIS professionals. It's 100% free, no registration required.

I am having a hard time finding any detailed documentation defining ESRI's JSON specs. I am hoping someone can shed some light on the following two questions.

  1. Similar to the GeoJSON spec, the first array in the 'paths' collection is always an exterior ring, and all subsequent arrays in this collection are interior rings (holes)?

  2. Is above is true, how does the ESRI JSON spec deal with multi-polygons?

share|improve this question
add comment

2 Answers 2

up vote 8 down vote accepted

Here's a link to Esri's doc on JSON geometry objects. From that page:

The REST API supports 4 geometry types - points, polylines, polygons and envelopes.

Sounds like multi-polygons are not supported. See below. You can create multi-polygons by adding additional rings. There's nothing explicit about interior v. exterior rings. I'm curious so I'm going to look into this further...will edit this post if I find anything else.

Edit: I looked into this a bit more. It looks like if you add rings that fall inside an existing ring, the interior rings are holes. If you add a ring that is not inside another ring, it's added as an additional polygon which is basically a multi-polygon. Here's a simple page that shows this:

<!DOCTYPE html> 
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>Polygons!</title>
    <link rel="stylesheet" type="text/css" href="http://serverapi.arcgisonline.com/jsapi/arcgis/2.1/js/dojo/dijit/themes/claro/claro.css">
    <style>
      html, body { height: 100%; width: 100%; margin: 0; padding: 0; }
      #map{
        padding:0;
      }
    </style>
    <script type="text/javascript">var djConfig = {parseOnLoad: true};</script>
    <script type="text/javascript" src="http://serverapi.arcgisonline.com/jsapi/arcgis/?v=2.1"></script>
    <script type="text/javascript">
      dojo.require("dijit.layout.BorderContainer");
      dojo.require("dijit.layout.ContentPane");
      dojo.require("esri.map");
      var map;
      function init() {
        var initExtent = new esri.geometry.Extent({"xmin":-12959519,"ymin":3696971,"xmax":-9444639,"ymax":5453188,"spatialReference":{"wkid":102100}});
        map = new esri.Map("map",{extent:initExtent});
        var basemap = new esri.layers.ArcGISTiledMapServiceLayer("http://server.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer");
        map.addLayer(basemap);
        var resizeTimer;
        dojo.connect(map, 'onLoad', function(theMap) {
          dojo.connect(dijit.byId('map'), 'resize', function() {  //resize the map if the div is resized
            clearTimeout(resizeTimer);
            resizeTimer = setTimeout( function() {
              map.resize();
              map.reposition();
            }, 500);
          });
          var poly = new esri.geometry.Polygon({"rings":
            [
              [[-11214840,4858704],[-10520181,4853812],[-10510397,4149368],[-11219732,4144476],[-11214840,4858704]], // ring #1, poly with two holes
              [[-11097433,4770648],[-10916430,4770648],[-10916430,4609213],[-10984918,4560294],[-11097433,4614105],[-11097433,4770648]], // ring #2, a hole
              [[-10779455,4472238],[-10622912,4349939],[-10750103,4242315],[-10833267,4296127],[-10779455,4472238]],  // ring #3, another hole
              [[-11298004,4614105],[-11293112,4310803],[-11571954,4305911],[-11542602,4584753],[-11298004,4614105]] // ring #4, western polygon
            ],
            "spatialReference":{"wkid":102100}
          });
          var sym = new esri.symbol.SimpleFillSymbol({"color":[255,255,0,64],"outline":{"color":[255,0,0,255],"width":1.5,"type":"esriSLS","style":"esriSLSDashDot"},"type":"esriSFS","style":"esriSFSSolid"});
          var graphic = new esri.Graphic(poly, sym);
          map.graphics.add(graphic);
        });
      }
      dojo.addOnLoad(init);
    </script>
  </head>
  <body class="claro">
    <div dojotype="dijit.layout.BorderContainer" design="headline" gutters="false"
    style="width: 100%; height: 100%; margin: 0;">
      <div id="map" dojotype="dijit.layout.ContentPane" region="center" style="overflow:hidden;">
      </div>
    </div>
  </body>
</html>

If you load that page, the first ring is the square with two holes. The two holes are rings two and three. The fourth ring in the western most polygon. This might look like two graphics but it's actually just one.

share|improve this answer
    
Most excellent answer, thanks. Now for the hard work, since there are no built in methods, I guess I will have to write a function that tests the orientation of each ring. –  user890 Oct 20 '10 at 17:25
    
Glad to help. No need to re-invent the wheel though, esri provides an "isClockwise()" function in the geometry namespace: help.arcgis.com/en/webapi/javascript/arcgis/help/… –  Derek Swingley Oct 20 '10 at 17:31
add comment

The esri json format closely follows that of the esri shape.

The esri polygons consist of rings. They can represent both Multipolygon and Polygon entities from OGC.

The geometrically simple polygons will have no self-intersections and will have exterior rings clockwise and interior rings (holes) counterclockwise. If you are reading from Esri services that's what you get usually.

The non-simple polygons (those that have rings oriented differently or have self-intersections) should be interpreted using the regular even-odd fill rule when drawing or making a point in polygon test.

When converting from OGC Multipolygon to Esri polygon, just make sure the exterior rings are oriented clockwise and holes are counterclockwise.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.