10

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?

2 Answers 2

13

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.

3
  • 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
    Commented Oct 20, 2010 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/… Commented Oct 20, 2010 at 17:31
  • Good answer. Just make sure that the interior rings or holes are counter-clockwise. Commented Jan 9, 2019 at 11:43
3

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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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