1

I'm trying to unpack shapefiles in C# using GDAL-OGR library, but I'm confused about the structure of multipolygon with holes in OGR. As far as I know, the models of shapefiles and OGR geometry (the latter following simple feature specifications) are different. Shapefiles have a "polygon" type that might be in OGR term either a polygon or a multipolygon. So I must handle both cases. When reading a shapefile, OGR does some topological analysis to figure out the spatial relationship between rings and determine if they must be outer or inner rings.

An OGR polygon is a collection of rings, the first one being the outer ring and the following ones the inner rings. So, this code will work fine.

Feature feat;
while ((feat = layer.GetNextFeature()) != null) 
{
     var geom = feat.GetGeometryRef();
     for (var i = 0; i < geom.GetGeometryCount(); i++)
     {
          //First one is the outer ring and, all the next ones are the inner rings
          var ring = geom.GetGeometryRef(i);
          ...
     }
}

But, if the geometry is multipolygon, e.g 2 polygons with holes. How do you determine which one is the outer ring of the second polygon? Because if I understand it correctly, geom.GetGeometryRef() will only return the first polygon. Shouldn't Feature have something like feat.GetGeometryCount() (to determine the number of polygons - the outer rings only) and feat.GetGeometryRef(i) (to get the i outer ring of i polygon) or something? I checked, and there is none. How do you handle such case? Can anyone help me with it, please?

Also, how many nested levels that OGR support for polygons (i.e, holes inside holes)? How do handle such cases?

Sorry for my English! I'm not a native speaker.

3
  • Perhaps answered in gis.stackexchange.com/questions/95280/…
    – user30184
    Sep 27, 2018 at 14:21
  • I checked that one, but that is for polygon. My question is about multipolygon. I don't know to get the next polygons after the first 1.
    – madlink
    Sep 27, 2018 at 14:30
  • If you have a multipolygon then GetGeometryCount returns the number of polygons that it contains. See also gis.stackexchange.com/questions/136480/…. I am not sure what you mean by Holes inside holes "nothing inside nothing". But if you have something inside the hole you can first make a polygon with a hole, and another polygon inside the hole, and then combine those two into a two-part multipolygon.
    – user30184
    Sep 27, 2018 at 14:52

1 Answer 1

3

A multipolygon is a different type of geometry than a polygon. So feature.getGeomtryRef() will give you the Multipolygon. Multipolygon itself inherits from MultiSurface, which inherits from GeometryCollection, which inherits from Geometry.

Polygon inherits from CurvePolygon, then from Surface, then from Geometry.

So all you have to do is "go one level deeper". Use getNumGeometries() or GetGeometryCount() - depending on what ogr implementation you use - to get the number of geometries in a GeometryCollection, which is the number of polygons inside the multipolygon.

In the case of a Multipolygon, calling getGeometryRef(i) will return a Polygon, which you then treat exactly as you already do in your example to retrieve the single outer ring and zero or more inner rings.

This also answers the second part of your question: As each Polygon is still distinctly separate, each of them still has an outer and 0+ inner rings, which you can treat separately.

This also means it doesn't matter how these polygons are situated inside the multipolygon: Each of them has to be a valid polygon itself and adhere to the rules of multipolygons to be valid, which makes any problems like nested polygons (islands inside a hole of an outer polygon) perfectly possible, as long as no invalid line intersections occur.

Multiple inner rings for a single polygon are meant to be used when there are multiple holes inside it.

Example: A multipolygon "park" consists of:

  • One polygon defines the landmass. There are multiple lakes, which are represented by holes, each of those being an inner ring.
    • If there are islands in those lakes, those will be their own polygons. But still part of the same multipolygon!
      • These islands could then have their own lakes/holes, and so on.

This should work, then (no guarantees, I rarely work with C# these days):

Feature feat;
while ((feat = layer.GetNextFeature()) != null) 
{
     // Get GeometryCollection/Multipolygon
     var gc = feat.GetGeometryRef(); 
     // Let's see how many child geometries this has
     for (var i = 0; i < gc.GetGeometryCount(); i++)
     {
         // So this must be our polygon
         var geometry = gc.getGeometryRef(i);
         for (var j = 0; j < geometry.GetGeometryCount(); j++)
         {
             //And here we have the rings. First one is the outer, all others are inner, defining holes
             var ring = geometry.GetGeometryRef(j);
     }
}

This only works if you already know it's a multipolygon. Unless this is an entirely static script where you know the inputs, you'll need to add type checks (GetGeometryType()) to ensure the GeometryCollection is what you expect it to be.

If you check the main API page for OGRGeometry, you can nicely see how the different types of geometry are "related" and inherit from each other.

5
  • Thanks for your answer. I appreciate it. Just to be clear about the nested holes, if there is an island inside a lake, it will be treated as a landmass, i.e, it's on the first level, not nested inside the lake polygon, right?
    – madlink
    Sep 28, 2018 at 6:45
  • Yes. The island would not have any "special" relationship with the landmass/lake, it would logically exist as its own landmass, next to the main landmass. OGR Multipolygons do not handle "hierarchy" of multiple polygons, all of them are equal. Any hierarchical logic will have to come out of your code or data management.
    – Senshi
    Sep 28, 2018 at 7:16
  • Thanks. That really clears thing up for me. I appreciate it!
    – madlink
    Sep 28, 2018 at 7:18
  • Note that multipolygons are not handled this way with every implementation, though OGR is used in GDAL and thus most code languages. Some of them (e.g. OSM multipolygons) indeed allow "nested outer rings" so you effectively have multiple fully qualified hierarchical polygons.
    – Senshi
    Oct 1, 2018 at 6:31
  • I thought OGR handles that for us, i.e it already flatten out the geometry and put similar ones in the same level (island with landmass, sea with lake...) or do I have to go deeper and check the nested levels?
    – madlink
    Oct 1, 2018 at 7:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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