52 , reversed( isReversed )
54 , quadrant( quadrant )
56 , mHasObstacleConflict( false )
57 , mUpsideDownCharCount( 0 )
65 while ( this->alpha > 2 * M_PI )
66 this->alpha -= 2 * M_PI;
68 while ( this->alpha < 0 )
69 this->alpha += 2 * M_PI;
71 double beta = this->alpha + M_PI_2;
73 double dx1, dx2, dy1, dy2;
75 dx1 = std::cos( this->alpha ) *
w;
76 dy1 = std::sin( this->alpha ) *
w;
78 dx2 = std::cos( beta ) *
h;
79 dy2 = std::sin( beta ) *
h;
87 x[2] = x1 + dx1 + dx2;
88 y[2] = y1 + dy1 + dy2;
95 this->alpha > M_PI_2 && this->alpha <= 3 * M_PI_2 )
120 if ( this->alpha < M_PI )
131 for (
int i = 0; i <
nbPoints; ++i )
153 if ( other.mNextPart )
154 mNextPart = qgis::make_unique< LabelPosition >( *other.mNextPart );
160 mHasObstacleConflict = other.mHasObstacleConflict;
161 mUpsideDownCharCount = other.mUpsideDownCharCount;
168 for ( i = 0; i < 4; i++ )
170 if (
x[i] >= bbox[0] &&
x[i] <= bbox[2] &&
171 y[i] >= bbox[1] &&
y[i] <= bbox[3] )
176 return mNextPart->isIn( bbox );
185 for ( i = 0; i < 4; i++ )
187 if (
x[i] >= bbox[0] &&
x[i] <= bbox[2] &&
188 y[i] >= bbox[1] &&
y[i] <= bbox[3] )
193 return mNextPart->isIntersect( bbox );
209 else if ( mNextPart )
211 return mNextPart->intersects( geometry );
214 catch ( GEOSException &e )
234 else if ( mNextPart )
236 return mNextPart->within( geometry );
239 catch ( GEOSException &e )
250 for (
int i = 0; i < 4; i++ )
252 if ( !(
x[i] >= bbox[0] &&
x[i] <= bbox[2] &&
253 y[i] >= bbox[1] &&
y[i] <= bbox[3] ) )
258 return mNextPart->isInside( bbox );
269 return isInConflictSinglePart( lp );
271 return isInConflictMultiPart( lp );
274 bool LabelPosition::isInConflictSinglePart(
const LabelPosition *lp )
const 291 bool result = ( GEOSPreparedIntersects_r( geosctxt,
preparedGeom(), lp->
mGeos ) == 1 );
294 catch ( GEOSException &e )
301 bool LabelPosition::isInConflictMultiPart(
const LabelPosition *lp )
const 311 if ( tmp1->isInConflictSinglePart( tmp2 ) )
321 int LabelPosition::partCount()
const 324 return mNextPart->partCount() + 1;
331 for (
int i = 0; i < 4; i++ )
338 mNextPart->offsetPosition( xOffset, yOffset );
350 return ( i >= 0 && i < 4 ?
x[i] : -1 );
355 return ( i >= 0 && i < 4 ?
y[i] : -1 );
367 mCost -= int ( mCost );
380 mNextPart->getBoundingBox( amin, amax );
384 amin[0] = std::numeric_limits<double>::max();
385 amax[0] = std::numeric_limits<double>::lowest();
386 amin[1] = std::numeric_limits<double>::max();
387 amax[1] = std::numeric_limits<double>::lowest();
389 for (
int c = 0;
c < 4;
c++ )
391 if (
x[
c] < amin[0] )
393 if (
x[
c] > amax[0] )
395 if (
y[
c] < amin[1] )
397 if (
y[
c] > amax[1] )
404 mHasObstacleConflict = conflicts;
406 mNextPart->setConflictsWithObstacle( conflicts );
411 mHasHardConflict = conflicts;
413 mNextPart->setHasHardObstacleConflict( conflicts );
438 if ( mNextPart && distance > 0 )
439 return std::min( distance, mNextPart->getDistanceToPoint( xp, yp ) );
459 else if ( mNextPart )
461 return mNextPart->crossesLine( line );
464 catch ( GEOSException &e )
478 if ( !polygon->
mGeos )
489 else if ( mNextPart )
491 return mNextPart->crossesBoundary( polygon );
494 catch ( GEOSException &e )
506 double totalCost = polygonIntersectionCostForParts( polygon );
508 return std::ceil( totalCost / n );
516 if ( !polygon->
mGeos )
527 catch ( GEOSException &e )
534 return mNextPart->intersectsWithPolygon( polygon );
542 double LabelPosition::polygonIntersectionCostForParts(
PointSet *polygon )
const 547 if ( !polygon->
mGeos )
562 for (
int i = 0; i < 4; ++i )
567 for (
int a = 0; a < 2; ++a )
571 px = (
x[i] +
x[( i + 1 ) % 4] ) / 2.0;
572 py = (
y[i] +
y[( i + 1 ) % 4] ) / 2.0;
576 px = (
x[0] +
x[2] ) / 2.0;
577 py = (
y[0] +
y[2] ) / 2.0;
584 catch ( GEOSException &e )
590 cost = 12.0 * cost / 13.0;
594 cost += mNextPart->polygonIntersectionCostForParts( polygon );
LabelPosition * nextPart() const
Returns the next part of this label position (i.e.
A rectangle specified with double values.
bool isIntersect(double *bbox)
Is the labelposition intersect the bounding-box ?
bool containsPoint(double x, double y) const
Tests whether point set contains a specified point.
void getBoundingBox(double amin[2], double amax[2]) const
Returns bounding box - amin: xmin,ymin - amax: xmax,ymax.
bool intersectsWithPolygon(PointSet *polygon) const
Returns true if any intersection between polygon and position exists.
double getY(int i=0) const
Returns the down-left y coordinate.
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
void offsetPosition(double xOffset, double yOffset)
Shift the label by specified offset.
void createGeosGeom() const
bool isInConflict(const LabelPosition *ls) const
Check whether or not this overlap with another labelPosition.
void setHasHardObstacleConflict(bool conflicts)
Sets whether the position is marked as having a hard conflict with an obstacle feature.
A rtree spatial index for use in the pal labeling engine.
static GEOSContextHandle_t getGEOSHandler()
bool boundingBoxIntersects(const PointSet *other) const
Returns true if the bounding box of this pointset intersects the bounding box of another pointset...
bool isInside(double *bbox)
Is the labelposition inside the bounding-box ?
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c
double cost() const
Returns the candidate label position's geographical cost.
FeaturePart * getFeaturePart() const
Returns the feature corresponding to this labelposition.
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::Warning, bool notifyUser=true)
Adds a message to the log instance (and creates it if necessary).
LabelPosition(int id, double x1, double y1, double w, double h, double alpha, double cost, FeaturePart *feature, bool isReversed=false, Quadrant quadrant=QuadrantOver)
create a new LabelPosition
Layer * layer()
Returns the layer that feature belongs to.
void validateCost()
Make sure the cost is less than 1.
Main class to handle feature.
int getId() const
Returns the id.
int polygonIntersectionCost(PointSet *polygon) const
Returns cost of position intersection with polygon (testing area of intersection and center)...
void setConflictsWithObstacle(bool conflicts)
Sets whether the position is marked as conflicting with an obstacle feature.
double getAlpha() const
Returns the angle to rotate text (in rad).
double getX(int i=0) const
Returns the down-left x coordinate.
bool isIn(double *bbox)
Is the labelposition in the bounding-box ? (intersect or inside????)
LabelPosition is a candidate feature label position.
Quadrant
Position of label candidate relative to feature.
const GEOSPreparedGeometry * preparedGeom() const
bool within(const GEOSPreparedGeometry *geometry)
Returns true if the label position is within a geometry.
void insert(T *data, const QgsRectangle &bounds)
Inserts new data into the spatial index, with the specified bounds.
bool intersects(const GEOSPreparedGeometry *geometry)
Returns true if the label position intersects a geometry.
void remove(T *data, const QgsRectangle &bounds)
Removes existing data from the spatial index, with the specified bounds.
bool crossesBoundary(PointSet *polygon) const
Returns true if this label crosses the boundary of the specified polygon.
void removeFromIndex(PalRtree< LabelPosition > &index)
Removes the label position from the specified index.
double minDistanceToPoint(double px, double py, double *rx=nullptr, double *ry=nullptr) const
Returns the squared minimum distance between the point set geometry and the point (px...
bool isCurved() const
Returns true if the layer has curved labels.
bool showUprightLabels() const
Returns true if feature's label must be displayed upright.
bool crossesLine(PointSet *line) const
Returns true if this label crosses the specified line.
LabelPosition::Quadrant quadrant
void insertIntoIndex(PalRtree< LabelPosition > &index)
Inserts the label position into the specified index.
double getDistanceToPoint(double xp, double yp) const
Gets distance from this label to a point. If point lies inside, returns negative number.