Skip to content

Commit

Permalink
Followup f9fa979, avoid expensive intersection calculation when
Browse files Browse the repository at this point in the history
testing label candidates against polygon obstacles

Fix #13556

(cherry-picked from b384f18)
  • Loading branch information
nyalldawson committed Nov 18, 2015
1 parent 32cdd85 commit b9326a5
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 17 deletions.
41 changes: 26 additions & 15 deletions src/core/pal/labelposition.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -593,36 +593,47 @@ namespace pal
polygon->createGeosGeom();

GEOSContextHandle_t geosctxt = geosContext();

double cost = 0;
//check the label center. if covered by polygon, initial cost of 4
if ( polygon->containsPoint(( x[0] + x[2] ) / 2.0, ( y[0] + y[2] ) / 2.0 ) )
cost += 4;

try
{
//calculate proportion of label candidate which is covered by polygon
GEOSGeometry* intersectionGeom = GEOSIntersection_r( geosctxt, mGeos, polygon->mGeos );
if ( intersectionGeom )
if ( GEOSPreparedIntersects_r( geosctxt, polygon->preparedGeom(), mGeos ) == 1 )
{
double positionArea = 0;
if ( GEOSArea_r( geosctxt, mGeos, &positionArea ) == 1 )
//at least a partial intersection
cost += 1;

double px, py;

// check each corner
for ( int i = 0; i < 4; ++i )
{
double intersectionArea = 0;
if ( GEOSArea_r( geosctxt, intersectionGeom, &intersectionArea ) == 1 )
px = x[i];
py = y[i];

for ( int a = 0; a < 2; ++a ) // and each middle of segment
{
double portionCovered = intersectionArea / positionArea;
cost += portionCovered * 8.0; //cost of 8 if totally covered
if ( polygon->containsPoint( px, py ) )
cost++;
px = ( x[i] + x[( i+1 ) %4] ) / 2.0;
py = ( y[i] + y[( i+1 ) %4] ) / 2.0;
}
}
GEOSGeom_destroy_r( geosctxt, intersectionGeom );

px = ( x[0] + x[2] ) / 2.0;
py = ( y[0] + y[2] ) / 2.0;

//check the label center. if covered by polygon, cost of 4
if ( polygon->containsPoint( px, py ) )
cost += 4;
}
}
catch ( GEOSException &e )
{
QgsMessageLog::logMessage( QObject::tr( "Exception: %1" ).arg( e.what() ), QObject::tr( "GEOS" ) );
}

//maintain scaling from 0 -> 12
cost = 12.0 * cost / 13.0;

if ( nextPart )
{
cost += nextPart->polygonIntersectionCostForParts( polygon );
Expand Down
4 changes: 2 additions & 2 deletions src/core/pal/pointset.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,7 @@ namespace pal
GEOSCoordSeq_setX_r( geosctxt, seq, 0, x );
GEOSCoordSeq_setY_r( geosctxt, seq, 0, y );
GEOSGeometry* point = GEOSGeom_createPoint_r( geosctxt, seq );
bool result = ( GEOSPreparedContains_r( geosctxt, preparedGeom(), point ) == 1 );
bool result = ( GEOSPreparedContainsProperly_r( geosctxt, preparedGeom(), point ) == 1 );
GEOSGeom_destroy_r( geosctxt, point );

return result;
Expand Down Expand Up @@ -349,7 +349,7 @@ namespace pal
try
{
GEOSGeometry* bboxGeos = GEOSGeom_createLinearRing_r( geosctxt, coord );
bool result = ( GEOSPreparedContains_r( geosctxt, preparedGeom(), bboxGeos ) == 1 );
bool result = ( GEOSPreparedContainsProperly_r( geosctxt, preparedGeom(), bboxGeos ) == 1 );
GEOSGeom_destroy_r( geosctxt, bboxGeos );
return result;
}
Expand Down

0 comments on commit b9326a5

Please sign in to comment.