QGIS API Documentation  2.14.0-Essen
qgslabelingenginev2.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgslabelingenginev2.cpp
3  --------------------------------------
4  Date : September 2015
5  Copyright : (C) 2015 by Martin Dobias
6  Email : wonder dot sk at gmail dot com
7  ***************************************************************************
8  * *
9  * This program is free software; you can redistribute it and/or modify *
10  * it under the terms of the GNU General Public License as published by *
11  * the Free Software Foundation; either version 2 of the License, or *
12  * (at your option) any later version. *
13  * *
14  ***************************************************************************/
15 
16 #include "qgslabelingenginev2.h"
17 
18 #include "qgslogger.h"
19 #include "qgsproject.h"
20 
21 #include "feature.h"
22 #include "labelposition.h"
23 #include "layer.h"
24 #include "pal.h"
25 #include "problem.h"
26 
27 
28 
29 // helper function for checking for job cancellation within PAL
30 static bool _palIsCancelled( void* ctx )
31 {
32  return ( reinterpret_cast< QgsRenderContext* >( ctx ) )->renderingStopped();
33 }
34 
35 // helper class for sorting labels into correct draw order
37 {
38  public:
39 
40  QgsLabelSorter( const QgsMapSettings& mapSettings )
41  : mMapSettings( mapSettings )
42  {}
43 
45  {
46  QgsLabelFeature* lf1 = lp1->getFeaturePart()->feature();
47  QgsLabelFeature* lf2 = lp2->getFeaturePart()->feature();
48 
49  if ( !qgsDoubleNear( lf1->zIndex(), lf2->zIndex() ) )
50  return lf1->zIndex() < lf2->zIndex();
51 
52  //equal z-index, so fallback to respecting layer render order
53  int layer1Pos = mMapSettings.layers().indexOf( lf1->provider()->layerId() );
54  int layer2Pos = mMapSettings.layers().indexOf( lf2->provider()->layerId() );
55  if ( layer1Pos != layer2Pos && layer1Pos >= 0 && layer2Pos >= 0 )
56  return layer1Pos > layer2Pos; //higher positions are rendered first
57 
58  //same layer, so render larger labels first
59  return lf1->size().width() * lf1->size().height() > lf2->size().width() * lf2->size().height();
60  }
61 
62  private:
63 
64  const QgsMapSettings& mMapSettings;
65 };
66 
67 
69  : mFlags( RenderOutlineLabels | UsePartialCandidates )
70  , mSearchMethod( QgsPalLabeling::Chain )
71  , mCandPoint( 8 )
72  , mCandLine( 8 )
73  , mCandPolygon( 8 )
74  , mResults( nullptr )
75 {
77 }
78 
80 {
81  delete mResults;
82  qDeleteAll( mProviders );
83  qDeleteAll( mSubProviders );
84 }
85 
87 {
88  provider->setEngine( this );
89  mProviders << provider;
90 }
91 
93 {
94  int idx = mProviders.indexOf( provider );
95  if ( idx >= 0 )
96  {
97  delete mProviders.takeAt( idx );
98  }
99 }
100 
102 {
103  QgsAbstractLabelProvider::Flags flags = provider->flags();
104 
105  // create the pal layer
106  pal::Layer* l = p.addLayer( provider,
107  provider->name(),
108  provider->placement(),
109  provider->priority(),
110  true,
111  flags.testFlag( QgsAbstractLabelProvider::DrawLabels ),
112  flags.testFlag( QgsAbstractLabelProvider::DrawAllLabels ) );
113 
114  // extra flags for placement of labels for linestrings
115  l->setArrangementFlags( static_cast< pal::LineArrangementFlags >( provider->linePlacementFlags() ) );
116 
117  // set label mode (label per feature is the default)
119 
120  // set whether adjacent lines should be merged
122 
123  // set obstacle type
124  l->setObstacleType( provider->obstacleType() );
125 
126  // set whether location of centroid must be inside of polygons
128 
129  // set whether labels must fall completely within the polygon
131 
132  // set how to show upside-down labels
133  pal::Layer::UpsideDownLabels upsdnlabels;
134  switch ( provider->upsidedownLabels() )
135  {
137  upsdnlabels = pal::Layer::Upright;
138  break;
140  upsdnlabels = pal::Layer::ShowDefined;
141  break;
143  upsdnlabels = pal::Layer::ShowAll;
144  break;
145  default:
146  Q_ASSERT( "unsupported upside-down label setting" && 0 );
147  return;
148  }
149  l->setUpsidedownLabels( upsdnlabels );
150 
151 
152  QList<QgsLabelFeature*> features = provider->labelFeatures( context );
153 
154  Q_FOREACH ( QgsLabelFeature* feature, features )
155  {
156  try
157  {
158  l->registerFeature( feature );
159  }
160  catch ( std::exception &e )
161  {
162  Q_UNUSED( e );
163  QgsDebugMsgLevel( QString( "Ignoring feature %1 due PAL exception:" ).arg( feature->id() ) + QString::fromLatin1( e.what() ), 4 );
164  continue;
165  }
166  }
167 
168  // any sub-providers?
169  Q_FOREACH ( QgsAbstractLabelProvider* subProvider, provider->subProviders() )
170  {
171  mSubProviders << subProvider;
172  processProvider( subProvider, context, p );
173  }
174 }
175 
176 
178 {
179  pal::Pal p;
180 
182  switch ( mSearchMethod )
183  {
184  default:
186  s = pal::CHAIN;
187  break;
189  s = pal::POPMUSIC_TABU;
190  break;
193  break;
196  break;
198  s = pal::FALP;
199  break;
200  }
201  p.setSearch( s );
202 
203  // set number of candidates generated per feature
204  p.setPointP( mCandPoint );
205  p.setLineP( mCandLine );
206  p.setPolyP( mCandPolygon );
207 
208  p.setShowPartial( mFlags.testFlag( UsePartialCandidates ) );
209 
210 
211  // for each provider: get labels and register them in PAL
212  Q_FOREACH ( QgsAbstractLabelProvider* provider, mProviders )
213  {
214  processProvider( provider, context, p );
215  }
216 
217 
218  // NOW DO THE LAYOUT (from QgsPalLabeling::drawLabeling)
219 
220  QPainter* painter = context.painter();
221 
223  if ( !qgsDoubleNear( mMapSettings.rotation(), 0.0 ) )
224  {
225  //PAL features are prerotated, so extent also needs to be unrotated
227  }
228 
229  QgsRectangle extent = extentGeom->boundingBox();
230  delete extentGeom;
231 
232  p.registerCancellationCallback( &_palIsCancelled, reinterpret_cast< void* >( &context ) );
233 
234  QTime t;
235  t.start();
236 
237  // do the labeling itself
238  double bbox[] = { extent.xMinimum(), extent.yMinimum(), extent.xMaximum(), extent.yMaximum() };
239 
241  pal::Problem *problem;
242  try
243  {
244  problem = p.extractProblem( bbox );
245  }
246  catch ( std::exception& e )
247  {
248  Q_UNUSED( e );
249  QgsDebugMsgLevel( "PAL EXCEPTION :-( " + QString::fromLatin1( e.what() ), 4 );
250  return;
251  }
252 
253 
254  if ( context.renderingStopped() )
255  {
256  delete problem;
257  return; // it has been cancelled
258  }
259 
260 #if 1 // XXX strk
261  // features are pre-rotated but not scaled/translated,
262  // so we only disable rotation here. Ideally, they'd be
263  // also pre-scaled/translated, as suggested here:
264  // http://hub.qgis.org/issues/11856
266  xform.setMapRotation( 0, 0, 0 );
267 #else
268  const QgsMapToPixel& xform = mMapSettings->mapToPixel();
269 #endif
270 
271  // draw rectangles with all candidates
272  // this is done before actual solution of the problem
273  // before number of candidates gets reduced
274  // TODO mCandidates.clear();
275  if ( mFlags.testFlag( DrawCandidates ) && problem )
276  {
277  painter->setBrush( Qt::NoBrush );
278  for ( int i = 0; i < problem->getNumFeatures(); i++ )
279  {
280  for ( int j = 0; j < problem->getFeatureCandidateCount( i ); j++ )
281  {
282  pal::LabelPosition* lp = problem->getFeatureCandidate( i, j );
283 
284  QgsPalLabeling::drawLabelCandidateRect( lp, painter, &xform );
285  }
286  }
287  }
288 
289  // find the solution
290  labels = p.solveProblem( problem, mFlags.testFlag( UseAllLabels ) );
291 
292  QgsDebugMsgLevel( QString( "LABELING work: %1 ms ... labels# %2" ).arg( t.elapsed() ).arg( labels->size() ), 4 );
293  t.restart();
294 
295  if ( context.renderingStopped() )
296  {
297  delete problem;
298  delete labels;
299  return;
300  }
301  painter->setRenderHint( QPainter::Antialiasing );
302 
303  // sort labels
304  qSort( labels->begin(), labels->end(), QgsLabelSorter( mMapSettings ) );
305 
306  // draw the labels
308  for ( ; it != labels->end(); ++it )
309  {
310  if ( context.renderingStopped() )
311  break;
312 
313  QgsLabelFeature* lf = ( *it )->getFeaturePart()->feature();
314  if ( !lf )
315  {
316  continue;
317  }
318 
319  lf->provider()->drawLabel( context, *it );
320  }
321 
322  // Reset composition mode for further drawing operations
323  painter->setCompositionMode( QPainter::CompositionMode_SourceOver );
324 
325  QgsDebugMsgLevel( QString( "LABELING draw: %1 ms" ).arg( t.elapsed() ), 4 );
326 
327  delete problem;
328  delete labels;
329 
330 
331 }
332 
334 {
336  mResults = nullptr;
337  return res;
338 }
339 
340 
342 {
343  bool saved = false;
345  mSearchMethod = static_cast< QgsPalLabeling::Search >( prj->readNumEntry( "PAL", "/SearchMethod", static_cast< int >( QgsPalLabeling::Chain ), &saved ) );
346  mCandPoint = prj->readNumEntry( "PAL", "/CandidatesPoint", 8, &saved );
347  mCandLine = prj->readNumEntry( "PAL", "/CandidatesLine", 8, &saved );
348  mCandPolygon = prj->readNumEntry( "PAL", "/CandidatesPolygon", 8, &saved );
349 
350  mFlags = nullptr;
351  if ( prj->readBoolEntry( "PAL", "/ShowingCandidates", false, &saved ) ) mFlags |= DrawCandidates;
352  if ( prj->readBoolEntry( "PAL", "/DrawRectOnly", false, &saved ) ) mFlags |= DrawLabelRectOnly;
353  if ( prj->readBoolEntry( "PAL", "/ShowingShadowRects", false, &saved ) ) mFlags |= DrawShadowRects;
354  if ( prj->readBoolEntry( "PAL", "/ShowingAllLabels", false, &saved ) ) mFlags |= UseAllLabels;
355  if ( prj->readBoolEntry( "PAL", "/ShowingPartialsLabels", true, &saved ) ) mFlags |= UsePartialCandidates;
356  if ( prj->readBoolEntry( "PAL", "/DrawOutlineLabels", true, &saved ) ) mFlags |= RenderOutlineLabels;
357 }
358 
360 {
361  QgsProject::instance()->writeEntry( "PAL", "/SearchMethod", static_cast< int >( mSearchMethod ) );
362  QgsProject::instance()->writeEntry( "PAL", "/CandidatesPoint", mCandPoint );
363  QgsProject::instance()->writeEntry( "PAL", "/CandidatesLine", mCandLine );
364  QgsProject::instance()->writeEntry( "PAL", "/CandidatesPolygon", mCandPolygon );
365 
366  QgsProject::instance()->writeEntry( "PAL", "/ShowingCandidates", mFlags.testFlag( DrawCandidates ) );
367  QgsProject::instance()->writeEntry( "PAL", "/DrawRectOnly", mFlags.testFlag( DrawLabelRectOnly ) );
368  QgsProject::instance()->writeEntry( "PAL", "/ShowingShadowRects", mFlags.testFlag( DrawShadowRects ) );
369  QgsProject::instance()->writeEntry( "PAL", "/ShowingAllLabels", mFlags.testFlag( UseAllLabels ) );
370  QgsProject::instance()->writeEntry( "PAL", "/ShowingPartialsLabels", mFlags.testFlag( UsePartialCandidates ) );
371  QgsProject::instance()->writeEntry( "PAL", "/DrawOutlineLabels", mFlags.testFlag( RenderOutlineLabels ) );
372 }
373 
374 
375 
377 
379 {
380  return mLayer ? mLayer->provider() : nullptr;
381 
382 }
383 
385  : mEngine( nullptr )
386  , mLayerId( layerId )
387  , mFlags( DrawLabels )
388  , mPlacement( QgsPalLayerSettings::AroundPoint )
389  , mLinePlacementFlags( 0 )
390  , mPriority( 0.5 )
391  , mObstacleType( QgsPalLayerSettings::PolygonInterior )
392  , mUpsidedownLabels( QgsPalLayerSettings::Upright )
393 {
394 }
395 
396 
397 //
398 // QgsLabelingUtils
399 //
400 
402 {
403  QStringList predefinedOrderString;
404  Q_FOREACH ( QgsPalLayerSettings::PredefinedPointPosition position, positions )
405  {
406  switch ( position )
407  {
409  predefinedOrderString << "TL";
410  break;
412  predefinedOrderString << "TSL";
413  break;
415  predefinedOrderString << "T";
416  break;
418  predefinedOrderString << "TSR";
419  break;
421  predefinedOrderString << "TR";
422  break;
424  predefinedOrderString << "L";
425  break;
427  predefinedOrderString << "R";
428  break;
430  predefinedOrderString << "BL";
431  break;
433  predefinedOrderString << "BSL";
434  break;
436  predefinedOrderString << "B";
437  break;
439  predefinedOrderString << "BSR";
440  break;
442  predefinedOrderString << "BR";
443  break;
444  }
445  }
446  return predefinedOrderString.join( "," );
447 }
448 
450 {
452  QStringList predefinedOrderList = positionString.split( ',' );
453  Q_FOREACH ( const QString& position, predefinedOrderList )
454  {
455  QString cleaned = position.trimmed().toUpper();
456  if ( cleaned == "TL" )
458  else if ( cleaned == "TSL" )
460  else if ( cleaned == "T" )
462  else if ( cleaned == "TSR" )
464  else if ( cleaned == "TR" )
466  else if ( cleaned == "L" )
468  else if ( cleaned == "R" )
470  else if ( cleaned == "BL" )
472  else if ( cleaned == "BSL" )
474  else if ( cleaned == "B" )
476  else if ( cleaned == "BSR" )
478  else if ( cleaned == "BR" )
480  }
481  return result;
482 }
Label below point, slightly right of center.
Layer * addLayer(QgsAbstractLabelProvider *provider, const QString &layerName, QgsPalLayerSettings::Placement arrangement, double defaultPriority, bool active, bool toLabel, bool displayAll=false)
add a new layer
Definition: pal.cpp:108
QString name() const
Name of the layer (for statistics, debugging etc.) - does not need to be unique.
A rectangle specified with double values.
Definition: qgsrectangle.h:35
Label on bottom-left of point.
void processProvider(QgsAbstractLabelProvider *provider, QgsRenderContext &context, pal::Pal &p)
QString toUpper() const
void setMapRotation(double degrees, double cx, double cy)
Set map rotation in degrees (clockwise)
static bool _palIsCancelled(void *ctx)
Definition: pal.h:63
void setCompositionMode(CompositionMode mode)
int getFeatureCandidateCount(int i)
Definition: problem.h:121
unsigned int linePlacementFlags() const
For layers with linestring geometries - extra placement flags (or-ed combination of QgsPalLayerSettin...
void setRenderHint(RenderHint hint, bool on)
QgsLabelFeature * feature()
Returns the parent feature.
Definition: feature.h:109
Label on top-left of point.
~QgsLabelingEngineV2()
Clean up everything (especially the registered providers)
double yMaximum() const
Get the y maximum value (top side of rectangle)
Definition: qgsrectangle.h:197
void registerCancellationCallback(FnIsCancelled fnCancelled, void *context)
Register a function that returns whether this job has been cancelled - PAL calls it during the comput...
Definition: pal.cpp:506
Whether to show debugging rectangles for drop shadows.
QStringList split(const QString &sep, SplitBehavior behavior, Qt::CaseSensitivity cs) const
static void drawLabelCandidateRect(pal::LabelPosition *lp, QPainter *painter, const QgsMapToPixel *xform, QList< QgsLabelCandidate > *candidates=nullptr)
QgsAbstractLabelProvider * provider() const
Return provider of this instance.
A set of features which influence the labelling process.
Definition: layer.h:55
PredefinedPointPosition
Positions for labels when using the QgsPalLabeling::OrderedPositionsAroundPoint placement mode...
bool operator()(pal::LabelPosition *lp1, pal::LabelPosition *lp2) const
void addProvider(QgsAbstractLabelProvider *provider)
Add provider of label features. Takes ownership of the provider.
QgsRectangle boundingBox() const
Returns the bounding box of this feature.
QgsRectangle visibleExtent() const
Return the actual extent derived from requested extent that takes takes output image size into accoun...
Main Pal labelling class.
Definition: pal.h:84
is slower and best than TABU, worse and faster than TABU_CHAIN
Definition: pal.h:62
UpsideDownLabels
Definition: layer.h:66
Label on top of point, slightly right of center.
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:76
int mCandPoint
Number of candedate positions that will be generated for features.
void setUpsidedownLabels(UpsideDownLabels ud)
Sets how upside down labels will be handled within the layer.
Definition: layer.h:192
T takeAt(int i)
const QgsMapToPixel & mapToPixel() const
void setShowPartial(bool show)
Set flag show partial label.
Definition: pal.cpp:594
QString join(const QString &separator) const
whether to label each part of multi-part features separately
double rotation() const
Return the rotation of the resulting map image Units are clockwise degrees.
FeaturePart * getFeaturePart()
return the feature corresponding to this labelposition
void readSettingsFromProject()
Read configuration of the labeling engine from the current project file.
QgsPalLayerSettings::UpsideDownLabels upsidedownLabels() const
How to handle labels that would be upside down.
virtual QList< QgsAbstractLabelProvider * > subProviders()
Return list of child providers - useful if the provider needs to put labels into more layers with dif...
void setObstacleType(QgsPalLayerSettings::ObstacleType obstacleType)
Sets the obstacle type, which controls how features within the layer act as obstacles for labels...
Definition: layer.h:151
bool qgsDoubleNear(double a, double b, double epsilon=4 *DBL_EPSILON)
Definition: qgis.h:285
void setCentroidInside(bool forceInside)
Sets whether labels placed at the centroid of features within the layer are forced to be placed insid...
Definition: layer.h:205
is a little bit better than CHAIN but slower
Definition: pal.h:61
int size() const
void setFitInPolygonOnly(bool fitInPolygon)
Sets whether labels which do not fit completely within a polygon feature are discarded.
Definition: layer.h:220
whether adjacent lines (with the same label text) should be merged
The QgsMapSettings class contains configuration for rendering of the map.
int indexOf(const T &value, int from) const
void removeProvider(QgsAbstractLabelProvider *provider)
Remove provider if the provider&#39;s initialization failed. Provider instance is deleted.
QSizeF size() const
Size of the label (in map units)
virtual QList< QgsLabelFeature * > labelFeatures(QgsRenderContext &context)=0
Return list of label features (they are owned by the provider and thus deleted on its destruction) ...
Perform transforms between map coordinates and device coordinates.
Definition: qgsmaptopixel.h:34
bool writeEntry(const QString &scope, const QString &key, bool value)
int elapsed() const
QgsPalLayerSettings::Placement placement() const
What placement strategy to use for the labels.
Label on left of point.
double yMinimum() const
Get the y minimum value (bottom side of rectangle)
Definition: qgsrectangle.h:202
double xMaximum() const
Get the x maximum value (right side of rectangle)
Definition: qgsrectangle.h:187
#define QgsDebugMsgLevel(str, level)
Definition: qgslogger.h:34
QgsMapSettings mMapSettings
Associated map settings instance.
QList< QgsAbstractLabelProvider * > mProviders
List of providers (the are owned by the labeling engine)
bool renderingStopped() const
Whether to draw rectangles of generated candidates (good for debugging)
is the best but slowest
Definition: pal.h:60
QString trimmed() const
struct pal::_chain Chain
Flags flags() const
Get flags of the labeling engine.
void setPointP(int point_p)
set # candidates to generate for points features Higher the value is, longer Pal::labeller will spend...
Definition: pal.cpp:542
whether location of centroid must be inside of polygons
QgsPalLabeling::Search mSearchMethod
search method to use for removal collisions between labels
void setBrush(const QBrush &brush)
double priority() const
Default priority of labels (may be overridden by individual labels)
void setLineP(int line_p)
set maximum # candidates to generate for lines features Higher the value is, longer Pal::labeller wil...
Definition: pal.cpp:548
int restart()
Reads and writes project states.
Definition: qgsproject.h:70
QgsLabelingResults * mResults
Resulting labeling layout.
Flags flags() const
Flags associated with the provider.
void setEngine(const QgsLabelingEngineV2 *engine)
Associate provider with a labeling engine (should be only called internally from QgsLabelingEngineV2)...
whether labels must fall completely within the polygon
whether all features will be labelled even though overlaps occur
QgsLabelingEngineV2()
Construct the labeling engine with default settings.
The QgsAbstractLabelProvider class is an interface class.
void setArrangementFlags(const LineArrangementFlags &flags)
Sets the layer&#39;s arrangement flags.
Definition: layer.h:108
void writeSettingsToProject()
Write configuration of the labeling engine to the current project file.
iterator end()
QString layerId() const
Returns ID of associated layer, or empty string if no layer is associated with the provider...
int readNumEntry(const QString &scope, const QString &key, int def=0, bool *ok=nullptr) const
QgsLabelSorter(const QgsMapSettings &mapSettings)
void run(QgsRenderContext &context)
compute the labeling with given map settings and providers
double zIndex() const
Returns the label&#39;s z-index.
Whether to draw all labels even if there would be collisions.
bool registerFeature(QgsLabelFeature *label)
Register a feature in the layer.
Definition: layer.cpp:96
Whether to use also label candidates that are partially outside of the map view.
static QString encodePredefinedPositionOrder(const QVector< QgsPalLayerSettings::PredefinedPointPosition > &positions)
Encodes an ordered list of predefined point label positions to a string.
Contains information about the context of a rendering operation.
Problem * extractProblem(double bbox[4])
Definition: pal.cpp:512
QPainter * painter()
The QgsLabelFeature class describes a feature that should be used within the labeling engine...
Whether to only draw the label rect and not the actual label text (used for unit tests) ...
void setPolyP(int poly_p)
set maximum # candidates to generate for polygon features Higher the value is, longer Pal::labeller w...
Definition: pal.cpp:554
QList< LabelPosition * > * solveProblem(Problem *prob, bool displayAll)
Definition: pal.cpp:517
QgsPalLayerSettings::ObstacleType obstacleType() const
How the feature geometries will work as obstacles.
int getNumFeatures()
Definition: problem.h:119
int rotate(double rotation, const QgsPoint &center)
Rotate this geometry around the Z axis.
static QgsProject * instance()
access to canonical QgsProject instance
Definition: qgsproject.cpp:381
void setLabelMode(LabelMode mode)
Sets the layer&#39;s labeling mode.
Definition: layer.h:170
QgsAbstractLabelProvider(const QString &layerId=QString())
Construct the provider with default values.
Label below point, slightly left of center.
static QgsGeometry * fromRect(const QgsRectangle &rect)
Creates a new geometry from a QgsRectangle.
LabelPosition is a candidate feature label position.
Definition: labelposition.h:50
Label on top of point, slightly left of center.
QString fromLatin1(const char *str, int size)
Label on right of point.
Representation of a labeling problem.
Definition: problem.h:99
QStringList layers() const
Get list of layer IDs for map rendering The layers are stored in the reverse order of how they are re...
void start()
int indexOf(const QRegExp &rx, int from) const
whether the labels should be rendered
bool readBoolEntry(const QString &scope, const QString &key, bool def=false, bool *ok=nullptr) const
LabelPosition * getFeatureCandidate(int fi, int ci)
Definition: problem.h:123
Class that stores computed placement from labeling engine.
static QVector< QgsPalLayerSettings::PredefinedPointPosition > decodePredefinedPositionOrder(const QString &positionString)
Decodes a string to an ordered list of predefined point label positions.
SearchMethod
Search method to use.
Definition: pal.h:57
virtual void drawLabel(QgsRenderContext &context, pal::LabelPosition *label) const =0
draw this label at the position determined by the labeling engine
qreal height() const
is the worst but fastest method
Definition: pal.h:59
double xMinimum() const
Get the x minimum value (left side of rectangle)
Definition: qgsrectangle.h:192
Whether to render labels as text or outlines.
QgsPoint center() const
Center point of the rectangle.
Definition: qgsrectangle.h:217
QList< QgsAbstractLabelProvider * > mSubProviders
QgsLabelingResults * takeResults()
Return pointer to recently computed results and pass the ownership of results to the caller...
iterator begin()
qreal width() const
void setSearch(SearchMethod method)
Select the search method to use.
Definition: pal.cpp:634
void setMergeConnectedLines(bool merge)
Sets whether connected lines should be merged before labeling.
Definition: layer.h:181
QgsFeatureId id() const
Identifier of the label (unique within the parent label provider)