QGIS API Documentation  3.16.0-Hannover (43b64b13f3)
labelposition.cpp
Go to the documentation of this file.
1 /*
2  * libpal - Automated Placement of Labels Library
3  *
4  * Copyright (C) 2008 Maxence Laurent, MIS-TIC, HEIG-VD
5  * University of Applied Sciences, Western Switzerland
6  * http://www.hes-so.ch
7  *
8  * Contact:
9  * maxence.laurent <at> heig-vd <dot> ch
10  * or
11  * eric.taillard <at> heig-vd <dot> ch
12  *
13  * This file is part of libpal.
14  *
15  * libpal is free software: you can redistribute it and/or modify
16  * it under the terms of the GNU General Public License as published by
17  * the Free Software Foundation, either version 3 of the License, or
18  * (at your option) any later version.
19  *
20  * libpal is distributed in the hope that it will be useful,
21  * but WITHOUT ANY WARRANTY; without even the implied warranty of
22  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23  * GNU General Public License for more details.
24  *
25  * You should have received a copy of the GNU General Public License
26  * along with libpal. If not, see <http://www.gnu.org/licenses/>.
27  *
28  */
29 
30 #include "layer.h"
31 #include "pal.h"
32 #include "costcalculator.h"
33 #include "feature.h"
34 #include "geomfunction.h"
35 #include "labelposition.h"
36 #include "qgsgeos.h"
37 #include "qgsmessagelog.h"
38 #include <cmath>
39 #include <cfloat>
40 
41 using namespace pal;
42 
43 LabelPosition::LabelPosition( int id, double x1, double y1, double w, double h, double alpha, double cost, FeaturePart *feature, bool isReversed, Quadrant quadrant )
44  : id( id )
45  , feature( feature )
46  , probFeat( 0 )
47  , nbOverlap( 0 )
48  , alpha( alpha )
49  , w( w )
50  , h( h )
51  , partId( -1 )
52  , reversed( isReversed )
53  , upsideDown( false )
54  , quadrant( quadrant )
55  , mCost( cost )
56  , mHasObstacleConflict( false )
57  , mUpsideDownCharCount( 0 )
58 {
59  type = GEOS_POLYGON;
60  nbPoints = 4;
61  x.resize( nbPoints );
62  y.resize( nbPoints );
63 
64  // alpha take his value bw 0 and 2*pi rad
65  while ( this->alpha > 2 * M_PI )
66  this->alpha -= 2 * M_PI;
67 
68  while ( this->alpha < 0 )
69  this->alpha += 2 * M_PI;
70 
71  double beta = this->alpha + M_PI_2;
72 
73  double dx1, dx2, dy1, dy2;
74 
75  dx1 = std::cos( this->alpha ) * w;
76  dy1 = std::sin( this->alpha ) * w;
77 
78  dx2 = std::cos( beta ) * h;
79  dy2 = std::sin( beta ) * h;
80 
81  x[0] = x1;
82  y[0] = y1;
83 
84  x[1] = x1 + dx1;
85  y[1] = y1 + dy1;
86 
87  x[2] = x1 + dx1 + dx2;
88  y[2] = y1 + dy1 + dy2;
89 
90  x[3] = x1 + dx2;
91  y[3] = y1 + dy2;
92 
93  // upside down ? (curved labels are always correct)
94  if ( !feature->layer()->isCurved() &&
95  this->alpha > M_PI_2 && this->alpha <= 3 * M_PI_2 )
96  {
97  if ( feature->showUprightLabels() )
98  {
99  // Turn label upsidedown by inverting boundary points
100  double tx, ty;
101 
102  tx = x[0];
103  ty = y[0];
104 
105  x[0] = x[2];
106  y[0] = y[2];
107 
108  x[2] = tx;
109  y[2] = ty;
110 
111  tx = x[1];
112  ty = y[1];
113 
114  x[1] = x[3];
115  y[1] = y[3];
116 
117  x[3] = tx;
118  y[3] = ty;
119 
120  if ( this->alpha < M_PI )
121  this->alpha += M_PI;
122  else
123  this->alpha -= M_PI;
124 
125  // labels with text shown upside down are not classified as upsideDown,
126  // only those whose boundary points have been inverted
127  upsideDown = true;
128  }
129  }
130 
131  for ( int i = 0; i < nbPoints; ++i )
132  {
133  xmin = std::min( xmin, x[i] );
134  xmax = std::max( xmax, x[i] );
135  ymin = std::min( ymin, y[i] );
136  ymax = std::max( ymax, y[i] );
137  }
138 }
139 
141  : PointSet( other )
142 {
143  id = other.id;
144  mCost = other.mCost;
145  feature = other.feature;
146  probFeat = other.probFeat;
147  nbOverlap = other.nbOverlap;
148 
149  alpha = other.alpha;
150  w = other.w;
151  h = other.h;
152 
153  if ( other.mNextPart )
154  mNextPart = qgis::make_unique< LabelPosition >( *other.mNextPart );
155 
156  partId = other.partId;
157  upsideDown = other.upsideDown;
158  reversed = other.reversed;
159  quadrant = other.quadrant;
160  mHasObstacleConflict = other.mHasObstacleConflict;
161  mUpsideDownCharCount = other.mUpsideDownCharCount;
162 }
163 
164 bool LabelPosition::isIn( double *bbox )
165 {
166  int i;
167 
168  for ( i = 0; i < 4; i++ )
169  {
170  if ( x[i] >= bbox[0] && x[i] <= bbox[2] &&
171  y[i] >= bbox[1] && y[i] <= bbox[3] )
172  return true;
173  }
174 
175  if ( mNextPart )
176  return mNextPart->isIn( bbox );
177  else
178  return false;
179 }
180 
181 bool LabelPosition::isIntersect( double *bbox )
182 {
183  int i;
184 
185  for ( i = 0; i < 4; i++ )
186  {
187  if ( x[i] >= bbox[0] && x[i] <= bbox[2] &&
188  y[i] >= bbox[1] && y[i] <= bbox[3] )
189  return true;
190  }
191 
192  if ( mNextPart )
193  return mNextPart->isIntersect( bbox );
194  else
195  return false;
196 }
197 
198 bool LabelPosition::intersects( const GEOSPreparedGeometry *geometry )
199 {
200  if ( !mGeos )
201  createGeosGeom();
202 
203  try
204  {
205  if ( GEOSPreparedIntersects_r( QgsGeos::getGEOSHandler(), geometry, mGeos ) == 1 )
206  {
207  return true;
208  }
209  else if ( mNextPart )
210  {
211  return mNextPart->intersects( geometry );
212  }
213  }
214  catch ( GEOSException &e )
215  {
216  qWarning( "GEOS exception: %s", e.what() );
217  QgsMessageLog::logMessage( QObject::tr( "Exception: %1" ).arg( e.what() ), QObject::tr( "GEOS" ) );
218  return false;
219  }
220 
221  return false;
222 }
223 
224 bool LabelPosition::within( const GEOSPreparedGeometry *geometry )
225 {
226  if ( !mGeos )
227  createGeosGeom();
228 
229  try
230  {
231  if ( GEOSPreparedContains_r( QgsGeos::getGEOSHandler(), geometry, mGeos ) != 1 )
232  {
233  return false;
234  }
235  else if ( mNextPart )
236  {
237  return mNextPart->within( geometry );
238  }
239  }
240  catch ( GEOSException &e )
241  {
242  qWarning( "GEOS exception: %s", e.what() );
243  QgsMessageLog::logMessage( QObject::tr( "Exception: %1" ).arg( e.what() ), QObject::tr( "GEOS" ) );
244  return false;
245  }
246 
247  return true;
248 }
249 
250 bool LabelPosition::isInside( double *bbox )
251 {
252  for ( int i = 0; i < 4; i++ )
253  {
254  if ( !( x[i] >= bbox[0] && x[i] <= bbox[2] &&
255  y[i] >= bbox[1] && y[i] <= bbox[3] ) )
256  return false;
257  }
258 
259  if ( mNextPart )
260  return mNextPart->isInside( bbox );
261  else
262  return true;
263 }
264 
266 {
267  if ( this->probFeat == lp->probFeat ) // bugfix #1
268  return false; // always overlaping itself !
269 
270  if ( !nextPart() && !lp->nextPart() )
271  return isInConflictSinglePart( lp );
272  else
273  return isInConflictMultiPart( lp );
274 }
275 
276 bool LabelPosition::isInConflictSinglePart( const LabelPosition *lp ) const
277 {
278  if ( qgsDoubleNear( alpha, 0 ) && qgsDoubleNear( lp->alpha, 0 ) )
279  {
280  // simple case -- both candidates are oriented to axis, so shortcut with easy calculation
281  return boundingBoxIntersects( lp );
282  }
283 
284  if ( !mGeos )
285  createGeosGeom();
286 
287  if ( !lp->mGeos )
288  lp->createGeosGeom();
289 
290  GEOSContextHandle_t geosctxt = QgsGeos::getGEOSHandler();
291  try
292  {
293  bool result = ( GEOSPreparedIntersects_r( geosctxt, preparedGeom(), lp->mGeos ) == 1 );
294  return result;
295  }
296  catch ( GEOSException &e )
297  {
298  qWarning( "GEOS exception: %s", e.what() );
299  QgsMessageLog::logMessage( QObject::tr( "Exception: %1" ).arg( e.what() ), QObject::tr( "GEOS" ) );
300  return false;
301  }
302 }
303 
304 bool LabelPosition::isInConflictMultiPart( const LabelPosition *lp ) const
305 {
306  // check all parts against all parts of other one
307  const LabelPosition *tmp1 = this;
308  while ( tmp1 )
309  {
310  // check tmp1 against parts of other label
311  const LabelPosition *tmp2 = lp;
312  while ( tmp2 )
313  {
314  if ( tmp1->isInConflictSinglePart( tmp2 ) )
315  return true;
316  tmp2 = tmp2->nextPart();
317  }
318 
319  tmp1 = tmp1->nextPart();
320  }
321  return false; // no conflict found
322 }
323 
324 int LabelPosition::partCount() const
325 {
326  if ( mNextPart )
327  return mNextPart->partCount() + 1;
328  else
329  return 1;
330 }
331 
332 void LabelPosition::offsetPosition( double xOffset, double yOffset )
333 {
334  for ( int i = 0; i < 4; i++ )
335  {
336  x[i] += xOffset;
337  y[i] += yOffset;
338  }
339 
340  if ( mNextPart )
341  mNextPart->offsetPosition( xOffset, yOffset );
342 
343  invalidateGeos();
344 }
345 
347 {
348  return id;
349 }
350 
351 double LabelPosition::getX( int i ) const
352 {
353  return ( i >= 0 && i < 4 ? x[i] : -1 );
354 }
355 
356 double LabelPosition::getY( int i ) const
357 {
358  return ( i >= 0 && i < 4 ? y[i] : -1 );
359 }
360 
362 {
363  return alpha;
364 }
365 
367 {
368  if ( mCost >= 1 )
369  {
370  mCost -= int ( mCost ); // label cost up to 1
371  }
372 }
373 
375 {
376  return feature;
377 }
378 
379 void LabelPosition::getBoundingBox( double amin[2], double amax[2] ) const
380 {
381  if ( mNextPart )
382  {
383  mNextPart->getBoundingBox( amin, amax );
384  }
385  else
386  {
387  amin[0] = std::numeric_limits<double>::max();
388  amax[0] = std::numeric_limits<double>::lowest();
389  amin[1] = std::numeric_limits<double>::max();
390  amax[1] = std::numeric_limits<double>::lowest();
391  }
392  for ( int c = 0; c < 4; c++ )
393  {
394  if ( x[c] < amin[0] )
395  amin[0] = x[c];
396  if ( x[c] > amax[0] )
397  amax[0] = x[c];
398  if ( y[c] < amin[1] )
399  amin[1] = y[c];
400  if ( y[c] > amax[1] )
401  amax[1] = y[c];
402  }
403 }
404 
406 {
407  mHasObstacleConflict = conflicts;
408  if ( mNextPart )
409  mNextPart->setConflictsWithObstacle( conflicts );
410 }
411 
413 {
414  mHasHardConflict = conflicts;
415  if ( mNextPart )
416  mNextPart->setHasHardObstacleConflict( conflicts );
417 }
418 
420 {
421  double amin[2];
422  double amax[2];
423  getBoundingBox( amin, amax );
424  index.remove( this, QgsRectangle( amin[0], amin[1], amax[0], amax[1] ) );
425 }
426 
428 {
429  double amin[2];
430  double amax[2];
431  getBoundingBox( amin, amax );
432  index.insert( this, QgsRectangle( amin[0], amin[1], amax[0], amax[1] ) );
433 }
434 
435 double LabelPosition::getDistanceToPoint( double xp, double yp ) const
436 {
437  //first check if inside, if so then distance is -1
438  bool contains = false;
439  if ( alpha == 0 )
440  {
441  // easy case -- horizontal label
442  contains = x[0] <= xp && x[1] >= xp && y[0] <= yp && y[2] >= yp;
443  }
444  else
445  {
446  contains = containsPoint( xp, yp );
447  }
448 
449  double distance = -1;
450  if ( !contains )
451  {
452  if ( alpha == 0 )
453  {
454  const double dx = std::max( std::max( x[0] - xp, 0.0 ), xp - x[1] );
455  const double dy = std::max( std::max( y[0] - yp, 0.0 ), yp - y[2] );
456  distance = std::sqrt( dx * dx + dy * dy );
457  }
458  else
459  {
460  distance = std::sqrt( minDistanceToPoint( xp, yp ) );
461  }
462  }
463 
464  if ( mNextPart && distance > 0 )
465  return std::min( distance, mNextPart->getDistanceToPoint( xp, yp ) );
466 
467  return distance;
468 }
469 
471 {
472  if ( !mGeos )
473  createGeosGeom();
474 
475  if ( !line->mGeos )
476  line->createGeosGeom();
477 
478  GEOSContextHandle_t geosctxt = QgsGeos::getGEOSHandler();
479  try
480  {
481  if ( GEOSPreparedIntersects_r( geosctxt, line->preparedGeom(), mGeos ) == 1 )
482  {
483  return true;
484  }
485  else if ( mNextPart )
486  {
487  return mNextPart->crossesLine( line );
488  }
489  }
490  catch ( GEOSException &e )
491  {
492  qWarning( "GEOS exception: %s", e.what() );
493  QgsMessageLog::logMessage( QObject::tr( "Exception: %1" ).arg( e.what() ), QObject::tr( "GEOS" ) );
494  return false;
495  }
496 
497  return false;
498 }
499 
501 {
502  if ( !mGeos )
503  createGeosGeom();
504 
505  if ( !polygon->mGeos )
506  polygon->createGeosGeom();
507 
508  GEOSContextHandle_t geosctxt = QgsGeos::getGEOSHandler();
509  try
510  {
511  if ( GEOSPreparedIntersects_r( geosctxt, polygon->preparedGeom(), mGeos ) == 1
512  && GEOSPreparedContains_r( geosctxt, polygon->preparedGeom(), mGeos ) != 1 )
513  {
514  return true;
515  }
516  else if ( mNextPart )
517  {
518  return mNextPart->crossesBoundary( polygon );
519  }
520  }
521  catch ( GEOSException &e )
522  {
523  qWarning( "GEOS exception: %s", e.what() );
524  QgsMessageLog::logMessage( QObject::tr( "Exception: %1" ).arg( e.what() ), QObject::tr( "GEOS" ) );
525  return false;
526  }
527 
528  return false;
529 }
530 
532 {
533  //effectively take the average polygon intersection cost for all label parts
534  double totalCost = polygonIntersectionCostForParts( polygon );
535  int n = partCount();
536  return std::ceil( totalCost / n );
537 }
538 
540 {
541  if ( !mGeos )
542  createGeosGeom();
543 
544  if ( !polygon->mGeos )
545  polygon->createGeosGeom();
546 
547  GEOSContextHandle_t geosctxt = QgsGeos::getGEOSHandler();
548  try
549  {
550  if ( GEOSPreparedIntersects_r( geosctxt, polygon->preparedGeom(), mGeos ) == 1 )
551  {
552  return true;
553  }
554  }
555  catch ( GEOSException &e )
556  {
557  qWarning( "GEOS exception: %s", e.what() );
558  QgsMessageLog::logMessage( QObject::tr( "Exception: %1" ).arg( e.what() ), QObject::tr( "GEOS" ) );
559  }
560 
561  if ( mNextPart )
562  {
563  return mNextPart->intersectsWithPolygon( polygon );
564  }
565  else
566  {
567  return false;
568  }
569 }
570 
571 double LabelPosition::polygonIntersectionCostForParts( PointSet *polygon ) const
572 {
573  if ( !mGeos )
574  createGeosGeom();
575 
576  if ( !polygon->mGeos )
577  polygon->createGeosGeom();
578 
579  GEOSContextHandle_t geosctxt = QgsGeos::getGEOSHandler();
580  double cost = 0;
581  try
582  {
583  if ( GEOSPreparedIntersects_r( geosctxt, polygon->preparedGeom(), mGeos ) == 1 )
584  {
585  //at least a partial intersection
586  cost += 1;
587 
588  double px, py;
589 
590  // check each corner
591  for ( int i = 0; i < 4; ++i )
592  {
593  px = x[i];
594  py = y[i];
595 
596  for ( int a = 0; a < 2; ++a ) // and each middle of segment
597  {
598  if ( polygon->containsPoint( px, py ) )
599  cost++;
600  px = ( x[i] + x[( i + 1 ) % 4] ) / 2.0;
601  py = ( y[i] + y[( i + 1 ) % 4] ) / 2.0;
602  }
603  }
604 
605  px = ( x[0] + x[2] ) / 2.0;
606  py = ( y[0] + y[2] ) / 2.0;
607 
608  //check the label center. if covered by polygon, cost of 4
609  if ( polygon->containsPoint( px, py ) )
610  cost += 4;
611  }
612  }
613  catch ( GEOSException &e )
614  {
615  qWarning( "GEOS exception: %s", e.what() );
616  QgsMessageLog::logMessage( QObject::tr( "Exception: %1" ).arg( e.what() ), QObject::tr( "GEOS" ) );
617  }
618 
619  //maintain scaling from 0 -> 12
620  cost = 12.0 * cost / 13.0;
621 
622  if ( mNextPart )
623  {
624  cost += mNextPart->polygonIntersectionCostForParts( polygon );
625  }
626 
627  return cost;
628 }
pal::LabelPosition::quadrant
LabelPosition::Quadrant quadrant
Definition: labelposition.h:330
pal::PointSet::xmax
double xmax
Definition: pointset.h:230
pal::LabelPosition::getY
double getY(int i=0) const
Returns the down-left y coordinate.
Definition: labelposition.cpp:356
pal::LabelPosition::crossesBoundary
bool crossesBoundary(PointSet *polygon) const
Returns true if this label crosses the boundary of the specified polygon.
Definition: labelposition.cpp:500
pal::LabelPosition::Quadrant
Quadrant
Position of label candidate relative to feature.
Definition: labelposition.h:66
pal::LabelPosition::isInConflict
bool isInConflict(const LabelPosition *ls) const
Check whether or not this overlap with another labelPosition.
Definition: labelposition.cpp:265
pal::Layer::isCurved
bool isCurved() const
Returns true if the layer has curved labels.
Definition: layer.h:182
pal::LabelPosition::crossesLine
bool crossesLine(PointSet *line) const
Returns true if this label crosses the specified line.
Definition: labelposition.cpp:470
pal::LabelPosition::partId
int partId
Definition: labelposition.h:321
pal::LabelPosition::isInside
bool isInside(double *bbox)
Is the labelposition inside the bounding-box ?
Definition: labelposition.cpp:250
pal::LabelPosition::within
bool within(const GEOSPreparedGeometry *geometry)
Returns true if the label position is within a geometry.
Definition: labelposition.cpp:224
labelposition.h
pal::LabelPosition::cost
double cost() const
Returns the candidate label position's geographical cost.
Definition: labelposition.h:206
pal::LabelPosition::intersects
bool intersects(const GEOSPreparedGeometry *geometry)
Returns true if the label position intersects a geometry.
Definition: labelposition.cpp:198
pal::LabelPosition
LabelPosition is a candidate feature label position.
Definition: labelposition.h:56
pal::LabelPosition::w
double w
Definition: labelposition.h:318
layer.h
pal::LabelPosition::nextPart
LabelPosition * nextPart() const
Returns the next part of this label position (i.e.
Definition: labelposition.h:277
QgsRectangle
A rectangle specified with double values.
Definition: qgsrectangle.h:42
pal::LabelPosition::getFeaturePart
FeaturePart * getFeaturePart() const
Returns the feature corresponding to this labelposition.
Definition: labelposition.cpp:374
pal
Definition: qgsdiagramrenderer.h:49
pal::PointSet::containsPoint
bool containsPoint(double x, double y) const
Tests whether point set contains a specified point.
Definition: pointset.cpp:246
pal::LabelPosition::nbOverlap
int nbOverlap
Definition: labelposition.h:315
pal::FeaturePart::layer
Layer * layer()
Returns the layer that feature belongs to.
Definition: feature.cpp:152
pal::LabelPosition::setHasHardObstacleConflict
void setHasHardObstacleConflict(bool conflicts)
Sets whether the position is marked as having a hard conflict with an obstacle feature.
Definition: labelposition.cpp:412
pal::PointSet::ymin
double ymin
Definition: pointset.h:231
pal::LabelPosition::getBoundingBox
void getBoundingBox(double amin[2], double amax[2]) const
Returns bounding box - amin: xmin,ymin - amax: xmax,ymax.
Definition: labelposition.cpp:379
feature.h
pal::PointSet::minDistanceToPoint
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,...
Definition: pointset.cpp:789
pal::LabelPosition::upsideDown
bool upsideDown
Definition: labelposition.h:328
costcalculator.h
qgsDoubleNear
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
Definition: qgis.h:315
pal::PointSet::boundingBoxIntersects
bool boundingBoxIntersects(const PointSet *other) const
Returns true if the bounding box of this pointset intersects the bounding box of another pointset.
Definition: pointset.cpp:906
pal::LabelPosition::reversed
bool reversed
Definition: labelposition.h:326
pal::LabelPosition::getId
int getId() const
Returns the id.
Definition: labelposition.cpp:346
pal::PointSet::x
std::vector< double > x
Definition: pointset.h:201
pal::LabelPosition::isIn
bool isIn(double *bbox)
Is the labelposition in the bounding-box ? (intersect or inside????)
Definition: labelposition.cpp:164
pal::PointSet::type
int type
Definition: pointset.h:211
pal::LabelPosition::polygonIntersectionCost
int polygonIntersectionCost(PointSet *polygon) const
Returns cost of position intersection with polygon (testing area of intersection and center).
Definition: labelposition.cpp:531
pal::PointSet::LabelPosition
friend class LabelPosition
Definition: pointset.h:74
geomfunction.h
pal::LabelPosition::h
double h
Definition: labelposition.h:319
pal::FeaturePart
Main class to handle feature.
Definition: feature.h:96
PalRtree::remove
void remove(T *data, const QgsRectangle &bounds)
Removes existing data from the spatial index, with the specified bounds.
Definition: palrtree.h:78
pal::PointSet::invalidateGeos
void invalidateGeos()
Definition: pointset.cpp:179
QgsGeos::getGEOSHandler
static GEOSContextHandle_t getGEOSHandler()
Definition: qgsgeos.cpp:2888
pal::PointSet::createGeosGeom
void createGeosGeom() const
Definition: pointset.cpp:117
pal::LabelPosition::id
int id
Definition: labelposition.h:308
pal::PointSet::mGeos
GEOSGeometry * mGeos
Definition: pointset.h:205
pal::PointSet::y
std::vector< double > y
Definition: pointset.h:202
pal::PointSet
Definition: pointset.h:72
pal::PointSet::xmin
double xmin
Definition: pointset.h:229
pal::PointSet::preparedGeom
const GEOSPreparedGeometry * preparedGeom() const
Definition: pointset.cpp:167
c
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
Definition: porting_processing.dox:1
PalRtree
A rtree spatial index for use in the pal labeling engine.
Definition: palrtree.h:36
pal::LabelPosition::getX
double getX(int i=0) const
Returns the down-left x coordinate.
Definition: labelposition.cpp:351
QgsMessageLog::logMessage
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).
Definition: qgsmessagelog.cpp:27
pal::LabelPosition::validateCost
void validateCost()
Make sure the cost is less than 1.
Definition: labelposition.cpp:366
pal::LabelPosition::removeFromIndex
void removeFromIndex(PalRtree< LabelPosition > &index)
Removes the label position from the specified index.
Definition: labelposition.cpp:419
pal::FeaturePart::showUprightLabels
bool showUprightLabels() const
Returns true if feature's label must be displayed upright.
Definition: feature.cpp:2280
pal::LabelPosition::setConflictsWithObstacle
void setConflictsWithObstacle(bool conflicts)
Sets whether the position is marked as conflicting with an obstacle feature.
Definition: labelposition.cpp:405
pal::LabelPosition::insertIntoIndex
void insertIntoIndex(PalRtree< LabelPosition > &index)
Inserts the label position into the specified index.
Definition: labelposition.cpp:427
pal.h
pal::LabelPosition::feature
FeaturePart * feature
Definition: labelposition.h:310
pal::LabelPosition::getAlpha
double getAlpha() const
Returns the angle to rotate text (in rad).
Definition: labelposition.cpp:361
pal::LabelPosition::intersectsWithPolygon
bool intersectsWithPolygon(PointSet *polygon) const
Returns true if any intersection between polygon and position exists.
Definition: labelposition.cpp:539
pal::LabelPosition::getDistanceToPoint
double getDistanceToPoint(double xp, double yp) const
Gets distance from this label to a point. If point lies inside, returns negative number.
Definition: labelposition.cpp:435
pal::LabelPosition::alpha
double alpha
Definition: labelposition.h:317
pal::LabelPosition::offsetPosition
void offsetPosition(double xOffset, double yOffset)
Shift the label by specified offset.
Definition: labelposition.cpp:332
pal::PointSet::nbPoints
int nbPoints
Definition: pointset.h:200
PalRtree::insert
void insert(T *data, const QgsRectangle &bounds)
Inserts new data into the spatial index, with the specified bounds.
Definition: palrtree.h:59
pal::LabelPosition::probFeat
int probFeat
Definition: labelposition.h:313
pal::LabelPosition::isIntersect
bool isIntersect(double *bbox)
Is the labelposition intersect the bounding-box ?
Definition: labelposition.cpp:181
qgsgeos.h
qgsmessagelog.h
pal::PointSet::ymax
double ymax
Definition: pointset.h:232