QGIS API Documentation  3.4.15-Madeira (e83d02e274)
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 {
64  mFlags = Flags();
65  if ( mSettings.drawLabels )
66  mFlags |= DrawLabels;
67  if ( mSettings.displayAll )
73  if ( mSettings.labelPerPart )
75 
76  mPriority = 1 - mSettings.priority / 10.0; // convert 0..10 --> 1..0
77 
79  {
80  //override obstacle type to treat any intersection of a label with the point symbol as a high cost conflict
82  }
83  else
84  {
86  }
87 
89 }
90 
91 
93 {
94  qDeleteAll( mLabels );
95 
96  if ( mOwnsSource )
97  delete mSource;
98 }
99 
100 
101 bool QgsVectorLayerLabelProvider::prepare( const QgsRenderContext &context, QSet<QString> &attributeNames )
102 {
104  const QgsMapSettings &mapSettings = mEngine->mapSettings();
105 
106  QgsDebugMsgLevel( "PREPARE LAYER " + mLayerId, 4 );
107 
108  if ( lyr.drawLabels )
109  {
110  if ( lyr.fieldName.isEmpty() )
111  {
112  return false;
113  }
114 
115  if ( lyr.isExpression )
116  {
117  QgsExpression exp( lyr.fieldName );
118  if ( exp.hasEvalError() )
119  {
120  QgsDebugMsgLevel( "Prepare error:" + exp.evalErrorString(), 4 );
121  return false;
122  }
123  }
124  else
125  {
126  // If we aren't an expression, we check to see if we can find the column.
127  if ( mFields.lookupField( lyr.fieldName ) == -1 )
128  {
129  return false;
130  }
131  }
132  }
133 
134  lyr.mCurFields = mFields;
135 
136  if ( lyr.drawLabels || lyr.obstacle )
137  {
138  if ( lyr.drawLabels )
139  {
140  // add field indices for label's text, from expression or field
141  if ( lyr.isExpression )
142  {
143  // prepare expression for use in QgsPalLayerSettings::registerFeature()
144  QgsExpression *exp = lyr.getLabelExpression();
145  exp->prepare( &context.expressionContext() );
146  if ( exp->hasEvalError() )
147  {
148  QgsDebugMsgLevel( "Prepare error:" + exp->evalErrorString(), 4 );
149  }
150  Q_FOREACH ( const QString &name, exp->referencedColumns() )
151  {
152  QgsDebugMsgLevel( "REFERENCED COLUMN = " + name, 4 );
153  attributeNames.insert( name );
154  }
155  }
156  else
157  {
158  attributeNames.insert( lyr.fieldName );
159  }
160  }
161 
163  // add field indices of data defined expression or field
164  attributeNames.unite( lyr.dataDefinedProperties().referencedFields( context.expressionContext() ) );
165  }
166 
167  // NOW INITIALIZE QgsPalLayerSettings
168 
169  // TODO: ideally these (non-configuration) members should get out of QgsPalLayerSettings to here
170  // (together with registerFeature() & related methods) and QgsPalLayerSettings just stores config
171 
172  // save the pal layer to our layer context (with some additional info)
174 
175  lyr.xform = &mapSettings.mapToPixel();
176  lyr.ct = QgsCoordinateTransform();
177  if ( context.coordinateTransform().isValid() )
178  // this is context for layer rendering
179  lyr.ct = context.coordinateTransform();
180  else
181  {
182  // otherwise fall back to creating our own CT
183  lyr.ct = QgsCoordinateTransform( mCrs, mapSettings.destinationCrs(), mapSettings.transformContext() );
184  }
185  lyr.ptZero = lyr.xform->toMapCoordinates( 0, 0 );
186  lyr.ptOne = lyr.xform->toMapCoordinates( 1, 0 );
187 
188  // rect for clipping
189  lyr.extentGeom = QgsGeometry::fromRect( mapSettings.visibleExtent() );
190  if ( !qgsDoubleNear( mapSettings.rotation(), 0.0 ) )
191  {
192  //PAL features are prerotated, so extent also needs to be unrotated
193  lyr.extentGeom.rotate( -mapSettings.rotation(), mapSettings.visibleExtent().center() );
194  }
195 
196  lyr.mFeatsSendingToPal = 0;
197 
198  return true;
199 }
200 
201 
202 
204 {
205  if ( !mSource )
206  {
207  // we have created the provider with "own feature loop" == false
208  // so it is assumed that prepare() has been already called followed by registerFeature() calls
209  return mLabels;
210  }
211 
212  QSet<QString> attrNames;
213  if ( !prepare( ctx, attrNames ) )
214  return QList<QgsLabelFeature *>();
215 
216  if ( mRenderer )
217  mRenderer->startRender( ctx, mFields );
218 
219  QgsRectangle layerExtent = ctx.extent();
222 
223  QgsFeatureRequest request;
224  request.setFilterRect( layerExtent );
225  request.setSubsetOfAttributes( attrNames, mFields );
226  QgsFeatureIterator fit = mSource->getFeatures( request );
227 
229  ctx.expressionContext().appendScope( symbolScope );
230  QgsFeature fet;
231  while ( fit.nextFeature( fet ) )
232  {
233  QgsGeometry obstacleGeometry;
234  if ( mRenderer )
235  {
236  QgsSymbolList symbols = mRenderer->originalSymbolsForFeature( fet, ctx );
237  if ( !symbols.isEmpty() && fet.geometry().type() == QgsWkbTypes::PointGeometry )
238  {
239  //point feature, use symbol bounds as obstacle
240  obstacleGeometry = QgsVectorLayerLabelProvider::getPointObstacleGeometry( fet, ctx, symbols );
241  }
242  if ( !symbols.isEmpty() )
243  {
244  symbolScope = QgsExpressionContextUtils::updateSymbolScope( symbols.at( 0 ), symbolScope );
245  }
246  }
247  ctx.expressionContext().setFeature( fet );
248  registerFeature( fet, ctx, obstacleGeometry );
249  }
250 
251  if ( ctx.expressionContext().lastScope() == symbolScope )
252  delete ctx.expressionContext().popScope();
253 
254  if ( mRenderer )
255  mRenderer->stopRender( ctx );
256 
257  return mLabels;
258 }
259 
260 void QgsVectorLayerLabelProvider::registerFeature( QgsFeature &feature, QgsRenderContext &context, const QgsGeometry &obstacleGeometry )
261 {
262  QgsLabelFeature *label = nullptr;
263  mSettings.registerFeature( feature, context, &label, obstacleGeometry );
264  if ( label )
265  mLabels << label;
266 }
267 
269 {
270  if ( !fet.hasGeometry() || fet.geometry().type() != QgsWkbTypes::PointGeometry )
271  return QgsGeometry();
272 
273  bool isMultiPoint = fet.geometry().constGet()->nCoordinates() > 1;
274  std::unique_ptr< QgsAbstractGeometry > obstacleGeom;
275  if ( isMultiPoint )
276  obstacleGeom = qgis::make_unique< QgsMultiPolygon >();
277 
278  // for each point
279  for ( int i = 0; i < fet.geometry().constGet()->nCoordinates(); ++i )
280  {
281  QRectF bounds;
282  QgsPoint p = fet.geometry().constGet()->vertexAt( QgsVertexId( i, 0, 0 ) );
283  double x = p.x();
284  double y = p.y();
285  double z = 0; // dummy variable for coordinate transforms
286 
287  //transform point to pixels
288  if ( context.coordinateTransform().isValid() )
289  {
290  try
291  {
292  context.coordinateTransform().transformInPlace( x, y, z );
293  }
294  catch ( QgsCsException & )
295  {
296  return QgsGeometry();
297  }
298  }
299  context.mapToPixel().transformInPlace( x, y );
300 
301  QPointF pt( x, y );
302  Q_FOREACH ( QgsSymbol *symbol, symbols )
303  {
304  if ( symbol->type() == QgsSymbol::Marker )
305  {
306  if ( bounds.isValid() )
307  bounds = bounds.united( static_cast< QgsMarkerSymbol * >( symbol )->bounds( pt, context, fet ) );
308  else
309  bounds = static_cast< QgsMarkerSymbol * >( symbol )->bounds( pt, context, fet );
310  }
311  }
312 
313  //convert bounds to a geometry
314  QVector< double > bX;
315  bX << bounds.left() << bounds.right() << bounds.right() << bounds.left();
316  QVector< double > bY;
317  bY << bounds.top() << bounds.top() << bounds.bottom() << bounds.bottom();
318  std::unique_ptr< QgsLineString > boundLineString = qgis::make_unique< QgsLineString >( bX, bY );
319 
320  //then transform back to map units
321  //TODO - remove when labeling is refactored to use screen units
322  for ( int i = 0; i < boundLineString->numPoints(); ++i )
323  {
324  QgsPointXY point = context.mapToPixel().toMapCoordinates( static_cast<int>( boundLineString->xAt( i ) ),
325  static_cast<int>( boundLineString->yAt( i ) ) );
326  boundLineString->setXAt( i, point.x() );
327  boundLineString->setYAt( i, point.y() );
328  }
329  if ( context.coordinateTransform().isValid() )
330  {
331  try
332  {
333  boundLineString->transform( context.coordinateTransform(), QgsCoordinateTransform::ReverseTransform );
334  }
335  catch ( QgsCsException & )
336  {
337  return QgsGeometry();
338  }
339  }
340  boundLineString->close();
341 
342  if ( context.coordinateTransform().isValid() )
343  {
344  // coordinate transforms may have resulted in nan coordinates - if so, strip these out
345  boundLineString->filterVertices( []( const QgsPoint & point )->bool
346  {
347  return std::isfinite( point.x() ) && std::isfinite( point.y() );
348  } );
349  if ( !boundLineString->isRing() )
350  return QgsGeometry();
351  }
352 
353  std::unique_ptr< QgsPolygon > obstaclePolygon = qgis::make_unique< QgsPolygon >();
354  obstaclePolygon->setExteriorRing( boundLineString.release() );
355 
356  if ( isMultiPoint )
357  {
358  static_cast<QgsMultiPolygon *>( obstacleGeom.get() )->addGeometry( obstaclePolygon.release() );
359  }
360  else
361  {
362  obstacleGeom = std::move( obstaclePolygon );
363  }
364  }
365 
366  return QgsGeometry( std::move( obstacleGeom ) );
367 }
368 
370 {
371  if ( !mSettings.drawLabels )
372  return;
373 
374  QgsTextLabelFeature *lf = dynamic_cast<QgsTextLabelFeature *>( label->getFeaturePart()->feature() );
375 
376  // Copy to temp, editable layer settings
377  // these settings will be changed by any data defined values, then used for rendering label components
378  // settings may be adjusted during rendering of components
379  QgsPalLayerSettings tmpLyr( mSettings );
380 
381  // apply any previously applied data defined settings for the label
382  const QMap< QgsPalLayerSettings::Property, QVariant > &ddValues = lf->dataDefinedValues();
383 
384  //font
385  QFont dFont = lf->definedFont();
386  QgsDebugMsgLevel( QStringLiteral( "PAL font tmpLyr: %1, Style: %2" ).arg( tmpLyr.format().font().toString(), tmpLyr.format().font().styleName() ), 4 );
387  QgsDebugMsgLevel( QStringLiteral( "PAL font definedFont: %1, Style: %2" ).arg( dFont.toString(), dFont.styleName() ), 4 );
388 
389  QgsTextFormat format = tmpLyr.format();
390  format.setFont( dFont );
391 
392  // size has already been calculated and stored in the defined font - this calculated size
393  // is in pixels
394  format.setSize( dFont.pixelSize() );
396  tmpLyr.setFormat( format );
397 
399  {
400  //calculate font alignment based on label quadrant
401  switch ( label->getQuadrant() )
402  {
403  case LabelPosition::QuadrantAboveLeft:
404  case LabelPosition::QuadrantLeft:
405  case LabelPosition::QuadrantBelowLeft:
407  break;
408  case LabelPosition::QuadrantAbove:
409  case LabelPosition::QuadrantOver:
410  case LabelPosition::QuadrantBelow:
412  break;
413  case LabelPosition::QuadrantAboveRight:
414  case LabelPosition::QuadrantRight:
415  case LabelPosition::QuadrantBelowRight:
417  break;
418  }
419  }
420 
421  // update tmpLyr with any data defined text style values
422  QgsPalLabeling::dataDefinedTextStyle( tmpLyr, ddValues );
423 
424  // update tmpLyr with any data defined text buffer values
425  QgsPalLabeling::dataDefinedTextBuffer( tmpLyr, ddValues );
426 
427  // update tmpLyr with any data defined text formatting values
428  QgsPalLabeling::dataDefinedTextFormatting( tmpLyr, ddValues );
429 
430  // update tmpLyr with any data defined shape background values
431  QgsPalLabeling::dataDefinedShapeBackground( tmpLyr, ddValues );
432 
433  // update tmpLyr with any data defined drop shadow values
434  QgsPalLabeling::dataDefinedDropShadow( tmpLyr, ddValues );
435 
436  // Render the components of a label in reverse order
437  // (backgrounds -> text)
438 
440  {
441  QgsTextFormat format = tmpLyr.format();
442 
443  if ( tmpLyr.format().background().enabled() )
444  {
446  }
447  else if ( tmpLyr.format().buffer().enabled() )
448  {
450  }
451  else
452  {
454  }
455 
456  tmpLyr.setFormat( format );
457  }
458 
459  if ( tmpLyr.format().background().enabled() )
460  {
461  drawLabelPrivate( label, context, tmpLyr, QgsTextRenderer::Background );
462  }
463 
464  if ( tmpLyr.format().buffer().enabled() )
465  {
466  drawLabelPrivate( label, context, tmpLyr, QgsTextRenderer::Buffer );
467  }
468 
469  drawLabelPrivate( label, context, tmpLyr, QgsTextRenderer::Text );
470 
471  // add to the results
472  QString labeltext = label->getFeaturePart()->feature()->labelText();
473  mEngine->results()->mLabelSearchTree->insertLabel( label, label->getFeaturePart()->featureId(), mLayerId, labeltext, dFont, false, lf->hasFixedPosition(), mProviderId );
474 }
475 
476 
478 {
479  // NOTE: this is repeatedly called for multi-part labels
480  QPainter *painter = context.painter();
481 
482  // features are pre-rotated but not scaled/translated,
483  // so we only disable rotation here. Ideally, they'd be
484  // also pre-scaled/translated, as suggested here:
485  // https://issues.qgis.org/issues/11856
486  QgsMapToPixel xform = context.mapToPixel();
487  xform.setMapRotation( 0, 0, 0 );
488 
489  QPointF outPt = xform.transform( label->getX(), label->getY() ).toQPointF();
490 
491  if ( mEngine->engineSettings().testFlag( QgsLabelingEngineSettings::DrawLabelRectOnly ) ) // TODO: this should get directly to labeling engine
492  {
493  //debugging rect
494  if ( drawType != QgsTextRenderer::Text )
495  return;
496 
497  QgsPointXY outPt2 = xform.transform( label->getX() + label->getWidth(), label->getY() + label->getHeight() );
498  QRectF rect( 0, 0, outPt2.x() - outPt.x(), outPt2.y() - outPt.y() );
499  painter->save();
500  painter->setRenderHint( QPainter::Antialiasing, false );
501  painter->translate( QPointF( outPt.x(), outPt.y() ) );
502  painter->rotate( -label->getAlpha() * 180 / M_PI );
503 
504  if ( label->conflictsWithObstacle() )
505  {
506  painter->setBrush( QColor( 255, 0, 0, 100 ) );
507  painter->setPen( QColor( 255, 0, 0, 150 ) );
508  }
509  else
510  {
511  painter->setBrush( QColor( 0, 255, 0, 100 ) );
512  painter->setPen( QColor( 0, 255, 0, 150 ) );
513  }
514 
515  painter->drawRect( rect );
516  painter->restore();
517 
518  if ( label->getNextPart() )
519  drawLabelPrivate( label->getNextPart(), context, tmpLyr, drawType, dpiRatio );
520 
521  return;
522  }
523 
524  QgsTextRenderer::Component component;
525  component.dpiRatio = dpiRatio;
526  component.origin = outPt;
527  component.rotation = label->getAlpha();
528 
529 
530 
531  if ( drawType == QgsTextRenderer::Background )
532  {
533  // get rotated label's center point
534  QPointF centerPt( outPt );
535  QgsPointXY outPt2 = xform.transform( label->getX() + label->getWidth() / 2,
536  label->getY() + label->getHeight() / 2 );
537 
538  double xc = outPt2.x() - outPt.x();
539  double yc = outPt2.y() - outPt.y();
540 
541  double angle = -component.rotation;
542  double xd = xc * std::cos( angle ) - yc * std::sin( angle );
543  double yd = xc * std::sin( angle ) + yc * std::cos( angle );
544 
545  centerPt.setX( centerPt.x() + xd );
546  centerPt.setY( centerPt.y() + yd );
547 
548  component.center = centerPt;
549 
550  // convert label size to render units
551  double labelWidthPx = context.convertToPainterUnits( label->getWidth(), QgsUnitTypes::RenderMapUnits, QgsMapUnitScale() );
552  double labelHeightPx = context.convertToPainterUnits( label->getHeight(), QgsUnitTypes::RenderMapUnits, QgsMapUnitScale() );
553 
554  component.size = QSizeF( labelWidthPx, labelHeightPx );
555 
556  QgsTextRenderer::drawBackground( context, component, tmpLyr.format(), QStringList(), QgsTextRenderer::Label );
557  }
558 
559  else if ( drawType == QgsTextRenderer::Buffer
560  || drawType == QgsTextRenderer::Text )
561  {
562 
563  // TODO: optimize access :)
564  QgsTextLabelFeature *lf = static_cast<QgsTextLabelFeature *>( label->getFeaturePart()->feature() );
565  QString txt = lf->text( label->getPartId() );
566  QFontMetricsF *labelfm = lf->labelFontMetrics();
567 
568  //add the direction symbol if needed
569  if ( !txt.isEmpty() && tmpLyr.placement == QgsPalLayerSettings::Line &&
570  tmpLyr.addDirectionSymbol )
571  {
572  bool prependSymb = false;
573  QString symb = tmpLyr.rightDirectionSymbol;
574 
575  if ( label->getReversed() )
576  {
577  prependSymb = true;
578  symb = tmpLyr.leftDirectionSymbol;
579  }
580 
581  if ( tmpLyr.reverseDirectionSymbol )
582  {
583  if ( symb == tmpLyr.rightDirectionSymbol )
584  {
585  prependSymb = true;
586  symb = tmpLyr.leftDirectionSymbol;
587  }
588  else
589  {
590  prependSymb = false;
591  symb = tmpLyr.rightDirectionSymbol;
592  }
593  }
594 
596  {
597  prependSymb = true;
598  symb = symb + QStringLiteral( "\n" );
599  }
601  {
602  prependSymb = false;
603  symb = QStringLiteral( "\n" ) + symb;
604  }
605 
606  if ( prependSymb )
607  {
608  txt.prepend( symb );
609  }
610  else
611  {
612  txt.append( symb );
613  }
614  }
615 
616  //QgsDebugMsgLevel( "drawLabel " + txt, 4 );
617  QStringList multiLineList = QgsPalLabeling::splitToLines( txt, tmpLyr.wrapChar, tmpLyr.autoWrapLength, tmpLyr.useMaxLineLengthForAutoWrap );
618 
622  else if ( tmpLyr.multilineAlign == QgsPalLayerSettings::MultiRight )
624 
625  QgsTextRenderer::Component component;
626  component.origin = outPt;
627  component.rotation = label->getAlpha();
628 
629  QgsTextRenderer::drawTextInternal( drawType, context, tmpLyr.format(), component, multiLineList, labelfm,
630  hAlign, QgsTextRenderer::Label );
631 
632  }
633 
634  // NOTE: this used to be within above multi-line loop block, at end. (a mistake since 2010? [LS])
635  if ( label->getNextPart() )
636  drawLabelPrivate( label->getNextPart(), context, tmpLyr, drawType, dpiRatio );
637 }
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.
bool hasEvalError() const
Returns true if an error occurred when evaluating last input.
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 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: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)
QFont font() const
Returns the font used for rendering text.
QgsPalLayerSettings::Placement mPlacement
Placement strategy.
Abstract base class for all rendered symbols.
Definition: qgssymbol.h:61
QgsLabelFeature * feature()
Returns the parent feature.
Definition: feature.h:118
void registerFeature(QgsFeature &f, QgsRenderContext &context, QgsLabelFeature **labelFeature=nullptr, QgsGeometry obstacleGeometry=QgsGeometry())
Register a feature for labeling.
const QgsLabelingEngine * mEngine
Associated labeling engine.
double getWidth() const
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 convertToPainterUnits(double size, QgsUnitTypes::RenderUnit unit, const QgsMapUnitScale &scale=QgsMapUnitScale()) const
Converts a size from the specified units to painter units (pixels).
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:278
QSet< QString > referencedColumns() const
Gets list of columns referenced by the expression.
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.
void drawLabelPrivate(pal::LabelPosition *label, QgsRenderContext &context, QgsPalLayerSettings &tmpLyr, QgsTextRenderer::TextPart drawType, double dpiRatio=1.0) const
Internal label drawing method.
QgsFeatureRequest & setSubsetOfAttributes(const QgsAttributeList &attrs)
Set a subset of attributes that will be fetched.
QgsRectangle visibleExtent() const
Returns the actual extent derived from requested extent that takes takes output image size into accou...
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.
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 mergeLines
True if connected line features with identical label text should be merged prior to generating label ...
const QgsRectangle & extent() const
When rendering a map layer, calling this method returns the "clipping" extent for the layer (in the l...
const QgsMapToPixel & mapToPixel() const
MultiLineAlign multilineAlign
Horizontal alignment of multi-line labels.
bool enabled() const
Returns whether the background is enabled.
Whether to label each part of multi-part features separately.
const QgsTextFormat & format() const
Returns the label text formatting settings, e.g., font settings, buffer settings, etc...
double rotation() const
Returns the rotation of the resulting map image, in degrees clockwise.
FeaturePart * getFeaturePart()
Returns the feature corresponding to this labelposition.
Label-specific draw mode.
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 isShortCircuited() const
Returns true if the transform short circuits because the source and destination are equivalent...
int autoWrapLength
If non-zero, indicates that label text should be automatically wrapped to (ideally) the specified num...
bool enabled() const
Returns whether the shadow is enabled.
QgsCoordinateTransform ct
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
void setFormat(const QgsTextFormat &format)
Sets the label text formatting settings, e.g., font settings, buffer settings, etc.
QgsCoordinateTransformContext transformContext() const
Returns the coordinate transform context, which stores various information regarding which datum tran...
QgsCoordinateReferenceSystem destinationCrs() const
returns CRS of destination coordinate reference system
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 init()
initialization method - called from constructors
bool hasFixedPosition() const
Whether the label should use a fixed position instead of being automatically placed.
bool conflictsWithObstacle() const
Returns whether the position is marked as conflicting with an obstacle feature.
Perform transforms between map coordinates and device coordinates.
Definition: qgsmaptopixel.h:36
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.
void transformInPlace(double &x, double &y) const
Transform device coordinates to map coordinates.
QgsExpressionContextScope * lastScope()
Returns the last scope added to the context.
ObstacleType obstacleType
Controls how features act as obstacles for labels.
const QgsAbstractGeometry * constGet() const
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
QList< QgsSymbol * > QgsSymbolList
Definition: qgsrenderer.h:43
virtual int nCoordinates() const
Returns the number of nodes contained in the geometry.
bool displayAll
If true, all features will be labelled even when overlaps occur.
void setSize(double size)
Sets the size for rendered text.
bool enabled() const
Returns whether the buffer is enabled.
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
Buffer component.
bool testFlag(Flag f) const
Test whether a particular flag is enabled.
QgsLabelingResults * results() const
For internal use by the providers.
Quadrant getQuadrant() const
QgsPalLayerSettings mSettings
Layer&#39;s labeling configuration.
const QMap< QgsPalLayerSettings::DataDefinedProperties, QVariant > & dataDefinedValues() const
Gets data-defined values.
double getY(int i=0) const
Returns the down-left y coordinate.
QgsPointXY center() const
Returns the center point of the rectangle.
Definition: qgsrectangle.h:229
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.
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.
QString id() const
Returns the layer&#39;s unique ID, which is used to access this layer from QgsProject.
virtual QgsSymbolList originalSymbolsForFeature(const QgsFeature &feature, QgsRenderContext &context) const
Equivalent of originalSymbolsForFeature() call extended to support renderers that may use more symbol...
LabelPosition * getNextPart() const
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...
QgsPointXY toMapCoordinates(int x, int y) const
Transform device coordinates to map (world) coordinates.
int lookupField(const QString &fieldName) const
Looks up field&#39;s index from the field name.
Definition: qgsfields.cpp:320
Single scope for storing variables and functions for use within a QgsExpressionContext.
double getX(int i=0) const
Returns the down-left x coordinate.
Point geometry type, with support for z-dimension and m-values.
Definition: qgspoint.h:37
The QgsAbstractLabelProvider class is an interface class.
bool getReversed() const
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 QgsMapSettings & mapSettings() const
Gets associated map settings.
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...
double getAlpha() const
Returns the angle to rotate text (in rad).
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.
QFont definedFont()
Font to be used for rendering.
int getPartId() const
const QgsLabelingEngineSettings & engineSettings() const
Gets associated labeling engine settings.
QString text(int partId) const
Returns the text component corresponding to a specified label part.
QPainter * painter()
Returns the destination QPainter for the render operation.
The QgsLabelFeature class describes a feature that should be used within the labeling engine...
QgsGeometry extentGeom
Transform from destination to source CRS.
Multi polygon geometry collection.
QString mName
Name of the layer.
double getHeight() const
Struct for storing maximum and minimum scales for measurements in map units.
QgsCoordinateReferenceSystem mCrs
Layer&#39;s CRS.
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.
bool hasGeometry() const
Returns true if the feature has an associated geometry.
Definition: qgsfeature.cpp:197
SymbolType type() const
Returns the symbol&#39;s type.
Definition: qgssymbol.h:120
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.
const QgsMapToPixel & mapToPixel() const
Returns the context&#39;s map to pixel transform, which transforms between map coordinates and device coo...
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;.
QgsGeometry geometry
Definition: qgsfeature.h:67
Custom exception class for Coordinate Reference System related exceptions.
Definition: qgsexception.h:65
QgsCoordinateTransform coordinateTransform() const
Returns the current coordinate transform for the context.
QgsExpressionContextScope * popScope()
Removes the last scope from the expression context and return it.
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.
Represents a vector layer which manages a vector based data sets.
QgsPointXY transform(const QgsPointXY &p) const
Transform the point from map (world) coordinates to device coordinates.
QgsWkbTypes::GeometryType type() const
Returns type of the geometry as a QgsWkbTypes::GeometryType.
QString mLayerId
Associated layer&#39;s ID, if applicable.
QgsTextShadowSettings::ShadowPlacement shadowPlacement() const
Returns the placement for the drop shadow.
QString labelText() const
Text of the label.
QString evalErrorString() const
Returns evaluation error.
int priority
Label priority.
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
bool useMaxLineLengthForAutoWrap
If true, indicates that when auto wrapping label text the autoWrapLength length indicates the maximum...
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.
bool isValid() const
Returns true if the coordinate transform is valid, ie both the source and destination CRS have been s...
QgsFeatureId featureId() const
Returns the unique ID of the feature.
Definition: feature.cpp:151
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