QGIS API Documentation  2.2.0-Valmiera
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
qgspallabeling.h
Go to the documentation of this file.
1 /***************************************************************************
2  qgspallabeling.h
3  Smart labeling for vector layers
4  -------------------
5  begin : June 2009
6  copyright : (C) Martin Dobias
7  email : wonder dot sk at gmail dot com
8 
9  ***************************************************************************
10  * *
11  * This program is free software; you can redistribute it and/or modify *
12  * it under the terms of the GNU General Public License as published by *
13  * the Free Software Foundation; either version 2 of the License, or *
14  * (at your option) any later version. *
15  * *
16  ***************************************************************************/
17 
18 //Note: although this file is in the core library, it is not part of the stable API
19 //and might change at any time!
20 
21 #ifndef QGSPALLABELING_H
22 #define QGSPALLABELING_H
23 
24 class QFontMetricsF;
25 class QPainter;
26 class QPicture;
27 class QgsGeometry;
28 class QgsMapRenderer;
29 class QgsRectangle;
31 class QgsLabelSearchTree;
32 
33 #include <QString>
34 #include <QFont>
35 #include <QFontDatabase>
36 #include <QColor>
37 #include <QHash>
38 #include <QList>
39 #include <QRectF>
40 
41 namespace pal
42 {
43  class Pal;
44  class Layer;
45  class LabelPosition;
46 }
47 
48 class QgsMapToPixel;
49 class QgsFeature;
50 
51 #include "qgspoint.h"
52 #include "qgsrectangle.h"
53 #include "qgsmaprenderer.h" // definition of QgsLabelingEngineInterface
54 #include "qgsexpression.h"
55 #include "qgsdatadefined.h"
56 #include "qgsdiagramrendererv2.h"
57 
58 class QgsPalGeometry;
59 class QgsVectorLayer;
60 
61 class CORE_EXPORT QgsPalLayerSettings
62 {
63  public:
67 
68  enum Placement
69  {
70  AroundPoint, // Point / Polygon
71  OverPoint, // Point / Polygon
72  Line, // Line / Polygon
73  Curved, // Line
74  Horizontal, // Polygon
75  Free // Polygon
76  };
77 
79  {
80  OnLine = 1,
81  AboveLine = 2,
82  BelowLine = 4,
83  MapOrientation = 8
84  };
85 
87  {
96  QuadrantBelowRight
97  };
98 
100  {
101  Upright, // upside-down labels (90 <= angle < 270) are shown upright
102  ShowDefined, // show upside down when rotation is layer- or data-defined
103  ShowAll // show upside down for all labels, including dynamic ones
104  };
105 
107  {
108  SymbolLeftRight, // place direction symbols on left/right of label
109  SymbolAbove, // place direction symbols on above label
110  SymbolBelow // place direction symbols on below label
111  };
112 
114  {
115  MultiLeft = 0,
117  MultiRight
118  };
119 
121  {
122  ShapeRectangle = 0,
126  ShapeSVG
127  };
128 
129  enum SizeType
130  {
131  SizeBuffer = 0,
133  SizePercent
134  };
135 
137  {
138  RotationSync = 0,
140  RotationFixed
141  };
142 
144  enum SizeUnit
145  {
146  Points = 0,
147  MM,
149  Percent
150  };
151 
153  {
154  ShadowLowest = 0,
157  ShadowShape
158  };
159 
160  // update mDataDefinedNames QMap in constructor when adding/deleting enum value
162  {
163  // text style
164  Size = 0,
165  Bold = 1,
166  Italic = 2,
167  Underline = 3,
168  Color = 4,
169  Strikeout = 5,
170  Family = 6,
171  FontStyle = 21,
172  FontSizeUnit = 22,
173  FontTransp = 18,
174  FontCase = 27,
175  FontLetterSpacing = 28,
176  FontWordSpacing = 29,
177  FontBlendMode = 30,
178 
179  // text formatting
180  MultiLineWrapChar = 31,
181  MultiLineHeight = 32,
182  MultiLineAlignment = 33,
183  DirSymbDraw = 34,
184  DirSymbLeft = 35,
185  DirSymbRight = 36,
186  DirSymbPlacement = 37,
187  DirSymbReverse = 38,
188  NumFormat = 39,
189  NumDecimals = 40,
190  NumPlusSign = 41,
191 
192  // text buffer
193  BufferDraw = 42,
194  BufferSize = 7,
195  BufferUnit = 43,
196  BufferColor = 8,
197  BufferTransp = 19,
198  BufferJoinStyle = 44,
199  BufferBlendMode = 45,
200 
201  // background
202  ShapeDraw = 46,
203  ShapeKind = 47,
204  ShapeSVGFile = 48,
205  ShapeSizeType = 49,
206  ShapeSizeX = 50,
207  ShapeSizeY = 85,
208  ShapeSizeUnits = 51,
209  ShapeRotationType = 52,
210  ShapeRotation = 53,
211  ShapeOffset = 54,
212  ShapeOffsetUnits = 55,
213  ShapeRadii = 56,
214  ShapeRadiiUnits = 57,
215  ShapeTransparency = 63,
216  ShapeBlendMode = 64,
217  ShapeFillColor = 58,
218  ShapeBorderColor = 59,
219  ShapeBorderWidth = 60,
220  ShapeBorderWidthUnits = 61,
221  ShapeJoinStyle = 62,
222 
223  // drop shadow
224  ShadowDraw = 65,
225  ShadowUnder = 66,
226  ShadowOffsetAngle = 67,
227  ShadowOffsetDist = 68,
228  ShadowOffsetUnits = 69,
229  ShadowRadius = 70,
230  ShadowRadiusUnits = 71,
231  ShadowTransparency = 72,
232  ShadowScale = 73,
233  ShadowColor = 74,
234  ShadowBlendMode = 75,
235 
236  // placement
237  CentroidWhole = 76,
238  OffsetQuad = 77,
239  OffsetXY = 78,
240  OffsetUnits = 80,
241  LabelDistance = 13,
242  DistanceUnits = 81,
243  OffsetRotation = 82,
244  CurvedCharAngleInOut = 83,
245  // (data defined only)
246  PositionX = 9, //x-coordinate data defined label position
247  PositionY = 10, //y-coordinate data defined label position
248  Hali = 11, //horizontal alignment for data defined label position (Left, Center, Right)
249  Vali = 12, //vertical alignment for data defined label position (Bottom, Base, Half, Cap, Top)
250  Rotation = 14, //data defined rotation
251 
252  // rendering
253  ScaleVisibility = 23,
254  MinScale = 16,
255  MaxScale = 17,
256  FontLimitPixel = 24,
257  FontMinPixel = 25,
258  FontMaxPixel = 26,
259  // (data defined only)
260  Show = 15,
261  AlwaysShow = 20
262  };
263 
264 
265  // whether to label this layer
266  bool enabled;
267 
268  //-- text style
269 
270  QString fieldName;
271 
275 
278  QgsExpression* getLabelExpression();
279 
280  QFont textFont;
281  QString textNamedStyle;
282  bool fontSizeInMapUnits; //true if font size is in map units (otherwise in points)
283  QColor textColor;
285  QPainter::CompositionMode blendMode;
287 
288  //-- text formatting
289 
290  QString wrapChar;
291  double multilineHeight; //0.0 to 10.0, leading between lines as multiplyer of line height
292  MultiLineAlign multilineAlign; // horizontal alignment of multi-line labels
293 
294  // Adds '<' or '>', or user-defined symbol to the label string pointing to the
295  // direction of the line / polygon ring
296  // Works only if Placement == Line
300  DirectionSymbols placeDirectionSymbol; // whether to place left/right, above or below label
302 
304  int decimals;
305  bool plusSign;
306 
307  //-- text buffer
308 
310  double bufferSize; // buffer size
311  bool bufferSizeInMapUnits; //true if buffer is in map units (otherwise in mm)
312  QColor bufferColor;
313  bool bufferNoFill; //set interior of buffer to 100% transparent
315  Qt::PenJoinStyle bufferJoinStyle;
316  QPainter::CompositionMode bufferBlendMode;
317 
318  //-- shape background
319 
320  bool shapeDraw;
322  QString shapeSVGFile;
324  QPointF shapeSize;
328  QPointF shapeOffset;
330  QPointF shapeRadii;
333  QPainter::CompositionMode shapeBlendMode;
338  Qt::PenJoinStyle shapeJoinStyle;
339 
340  //-- drop shadow
341 
348  double shadowRadius;
353  QColor shadowColor;
354  QPainter::CompositionMode shadowBlendMode;
355 
356  //-- placement
357 
359  unsigned int placementFlags;
360 
361  bool centroidWhole; // whether centroid calculated from whole or visible polygon
362  double dist; // distance from the feature (in mm)
363  bool distInMapUnits; //true if distance is in map units (otherwise in mm)
364 
365  // offset labels of point/centroid features default to center
366  // move label to quadrant: left/down, don't move, right/up (-1, 0, 1)
368 
369  double xOffset; // offset from point in mm or map units
370  double yOffset; // offset from point in mm or map units
371  bool labelOffsetInMapUnits; //true if label offset is in map units (otherwise in mm)
372  double angleOffset; // rotation applied to offset labels
373  bool preserveRotation; // preserve predefined rotation data during label pin/unpin operations
374 
375  double maxCurvedCharAngleIn; // maximum angle between inside curved label characters (defaults to 20.0, range 20.0 to 60.0)
376  double maxCurvedCharAngleOut; // maximum angle between outside curved label characters (defaults to -20.0, range -20.0 to -95.0)
377 
378  int priority; // 0 = low, 10 = high
379 
380  //-- rendering
381 
383  int scaleMin;
384  int scaleMax;
385 
386  bool fontLimitPixelSize; // true is label should be limited by fontMinPixelSize/fontMaxPixelSize
387  int fontMinPixelSize; // minimum pixel size for showing rendered map unit labels (1 - 1000)
388  int fontMaxPixelSize; // maximum pixel size for showing rendered map unit labels (1 - 10000)
389 
390  bool displayAll; // if true, all features will be labelled even though overlaps occur
391  unsigned int upsidedownLabels; // whether, or how, to show upsidedown labels
392 
393  bool labelPerPart; // whether to label every feature's part or only the biggest one
395 
396  bool limitNumLabels; // whether to limit the number of labels to be drawn
397  int maxNumLabels; // maximum number of labels to be drawn
398 
399  double minFeatureSize; // minimum feature size to be labelled (in mm)
400  bool obstacle; // whether features for layer are obstacles to labels of other layers
401 
402  //-- scale factors
403  double vectorScaleFactor; //scale factor painter units->pixels
404  double rasterCompressFactor; //pixel resolution scale factor
405 
406  // called from register feature hook
407  void calculateLabelSize( const QFontMetricsF* fm, QString text, double& labelX, double& labelY, QgsFeature* f = 0 );
408 
409  // implementation of register feature hook
410  void registerFeature( QgsVectorLayer* layer, QgsFeature& f, const QgsRenderContext& context );
411 
412  void readFromLayer( QgsVectorLayer* layer );
413  void writeToLayer( QgsVectorLayer* layer );
414 
419 
423  void setDataDefinedProperty( QgsPalLayerSettings::DataDefinedProperties p,
424  bool active, bool useExpr, const QString& expr, const QString& field );
425 
427  void removeDataDefinedProperty( QgsPalLayerSettings::DataDefinedProperties p );
428 
432  QString updateDataDefinedString( const QString& value );
433 
437  QMap<QString, QString> dataDefinedMap( QgsPalLayerSettings::DataDefinedProperties p ) const;
438 
443  QVariant dataDefinedValue( QgsPalLayerSettings::DataDefinedProperties p, QgsFeature& f, const QgsFields& fields ) const;
444 
449  bool dataDefinedEvaluate( QgsPalLayerSettings::DataDefinedProperties p, QVariant& exprVal ) const;
450 
453  bool dataDefinedIsActive( QgsPalLayerSettings::DataDefinedProperties p ) const;
454 
457  bool dataDefinedUseExpression( QgsPalLayerSettings::DataDefinedProperties p ) const;
458 
461  QMap< QgsPalLayerSettings::DataDefinedProperties, QgsDataDefined* > dataDefinedProperties;
462 
463 
471  int sizeToPixel( double size, const QgsRenderContext& c , SizeUnit unit, bool rasterfactor = false ) const;
472 
481  double scaleToPixelContext( double size, const QgsRenderContext& c, SizeUnit unit, bool rasterfactor = false ) const;
482 
487  QMap<QgsPalLayerSettings::DataDefinedProperties, QPair<QString, int> > dataDefinedNames() const { return mDataDefinedNames; }
488 
489  // temporary stuff: set when layer gets prepared or labeled
490  // NOTE: not in Python binding
491  pal::Layer* palLayer;
497  QgsPoint ptZero, ptOne;
498  QList<QgsPalGeometry*> geometries;
500  int mFeaturesToLabel; // total features that will probably be labeled, may be less (figured before PAL)
501  int mFeatsSendingToPal; // total features tested for sending into PAL (relative to maxNumLabels)
502  int mFeatsRegPal; // number of features registered in PAL, when using limitNumLabels
503 
506 
507  bool showingShadowRects; // whether to show debug rectangles for drop shadows
508 
509  private:
510  void readDataDefinedPropertyMap( QgsVectorLayer* layer,
512  QgsDataDefined* > & propertyMap );
513  void writeDataDefinedPropertyMap( QgsVectorLayer* layer,
515  QgsDataDefined* > & propertyMap );
516  void readDataDefinedProperty( QgsVectorLayer* layer,
519  QgsDataDefined* > & propertyMap );
520 
521  // convenience data defined evaluation function
522  bool dataDefinedValEval( const QString& valType,
524  QVariant& exprVal );
525 
526  void parseTextStyle( QFont& labelFont,
528  const QgsRenderContext& context );
529 
530  void parseTextBuffer();
531 
532  void parseTextFormatting();
533 
534  void parseShapeBackground();
535 
536  void parseDropShadow();
537 
540  bool checkMinimumSizeMM( const QgsRenderContext& ct, QgsGeometry* geom, double minSize ) const;
541 
542 
543  QMap<DataDefinedProperties, QVariant> dataDefinedValues;
545  QMap<QgsPalLayerSettings::DataDefinedProperties, QPair<QString, int> > mDataDefinedNames;
546 
547  QFontDatabase mFontDB;
548 };
549 
550 class CORE_EXPORT QgsLabelCandidate
551 {
552  public:
553  QgsLabelCandidate( QRectF r, double c ): rect( r ), cost( c ) {}
554 
555  QRectF rect;
556  double cost;
557 };
558 
563 class CORE_EXPORT QgsLabelComponent
564 {
565  public:
567  : mText( QString() )
568  , mOrigin( QgsPoint() )
569  , mUseOrigin( false )
570  , mRotation( 0.0 )
571  , mRotationOffset( 0.0 )
572  , mUseRotation( false )
573  , mCenter( QgsPoint() )
574  , mUseCenter( false )
575  , mSize( QgsPoint() )
576  , mOffset( QgsPoint() )
577  , mPicture( 0 )
578  , mPictureBuffer( 0.0 )
579  , mDpiRatio( 1.0 )
580  {}
581 
582  const QString& text() { return mText; }
583  void setText( const QString& text ) { mText = text; }
584 
585  const QgsPoint& origin() { return mOrigin; }
586  void setOrigin( QgsPoint point ) { mOrigin = point; }
587 
588  bool useOrigin() const { return mUseOrigin; }
589  void setUseOrigin( bool use ) { mUseOrigin = use; }
590 
591  double rotation() const { return mRotation; }
592  void setRotation( double rotation ) { mRotation = rotation; }
593 
594  double rotationOffset() const { return mRotationOffset; }
595  void setRotationOffset( double rotation ) { mRotationOffset = rotation; }
596 
597  bool useRotation() const { return mUseRotation; }
598  void setUseRotation( bool use ) { mUseRotation = use; }
599 
600  const QgsPoint& center() { return mCenter; }
601  void setCenter( QgsPoint point ) { mCenter = point; }
602 
603  bool useCenter() const { return mUseCenter; }
604  void setUseCenter( bool use ) { mUseCenter = use; }
605 
606  const QgsPoint& size() { return mSize; }
607  void setSize( QgsPoint point ) { mSize = point; }
608 
609  const QgsPoint& offset() { return mOffset; }
610  void setOffset( QgsPoint point ) { mOffset = point; }
611 
612  const QPicture* picture() { return mPicture; }
613  void setPicture( QPicture* picture ) { mPicture = picture; }
614 
615  double pictureBuffer() const { return mPictureBuffer; }
616  void setPictureBuffer( double buffer ) { mPictureBuffer = buffer; }
617 
618  double dpiRatio() const { return mDpiRatio; }
619  void setDpiRatio( double ratio ) { mDpiRatio = ratio; }
620 
621  private:
622  // current label component text,
623  // e.g. single line in a multi-line label or charcater in curved labeling
624  QString mText;
625  // current origin point for painting (generally current painter rotation point)
627  // whether to translate the painter to supplied origin
629  // any rotation to be applied to painter (in radians)
630  double mRotation;
631  // any rotation to be applied to painter (in radians) after initial rotation
633  // whether to use the rotation to rotate the painter
635  // current center point of label compnent, after rotation
637  // whether to translate the painter to supplied origin based upon center
639  // width and height of label component, transformed and ready for painting
641  // any translation offsets to be applied before painting, transformed and ready for painting
643 
644  // a stored QPicture of painting for the component
645  QPicture* mPicture;
646  // buffer for component to accommodate graphic items ignored by QPicture,
647  // e.g. half-width of an applied QPen, which would extend beyond boundingRect() of QPicture
649 
650  // a ratio of native painter dpi and that of rendering context's painter
651  double mDpiRatio;
652 };
653 
654 class CORE_EXPORT QgsPalLabeling : public QgsLabelingEngineInterface
655 {
656  public:
658  {
659  LabelText = 0,
663  LabelShadow
664  };
665 
666  QgsPalLabeling();
667  ~QgsPalLabeling();
668 
669  QgsPalLayerSettings& layer( const QString& layerName );
670 
671  void numCandidatePositions( int& candPoint, int& candLine, int& candPolygon );
672  void setNumCandidatePositions( int candPoint, int candLine, int candPolygon );
673 
674  enum Search { Chain, Popmusic_Tabu, Popmusic_Chain, Popmusic_Tabu_Chain, Falp };
675 
676  void setSearchMethod( Search s );
677  Search searchMethod() const;
678 
679  bool isShowingCandidates() const { return mShowingCandidates; }
680  void setShowingCandidates( bool showing ) { mShowingCandidates = showing; }
681  const QList<QgsLabelCandidate>& candidates() { return mCandidates; }
682 
683  bool isShowingShadowRectangles() const { return mShowingShadowRects; }
684  void setShowingShadowRectangles( bool showing ) { mShowingShadowRects = showing; }
685 
686  bool isShowingAllLabels() const { return mShowingAllLabels; }
687  void setShowingAllLabels( bool showing ) { mShowingAllLabels = showing; }
688 
689  bool isShowingPartialsLabels() const { return mShowingPartialsLabels; }
690  void setShowingPartialsLabels( bool showing ) { mShowingPartialsLabels = showing; }
691 
692  // implemented methods from labeling engine interface
693 
695  virtual void init( QgsMapRenderer* mr );
697  virtual bool willUseLayer( QgsVectorLayer* layer );
700  virtual void clearActiveLayers();
703  virtual void clearActiveLayer( QgsVectorLayer* layer );
705  virtual int prepareLayer( QgsVectorLayer* layer, QSet<int>& attrIndices, QgsRenderContext& ctx );
707  virtual int addDiagramLayer( QgsVectorLayer* layer, QgsDiagramLayerSettings *s );
709  virtual void registerFeature( QgsVectorLayer* layer, QgsFeature& feat, const QgsRenderContext& context = QgsRenderContext() );
710  virtual void registerDiagramFeature( QgsVectorLayer* layer, QgsFeature& feat, const QgsRenderContext& context = QgsRenderContext() );
712  virtual void drawLabeling( QgsRenderContext& context );
714  virtual void exit();
716  virtual QList<QgsLabelPosition> labelsAtPosition( const QgsPoint& p );
718  virtual QList<QgsLabelPosition> labelsWithinRect( const QgsRectangle& r );
719 
722 
724  void drawLabelCandidateRect( pal::LabelPosition* lp, QPainter* painter, const QgsMapToPixel* xform );
727  virtual void drawLabel( pal::LabelPosition* label, QgsRenderContext& context, QgsPalLayerSettings& tmpLyr, DrawLabelType drawType, double dpiRatio = 1.0 );
728 
729  static void drawLabelBuffer( QgsRenderContext& context,
730  QgsLabelComponent component,
731  const QgsPalLayerSettings& tmpLyr );
732 
733  static void drawLabelBackground( QgsRenderContext& context,
734  QgsLabelComponent component,
735  const QgsPalLayerSettings& tmpLyr );
736 
737  static void drawLabelShadow( QgsRenderContext& context,
738  QgsLabelComponent component,
739  const QgsPalLayerSettings& tmpLyr );
740 
743  void loadEngineSettings();
744  void saveEngineSettings();
745  void clearEngineSettings();
746  bool isStoredWithProject() const { return mSavedWithProject; }
747  void setStoredWithProject( bool store ) { mSavedWithProject = store; }
748 
749  protected:
750  // update temporary QgsPalLayerSettings with any data defined text style values
751  void dataDefinedTextStyle( QgsPalLayerSettings& tmpLyr,
752  const QMap< QgsPalLayerSettings::DataDefinedProperties, QVariant >& ddValues );
753 
754  // update temporary QgsPalLayerSettings with any data defined text formatting values
755  void dataDefinedTextFormatting( QgsPalLayerSettings& tmpLyr,
756  const QMap< QgsPalLayerSettings::DataDefinedProperties, QVariant >& ddValues );
757 
758  // update temporary QgsPalLayerSettings with any data defined text buffer values
759  void dataDefinedTextBuffer( QgsPalLayerSettings& tmpLyr,
760  const QMap< QgsPalLayerSettings::DataDefinedProperties, QVariant >& ddValues );
761 
762  // update temporary QgsPalLayerSettings with any data defined shape background values
763  void dataDefinedShapeBackground( QgsPalLayerSettings& tmpLyr,
764  const QMap< QgsPalLayerSettings::DataDefinedProperties, QVariant >& ddValues );
765 
766  // update temporary QgsPalLayerSettings with any data defined drop shadow values
767  void dataDefinedDropShadow( QgsPalLayerSettings& tmpLyr,
768  const QMap< QgsPalLayerSettings::DataDefinedProperties, QVariant >& ddValues );
769 
770  // hashtable of layer settings, being filled during labeling
771  QHash<QgsVectorLayer*, QgsPalLayerSettings> mActiveLayers;
772  // hashtable of active diagram layers
773  QHash<QgsVectorLayer*, QgsDiagramLayerSettings> mActiveDiagramLayers;
775 
777  int mCandPoint, mCandLine, mCandPolygon;
779 
780  pal::Pal* mPal;
781 
782  // list of candidates from last labeling
783  QList<QgsLabelCandidate> mCandidates;
785  bool mShowingAllLabels; // whether to avoid collisions or not
786  bool mSavedWithProject; // whether engine settings have been read from project file
787  bool mShowingShadowRects; // whether to show debugging rectangles for drop shadows
788  bool mShowingPartialsLabels; // whether to avoid partials labels or not
789 
791 };
792 
793 #endif // QGSPALLABELING_H