QGIS API Documentation  3.6.0-Noosa (5873452)
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"
30 
31 #include "feature.h"
32 #include "labelposition.h"
33 
34 #include <QPicture>
35 
36 using namespace pal;
37 
38 QgsVectorLayerLabelProvider::QgsVectorLayerLabelProvider( QgsVectorLayer *layer, const QString &providerId, bool withFeatureLoop, const QgsPalLayerSettings *settings, const QString &layerName )
39  : QgsAbstractLabelProvider( layer, providerId )
40  , mSettings( settings ? * settings : QgsPalLayerSettings() ) // TODO: all providers should have valid settings?
41  , mLayerGeometryType( layer->geometryType() )
42  , mRenderer( layer->renderer() )
43  , mFields( layer->fields() )
44  , mCrs( layer->crs() )
45 {
46  mName = layerName.isEmpty() ? layer->id() : layerName;
47 
48  if ( withFeatureLoop )
49  {
50  mSource = new QgsVectorLayerFeatureSource( layer );
51  mOwnsSource = true;
52  }
53  else
54  {
55  mSource = nullptr;
56  mOwnsSource = false;
57  }
58 
59  init();
60 }
61 
63 {
66  mFlags = Flags();
67  if ( mSettings.drawLabels )
68  mFlags |= DrawLabels;
69  if ( mSettings.displayAll )
75  if ( mSettings.labelPerPart )
77 
78  mPriority = 1 - mSettings.priority / 10.0; // convert 0..10 --> 1..0
79 
81  {
82  //override obstacle type to treat any intersection of a label with the point symbol as a high cost conflict
84  }
85  else
86  {
88  }
89 
91 }
92 
93 
95 {
96  qDeleteAll( mLabels );
97 
98  if ( mOwnsSource )
99  delete mSource;
100 }
101 
102 
103 bool QgsVectorLayerLabelProvider::prepare( const QgsRenderContext &context, QSet<QString> &attributeNames )
104 {
106  const QgsMapSettings &mapSettings = mEngine->mapSettings();
107 
108  QgsDebugMsgLevel( "PREPARE LAYER " + mLayerId, 4 );
109 
110  if ( lyr.drawLabels )
111  {
112  if ( lyr.fieldName.isEmpty() )
113  {
114  return false;
115  }
116 
117  if ( lyr.isExpression )
118  {
119  QgsExpression exp( lyr.fieldName );
120  if ( exp.hasEvalError() )
121  {
122  QgsDebugMsgLevel( "Prepare error:" + exp.evalErrorString(), 4 );
123  return false;
124  }
125  }
126  else
127  {
128  // If we aren't an expression, we check to see if we can find the column.
129  if ( mFields.lookupField( lyr.fieldName ) == -1 )
130  {
131  return false;
132  }
133  }
134  }
135 
136  lyr.mCurFields = mFields;
137 
138  if ( lyr.drawLabels || lyr.obstacle )
139  {
140  if ( lyr.drawLabels )
141  {
142  // add field indices for label's text, from expression or field
143  if ( lyr.isExpression )
144  {
145  // prepare expression for use in QgsPalLayerSettings::registerFeature()
146  QgsExpression *exp = lyr.getLabelExpression();
147  exp->prepare( &context.expressionContext() );
148  if ( exp->hasEvalError() )
149  {
150  QgsDebugMsgLevel( "Prepare error:" + exp->evalErrorString(), 4 );
151  }
152  Q_FOREACH ( const QString &name, exp->referencedColumns() )
153  {
154  QgsDebugMsgLevel( "REFERENCED COLUMN = " + name, 4 );
155  attributeNames.insert( name );
156  }
157  }
158  else
159  {
160  attributeNames.insert( lyr.fieldName );
161  }
162  }
163 
165  // add field indices of data defined expression or field
166  attributeNames.unite( lyr.dataDefinedProperties().referencedFields( context.expressionContext() ) );
167  }
168 
169  // NOW INITIALIZE QgsPalLayerSettings
170 
171  // TODO: ideally these (non-configuration) members should get out of QgsPalLayerSettings to here
172  // (together with registerFeature() & related methods) and QgsPalLayerSettings just stores config
173 
174  // save the pal layer to our layer context (with some additional info)
176 
177  lyr.xform = &mapSettings.mapToPixel();
178  lyr.ct = QgsCoordinateTransform();
179  if ( context.coordinateTransform().isValid() )
180  // this is context for layer rendering
181  lyr.ct = context.coordinateTransform();
182  else
183  {
184  // otherwise fall back to creating our own CT
185  lyr.ct = QgsCoordinateTransform( mCrs, mapSettings.destinationCrs(), mapSettings.transformContext() );
186  }
187  lyr.ptZero = lyr.xform->toMapCoordinates( 0, 0 );
188  lyr.ptOne = lyr.xform->toMapCoordinates( 1, 0 );
189 
190  // rect for clipping
191  lyr.extentGeom = QgsGeometry::fromRect( mapSettings.visibleExtent() );
192  if ( !qgsDoubleNear( mapSettings.rotation(), 0.0 ) )
193  {
194  //PAL features are prerotated, so extent also needs to be unrotated
195  lyr.extentGeom.rotate( -mapSettings.rotation(), mapSettings.visibleExtent().center() );
196  }
197 
198  lyr.mFeatsSendingToPal = 0;
199 
200  return true;
201 }
202 
203 
204 
206 {
207  if ( !mSource )
208  {
209  // we have created the provider with "own feature loop" == false
210  // so it is assumed that prepare() has been already called followed by registerFeature() calls
211  return mLabels;
212  }
213 
214  QSet<QString> attrNames;
215  if ( !prepare( ctx, attrNames ) )
216  return QList<QgsLabelFeature *>();
217 
218  if ( mRenderer )
219  mRenderer->startRender( ctx, mFields );
220 
221  QgsRectangle layerExtent = ctx.extent();
224 
225  QgsFeatureRequest request;
226  request.setFilterRect( layerExtent );
227  request.setSubsetOfAttributes( attrNames, mFields );
228  QgsFeatureIterator fit = mSource->getFeatures( request );
229 
231  ctx.expressionContext().appendScope( symbolScope );
232  QgsFeature fet;
233  while ( fit.nextFeature( fet ) )
234  {
235  QgsGeometry obstacleGeometry;
236  if ( mRenderer )
237  {
238  QgsSymbolList symbols = mRenderer->originalSymbolsForFeature( fet, ctx );
239  if ( !symbols.isEmpty() && fet.geometry().type() == QgsWkbTypes::PointGeometry )
240  {
241  //point feature, use symbol bounds as obstacle
242  obstacleGeometry = QgsVectorLayerLabelProvider::getPointObstacleGeometry( fet, ctx, symbols );
243  }
244  if ( !symbols.isEmpty() )
245  {
246  symbolScope = QgsExpressionContextUtils::updateSymbolScope( symbols.at( 0 ), symbolScope );
247  }
248  }
249  ctx.expressionContext().setFeature( fet );
250  registerFeature( fet, ctx, obstacleGeometry );
251  }
252 
253  if ( ctx.expressionContext().lastScope() == symbolScope )
254  delete ctx.expressionContext().popScope();
255 
256  if ( mRenderer )
257  mRenderer->stopRender( ctx );
258 
259  return mLabels;
260 }
261 
262 void QgsVectorLayerLabelProvider::registerFeature( const QgsFeature &feature, QgsRenderContext &context, const QgsGeometry &obstacleGeometry )
263 {
264  QgsLabelFeature *label = nullptr;
265 
266  mSettings.registerFeature( feature, context, &label, obstacleGeometry );
267  if ( label )
268  mLabels << label;
269 }
270 
272 {
273  if ( !fet.hasGeometry() || fet.geometry().type() != QgsWkbTypes::PointGeometry )
274  return QgsGeometry();
275 
276  bool isMultiPoint = fet.geometry().constGet()->nCoordinates() > 1;
277  std::unique_ptr< QgsAbstractGeometry > obstacleGeom;
278  if ( isMultiPoint )
279  obstacleGeom = qgis::make_unique< QgsMultiPolygon >();
280 
281  // for each point
282  for ( int i = 0; i < fet.geometry().constGet()->nCoordinates(); ++i )
283  {
284  QRectF bounds;
285  QgsPoint p = fet.geometry().constGet()->vertexAt( QgsVertexId( i, 0, 0 ) );
286  double x = p.x();
287  double y = p.y();
288  double z = 0; // dummy variable for coordinate transforms
289 
290  //transform point to pixels
291  if ( context.coordinateTransform().isValid() )
292  {
293  try
294  {
295  context.coordinateTransform().transformInPlace( x, y, z );
296  }
297  catch ( QgsCsException & )
298  {
299  return QgsGeometry();
300  }
301  }
302  context.mapToPixel().transformInPlace( x, y );
303 
304  QPointF pt( x, y );
305  Q_FOREACH ( QgsSymbol *symbol, symbols )
306  {
307  if ( symbol->type() == QgsSymbol::Marker )
308  {
309  if ( bounds.isValid() )
310  bounds = bounds.united( static_cast< QgsMarkerSymbol * >( symbol )->bounds( pt, context, fet ) );
311  else
312  bounds = static_cast< QgsMarkerSymbol * >( symbol )->bounds( pt, context, fet );
313  }
314  }
315 
316  //convert bounds to a geometry
317  QVector< double > bX;
318  bX << bounds.left() << bounds.right() << bounds.right() << bounds.left();
319  QVector< double > bY;
320  bY << bounds.top() << bounds.top() << bounds.bottom() << bounds.bottom();
321  std::unique_ptr< QgsLineString > boundLineString = qgis::make_unique< QgsLineString >( bX, bY );
322 
323  //then transform back to map units
324  //TODO - remove when labeling is refactored to use screen units
325  for ( int i = 0; i < boundLineString->numPoints(); ++i )
326  {
327  QgsPointXY point = context.mapToPixel().toMapCoordinates( static_cast<int>( boundLineString->xAt( i ) ),
328  static_cast<int>( boundLineString->yAt( i ) ) );
329  boundLineString->setXAt( i, point.x() );
330  boundLineString->setYAt( i, point.y() );
331  }
332  if ( context.coordinateTransform().isValid() )
333  {
334  try
335  {
336  boundLineString->transform( context.coordinateTransform(), QgsCoordinateTransform::ReverseTransform );
337  }
338  catch ( QgsCsException & )
339  {
340  return QgsGeometry();
341  }
342  }
343  boundLineString->close();
344 
345  if ( context.coordinateTransform().isValid() )
346  {
347  // coordinate transforms may have resulted in nan coordinates - if so, strip these out
348  boundLineString->filterVertices( []( const QgsPoint & point )->bool
349  {
350  return std::isfinite( point.x() ) && std::isfinite( point.y() );
351  } );
352  if ( !boundLineString->isRing() )
353  return QgsGeometry();
354  }
355 
356  std::unique_ptr< QgsPolygon > obstaclePolygon = qgis::make_unique< QgsPolygon >();
357  obstaclePolygon->setExteriorRing( boundLineString.release() );
358 
359  if ( isMultiPoint )
360  {
361  static_cast<QgsMultiPolygon *>( obstacleGeom.get() )->addGeometry( obstaclePolygon.release() );
362  }
363  else
364  {
365  obstacleGeom = std::move( obstaclePolygon );
366  }
367  }
368 
369  return QgsGeometry( std::move( obstacleGeom ) );
370 }
371 
373 {
374  if ( !mSettings.drawLabels )
375  return;
376 
377  QgsTextLabelFeature *lf = dynamic_cast<QgsTextLabelFeature *>( label->getFeaturePart()->feature() );
378 
379  // Copy to temp, editable layer settings
380  // these settings will be changed by any data defined values, then used for rendering label components
381  // settings may be adjusted during rendering of components
382  QgsPalLayerSettings tmpLyr( mSettings );
383 
384  // apply any previously applied data defined settings for the label
385  const QMap< QgsPalLayerSettings::Property, QVariant > &ddValues = lf->dataDefinedValues();
386 
387  //font
388  QFont dFont = lf->definedFont();
389  QgsDebugMsgLevel( QStringLiteral( "PAL font tmpLyr: %1, Style: %2" ).arg( tmpLyr.format().font().toString(), tmpLyr.format().font().styleName() ), 4 );
390  QgsDebugMsgLevel( QStringLiteral( "PAL font definedFont: %1, Style: %2" ).arg( dFont.toString(), dFont.styleName() ), 4 );
391 
392  QgsTextFormat format = tmpLyr.format();
393  format.setFont( dFont );
394 
395  // size has already been calculated and stored in the defined font - this calculated size
396  // is in pixels
397  format.setSize( dFont.pixelSize() );
399  tmpLyr.setFormat( format );
400 
402  {
403  //calculate font alignment based on label quadrant
404  switch ( label->getQuadrant() )
405  {
406  case LabelPosition::QuadrantAboveLeft:
407  case LabelPosition::QuadrantLeft:
408  case LabelPosition::QuadrantBelowLeft:
410  break;
411  case LabelPosition::QuadrantAbove:
412  case LabelPosition::QuadrantOver:
413  case LabelPosition::QuadrantBelow:
415  break;
416  case LabelPosition::QuadrantAboveRight:
417  case LabelPosition::QuadrantRight:
418  case LabelPosition::QuadrantBelowRight:
420  break;
421  }
422  }
423 
424  // update tmpLyr with any data defined text style values
425  QgsPalLabeling::dataDefinedTextStyle( tmpLyr, ddValues );
426 
427  // update tmpLyr with any data defined text buffer values
428  QgsPalLabeling::dataDefinedTextBuffer( tmpLyr, ddValues );
429 
430  // update tmpLyr with any data defined text formatting values
431  QgsPalLabeling::dataDefinedTextFormatting( tmpLyr, ddValues );
432 
433  // update tmpLyr with any data defined shape background values
434  QgsPalLabeling::dataDefinedShapeBackground( tmpLyr, ddValues );
435 
436  // update tmpLyr with any data defined drop shadow values
437  QgsPalLabeling::dataDefinedDropShadow( tmpLyr, ddValues );
438 
439  // Render the components of a label in reverse order
440  // (backgrounds -> text)
441 
443  {
444  QgsTextFormat format = tmpLyr.format();
445 
446  if ( tmpLyr.format().background().enabled() )
447  {
449  }
450  else if ( tmpLyr.format().buffer().enabled() )
451  {
453  }
454  else
455  {
457  }
458 
459  tmpLyr.setFormat( format );
460  }
461 
462  if ( tmpLyr.format().background().enabled() )
463  {
464  drawLabelPrivate( label, context, tmpLyr, QgsTextRenderer::Background );
465  }
466 
467  if ( tmpLyr.format().buffer().enabled() )
468  {
469  drawLabelPrivate( label, context, tmpLyr, QgsTextRenderer::Buffer );
470  }
471 
472  drawLabelPrivate( label, context, tmpLyr, QgsTextRenderer::Text );
473 
474  // add to the results
475  QString labeltext = label->getFeaturePart()->feature()->labelText();
476  mEngine->results()->mLabelSearchTree->insertLabel( label, label->getFeaturePart()->featureId(), mLayerId, labeltext, dFont, false, lf->hasFixedPosition(), mProviderId );
477 }
478 
479 
481 {
482  // NOTE: this is repeatedly called for multi-part labels
483  QPainter *painter = context.painter();
484 
485  // features are pre-rotated but not scaled/translated,
486  // so we only disable rotation here. Ideally, they'd be
487  // also pre-scaled/translated, as suggested here:
488  // https://issues.qgis.org/issues/11856
489  QgsMapToPixel xform = context.mapToPixel();
490  xform.setMapRotation( 0, 0, 0 );
491 
492  QPointF outPt = xform.transform( label->getX(), label->getY() ).toQPointF();
493 
494  if ( mEngine->engineSettings().testFlag( QgsLabelingEngineSettings::DrawLabelRectOnly ) ) // TODO: this should get directly to labeling engine
495  {
496  //debugging rect
497  if ( drawType != QgsTextRenderer::Text )
498  return;
499 
500  QgsPointXY outPt2 = xform.transform( label->getX() + label->getWidth(), label->getY() + label->getHeight() );
501  QRectF rect( 0, 0, outPt2.x() - outPt.x(), outPt2.y() - outPt.y() );
502  painter->save();
503  painter->setRenderHint( QPainter::Antialiasing, false );
504  painter->translate( QPointF( outPt.x(), outPt.y() ) );
505  painter->rotate( -label->getAlpha() * 180 / M_PI );
506 
507  if ( label->conflictsWithObstacle() )
508  {
509  painter->setBrush( QColor( 255, 0, 0, 100 ) );
510  painter->setPen( QColor( 255, 0, 0, 150 ) );
511  }
512  else
513  {
514  painter->setBrush( QColor( 0, 255, 0, 100 ) );
515  painter->setPen( QColor( 0, 255, 0, 150 ) );
516  }
517 
518  painter->drawRect( rect );
519  painter->restore();
520 
521  if ( label->getNextPart() )
522  drawLabelPrivate( label->getNextPart(), context, tmpLyr, drawType, dpiRatio );
523 
524  return;
525  }
526 
527  QgsTextRenderer::Component component;
528  component.dpiRatio = dpiRatio;
529  component.origin = outPt;
530  component.rotation = label->getAlpha();
531 
532 
533 
534  if ( drawType == QgsTextRenderer::Background )
535  {
536  // get rotated label's center point
537  QPointF centerPt( outPt );
538  QgsPointXY outPt2 = xform.transform( label->getX() + label->getWidth() / 2,
539  label->getY() + label->getHeight() / 2 );
540 
541  double xc = outPt2.x() - outPt.x();
542  double yc = outPt2.y() - outPt.y();
543 
544  double angle = -component.rotation;
545  double xd = xc * std::cos( angle ) - yc * std::sin( angle );
546  double yd = xc * std::sin( angle ) + yc * std::cos( angle );
547 
548  centerPt.setX( centerPt.x() + xd );
549  centerPt.setY( centerPt.y() + yd );
550 
551  component.center = centerPt;
552 
553  // convert label size to render units
554  double labelWidthPx = context.convertToPainterUnits( label->getWidth(), QgsUnitTypes::RenderMapUnits, QgsMapUnitScale() );
555  double labelHeightPx = context.convertToPainterUnits( label->getHeight(), QgsUnitTypes::RenderMapUnits, QgsMapUnitScale() );
556 
557  component.size = QSizeF( labelWidthPx, labelHeightPx );
558 
559  QgsTextRenderer::drawBackground( context, component, tmpLyr.format(), QStringList(), QgsTextRenderer::Label );
560  }
561 
562  else if ( drawType == QgsTextRenderer::Buffer
563  || drawType == QgsTextRenderer::Text )
564  {
565 
566  // TODO: optimize access :)
567  QgsTextLabelFeature *lf = static_cast<QgsTextLabelFeature *>( label->getFeaturePart()->feature() );
568  QString txt = lf->text( label->getPartId() );
569  QFontMetricsF *labelfm = lf->labelFontMetrics();
570 
571  //add the direction symbol if needed
572  if ( !txt.isEmpty() && tmpLyr.placement == QgsPalLayerSettings::Line &&
573  tmpLyr.addDirectionSymbol )
574  {
575  bool prependSymb = false;
576  QString symb = tmpLyr.rightDirectionSymbol;
577 
578  if ( label->getReversed() )
579  {
580  prependSymb = true;
581  symb = tmpLyr.leftDirectionSymbol;
582  }
583 
584  if ( tmpLyr.reverseDirectionSymbol )
585  {
586  if ( symb == tmpLyr.rightDirectionSymbol )
587  {
588  prependSymb = true;
589  symb = tmpLyr.leftDirectionSymbol;
590  }
591  else
592  {
593  prependSymb = false;
594  symb = tmpLyr.rightDirectionSymbol;
595  }
596  }
597 
599  {
600  prependSymb = true;
601  symb = symb + QStringLiteral( "\n" );
602  }
604  {
605  prependSymb = false;
606  symb = QStringLiteral( "\n" ) + symb;
607  }
608 
609  if ( prependSymb )
610  {
611  txt.prepend( symb );
612  }
613  else
614  {
615  txt.append( symb );
616  }
617  }
618 
619  //QgsDebugMsgLevel( "drawLabel " + txt, 4 );
620  QStringList multiLineList = QgsPalLabeling::splitToLines( txt, tmpLyr.wrapChar, tmpLyr.autoWrapLength, tmpLyr.useMaxLineLengthForAutoWrap );
621 
625  else if ( tmpLyr.multilineAlign == QgsPalLayerSettings::MultiRight )
627 
628  QgsTextRenderer::Component component;
629  component.origin = outPt;
630  component.rotation = label->getAlpha();
631 
632  QgsTextRenderer::drawTextInternal( drawType, context, tmpLyr.format(), component, multiLineList, labelfm,
633  hAlign, QgsTextRenderer::Label );
634 
635  }
636 
637  // NOTE: this used to be within above multi-line loop block, at end. (a mistake since 2010? [LS])
638  if ( label->getNextPart() )
639  drawLabelPrivate( label->getNextPart(), context, tmpLyr, drawType, dpiRatio );
640 }
int lookupField(const QString &fieldName) const
Looks up field&#39;s index from the field name.
Definition: qgsfields.cpp:324
void registerFeature(const QgsFeature &f, QgsRenderContext &context, QgsLabelFeature **labelFeature=nullptr, QgsGeometry obstacleGeometry=QgsGeometry())
Register a feature for labeling.
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:41
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
Abstract base class for all rendered symbols.
Definition: qgssymbol.h:61
QgsLabelFeature * feature()
Returns the parent feature.
Definition: feature.h:118
double rotation() const
Returns the rotation of the resulting map image, in degrees clockwise.
const QgsLabelingEngine * mEngine
Associated labeling engine.
Draw shadow under buffer.
UpsideDownLabels upsidedownLabels
Controls whether upside down labels are displayed and how they are handled.
virtual void registerFeature(const QgsFeature &feature, QgsRenderContext &context, const QgsGeometry &obstacleGeometry=QgsGeometry())
Register a feature for labeling as one or more QgsLabelFeature objects stored into mLabels...
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:265
OperationResult rotate(double rotation, const QgsPointXY &center)
Rotate this geometry around the Z axis.
HAlignment
Horizontal alignment.
bool obstacle
True if features for layer are obstacles to labels of other layers.
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:106
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:55
const QgsCoordinateReferenceSystem & crs
bool hasGeometry() const
Returns true if the feature has an associated geometry.
Definition: qgsfeature.cpp:197
int autoWrapLength
If non-zero, indicates that label text should be automatically wrapped to (ideally) the specified num...
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.
A marker symbol type, for rendering Point and MultiPoint geometries.
Definition: qgssymbol.h:732
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 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:37
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
When rendering a map layer, calling this method returns the "clipping" extent for the layer (in the l...
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.
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.
Single scope for storing variables and functions for use within a QgsExpressionContext.
Point geometry type, with support for z-dimension and m-values.
Definition: qgspoint.h:37
const QgsMapToPixel & mapToPixel() const
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
Returns the symbol&#39;s type.
Definition: qgssymbol.h:120
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:93
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;.
QgsWkbTypes::GeometryType type
Definition: qgsgeometry.h:110
QgsGeometry geometry
Definition: qgsfeature.h:67
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:230
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
Transform device coordinates to map (world) coordinates.
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.
bool useMaxLineLengthForAutoWrap
If true, indicates that when auto wrapping label text the autoWrapLength length indicates the maximum...
int getPartId() const
static QStringList splitToLines(const QString &text, const QString &wrapCharacter, int autoWrapLength=0, bool useMaxLineLengthWhenAutoWrapping=true)
Splits a text string to a list of separate lines, using a specified wrap character (wrapCharacter)...
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