QGIS API Documentation  3.2.0-Bonn (bc43194)
qgsvectorlayerlabelprovider.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsvectorlayerlabelprovider.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 
17 
18 #include "qgsgeometry.h"
19 #include "qgslabelsearchtree.h"
20 #include "qgspallabeling.h"
21 #include "qgstextlabelfeature.h"
22 #include "qgsvectorlayer.h"
24 #include "qgsrenderer.h"
25 #include "qgspolygon.h"
26 #include "qgslinestring.h"
27 #include "qgsmultipolygon.h"
28 #include "qgslogger.h"
29 
30 #include "feature.h"
31 #include "labelposition.h"
32 
33 #include <QPicture>
34 
35 using namespace pal;
36 
37 QgsVectorLayerLabelProvider::QgsVectorLayerLabelProvider( QgsVectorLayer *layer, const QString &providerId, bool withFeatureLoop, const QgsPalLayerSettings *settings, const QString &layerName )
38  : QgsAbstractLabelProvider( layer, providerId )
39  , mSettings( settings ? * settings : QgsPalLayerSettings() ) // TODO: all providers should have valid settings?
40  , mLayerGeometryType( layer->geometryType() )
41  , mRenderer( layer->renderer() )
42  , mFields( layer->fields() )
43  , mCrs( layer->crs() )
44 {
45  mName = layerName.isEmpty() ? layer->id() : layerName;
46 
47  if ( withFeatureLoop )
48  {
49  mSource = new QgsVectorLayerFeatureSource( layer );
50  mOwnsSource = true;
51  }
52  else
53  {
54  mSource = nullptr;
55  mOwnsSource = false;
56  }
57 
58  init();
59 }
60 
62 {
65  mFlags = Flags();
66  if ( mSettings.drawLabels )
67  mFlags |= DrawLabels;
68  if ( mSettings.displayAll )
74  if ( mSettings.labelPerPart )
76 
77  mPriority = 1 - mSettings.priority / 10.0; // convert 0..10 --> 1..0
78 
80  {
81  //override obstacle type to treat any intersection of a label with the point symbol as a high cost conflict
83  }
84  else
85  {
87  }
88 
90 }
91 
92 
94 {
95  qDeleteAll( mLabels );
96 
97  if ( mOwnsSource )
98  delete mSource;
99 }
100 
101 
102 bool QgsVectorLayerLabelProvider::prepare( const QgsRenderContext &context, QSet<QString> &attributeNames )
103 {
105  const QgsMapSettings &mapSettings = mEngine->mapSettings();
106 
107  QgsDebugMsgLevel( "PREPARE LAYER " + mLayerId, 4 );
108 
109  if ( lyr.drawLabels )
110  {
111  if ( lyr.fieldName.isEmpty() )
112  {
113  return false;
114  }
115 
116  if ( lyr.isExpression )
117  {
118  QgsExpression exp( lyr.fieldName );
119  if ( exp.hasEvalError() )
120  {
121  QgsDebugMsgLevel( "Prepare error:" + exp.evalErrorString(), 4 );
122  return false;
123  }
124  }
125  else
126  {
127  // If we aren't an expression, we check to see if we can find the column.
128  if ( mFields.lookupField( lyr.fieldName ) == -1 )
129  {
130  return false;
131  }
132  }
133  }
134 
135  lyr.mCurFields = mFields;
136 
137  if ( lyr.drawLabels )
138  {
139  // add field indices for label's text, from expression or field
140  if ( lyr.isExpression )
141  {
142  // prepare expression for use in QgsPalLayerSettings::registerFeature()
143  QgsExpression *exp = lyr.getLabelExpression();
144  exp->prepare( &context.expressionContext() );
145  if ( exp->hasEvalError() )
146  {
147  QgsDebugMsgLevel( "Prepare error:" + exp->evalErrorString(), 4 );
148  }
149  Q_FOREACH ( const QString &name, exp->referencedColumns() )
150  {
151  QgsDebugMsgLevel( "REFERENCED COLUMN = " + name, 4 );
152  attributeNames.insert( name );
153  }
154  }
155  else
156  {
157  attributeNames.insert( lyr.fieldName );
158  }
159 
161  // add field indices of data defined expression or field
162  attributeNames.unite( lyr.dataDefinedProperties().referencedFields( context.expressionContext() ) );
163  }
164 
165  // NOW INITIALIZE QgsPalLayerSettings
166 
167  // TODO: ideally these (non-configuration) members should get out of QgsPalLayerSettings to here
168  // (together with registerFeature() & related methods) and QgsPalLayerSettings just stores config
169 
170  // save the pal layer to our layer context (with some additional info)
172 
173  lyr.xform = &mapSettings.mapToPixel();
174  lyr.ct = QgsCoordinateTransform();
175  if ( context.coordinateTransform().isValid() )
176  // this is context for layer rendering
177  lyr.ct = context.coordinateTransform();
178  else
179  {
180  // otherwise fall back to creating our own CT
181  lyr.ct = QgsCoordinateTransform( mCrs, mapSettings.destinationCrs(), mapSettings.transformContext() );
182  }
183  lyr.ptZero = lyr.xform->toMapCoordinates( 0, 0 );
184  lyr.ptOne = lyr.xform->toMapCoordinates( 1, 0 );
185 
186  // rect for clipping
187  lyr.extentGeom = QgsGeometry::fromRect( mapSettings.visibleExtent() );
188  if ( !qgsDoubleNear( mapSettings.rotation(), 0.0 ) )
189  {
190  //PAL features are prerotated, so extent also needs to be unrotated
191  lyr.extentGeom.rotate( -mapSettings.rotation(), mapSettings.visibleExtent().center() );
192  }
193 
194  lyr.mFeatsSendingToPal = 0;
195 
196  return true;
197 }
198 
199 
200 
202 {
203  if ( !mSource )
204  {
205  // we have created the provider with "own feature loop" == false
206  // so it is assumed that prepare() has been already called followed by registerFeature() calls
207  return mLabels;
208  }
209 
210  QSet<QString> attrNames;
211  if ( !prepare( ctx, attrNames ) )
212  return QList<QgsLabelFeature *>();
213 
214  if ( mRenderer )
215  mRenderer->startRender( ctx, mFields );
216 
217  QgsRectangle layerExtent = ctx.extent();
220 
221  QgsFeatureRequest request;
222  request.setFilterRect( layerExtent );
223  request.setSubsetOfAttributes( attrNames, mFields );
224  QgsFeatureIterator fit = mSource->getFeatures( request );
225 
227  ctx.expressionContext().appendScope( symbolScope );
228  QgsFeature fet;
229  while ( fit.nextFeature( fet ) )
230  {
231  QgsGeometry obstacleGeometry;
232  if ( mRenderer )
233  {
234  QgsSymbolList symbols = mRenderer->originalSymbolsForFeature( fet, ctx );
235  if ( !symbols.isEmpty() && fet.geometry().type() == QgsWkbTypes::PointGeometry )
236  {
237  //point feature, use symbol bounds as obstacle
238  obstacleGeometry = QgsVectorLayerLabelProvider::getPointObstacleGeometry( fet, ctx, symbols );
239  }
240  if ( !symbols.isEmpty() )
241  {
242  symbolScope = QgsExpressionContextUtils::updateSymbolScope( symbols.at( 0 ), symbolScope );
243  }
244  }
245  ctx.expressionContext().setFeature( fet );
246  registerFeature( fet, ctx, obstacleGeometry );
247  }
248 
249  if ( ctx.expressionContext().lastScope() == symbolScope )
250  delete ctx.expressionContext().popScope();
251 
252  if ( mRenderer )
253  mRenderer->stopRender( ctx );
254 
255  return mLabels;
256 }
257 
258 void QgsVectorLayerLabelProvider::registerFeature( QgsFeature &feature, QgsRenderContext &context, const QgsGeometry &obstacleGeometry )
259 {
260  QgsLabelFeature *label = nullptr;
261  mSettings.registerFeature( feature, context, &label, obstacleGeometry );
262  if ( label )
263  mLabels << label;
264 }
265 
267 {
268  if ( !fet.hasGeometry() || fet.geometry().type() != QgsWkbTypes::PointGeometry )
269  return QgsGeometry();
270 
271  bool isMultiPoint = fet.geometry().constGet()->nCoordinates() > 1;
272  std::unique_ptr< QgsAbstractGeometry > obstacleGeom;
273  if ( isMultiPoint )
274  obstacleGeom = qgis::make_unique< QgsMultiPolygon >();
275 
276  // for each point
277  for ( int i = 0; i < fet.geometry().constGet()->nCoordinates(); ++i )
278  {
279  QRectF bounds;
280  QgsPoint p = fet.geometry().constGet()->vertexAt( QgsVertexId( i, 0, 0 ) );
281  double x = p.x();
282  double y = p.y();
283  double z = 0; // dummy variable for coordinate transforms
284 
285  //transform point to pixels
286  if ( context.coordinateTransform().isValid() )
287  {
288  try
289  {
290  context.coordinateTransform().transformInPlace( x, y, z );
291  }
292  catch ( QgsCsException & )
293  {
294  return QgsGeometry();
295  }
296  }
297  context.mapToPixel().transformInPlace( x, y );
298 
299  QPointF pt( x, y );
300  Q_FOREACH ( QgsSymbol *symbol, symbols )
301  {
302  if ( symbol->type() == QgsSymbol::Marker )
303  {
304  if ( bounds.isValid() )
305  bounds = bounds.united( static_cast< QgsMarkerSymbol * >( symbol )->bounds( pt, context, fet ) );
306  else
307  bounds = static_cast< QgsMarkerSymbol * >( symbol )->bounds( pt, context, fet );
308  }
309  }
310 
311  //convert bounds to a geometry
312  QVector< double > bX;
313  bX << bounds.left() << bounds.right() << bounds.right() << bounds.left();
314  QVector< double > bY;
315  bY << bounds.top() << bounds.top() << bounds.bottom() << bounds.bottom();
316  std::unique_ptr< QgsLineString > boundLineString = qgis::make_unique< QgsLineString >( bX, bY );
317 
318  //then transform back to map units
319  //TODO - remove when labeling is refactored to use screen units
320  for ( int i = 0; i < boundLineString->numPoints(); ++i )
321  {
322  QgsPointXY point = context.mapToPixel().toMapCoordinates( boundLineString->xAt( i ), boundLineString->yAt( i ) );
323  boundLineString->setXAt( i, point.x() );
324  boundLineString->setYAt( i, point.y() );
325  }
326  if ( context.coordinateTransform().isValid() )
327  {
328  try
329  {
330  boundLineString->transform( context.coordinateTransform(), QgsCoordinateTransform::ReverseTransform );
331  }
332  catch ( QgsCsException & )
333  {
334  return QgsGeometry();
335  }
336  }
337  boundLineString->close();
338 
339  if ( context.coordinateTransform().isValid() )
340  {
341  // coordinate transforms may have resulted in nan coordinates - if so, strip these out
342  boundLineString->filterVertices( []( const QgsPoint & point )->bool
343  {
344  return std::isfinite( point.x() ) && std::isfinite( point.y() );
345  } );
346  if ( !boundLineString->isRing() )
347  return QgsGeometry();
348  }
349 
350  std::unique_ptr< QgsPolygon > obstaclePolygon = qgis::make_unique< QgsPolygon >();
351  obstaclePolygon->setExteriorRing( boundLineString.release() );
352 
353  if ( isMultiPoint )
354  {
355  static_cast<QgsMultiPolygon *>( obstacleGeom.get() )->addGeometry( obstaclePolygon.release() );
356  }
357  else
358  {
359  obstacleGeom = std::move( obstaclePolygon );
360  }
361  }
362 
363  return QgsGeometry( std::move( obstacleGeom ) );
364 }
365 
367 {
368  if ( !mSettings.drawLabels )
369  return;
370 
371  QgsTextLabelFeature *lf = dynamic_cast<QgsTextLabelFeature *>( label->getFeaturePart()->feature() );
372 
373  // Copy to temp, editable layer settings
374  // these settings will be changed by any data defined values, then used for rendering label components
375  // settings may be adjusted during rendering of components
376  QgsPalLayerSettings tmpLyr( mSettings );
377 
378  // apply any previously applied data defined settings for the label
379  const QMap< QgsPalLayerSettings::Property, QVariant > &ddValues = lf->dataDefinedValues();
380 
381  //font
382  QFont dFont = lf->definedFont();
383  QgsDebugMsgLevel( QString( "PAL font tmpLyr: %1, Style: %2" ).arg( tmpLyr.format().font().toString(), tmpLyr.format().font().styleName() ), 4 );
384  QgsDebugMsgLevel( QString( "PAL font definedFont: %1, Style: %2" ).arg( dFont.toString(), dFont.styleName() ), 4 );
385 
386  QgsTextFormat format = tmpLyr.format();
387  format.setFont( dFont );
388 
389  // size has already been calculated and stored in the defined font - this calculated size
390  // is in pixels
391  format.setSize( dFont.pixelSize() );
393  tmpLyr.setFormat( format );
394 
396  {
397  //calculate font alignment based on label quadrant
398  switch ( label->getQuadrant() )
399  {
400  case LabelPosition::QuadrantAboveLeft:
401  case LabelPosition::QuadrantLeft:
402  case LabelPosition::QuadrantBelowLeft:
404  break;
405  case LabelPosition::QuadrantAbove:
406  case LabelPosition::QuadrantOver:
407  case LabelPosition::QuadrantBelow:
409  break;
410  case LabelPosition::QuadrantAboveRight:
411  case LabelPosition::QuadrantRight:
412  case LabelPosition::QuadrantBelowRight:
414  break;
415  }
416  }
417 
418  // update tmpLyr with any data defined text style values
419  QgsPalLabeling::dataDefinedTextStyle( tmpLyr, ddValues );
420 
421  // update tmpLyr with any data defined text buffer values
422  QgsPalLabeling::dataDefinedTextBuffer( tmpLyr, ddValues );
423 
424  // update tmpLyr with any data defined text formatting values
425  QgsPalLabeling::dataDefinedTextFormatting( tmpLyr, ddValues );
426 
427  // update tmpLyr with any data defined shape background values
428  QgsPalLabeling::dataDefinedShapeBackground( tmpLyr, ddValues );
429 
430  // update tmpLyr with any data defined drop shadow values
431  QgsPalLabeling::dataDefinedDropShadow( tmpLyr, ddValues );
432 
433  // Render the components of a label in reverse order
434  // (backgrounds -> text)
435 
437  {
438  QgsTextFormat format = tmpLyr.format();
439 
440  if ( tmpLyr.format().background().enabled() )
441  {
443  }
444  else if ( tmpLyr.format().buffer().enabled() )
445  {
447  }
448  else
449  {
451  }
452 
453  tmpLyr.setFormat( format );
454  }
455 
456  if ( tmpLyr.format().background().enabled() )
457  {
458  drawLabelPrivate( label, context, tmpLyr, QgsTextRenderer::Background );
459  }
460 
461  if ( tmpLyr.format().buffer().enabled() )
462  {
463  drawLabelPrivate( label, context, tmpLyr, QgsTextRenderer::Buffer );
464  }
465 
466  drawLabelPrivate( label, context, tmpLyr, QgsTextRenderer::Text );
467 
468  // add to the results
469  QString labeltext = label->getFeaturePart()->feature()->labelText();
470  mEngine->results()->mLabelSearchTree->insertLabel( label, label->getFeaturePart()->featureId(), mLayerId, labeltext, dFont, false, lf->hasFixedPosition(), mProviderId );
471 }
472 
473 
475 {
476  // NOTE: this is repeatedly called for multi-part labels
477  QPainter *painter = context.painter();
478 
479  // features are pre-rotated but not scaled/translated,
480  // so we only disable rotation here. Ideally, they'd be
481  // also pre-scaled/translated, as suggested here:
482  // https://issues.qgis.org/issues/11856
483  QgsMapToPixel xform = context.mapToPixel();
484  xform.setMapRotation( 0, 0, 0 );
485 
486  QPointF outPt = xform.transform( label->getX(), label->getY() ).toQPointF();
487 
488  if ( mEngine->engineSettings().testFlag( QgsLabelingEngineSettings::DrawLabelRectOnly ) ) // TODO: this should get directly to labeling engine
489  {
490  //debugging rect
491  if ( drawType != QgsTextRenderer::Text )
492  return;
493 
494  QgsPointXY outPt2 = xform.transform( label->getX() + label->getWidth(), label->getY() + label->getHeight() );
495  QRectF rect( 0, 0, outPt2.x() - outPt.x(), outPt2.y() - outPt.y() );
496  painter->save();
497  painter->setRenderHint( QPainter::Antialiasing, false );
498  painter->translate( QPointF( outPt.x(), outPt.y() ) );
499  painter->rotate( -label->getAlpha() * 180 / M_PI );
500 
501  if ( label->conflictsWithObstacle() )
502  {
503  painter->setBrush( QColor( 255, 0, 0, 100 ) );
504  painter->setPen( QColor( 255, 0, 0, 150 ) );
505  }
506  else
507  {
508  painter->setBrush( QColor( 0, 255, 0, 100 ) );
509  painter->setPen( QColor( 0, 255, 0, 150 ) );
510  }
511 
512  painter->drawRect( rect );
513  painter->restore();
514 
515  if ( label->getNextPart() )
516  drawLabelPrivate( label->getNextPart(), context, tmpLyr, drawType, dpiRatio );
517 
518  return;
519  }
520 
521  QgsTextRenderer::Component component;
522  component.dpiRatio = dpiRatio;
523  component.origin = outPt;
524  component.rotation = label->getAlpha();
525 
526 
527 
528  if ( drawType == QgsTextRenderer::Background )
529  {
530  // get rotated label's center point
531  QPointF centerPt( outPt );
532  QgsPointXY outPt2 = xform.transform( label->getX() + label->getWidth() / 2,
533  label->getY() + label->getHeight() / 2 );
534 
535  double xc = outPt2.x() - outPt.x();
536  double yc = outPt2.y() - outPt.y();
537 
538  double angle = -component.rotation;
539  double xd = xc * std::cos( angle ) - yc * std::sin( angle );
540  double yd = xc * std::sin( angle ) + yc * std::cos( angle );
541 
542  centerPt.setX( centerPt.x() + xd );
543  centerPt.setY( centerPt.y() + yd );
544 
545  component.center = centerPt;
546 
547  // convert label size to render units
548  double labelWidthPx = context.convertToPainterUnits( label->getWidth(), QgsUnitTypes::RenderMapUnits, QgsMapUnitScale() );
549  double labelHeightPx = context.convertToPainterUnits( label->getHeight(), QgsUnitTypes::RenderMapUnits, QgsMapUnitScale() );
550 
551  component.size = QSizeF( labelWidthPx, labelHeightPx );
552 
553  QgsTextRenderer::drawBackground( context, component, tmpLyr.format(), QStringList(), QgsTextRenderer::Label );
554  }
555 
556  else if ( drawType == QgsTextRenderer::Buffer
557  || drawType == QgsTextRenderer::Text )
558  {
559 
560  // TODO: optimize access :)
561  QgsTextLabelFeature *lf = static_cast<QgsTextLabelFeature *>( label->getFeaturePart()->feature() );
562  QString txt = lf->text( label->getPartId() );
563  QFontMetricsF *labelfm = lf->labelFontMetrics();
564 
565  //add the direction symbol if needed
566  if ( !txt.isEmpty() && tmpLyr.placement == QgsPalLayerSettings::Line &&
567  tmpLyr.addDirectionSymbol )
568  {
569  bool prependSymb = false;
570  QString symb = tmpLyr.rightDirectionSymbol;
571 
572  if ( label->getReversed() )
573  {
574  prependSymb = true;
575  symb = tmpLyr.leftDirectionSymbol;
576  }
577 
578  if ( tmpLyr.reverseDirectionSymbol )
579  {
580  if ( symb == tmpLyr.rightDirectionSymbol )
581  {
582  prependSymb = true;
583  symb = tmpLyr.leftDirectionSymbol;
584  }
585  else
586  {
587  prependSymb = false;
588  symb = tmpLyr.rightDirectionSymbol;
589  }
590  }
591 
593  {
594  prependSymb = true;
595  symb = symb + QStringLiteral( "\n" );
596  }
598  {
599  prependSymb = false;
600  symb = QStringLiteral( "\n" ) + symb;
601  }
602 
603  if ( prependSymb )
604  {
605  txt.prepend( symb );
606  }
607  else
608  {
609  txt.append( symb );
610  }
611  }
612 
613  //QgsDebugMsgLevel( "drawLabel " + txt, 4 );
614  QStringList multiLineList = QgsPalLabeling::splitToLines( txt, tmpLyr.wrapChar );
615 
619  else if ( tmpLyr.multilineAlign == QgsPalLayerSettings::MultiRight )
621 
622  QgsTextRenderer::Component component;
623  component.origin = outPt;
624  component.rotation = label->getAlpha();
625  QgsTextRenderer::drawTextInternal( drawType, context, tmpLyr.format(), component, multiLineList, labelfm,
627 
628  }
629 
630  // NOTE: this used to be within above multi-line loop block, at end. (a mistake since 2010? [LS])
631  if ( label->getNextPart() )
632  drawLabelPrivate( label->getNextPart(), context, tmpLyr, drawType, dpiRatio );
633 }
int lookupField(const QString &fieldName) const
Look up field&#39;s index from the field name.
Definition: qgsfields.cpp:299
Class for parsing and evaluation of expressions (formerly called "search strings").
QList< QgsLabelFeature * > mLabels
List of generated.
static QgsExpressionContextScope * updateSymbolScope(const QgsSymbol *symbol, QgsExpressionContextScope *symbolScope=nullptr)
Updates a symbol scope related to a QgsSymbol to an expression context.
Wrapper for iterator of features from vector data provider or vector layer.
QgsVectorLayerLabelProvider(QgsVectorLayer *layer, const QString &providerId, bool withFeatureLoop, const QgsPalLayerSettings *settings, const QString &layerName=QString())
Convenience constructor to initialize the provider from given vector layer.
QString labelText() const
Text of the label.
A rectangle specified with double values.
Definition: qgsrectangle.h:40
double y
Definition: qgspoint.h:42
QString leftDirectionSymbol
String to use for left direction arrows.
QgsWkbTypes::GeometryType mLayerGeometryType
Geometry type of layer.
void setMapRotation(double degrees, double cx, double cy)
Set map rotation in degrees (clockwise)
QgsTextShadowSettings::ShadowPlacement shadowPlacement() const
Returns the placement for the drop shadow.
QgsPalLayerSettings::Placement mPlacement
Placement strategy.
QgsCoordinateTransformContext transformContext() const
Returns the coordinate transform context, which stores various information regarding which datum tran...
QgsFeatureId featureId() const
Returns the unique ID of the feature.
Definition: feature.cpp:151
QgsLabelFeature * feature()
Returns the parent feature.
Definition: feature.h:118
double rotation() const
Returns the rotation of the resulting map image, in degrees clockwise.
void registerFeature(QgsFeature &f, QgsRenderContext &context, QgsLabelFeature **labelFeature=nullptr, QgsGeometry obstacleGeometry=QgsGeometry())
Register a feature for labeling.
const QgsLabelingEngine * mEngine
Associated labeling engine.
Draw shadow under buffer.
UpsideDownLabels upsidedownLabels
Controls whether upside down labels are displayed and how they are handled.
Place direction symbols on below label.
void setFeature(const QgsFeature &feature)
Convenience function for setting a feature for the context.
double mPriority
Default priority of labels.
bool mOwnsSource
Whether layer&#39;s feature source is owned.
QgsTextShadowSettings & shadow()
Returns a reference to the text drop shadow settings.
double getY(int i=0) const
Returns the down-left y coordinate.
double y
Definition: qgspointxy.h:48
A class to represent a 2D point.
Definition: qgspointxy.h:43
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
Definition: qgis.h:251
OperationResult rotate(double rotation, const QgsPointXY &center)
Rotate this geometry around the Z axis.
HAlignment
Horizontal alignment.
void setFont(const QFont &font)
Sets the font used for rendering text.
const QMap< QgsPalLayerSettings::DataDefinedProperties, QVariant > & dataDefinedValues() const
Gets data-defined values.
QgsFeatureRequest & setSubsetOfAttributes(const QgsAttributeList &attrs)
Set a subset of attributes that will be fetched.
virtual QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest())=0
Gets an iterator for features matching the specified request.
Class that adds extra information to QgsLabelFeature for text labels.
QString evalErrorString() const
Returns evaluation error.
bool addDirectionSymbol
If true, &#39;<&#39; or &#39;>&#39; (or custom strings set via leftDirectionSymbol and rightDirectionSymbol) will be ...
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:104
Whether to only draw the label rect and not the actual label text (used for unit tests) ...
bool drawLabels
Whether to draw labels for this layer.
bool insertLabel(pal::LabelPosition *labelPos, int featureId, const QString &layerName, const QString &labeltext, const QFont &labelfont, bool diagram=false, bool pinned=false, const QString &providerId=QString())
Inserts label position.
bool mergeLines
True if connected line features with identical label text should be merged prior to generating label ...
MultiLineAlign multilineAlign
Horizontal alignment of multi-line labels.
Whether to label each part of multi-part features separately.
FeaturePart * getFeaturePart()
Returns the feature corresponding to this labelposition.
Label-specific draw mode.
QSet< QString > referencedColumns() const
Gets list of columns referenced by the expression.
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:62
bool hasGeometry() const
Returns true if the feature has an associated geometry.
Definition: qgsfeature.cpp:190
static QStringList splitToLines(const QString &text, const QString &wrapCharacter)
Splits a text string to a list of separate lines, using a specified wrap character.
QgsCoordinateTransform ct
QgsRectangle visibleExtent() const
Returns the actual extent derived from requested extent that takes takes output image size into accou...
double ANALYSIS_EXPORT angle(QgsPoint *p1, QgsPoint *p2, QgsPoint *p3, QgsPoint *p4)
Calculates the angle between two segments (in 2 dimension, z-values are ignored)
Definition: MathUtils.cpp:786
bool reverseDirectionSymbol
True if direction symbols should be reversed.
bool isValid() const
Returns true if the coordinate transform is valid, ie both the source and destination CRS have been s...
void setFormat(const QgsTextFormat &format)
Sets the label text formatting settings, e.g., font settings, buffer settings, etc.
QgsCoordinateReferenceSystem destinationCrs() const
returns CRS of destination coordinate reference system
virtual QgsSymbolList originalSymbolsForFeature(const QgsFeature &feature, QgsRenderContext &context) const
Equivalent of originalSymbolsForFeature() call extended to support renderers that may use more symbol...
Whether to render labels as text or outlines.
Whether adjacent lines (with the same label text) should be merged.
The QgsMapSettings class contains configuration for rendering of the map.
QList< QgsLabelFeature * > labelFeatures(QgsRenderContext &context) override
Returns list of label features (they are owned by the provider and thus deleted on its destruction) ...
void transformInPlace(double &x, double &y) const
Transform device coordinates to map coordinates.
void init()
initialization method - called from constructors
Perform transforms between map coordinates and device coordinates.
Definition: qgsmaptopixel.h:36
QgsPointXY transform(const QgsPointXY &p) const
Transform the point from map (world) coordinates to device coordinates.
static QgsGeometry fromRect(const QgsRectangle &rect)
Creates a new geometry from a QgsRectangle.
bool prepare(const QgsExpressionContext &context=QgsExpressionContext()) const override
Prepares the collection against a specified expression context.
QgsExpressionContextScope * lastScope()
Returns the last scope added to the context.
ObstacleType obstacleType
Controls how features act as obstacles for labels.
QList< QgsSymbol * > QgsSymbolList
Definition: qgsrenderer.h:43
bool displayAll
If true, all features will be labelled even when overlaps occur.
void setSize(double size)
Sets the size for rendered text.
QString id() const
Returns the layer&#39;s unique ID, which is used to access this layer from QgsProject.
const QgsLabelingEngineSettings & engineSettings() const
Gets associated labeling engine settings.
virtual bool prepare(const QgsRenderContext &context, QSet< QString > &attributeNames)
Prepare for registration of features.
Utility class for identifying a unique vertex within a geometry.
#define QgsDebugMsgLevel(str, level)
Definition: qgslogger.h:39
const QgsRectangle & extent() const
unsigned int mLinePlacementFlags
Extra placement flags for linestring geometries.
bool isShortCircuited() const
Returns true if the transform short circuits because the source and destination are equivalent...
Buffer component.
double getHeight() const
QgsPalLayerSettings mSettings
Layer&#39;s labeling configuration.
LabelPosition * getNextPart() const
const QgsMapToPixel * xform
This class wraps a request for features to a vector layer (or directly its vector data provider)...
Flags mFlags
Flags altering drawing and registration of features.
Draw shadow under text.
Whether location of centroid must be inside of polygons.
Quadrant getQuadrant() const
QgsFeatureRequest & setFilterRect(const QgsRectangle &rectangle)
Sets the rectangle from which features will be taken.
QgsTextBackgroundSettings & background()
Returns a reference to the text background settings.
QgsTextBufferSettings & buffer()
Returns a reference to the text buffer settings.
void setSizeUnit(QgsUnitTypes::RenderUnit unit)
Sets the units for the size of rendered text.
QgsCoordinateTransform coordinateTransform() const
Returns the current coordinate transform for the context, or an invalid transform is no coordinate tr...
QString text(int partId) const
Returns the text component corresponding to a specified label part.
Whether all features will be labelled even though overlaps occur.
virtual void registerFeature(QgsFeature &feature, QgsRenderContext &context, const QgsGeometry &obstacleGeometry=QgsGeometry())
Register a feature for labeling as one or more QgsLabelFeature objects stored into mLabels...
Single scope for storing variables and functions for use within a QgsExpressionContext.
QgsGeometry geometry() const
Returns the geometry associated with this feature.
Definition: qgsfeature.cpp:101
Point geometry type, with support for z-dimension and m-values.
Definition: qgspoint.h:37
const QgsMapToPixel & mapToPixel() const
QgsWkbTypes::GeometryType type() const
Returns type of the geometry as a QgsWkbTypes::GeometryType.
The QgsAbstractLabelProvider class is an interface class.
const QgsTextFormat & format() const
Returns the label text formatting settings, e.g., font settings, buffer settings, etc...
double x
Definition: qgspointxy.h:47
Partial snapshot of vector layer&#39;s state (only the members necessary for access to features) ...
Place direction symbols on above label.
Draw shadow below all text components.
const QgsAbstractGeometry * constGet() const
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
QgsExpressionContext & expressionContext()
Gets the expression context.
void transformInPlace(double &x, double &y, double &z, TransformDirection direction=ForwardTransform) const SIP_THROW(QgsCsException)
Transforms an array of x, y and z double coordinates in place, from the source CRS to the destination...
unsigned int placementFlags
QString wrapChar
Wrapping character string.
TextPart
Components of text.
QSet< QString > referencedFields(const QgsExpressionContext &context=QgsExpressionContext()) const override
Returns the set of any fields referenced by the active properties from the collection.
QgsFields mFields
Layer&#39;s fields.
QgsAbstractFeatureSource * mSource
Layer&#39;s feature source.
QString rightDirectionSymbol
String to use for right direction arrows.
Marker symbol.
Definition: qgssymbol.h:85
QgsExpression * getLabelExpression()
Returns the QgsExpression for this label settings.
Arranges candidates over a point (or centroid of a polygon), or at a preset offset from the point...
Contains information about the context of a rendering operation.
double convertToPainterUnits(double size, QgsUnitTypes::RenderUnit unit, const QgsMapUnitScale &scale=QgsMapUnitScale()) const
Converts a size from the specified units to painter units (pixels).
QFont definedFont()
Font to be used for rendering.
bool hasFixedPosition() const
Whether the label should use a fixed position instead of being automatically placed.
QPainter * painter()
Returns the destination QPainter for the render operation.
The QgsLabelFeature class describes a feature that should be used within the labeling engine...
const QgsMapToPixel & mapToPixel() const
QgsGeometry extentGeom
QString name() const
Name of the layer (for statistics, debugging etc.) - does not need to be unique.
Transform from destination to source CRS.
double getAlpha() const
Returns the angle to rotate text (in rad).
Multi polygon geometry collection.
QString mName
Name of the layer.
bool enabled() const
Returns whether the shadow is enabled.
SymbolType type() const
Definition: qgssymbol.h:113
Struct for storing maximum and minimum scales for measurements in map units.
QgsCoordinateReferenceSystem mCrs
Layer&#39;s CRS.
double getWidth() const
bool conflictsWithObstacle() const
Returns whether the position is marked as conflicting with an obstacle feature.
double getX(int i=0) const
Returns the down-left x coordinate.
virtual void startRender(QgsRenderContext &context, const QgsFields &fields)
Must be called when a new render cycle is started.
Definition: qgsrenderer.cpp:92
bool prepare(const QgsExpressionContext *context)
Gets the expression ready for evaluation - find out column indexes.
void appendScope(QgsExpressionContextScope *scope)
Appends a scope to the end of the context.
const QgsMapSettings & mapSettings() const
Gets associated map settings.
bool enabled() const
Returns whether the background is enabled.
bool testFlag(Flag f) const
Test whether a particular flag is enabled.
QgsLabelingResults * results() const
For internal use by the providers.
virtual void stopRender(QgsRenderContext &context)
Must be called when a render cycle has finished, to allow the renderer to clean up.
QString mProviderId
Associated provider ID (one layer may have multiple providers, e.g. in rule-based labeling) ...
Class for doing transforms between two map coordinate systems.
LabelPosition is a candidate feature label position.
Definition: labelposition.h:55
QgsPalLayerSettings::ObstacleType mObstacleType
Type of the obstacle of feature geometries.
bool enabled() const
Returns whether the buffer is enabled.
QgsPalLayerSettings::UpsideDownLabels mUpsidedownLabels
How to handle labels that would be upside down.
void setShadowPlacement(QgsTextShadowSettings::ShadowPlacement placement)
Sets the placement for the drop shadow.
Draw shadow under background shape.
Whether the labels should be rendered.
bool isExpression
True if this label is made from a expression string, e.g., FieldName || &#39;mm&#39;.
Custom exception class for Coordinate Reference System related exceptions.
Definition: qgsexception.h:65
QgsPointXY center() const
Returns the center point of the rectangle.
Definition: qgsrectangle.h:229
QgsExpressionContextScope * popScope()
Removes the last scope from the expression context and return it.
bool getReversed() const
bool nextFeature(QgsFeature &f)
Container for all settings relating to text rendering.
QFontMetricsF * labelFontMetrics()
Metrics of the font for rendering.
bool centroidInside
True if centroid positioned labels must be placed inside their corresponding feature polygon...
virtual QgsPoint vertexAt(QgsVertexId id) const =0
Returns the point corresponding to a specified vertex id.
bool hasEvalError() const
Returns true if an error occurred when evaluating last input.
virtual int nCoordinates() const
Returns the number of nodes contained in the geometry.
Represents a vector layer which manages a vector based data sets.
QString mLayerId
Associated layer&#39;s ID, if applicable.
QFont font() const
Returns the font used for rendering text.
int priority
Label priority.
QgsPointXY toMapCoordinates(int x, int y) const
bool labelPerPart
True if every part of a multi-part feature should be labeled.
void drawLabel(QgsRenderContext &context, pal::LabelPosition *label) const override
draw this label at the position determined by the labeling engine
void drawLabelPrivate(pal::LabelPosition *label, QgsRenderContext &context, QgsPalLayerSettings &tmpLyr, QgsTextRenderer::TextPart drawType, double dpiRatio=1.0) const
Internal label drawing method.
int getPartId() const
QgsRectangle transformBoundingBox(const QgsRectangle &rectangle, TransformDirection direction=ForwardTransform, bool handle180Crossover=false) const SIP_THROW(QgsCsException)
Transforms a rectangle from the source CRS to the destination CRS.
QgsPropertyCollection & dataDefinedProperties()
Returns a reference to the label&#39;s property collection, used for data defined overrides.
static QgsGeometry getPointObstacleGeometry(QgsFeature &fet, QgsRenderContext &context, const QgsSymbolList &symbols)
Returns the geometry for a point feature which should be used as an obstacle for labels.
QString fieldName
Name of field (or an expression) to use for label text.
DirectionSymbols placeDirectionSymbol
Placement option for direction symbols.
double x
Definition: qgspoint.h:41