QGIS API Documentation  2.12.0-Lyon
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 "qgsdatadefined.h"
19 #include "qgsgeometry.h"
20 #include "qgslabelsearchtree.h"
21 #include "qgspalgeometry.h"
22 #include "qgspallabeling.h"
23 #include "qgsvectorlayer.h"
25 
26 #include "feature.h"
27 #include "labelposition.h"
28 
29 #include <QPicture>
30 
31 
32 Q_GUI_EXPORT extern int qt_defaultDpiX();
33 Q_GUI_EXPORT extern int qt_defaultDpiY();
34 
35 static void _fixQPictureDPI( QPainter* p )
36 {
37  // QPicture makes an assumption that we drawing to it with system DPI.
38  // Then when being drawn, it scales the painter. The following call
39  // negates the effect. There is no way of setting QPicture's DPI.
40  // See QTBUG-20361
41  p->scale(( double )qt_defaultDpiX() / p->device()->logicalDpiX(),
42  ( double )qt_defaultDpiY() / p->device()->logicalDpiY() );
43 }
44 
45 
46 
47 QgsVectorLayerLabelProvider::QgsVectorLayerLabelProvider( QgsVectorLayer* layer, bool withFeatureLoop, const QgsPalLayerSettings* settings, const QString& layerName )
48 {
49  mSettings = settings ? *settings : QgsPalLayerSettings::fromLayer( layer );
50  mName = layerName.isEmpty() ? layer->id() : layerName;
51  mLayerId = layer->id();
52  mFields = layer->fields();
53  mCrs = layer->crs();
54  if ( withFeatureLoop )
55  {
56  mSource = new QgsVectorLayerFeatureSource( layer );
57  mOwnsSource = true;
58  }
59  else
60  {
61  mSource = 0;
62  mOwnsSource = false;
63  }
64 
65  init();
66 }
67 
69  const QgsPalLayerSettings& settings,
70  const QString& layerId,
71  const QgsFields& fields,
74  bool ownsSource )
75  : mSettings( settings )
76  , mLayerId( layerId )
77  , mFields( fields )
78  , mCrs( crs )
79  , mSource( source )
80  , mOwnsSource( ownsSource )
81 {
82  init();
83 }
84 
85 
87 {
90  mFlags = Flags();
97  mPriority = 1 - mSettings.priority / 10.0; // convert 0..10 --> 1..0
100 }
101 
102 
104 {
105  qDeleteAll( mLabels );
106 
107  if ( mOwnsSource )
108  delete mSource;
109 }
110 
111 
113 {
115  const QgsMapSettings& mapSettings = mEngine->mapSettings();
116 
117  QgsDebugMsgLevel( "PREPARE LAYER " + mLayerId, 4 );
118 
119  if ( lyr.drawLabels )
120  {
121  if ( lyr.fieldName.isEmpty() )
122  {
123  return false;
124  }
125 
126  if ( lyr.isExpression )
127  {
128  QgsExpression exp( lyr.fieldName );
129  if ( exp.hasEvalError() )
130  {
131  QgsDebugMsgLevel( "Prepare error:" + exp.evalErrorString(), 4 );
132  return false;
133  }
134  }
135  else
136  {
137  // If we aren't an expression, we check to see if we can find the column.
138  if ( mFields.fieldNameIndex( lyr.fieldName ) == -1 )
139  {
140  return false;
141  }
142  }
143  }
144 
145  lyr.mCurFields = mFields;
146 
147  if ( lyr.drawLabels )
148  {
149  // add field indices for label's text, from expression or field
150  if ( lyr.isExpression )
151  {
152  // prepare expression for use in QgsPalLayerSettings::registerFeature()
153  QgsExpression* exp = lyr.getLabelExpression();
154  exp->prepare( &context.expressionContext() );
155  if ( exp->hasEvalError() )
156  {
157  QgsDebugMsgLevel( "Prepare error:" + exp->evalErrorString(), 4 );
158  }
159  Q_FOREACH ( const QString& name, exp->referencedColumns() )
160  {
161  QgsDebugMsgLevel( "REFERENCED COLUMN = " + name, 4 );
162  attributeNames.append( name );
163  }
164  }
165  else
166  {
167  attributeNames.append( lyr.fieldName );
168  }
169 
170  // add field indices of data defined expression or field
172  for ( ; dIt != lyr.dataDefinedProperties.constEnd(); ++dIt )
173  {
174  QgsDataDefined* dd = dIt.value();
175  if ( !dd->isActive() )
176  {
177  continue;
178  }
179 
180  // NOTE: the following also prepares any expressions for later use
181 
182  // store parameters for data defined expressions
183  QMap<QString, QVariant> exprParams;
184  exprParams.insert( "scale", context.rendererScale() );
185 
186  dd->setExpressionParams( exprParams );
187 
188  // this will return columns for expressions or field name, depending upon what is set to be used
189  QStringList cols = dd->referencedColumns( context.expressionContext() ); // <-- prepares any expressions, too
190 
191  //QgsDebugMsgLevel( QString( "Data defined referenced columns:" ) + cols.join( "," ), 4 );
192  Q_FOREACH ( const QString& name, cols )
193  {
194  attributeNames.append( name );
195  }
196  }
197  }
198 
199  // NOW INITIALIZE QgsPalLayerSettings
200 
201  // TODO: ideally these (non-configuration) members should get out of QgsPalLayerSettings to here
202  // (together with registerFeature() & related methods) and QgsPalLayerSettings just stores config
203 
204  //raster and vector scale factors
205  lyr.vectorScaleFactor = context.scaleFactor();
206  lyr.rasterCompressFactor = context.rasterScaleFactor();
207 
208  // save the pal layer to our layer context (with some additional info)
210 
211  lyr.xform = &mapSettings.mapToPixel();
212  lyr.ct = 0;
213  if ( mapSettings.hasCrsTransformEnabled() )
214  {
215  if ( context.coordinateTransform() )
216  // this is context for layer rendering - use its CT as it includes correct datum transform
217  lyr.ct = context.coordinateTransform()->clone();
218  else
219  // otherwise fall back to creating our own CT - this one may not have the correct datum transform!
220  lyr.ct = new QgsCoordinateTransform( mCrs, mapSettings.destinationCrs() );
221  }
222  lyr.ptZero = lyr.xform->toMapCoordinates( 0, 0 );
223  lyr.ptOne = lyr.xform->toMapCoordinates( 1, 0 );
224 
225  // rect for clipping
226  lyr.extentGeom = QgsGeometry::fromRect( mapSettings.visibleExtent() );
227  if ( !qgsDoubleNear( mapSettings.rotation(), 0.0 ) )
228  {
229  //PAL features are prerotated, so extent also needs to be unrotated
230  lyr.extentGeom->rotate( -mapSettings.rotation(), mapSettings.visibleExtent().center() );
231  }
232 
233  lyr.mFeatsSendingToPal = 0;
234 
235  return true;
236 }
237 
238 
239 
241 {
242  if ( !mSource )
243  {
244  // we have created the provider with "own feature loop" == false
245  // so it is assumed that prepare() has been already called followed by registerFeature() calls
246  return mLabels;
247  }
248 
249  QStringList attrNames;
250  if ( !prepare( ctx, attrNames ) )
251  return QList<QgsLabelFeature*>();
252 
253  QgsRectangle layerExtent = ctx.extent();
254  if ( mSettings.ct )
256 
257  QgsFeatureRequest request;
258  request.setFilterRect( layerExtent );
259  request.setSubsetOfAttributes( attrNames, mFields );
260  QgsFeatureIterator fit = mSource->getFeatures( request );
261 
262  QgsFeature fet;
263  while ( fit.nextFeature( fet ) )
264  {
265  registerFeature( fet, ctx );
266  }
267 
268  return mLabels;
269 }
270 
271 
273 {
274  QgsLabelFeature* label = 0;
275  mSettings.registerFeature( feature, context, QString(), &label );
276  if ( label )
277  mLabels << label;
278 }
279 
280 
281 
283 {
284  if ( !mSettings.drawLabels )
285  return;
286 
287  QgsTextLabelFeature* lf = dynamic_cast<QgsTextLabelFeature*>( label->getFeaturePart()->feature() );
288 
289  // Copy to temp, editable layer settings
290  // these settings will be changed by any data defined values, then used for rendering label components
291  // settings may be adjusted during rendering of components
292  QgsPalLayerSettings tmpLyr( mSettings );
293 
294  // apply any previously applied data defined settings for the label
296 
297  //font
298  QFont dFont = lf->definedFont();
299  QgsDebugMsgLevel( QString( "PAL font tmpLyr: %1, Style: %2" ).arg( tmpLyr.textFont.toString(), tmpLyr.textFont.styleName() ), 4 );
300  QgsDebugMsgLevel( QString( "PAL font definedFont: %1, Style: %2" ).arg( dFont.toString(), dFont.styleName() ), 4 );
301  tmpLyr.textFont = dFont;
302 
304  {
305  //calculate font alignment based on label quadrant
306  switch ( label->getQuadrant() )
307  {
308  case LabelPosition::QuadrantAboveLeft:
309  case LabelPosition::QuadrantLeft:
310  case LabelPosition::QuadrantBelowLeft:
312  break;
313  case LabelPosition::QuadrantAbove:
314  case LabelPosition::QuadrantOver:
315  case LabelPosition::QuadrantBelow:
317  break;
318  case LabelPosition::QuadrantAboveRight:
319  case LabelPosition::QuadrantRight:
320  case LabelPosition::QuadrantBelowRight:
322  break;
323  }
324  }
325 
326  // update tmpLyr with any data defined text style values
327  QgsPalLabeling::dataDefinedTextStyle( tmpLyr, ddValues );
328 
329  // update tmpLyr with any data defined text buffer values
330  QgsPalLabeling::dataDefinedTextBuffer( tmpLyr, ddValues );
331 
332  // update tmpLyr with any data defined text formatting values
333  QgsPalLabeling::dataDefinedTextFormatting( tmpLyr, ddValues );
334 
335  // update tmpLyr with any data defined shape background values
336  QgsPalLabeling::dataDefinedShapeBackground( tmpLyr, ddValues );
337 
338  // update tmpLyr with any data defined drop shadow values
339  QgsPalLabeling::dataDefinedDropShadow( tmpLyr, ddValues );
340 
342 
343  // Render the components of a label in reverse order
344  // (backgrounds -> text)
345 
346  if ( tmpLyr.shadowDraw && tmpLyr.shadowUnder == QgsPalLayerSettings::ShadowLowest )
347  {
348  if ( tmpLyr.shapeDraw )
349  {
351  }
352  else if ( tmpLyr.bufferDraw )
353  {
355  }
356  else
357  {
359  }
360  }
361 
362  if ( tmpLyr.shapeDraw )
363  {
364  drawLabelPrivate( label, context, tmpLyr, QgsPalLabeling::LabelShape );
365  }
366 
367  if ( tmpLyr.bufferDraw )
368  {
369  drawLabelPrivate( label, context, tmpLyr, QgsPalLabeling::LabelBuffer );
370  }
371 
372  drawLabelPrivate( label, context, tmpLyr, QgsPalLabeling::LabelText );
373 
374  // add to the results
375  QString labeltext = label->getFeaturePart()->feature()->labelText();
376  mEngine->results()->mLabelSearchTree->insertLabel( label, label->getFeaturePart()->featureId(), mLayerId, labeltext, dFont, false, lf->hasFixedPosition() );
377 }
378 
379 
381 {
382  // NOTE: this is repeatedly called for multi-part labels
383  QPainter* painter = context.painter();
384 #if 1 // XXX strk
385  // features are pre-rotated but not scaled/translated,
386  // so we only disable rotation here. Ideally, they'd be
387  // also pre-scaled/translated, as suggested here:
388  // http://hub.qgis.org/issues/11856
389  QgsMapToPixel xform = context.mapToPixel();
390  xform.setMapRotation( 0, 0, 0 );
391 #else
392  const QgsMapToPixel& xform = context.mapToPixel();
393 #endif
394 
395  QgsLabelComponent component;
396  component.setDpiRatio( dpiRatio );
397 
398  QgsPoint outPt = xform.transform( label->getX(), label->getY() );
399 // QgsPoint outPt2 = xform->transform( label->getX() + label->getWidth(), label->getY() + label->getHeight() );
400 // QRectF labelRect( 0, 0, outPt2.x() - outPt.x(), outPt2.y() - outPt.y() );
401 
402  component.setOrigin( outPt );
403  component.setRotation( label->getAlpha() );
404 
405  if ( mEngine->testFlag( QgsLabelingEngineV2::DrawLabelRectOnly ) ) // TODO: this should get directly to labeling engine
406  {
407  //debugging rect
408  if ( drawType != QgsPalLabeling::LabelText )
409  return;
410 
411  QgsPoint outPt2 = xform.transform( label->getX() + label->getWidth(), label->getY() + label->getHeight() );
412  QRectF rect( 0, 0, outPt2.x() - outPt.x(), outPt2.y() - outPt.y() );
413  painter->save();
414  painter->setRenderHint( QPainter::Antialiasing, false );
415  painter->translate( QPointF( outPt.x(), outPt.y() ) );
416  painter->rotate( -label->getAlpha() * 180 / M_PI );
417 
418  if ( label->conflictsWithObstacle() )
419  {
420  painter->setBrush( QColor( 255, 0, 0, 100 ) );
421  painter->setPen( QColor( 255, 0, 0, 150 ) );
422  }
423  else
424  {
425  painter->setBrush( QColor( 0, 255, 0, 100 ) );
426  painter->setPen( QColor( 0, 255, 0, 150 ) );
427  }
428 
429  painter->drawRect( rect );
430  painter->restore();
431 
432  if ( label->getNextPart() )
433  drawLabelPrivate( label->getNextPart(), context, tmpLyr, drawType, dpiRatio );
434 
435  return;
436  }
437 
438  if ( drawType == QgsPalLabeling::LabelShape )
439  {
440  // get rotated label's center point
441  QgsPoint centerPt( outPt );
442  QgsPoint outPt2 = xform.transform( label->getX() + label->getWidth() / 2,
443  label->getY() + label->getHeight() / 2 );
444 
445  double xc = outPt2.x() - outPt.x();
446  double yc = outPt2.y() - outPt.y();
447 
448  double angle = -label->getAlpha();
449  double xd = xc * cos( angle ) - yc * sin( angle );
450  double yd = xc * sin( angle ) + yc * cos( angle );
451 
452  centerPt.setX( centerPt.x() + xd );
453  centerPt.setY( centerPt.y() + yd );
454 
455  component.setCenter( centerPt );
456  component.setSize( QgsPoint( label->getWidth(), label->getHeight() ) );
457 
458  QgsPalLabeling::drawLabelBackground( context, component, tmpLyr );
459  }
460 
461  else if ( drawType == QgsPalLabeling::LabelBuffer
462  || drawType == QgsPalLabeling::LabelText )
463  {
464 
465  // TODO: optimize access :)
466  QgsTextLabelFeature* lf = static_cast<QgsTextLabelFeature*>( label->getFeaturePart()->feature() );
467  QString txt = lf->text( label->getPartId() );
468  QFontMetricsF* labelfm = lf->labelFontMetrics();
469 
470  //add the direction symbol if needed
471  if ( !txt.isEmpty() && tmpLyr.placement == QgsPalLayerSettings::Line &&
472  tmpLyr.addDirectionSymbol )
473  {
474  bool prependSymb = false;
475  QString symb = tmpLyr.rightDirectionSymbol;
476 
477  if ( label->getReversed() )
478  {
479  prependSymb = true;
480  symb = tmpLyr.leftDirectionSymbol;
481  }
482 
483  if ( tmpLyr.reverseDirectionSymbol )
484  {
485  if ( symb == tmpLyr.rightDirectionSymbol )
486  {
487  prependSymb = true;
488  symb = tmpLyr.leftDirectionSymbol;
489  }
490  else
491  {
492  prependSymb = false;
493  symb = tmpLyr.rightDirectionSymbol;
494  }
495  }
496 
498  {
499  prependSymb = true;
500  symb = symb + QLatin1String( "\n" );
501  }
503  {
504  prependSymb = false;
505  symb = QLatin1String( "\n" ) + symb;
506  }
507 
508  if ( prependSymb )
509  {
510  txt.prepend( symb );
511  }
512  else
513  {
514  txt.append( symb );
515  }
516  }
517 
518  //QgsDebugMsgLevel( "drawLabel " + txt, 4 );
519  QStringList multiLineList = QgsPalLabeling::splitToLines( txt, tmpLyr.wrapChar );
520  int lines = multiLineList.size();
521 
522  double labelWidest = 0.0;
523  for ( int i = 0; i < lines; ++i )
524  {
525  double labelWidth = labelfm->width( multiLineList.at( i ) );
526  if ( labelWidth > labelWidest )
527  {
528  labelWidest = labelWidth;
529  }
530  }
531 
532  double labelHeight = labelfm->ascent() + labelfm->descent(); // ignore +1 for baseline
533  // double labelHighest = labelfm->height() + ( double )(( lines - 1 ) * labelHeight * tmpLyr.multilineHeight );
534 
535  // needed to move bottom of text's descender to within bottom edge of label
536  double ascentOffset = 0.25 * labelfm->ascent(); // labelfm->descent() is not enough
537 
538  for ( int i = 0; i < lines; ++i )
539  {
540  painter->save();
541 #if 0 // TODO: generalize some of this
542  LabelPosition* lp = label;
543  double w = lp->getWidth();
544  double h = lp->getHeight();
545  double cx = lp->getX() + w / 2.0;
546  double cy = lp->getY() + h / 2.0;
547  double scale = 1.0 / xform->mapUnitsPerPixel();
548  double rotation = xform->mapRotation();
549  double sw = w * scale;
550  double sh = h * scale;
551  QRectF rect( -sw / 2, -sh / 2, sw, sh );
552  painter->translate( xform->transform( QPointF( cx, cy ) ).toQPointF() );
553  if ( rotation )
554  {
555  // Only if not horizontal
556  if ( lp->getFeaturePart()->getLayer()->getArrangement() != P_POINT &&
557  lp->getFeaturePart()->getLayer()->getArrangement() != P_POINT_OVER &&
558  lp->getFeaturePart()->getLayer()->getArrangement() != P_HORIZ )
559  {
560  painter->rotate( rotation );
561  }
562  }
563  painter->translate( rect.bottomLeft() );
564  painter->rotate( -lp->getAlpha() * 180 / M_PI );
565 #else
566  painter->translate( QPointF( outPt.x(), outPt.y() ) );
567  painter->rotate( -label->getAlpha() * 180 / M_PI );
568 #endif
569 
570  // scale down painter: the font size has been multiplied by raster scale factor
571  // to workaround a Qt font scaling bug with small font sizes
572  painter->scale( 1.0 / tmpLyr.rasterCompressFactor, 1.0 / tmpLyr.rasterCompressFactor );
573 
574  // figure x offset for horizontal alignment of multiple lines
575  double xMultiLineOffset = 0.0;
576  double labelWidth = labelfm->width( multiLineList.at( i ) );
577  if ( lines > 1 && tmpLyr.multilineAlign != QgsPalLayerSettings::MultiLeft )
578  {
579  double labelWidthDiff = labelWidest - labelWidth;
581  {
582  labelWidthDiff /= 2;
583  }
584  xMultiLineOffset = labelWidthDiff;
585  //QgsDebugMsgLevel( QString( "xMultiLineOffset: %1" ).arg( xMultiLineOffset ), 4 );
586  }
587 
588  double yMultiLineOffset = ( lines - 1 - i ) * labelHeight * tmpLyr.multilineHeight;
589  painter->translate( QPointF( xMultiLineOffset, - ascentOffset - yMultiLineOffset ) );
590 
591  component.setText( multiLineList.at( i ) );
592  component.setSize( QgsPoint( labelWidth, labelHeight ) );
593  component.setOffset( QgsPoint( 0.0, -ascentOffset ) );
594  component.setRotation( -component.rotation() * 180 / M_PI );
595  component.setRotationOffset( 0.0 );
596 
597  if ( drawType == QgsPalLabeling::LabelBuffer )
598  {
599  // draw label's buffer
600  QgsPalLabeling::drawLabelBuffer( context, component, tmpLyr );
601  }
602  else
603  {
604  // draw label's text, QPainterPath method
605  QPainterPath path;
606  path.setFillRule( Qt::WindingFill );
607  path.addText( 0, 0, tmpLyr.textFont, component.text() );
608 
609  // store text's drawing in QPicture for drop shadow call
610  QPicture textPict;
611  QPainter textp;
612  textp.begin( &textPict );
613  textp.setPen( Qt::NoPen );
614  textp.setBrush( tmpLyr.textColor );
615  textp.drawPath( path );
616  // TODO: why are some font settings lost on drawPicture() when using drawText() inside QPicture?
617  // e.g. some capitalization options, but not others
618  //textp.setFont( tmpLyr.textFont );
619  //textp.setPen( tmpLyr.textColor );
620  //textp.drawText( 0, 0, component.text() );
621  textp.end();
622 
623  if ( tmpLyr.shadowDraw && tmpLyr.shadowUnder == QgsPalLayerSettings::ShadowText )
624  {
625  component.setPicture( &textPict );
626  component.setPictureBuffer( 0.0 ); // no pen width to deal with
627  component.setOrigin( QgsPoint( 0.0, 0.0 ) );
628 
629  QgsPalLabeling::drawLabelShadow( context, component, tmpLyr );
630  }
631 
632  // paint the text
633  if ( context.useAdvancedEffects() )
634  {
635  painter->setCompositionMode( tmpLyr.blendMode );
636  }
637 
638  // scale for any print output or image saving @ specific dpi
639  painter->scale( component.dpiRatio(), component.dpiRatio() );
640 
642  {
643  // draw outlined text
644  _fixQPictureDPI( painter );
645  painter->drawPicture( 0, 0, textPict );
646  }
647  else
648  {
649  // draw text as text (for SVG and PDF exports)
650  painter->setFont( tmpLyr.textFont );
651  painter->setPen( tmpLyr.textColor );
652  painter->setRenderHint( QPainter::TextAntialiasing );
653  painter->drawText( 0, 0, component.text() );
654  }
655  }
656  painter->restore();
657  }
658  }
659 
660  // NOTE: this used to be within above multi-line loop block, at end. (a mistake since 2010? [LS])
661  if ( label->getNextPart() )
662  drawLabelPrivate( label->getNextPart(), context, tmpLyr, drawType, dpiRatio );
663 }
Class for parsing and evaluation of expressions (formerly called "search strings").
Definition: qgsexpression.h:92
void setExpressionParams(const QMap< QString, QVariant > &params)
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.
QString name() const
Name of the layer (for statistics, debugging etc.) - does not need to be unique.
FeaturePart * getFeaturePart()
return the feature corresponding to this labelposition
A rectangle specified with double values.
Definition: qgsrectangle.h:35
QString & append(QChar ch)
static void dataDefinedShapeBackground(QgsPalLayerSettings &tmpLyr, const QMap< QgsPalLayerSettings::DataDefinedProperties, QVariant > &ddValues)
void setMapRotation(double degrees, double cx, double cy)
Set map rotation in degrees (clockwise)
QStringList referencedColumns() const
Get list of columns referenced by the expression.
QgsPalLayerSettings::Placement mPlacement
Placement strategy.
static void dataDefinedTextStyle(QgsPalLayerSettings &tmpLyr, const QMap< QgsPalLayerSettings::DataDefinedProperties, QVariant > &ddValues)
A container class for data source field mapping or expression.
bool end()
void setOrigin(const QgsPoint &point)
virtual void registerFeature(QgsFeature &feature, QgsRenderContext &context)
Register a feature for labeling as one or more QgsLabelFeature objects stored into mLabels...
void setCompositionMode(CompositionMode mode)
void setRenderHint(RenderHint hint, bool on)
QgsLabelFeature * feature()
Returns the parent feature.
Definition: feature.h:140
arranges candidates around a point (centroid for polygon)
Definition: pal.h:79
const QString & text() const
double getWidth() const
Q_DECL_DEPRECATED bool prepare(const QgsFields &fields)
Get the expression ready for evaluation - find out column indexes.
UpsideDownLabels upsidedownLabels
QgsFields fields() const
Returns the list of fields of this layer.
double mPriority
Default priority of labels.
bool mOwnsSource
Whether layer's feature source is owned.
Whether to show debugging rectangles for drop shadows.
int fieldNameIndex(const QString &fieldName) const
Look up field's index from name also looks up case-insensitive if there is no match otherwise...
Definition: qgsfield.cpp:382
QString & prepend(QChar ch)
double rendererScale() const
void scale(qreal sx, qreal sy)
const_iterator constBegin() const
QgsPoint transform(const QgsPoint &p) const
Transform the point from map (world) coordinates to device coordinates.
const T & at(int i) const
static void drawLabelBuffer(QgsRenderContext &context, const QgsLabelComponent &component, const QgsPalLayerSettings &tmpLyr)
QgsFeatureRequest & setSubsetOfAttributes(const QgsAttributeList &attrs)
Set a subset of attributes that will be fetched.
QgsRectangle visibleExtent() const
Return the actual extent derived from requested extent that takes takes output image size into accoun...
Class that adds extra information to QgsLabelFeature for text labels.
void save()
bool hasCrsTransformEnabled() const
returns true if projections are enabled for this layer set
Container of fields for a vector layer.
Definition: qgsfield.h:177
static QgsPalLayerSettings fromLayer(QgsVectorLayer *layer)
QgsFeatureId featureId() const
Returns the unique ID of the feature.
Definition: feature.cpp:152
bool drawLabels
Whether to draw labels for this layer.
static void _fixQPictureDPI(QPainter *p)
const QgsRectangle & extent() const
const QgsMapToPixel & mapToPixel() const
static void dataDefinedDropShadow(QgsPalLayerSettings &tmpLyr, const QMap< QgsPalLayerSettings::DataDefinedProperties, QVariant > &ddValues)
MultiLineAlign multilineAlign
double scaleFactor() const
whether to label each part of multi-part features separately
double rotation() const
Return the rotation of the resulting map image Units are clockwise degrees.
void rotate(qreal angle)
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:176
void addText(const QPointF &point, const QFont &font, const QString &text)
double dpiRatio() const
const QgsCoordinateTransform * coordinateTransform() const
static QStringList splitToLines(const QString &text, const QString &wrapCharacter)
Splits a text string to a list of separate lines, using a specified wrap character.
virtual bool prepare(const QgsRenderContext &context, QStringList &attributeNames)
Prepare for registration of features.
double mapRotation() const
Return current map rotation in degrees.
qreal width(const QString &text) const
bool qgsDoubleNear(double a, double b, double epsilon=4 *DBL_EPSILON)
Definition: qgis.h:268
void setRotationOffset(const double rotation)
double x() const
Get the x value of the point.
Definition: qgspoint.h:126
static void drawLabelBackground(QgsRenderContext &context, QgsLabelComponent component, const QgsPalLayerSettings &tmpLyr)
int size() const
QList< QgsLabelFeature * > mLabels
List of generated.
whether adjacent lines (with the same label text) should be merged
The QgsMapSettings class contains configuration for rendering of the map.
QString styleName() const
QgsLabelingResults * results() const
For internal use by the providers.
bool useAdvancedEffects() const
Returns true if advanced effects such as blend modes such be used.
virtual QList< QgsLabelFeature * > labelFeatures(QgsRenderContext &context) override
Return 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.
QgsGeometry * extentGeom
bool conflictsWithObstacle() const
Returns whether the position is marked as conflicting with an obstacle feature.
void drawRect(const QRectF &rectangle)
Perform transforms between map coordinates and device coordinates.
Definition: qgsmaptopixel.h:34
double rotation() const
void setFont(const QFont &font)
ObstacleType obstacleType
Controls how features act as obstacles for labels.
void setRotation(const double rotation)
void append(const T &value)
static void dataDefinedTextBuffer(QgsPalLayerSettings &tmpLyr, const QMap< QgsPalLayerSettings::DataDefinedProperties, QVariant > &ddValues)
const QgsCoordinateTransform * ct
void setFillRule(Qt::FillRule fillRule)
double getY(int i=0) const
get the down-left y coordinate
#define QgsDebugMsgLevel(str, level)
Definition: qgslogger.h:34
double getAlpha() const
get alpha
QPainter::CompositionMode blendMode
unsigned int mLinePlacementFlags
Extra placement flags for linestring geometries.
void setPen(const QColor &color)
const QgsMapSettings & mapSettings() const
Get associated map settings.
Quadrant getQuadrant() const
const QgsCoordinateReferenceSystem & destinationCrs() const
returns CRS of destination coordinate reference system
QgsPalLayerSettings mSettings
Layer's labeling configuration.
bool isEmpty() const
const QMap< QgsPalLayerSettings::DataDefinedProperties, QVariant > & dataDefinedValues() const
Get data-defined values.
const_iterator constEnd() const
void setCenter(const QgsPoint &point)
#define M_PI
const QgsMapToPixel * xform
QMap< QgsPalLayerSettings::DataDefinedProperties, QgsDataDefined * > dataDefinedProperties
Map of current data defined properties.
QPaintDevice * device() const
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.
whether location of centroid must be inside of polygons
void setBrush(const QBrush &brush)
void drawText(const QPointF &position, const QString &text)
double rasterScaleFactor() const
void setText(const QString &text)
QString id() const
Get this layer's unique ID, this ID is used to access this layer from map layer registry.
const QgsLabelingEngineV2 * mEngine
Associated labeling engine.
double mapUnitsPerPixel() const
Return current map units per pixel.
LabelPosition * getNextPart() const
whether labels must fall completely within the polygon
whether all features will be labelled even though overlaps occur
Base class that can be used for any class that is capable of returning features.
A class to represent a point.
Definition: qgspoint.h:63
bool getReversed() const
int logicalDpiX() const
int logicalDpiY() const
bool insertLabel(LabelPosition *labelPos, int featureId, const QString &layerName, const QString &labeltext, const QFont &labelfont, bool diagram=false, bool pinned=false)
Inserts label position.
double ANALYSIS_EXPORT angle(Point3D *p1, Point3D *p2, Point3D *p3, Point3D *p4)
Calculates the angle between two segments (in 2 dimension, z-values are ignored)
void setDpiRatio(const double ratio)
bool testFlag(Flag f) const
Test whether a particular flag is enabled.
Partial snapshot of vector layer's state (only the members necessary for access to features) ...
void setX(double x)
Sets the x value of the point.
Definition: qgspoint.h:103
void setY(double y)
Sets the y value of the point.
Definition: qgspoint.h:111
Only for lines, labels along the line.
Definition: pal.h:83
QgsExpressionContext & expressionContext()
Gets the expression context.
unsigned int placementFlags
QgsPoint toMapCoordinates(int x, int y) const
void restore()
QgsAbstractFeatureSource * mSource
Layer's feature source.
QgsExpression * getLabelExpression()
Returns the QgsExpression for this label settings.
Contains information about the context of a rendering operation.
QFont definedFont()
Font to be used for rendering.
void setPicture(QPicture *picture)
int getPartId() const
QgsVectorLayerLabelProvider(QgsVectorLayer *layer, bool withFeatureLoop=true, const QgsPalLayerSettings *settings=0, const QString &layerName=QString())
Convenience constructor to initialize the provider from given vector layer.
QString text(int partId) const
Returns the text component corresponding to a specified label part.
QPainter * painter()
The QgsLabelFeature class describes a feature that should be used within the labeling engine...
void drawPath(const QPainterPath &path)
Whether to only draw the label rect and not the actual label text (used for unit tests) ...
void setOffset(const QgsPoint &point)
QString mName
Name of the layer.
double getHeight() const
QString toString() const
qreal ascent() const
QgsCoordinateReferenceSystem mCrs
Layer's CRS.
bool fitInPolygonOnly
True if only labels which completely fit within a polygon are allowed.
int rotate(double rotation, const QgsPoint &center)
Rotate this geometry around the Z axis.
Class for storing a coordinate reference system (CRS)
QPointF bottomLeft() const
qreal descent() const
Class for doing transforms between two map coordinate systems.
static QgsGeometry * fromRect(const QgsRectangle &rect)
Creates a new geometry from a QgsRectangle.
LabelPosition is a candidate feature label position.
Definition: labelposition.h:48
void translate(const QPointF &offset)
QgsPalLayerSettings::ObstacleType mObstacleType
Type of the obstacle of feature geometries.
void registerFeature(QgsFeature &f, QgsRenderContext &context, const QString &dxfLayer, QgsLabelFeature **labelFeature=0)
Register a feature for labelling.
const QgsMapToPixel & mapToPixel() const
QgsPalLayerSettings::UpsideDownLabels mUpsidedownLabels
How to handle labels that would be upside down.
double y() const
Get the y value of the point.
Definition: qgspoint.h:134
const QgsCoordinateReferenceSystem & crs() const
Returns layer's spatial reference system.
double getX(int i=0) const
get the down-left x coordinate
whether the labels should be rendered
iterator insert(const Key &key, const T &value)
bool isExpression
Is this label made from a expression string eg FieldName || 'mm'.
void setSize(const QgsPoint &point)
void drawPicture(const QPointF &point, const QPicture &picture)
virtual QgsFeatureIterator getFeatures(const QgsFeatureRequest &request)=0
Get an iterator for features matching the specified request.
void setPictureBuffer(const double buffer)
bool nextFeature(QgsFeature &f)
QFontMetricsF * labelFontMetrics()
Metrics of the font for rendering.
Represents a vector layer which manages a vector based data sets.
bool begin(QPaintDevice *device)
Q_GUI_EXPORT int qt_defaultDpiY()
Whether to render labels as text or outlines.
QgsPoint center() const
Center point of the rectangle.
Definition: qgsrectangle.h:216
QString labelText() const
Text of the label.
QString evalErrorString() const
Returns evaluation error.
bool isActive() const
Maintains current state of more grainular and temporal values when creating/painting component parts ...
virtual void drawLabel(QgsRenderContext &context, pal::LabelPosition *label) const override
draw this label at the position determined by the labeling engine
Q_DECL_DEPRECATED QStringList referencedColumns(QgsVectorLayer *layer)
Returns the columns referenced by the QgsDataDefined.
Q_GUI_EXPORT int qt_defaultDpiX()
QgsFeatureRequest & setFilterRect(const QgsRectangle &rect)
Set rectangle from which features will be taken.
QgsRectangle transformBoundingBox(const QgsRectangle &theRect, TransformDirection direction=ForwardTransform, const bool handle180Crossover=false) const
Transform a QgsRectangle to the dest Coordinate system If the direction is ForwardTransform then coor...
void drawLabelPrivate(pal::LabelPosition *label, QgsRenderContext &context, QgsPalLayerSettings &tmpLyr, QgsPalLabeling::DrawLabelType drawType, double dpiRatio=1.0) const
Internal label drawing method.
QgsCoordinateTransform * clone() const
const T value(const Key &key) const
DirectionSymbols placeDirectionSymbol
QPointF toQPointF() const
Converts a point to a QPointF.
Definition: qgspoint.cpp:121
static void drawLabelShadow(QgsRenderContext &context, const QgsLabelComponent &component, const QgsPalLayerSettings &tmpLyr)
static void dataDefinedTextFormatting(QgsPalLayerSettings &tmpLyr, const QMap< QgsPalLayerSettings::DataDefinedProperties, QVariant > &ddValues)