[gdal-dev] S57 questions

Frank Warmerdam warmerdam at pobox.com
Mon May 31 22:54:40 EDT 2010


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 at lists.osgeo.org
> http://lists.osgeo.org/mailman/listinfo/gdal-dev
> 
> 


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



More information about the gdal-dev mailing list