ogr user wrote:
Dear all and Frank,

 I sent this patch out a few times before - never got any replies. It's
ok if you are not interested, though I have to say that it works very
well for me and improved handling of data. However, would someone kindly
confirm that you have looked at this patch, acknowledged it and do not
wish to apply it. I'll then go back to maintaining my private copy :)

This following is a fix to a problem I encountered back in the day, to
properly identify exterior vs. interior rings of polygons. This solves
incorrect reading of a number of S57 charts (as an example see US5CA92M,
feature RCID 1167).

Mike,

There is no expectation for OGR drivers to return polygons with any
particular winding direction, so I'm not sure what the point of
the patch is.  Perhaps I'm missing something?

Generally speaking it is better to file suggested patches in Trac
so they aren't lost in the gdal-dev email stream.

Best regards,

===================================================================
--- ogr/ograssemblepolygon.cpp    (revision 17)
+++ ogr/ograssemblepolygon.cpp    (working copy)
@@ -276,6 +276,40 @@
 // perhaps even ordering the direction of rings, though this isn't
 // required by the OGC geometry model.

+    double maxarea, tarea;
+    int maxring = -1, rn, rcount;
+    OGREnvelope tenv;
+    OGRLinearRing *tring;
+
+    tring = poPolygon->getExteriorRing();
+    if (tring) tring->getEnvelope(&tenv);
+    maxarea = (tenv.MaxX - tenv.MinX) * (tenv.MaxY - tenv.MinY);
+
+    rcount = poPolygon->getNumInteriorRings();
+    for (rn = 0; rn < rcount; ++rn) {
+      tring = poPolygon->getInteriorRing(rn);
+      tring->getEnvelope(&tenv);
+      tarea = (tenv.MaxX - tenv.MinX) * (tenv.MaxY - tenv.MinY);
+      if (tarea > maxarea) {
+         maxarea = tarea;
+         maxring = rn;
+      }
+    }
+
+    if (maxring != -1) {
+       OGRPolygon  *poNewPoly = new OGRPolygon();
+
+       poNewPoly->addRing(poPolygon->getInteriorRing(maxring));
+       poNewPoly->addRing(poPolygon->getExteriorRing());
+       for (rn = 0; rn < rcount; ++rn) {
+          if (rn == maxring) continue;
+          poNewPoly->addRing(poPolygon->getInteriorRing(rn));
+       }
+
+       delete poPolygon;
+       poPolygon = poNewPoly;
+    }
+
     if( peErr != NULL )
     {
         if( bSuccess )

Frank Warmerdam wrote:
Mike,

The S-57 driver uses OGRBuildPolygonFromEdges() to form the set of lines
into a polygon.  No effort is currently made to properly represent
exterior vs. interior rings as is required by the simple features
geometry
specification.

So, I believe this is a bug of the S-57 driver and
OGRBuildPolygonFromEdges()
function.  In OGRBuildPolygonFromEdges() I see this comment:

// Eventually we should at least identify the external ring properly,
// perhaps even ordering the direction of rings, though this isn't
// required by the OGC geometry model.

You might want to file a ticket on this issue, though I can't say when
the
issue will be fixed.

Best regards,

_______________________________________________
gdal-dev mailing list
gdal-dev@lists.osgeo.org
http://lists.osgeo.org/mailman/listinfo/gdal-dev




--
---------------------------------------+--------------------------------------
I set the clouds in motion - turn up   | Frank Warmerdam, warmer...@pobox.com
light and sound - activate the windows | http://pobox.com/~warmerdam
and watch the world go round - Rush    | Geospatial Programmer for Rent

_______________________________________________
gdal-dev mailing list
gdal-dev@lists.osgeo.org
http://lists.osgeo.org/mailman/listinfo/gdal-dev

Reply via email to