Skip to content

Commit b9326a5

Browse files
committed
Followup f9fa979, avoid expensive intersection calculation when
testing label candidates against polygon obstacles Fix #13556 (cherry-picked from b384f18)
1 parent 32cdd85 commit b9326a5

File tree

2 files changed

+28
-17
lines changed

2 files changed

+28
-17
lines changed

src/core/pal/labelposition.cpp

+26-15
Original file line numberDiff line numberDiff line change
@@ -593,36 +593,47 @@ namespace pal
593593
polygon->createGeosGeom();
594594

595595
GEOSContextHandle_t geosctxt = geosContext();
596-
597596
double cost = 0;
598-
//check the label center. if covered by polygon, initial cost of 4
599-
if ( polygon->containsPoint(( x[0] + x[2] ) / 2.0, ( y[0] + y[2] ) / 2.0 ) )
600-
cost += 4;
601-
602597
try
603598
{
604-
//calculate proportion of label candidate which is covered by polygon
605-
GEOSGeometry* intersectionGeom = GEOSIntersection_r( geosctxt, mGeos, polygon->mGeos );
606-
if ( intersectionGeom )
599+
if ( GEOSPreparedIntersects_r( geosctxt, polygon->preparedGeom(), mGeos ) == 1 )
607600
{
608-
double positionArea = 0;
609-
if ( GEOSArea_r( geosctxt, mGeos, &positionArea ) == 1 )
601+
//at least a partial intersection
602+
cost += 1;
603+
604+
double px, py;
605+
606+
// check each corner
607+
for ( int i = 0; i < 4; ++i )
610608
{
611-
double intersectionArea = 0;
612-
if ( GEOSArea_r( geosctxt, intersectionGeom, &intersectionArea ) == 1 )
609+
px = x[i];
610+
py = y[i];
611+
612+
for ( int a = 0; a < 2; ++a ) // and each middle of segment
613613
{
614-
double portionCovered = intersectionArea / positionArea;
615-
cost += portionCovered * 8.0; //cost of 8 if totally covered
614+
if ( polygon->containsPoint( px, py ) )
615+
cost++;
616+
px = ( x[i] + x[( i+1 ) %4] ) / 2.0;
617+
py = ( y[i] + y[( i+1 ) %4] ) / 2.0;
616618
}
617619
}
618-
GEOSGeom_destroy_r( geosctxt, intersectionGeom );
620+
621+
px = ( x[0] + x[2] ) / 2.0;
622+
py = ( y[0] + y[2] ) / 2.0;
623+
624+
//check the label center. if covered by polygon, cost of 4
625+
if ( polygon->containsPoint( px, py ) )
626+
cost += 4;
619627
}
620628
}
621629
catch ( GEOSException &e )
622630
{
623631
QgsMessageLog::logMessage( QObject::tr( "Exception: %1" ).arg( e.what() ), QObject::tr( "GEOS" ) );
624632
}
625633

634+
//maintain scaling from 0 -> 12
635+
cost = 12.0 * cost / 13.0;
636+
626637
if ( nextPart )
627638
{
628639
cost += nextPart->polygonIntersectionCostForParts( polygon );

src/core/pal/pointset.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -299,7 +299,7 @@ namespace pal
299299
GEOSCoordSeq_setX_r( geosctxt, seq, 0, x );
300300
GEOSCoordSeq_setY_r( geosctxt, seq, 0, y );
301301
GEOSGeometry* point = GEOSGeom_createPoint_r( geosctxt, seq );
302-
bool result = ( GEOSPreparedContains_r( geosctxt, preparedGeom(), point ) == 1 );
302+
bool result = ( GEOSPreparedContainsProperly_r( geosctxt, preparedGeom(), point ) == 1 );
303303
GEOSGeom_destroy_r( geosctxt, point );
304304

305305
return result;
@@ -349,7 +349,7 @@ namespace pal
349349
try
350350
{
351351
GEOSGeometry* bboxGeos = GEOSGeom_createLinearRing_r( geosctxt, coord );
352-
bool result = ( GEOSPreparedContains_r( geosctxt, preparedGeom(), bboxGeos ) == 1 );
352+
bool result = ( GEOSPreparedContainsProperly_r( geosctxt, preparedGeom(), bboxGeos ) == 1 );
353353
GEOSGeom_destroy_r( geosctxt, bboxGeos );
354354
return result;
355355
}

0 commit comments

Comments
 (0)