Skip to content
Permalink
Browse files
[pal] Offseting lines sometimes results in a multilinestring result
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 8d0d677f1f601b07238f3318360e1d3895df4b43
Showing with 34 additions and 0 deletions.
  1. +34 −0 src/core/pal/pointset.cpp
@@ -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;

0 comments on commit 8d0d677

Please sign in to comment.