I am using code from shape2ogr.cpp to determine outer/inner rings and their association. The method RingExtent::calculate() is used to find the max and min of the object. This is used later to check if the inner rings are contained by the inner.
However, the code has a bug in it:
void RingExtent::calculate( int ringParts, double *ringX, double *ringY )
{
empty = ringParts <= 0;
if ( !empty )
{
xMin = xMax = *ringX;
yMin = yMax = *ringY;
while( --ringParts > 0 )
{
if ( xMin > *ringX )
xMin = *ringX;
else if ( xMax < *ringX )
xMax = *ringX;
if ( yMin > *ringY )
yMin = *ringY;
else if ( yMax < *ringY )
yMax = *ringY;
++ringX;
++ringY;
}
}
}
The problem is in the while loop. Because SHPReadOGRObject() calls this by:
int start = 0;
int end = 0;
RingStartEnd ( psShape, iRing, &start, &end );
extents[ iRing ].calculate( end-start, psShape->padfX + start, psShape->padfY + start );
So, if the ring has 4 points (causing 5 in the shape file because the first and last must be repeated), start would be 0 and end would be 4. So, the loop will evaluate points 0, 1, and 2 skipping the fourth point. If that point happens to be a max or min, the later calculations will not be correct.
It appears this can be fixed by changing
while( --ringParts > 0 )
to
while( ringParts-- > 0 )
at least in my limited testing.
If I can attach a file after submission, I will attach a shapefile set that proves this.