Skip to content

Commit

Permalink
[pal] Consider all label parts when checking polygon obstacle cost
Browse files Browse the repository at this point in the history
Fixes curved label candidates not being marked as in conflict with
polygon obstacles when letters other than the first letter conflict
with the polygon.
  • Loading branch information
nyalldawson committed Sep 1, 2015
1 parent 8c716f6 commit a7e9ef5
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 20 deletions.
55 changes: 35 additions & 20 deletions src/core/pal/labelposition.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,14 @@ namespace pal
return false; // no conflict found
}

int LabelPosition::partCount() const
{
if ( nextPart )
return nextPart->partCount() + 1;
else
return 1;
}

void LabelPosition::offsetPosition( double xOffset, double yOffset )
{
for ( int i = 0; i < 4; i++ )
Expand Down Expand Up @@ -574,6 +582,14 @@ namespace pal
}

int LabelPosition::polygonIntersectionCost( PointSet *polygon ) const
{
//effectively take the average polygon intersection cost for all label parts
double totalCost = polygonIntersectionCostForParts( polygon );
int n = partCount();
return ceil( totalCost / n );
}

double LabelPosition::polygonIntersectionCostForParts( PointSet *polygon ) const
{
if ( !mGeos )
createGeosGeom();
Expand All @@ -583,7 +599,7 @@ namespace pal

GEOSContextHandle_t geosctxt = geosContext();

int cost = 0;
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;
Expand All @@ -592,33 +608,32 @@ namespace pal
{
//calculate proportion of label candidate which is covered by polygon
GEOSGeometry* intersectionGeom = GEOSIntersection_r( geosctxt, mGeos, polygon->mGeos );
if ( !intersectionGeom )
return cost;

double positionArea = 0;
if ( GEOSArea_r( geosctxt, mGeos, &positionArea ) != 1 )
if ( intersectionGeom )
{
double positionArea = 0;
if ( GEOSArea_r( geosctxt, mGeos, &positionArea ) == 1 )
{
double intersectionArea = 0;
if ( GEOSArea_r( geosctxt, intersectionGeom, &intersectionArea ) == 1 )
{
double portionCovered = intersectionArea / positionArea;
cost += portionCovered * 8.0; //cost of 8 if totally covered
}
}
GEOSGeom_destroy_r( geosctxt, intersectionGeom );
return cost;
}

double intersectionArea = 0;
if ( GEOSArea_r( geosctxt, intersectionGeom, &intersectionArea ) != 1 )
{
intersectionArea = 0;
}

GEOSGeom_destroy_r( geosctxt, intersectionGeom );

double portionCovered = intersectionArea / positionArea;
cost += ceil( portionCovered * 8.0 ); //cost of 8 if totally covered
return cost;
}
catch ( GEOSException &e )
{
QgsMessageLog::logMessage( QObject::tr( "Exception: %1" ).arg( e.what() ), QObject::tr( "GEOS" ) );
return cost;
}

if ( nextPart )
{
cost += nextPart->polygonIntersectionCostForParts( polygon );
}

return cost;
}

} // end namespace
Expand Down
9 changes: 9 additions & 0 deletions src/core/pal/labelposition.h
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,15 @@ namespace pal
double mCost;
bool mHasObstacleConflict;

/** Calculates the total number of parts for this label position
*/
int partCount() const;

/** Calculates the polygon intersection cost for a single label position part
* @returns double between 0 - 12
*/
double polygonIntersectionCostForParts( PointSet* polygon ) const;

};

} // end namespace
Expand Down

0 comments on commit a7e9ef5

Please sign in to comment.