Skip to content

Commit

Permalink
[pal] Offseting lines sometimes results in a multilinestring result
Browse files Browse the repository at this point in the history
If the offset lines self-intersect or form isolated rings then
we'll sometimes get multiline string results. In this case we
just take the largest part as the offset curve instead of
returning no offset line geometry
  • Loading branch information
nyalldawson committed Apr 30, 2021
1 parent d25b409 commit 8d0d677
Showing 1 changed file with 34 additions and 0 deletions.
34 changes: 34 additions & 0 deletions src/core/pal/pointset.cpp
Expand Up @@ -558,6 +558,40 @@ void PointSet::offsetCurveByDistance( double distance )
try
{
newGeos = GEOSOffsetCurve_r( geosctxt, mGeos, distance, 0, GEOSBUF_JOIN_MITRE, 2 );

// happens sometime, if the offset curve self-intersects
if ( GEOSGeomTypeId_r( geosctxt, newGeos ) == GEOS_MULTILINESTRING )
{
// we keep the longest part
const int nParts = GEOSGetNumGeometries_r( geosctxt, newGeos );
double maximumLength = -1;
const GEOSGeometry *longestPart = nullptr;
for ( int i = 0; i < nParts; ++i )
{
const GEOSGeometry *part = GEOSGetGeometryN_r( geosctxt, newGeos, i );
double partLength = -1;
if ( GEOSLength_r( geosctxt, part, &partLength ) == 1 )
{
if ( partLength > maximumLength )
{
maximumLength = partLength;
longestPart = part;
}
}
}

if ( !longestPart )
{
// something is really wrong!
GEOSGeom_destroy_r( geosctxt, newGeos );
return;
}

geos::unique_ptr longestPartClone( GEOSGeom_clone_r( geosctxt, longestPart ) );
GEOSGeom_destroy_r( geosctxt, newGeos );
newGeos = longestPartClone.release();
}

const int newNbPoints = GEOSGeomGetNumPoints_r( geosctxt, newGeos );
const GEOSCoordSequence *coordSeq = GEOSGeom_getCoordSeq_r( geosctxt, newGeos );
std::vector< double > newX;
Expand Down

0 comments on commit 8d0d677

Please sign in to comment.