Skip to content
Permalink
Browse files

Followup f9fa979, avoid expensive intersection calculation when

testing label candidates against polygon obstacles

Fix #13556

(cherry-picked from b384f18)
  • Loading branch information
nyalldawson committed Nov 18, 2015
1 parent 32cdd85 commit b9326a5bf15a81776088b6effa78bc89b81acc32
Showing with 28 additions and 17 deletions.
  1. +26 −15 src/core/pal/labelposition.cpp
  2. +2 −2 src/core/pal/pointset.cpp
@@ -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 );
@@ -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;
@@ -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;
}

0 comments on commit b9326a5

Please sign in to comment.
You can’t perform that action at this time.