In an ESRI shapefile, a polygon can have multiple parts. Each part is a closed ring. Rings that wrap clockwise are... um... rings. Rings that wrap counterclockwise are holes in (some upstream) rings.

Suppose I want a polygon to represent the land portions of: a) a state, b) with a lake in the state, and c) with an island on the lake.

Would it be common to represent this as a single polygon with three parts: a) a clockwise ring for the state, b) a counterclockwise ring for the lake, and c) another clockwise ring for the island?

Similarly, a state with two lakes each with one island would have 5 parts.

If so, do I have to figure out, own my own, which parts are clockwise and which are counterclockwise, and which parts are contained in other parts; or is there some more direct way of figuring this out?

If not, what is the proper representation?

I am processing the shapefile on my own (in C#) to learn how it's done. I'm not really looking for links to libraries that do everything for me.

  • 4
    You have laid out the clockwise polygons, counterclockwise holes situation perfectly.
    – J Kelly
    Commented Jun 17, 2020 at 2:51
  • 3
    Normally the 'state' is one feature class and 'lakes' are another feature class entirely. I get your point though and yes in a simple polygon you have exterior rings and interior rings, exteriors being clockwise and interiors being counter clockwise so there is no limit to island in a lake on an island in a lake on an island in a lake and so on. Are you using ArcObjects? If so just add the rings and the API will sort it out for you, it's unavoidable, working to put the pointcollection in the correct order is unnecessary. Point order only comes into play when you read the rings. Commented Jun 17, 2020 at 5:46

1 Answer 1


In order to have an island in a hole you need a multi-part polygon (exterior ring, interior ring, exterior ring).

It is not required that interior rings follow the exterior ring for which they are an exclusion, as per page 9 of the specification:

The order of rings in the points array is not significant.

but the most common implementations do track that, since it's significant in Well-Known Text, and KML, and pretty much every other transfer format, so yes, you should probably be tracking that.

Determining if a ring is exterior or interior is easy enough -- Use the "shoelace formula" (aka trapezoid rule) to determine positive or negative area (zero area indicates ring-crosses-ring error, as in a bowtie).

"Within" only applies to interior rings, in which case all points should be within and the interior ring cannot cross the exterior ring (or overlap with other interior rings), but exterior rings cannot overlap or touch at more than a point, and Esri and the OGC have different definitions of "valid" on certain exceptional conditions, like inversions.

At some point, this becomes less of a fun exercise, and more a snarl of complexity that calls for using a validated library.

  • 1
    I deduce that you've been burnt by the non-simple geometry with spatial filters/topological operators problem before. Have you come across the SDE refusing to store non-simple (half hour to digitize) polygons as well? Further complications can occur if a polygon is a multipart as well as having holes, not just lakes on islands but a chain of lakes as a multipolygon - In ArcObjects I've found that using exterior geometry bag then for each exterior ring get interior rings is the best way to sort out which holes belong to what polygon. Commented Jun 17, 2020 at 5:56
  • 2
    The OP stated this was being done au naturel. I wrote a Java shapefile library once which needed to correct ring topology and rewrite rings that crossed the date line and poles, sometimes repeatedly, before exporting to KML I certainly didn't long for ArcObjects, but having the SDE API's flexibility in correcting rings would have been nice.
    – Vince
    Commented Jun 17, 2020 at 12:06

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.