QGIS API Documentation  3.6.0-Noosa (5873452)
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 #include "qgis_core.h"
25 #include "qgis_sip.h"
26 #include <QString>
27 #include <QFont>
28 #include <QFontDatabase>
29 #include <QColor>
30 #include <QHash>
31 #include <QList>
32 #include <QPainter>
33 #include <QRectF>
34 #include <QMap>
35 #include "qgsfeature.h"
36 #include "qgsgeometry.h"
37 #include "qgsfields.h"
39 #include "qgspointxy.h"
40 #include "qgsmapunitscale.h"
41 #include "qgsstringutils.h"
42 #include "qgstextrenderer.h"
43 #include "qgspropertycollection.h"
44 
45 namespace pal SIP_SKIP
46 {
47  class Pal;
48  class Layer;
49  class LabelPosition;
50 }
51 
53 class QgsRectangle;
54 class QgsMapToPixel;
55 class QgsFeature;
57 class QgsVectorLayer;
58 class QgsExpression;
59 class QFontMetricsF;
60 class QPainter;
61 class QPicture;
62 class QgsGeometry;
64 class QgsLabelSearchTree;
65 class QgsMapSettings;
66 class QgsLabelFeature;
67 class QgsLabelingEngine;
70 class QgsDxfExport;
73 
74 
79 class CORE_EXPORT QgsLabelPosition
80 {
81  public:
82  QgsLabelPosition( int id, double r, const QVector< QgsPointXY > &corners, const QgsRectangle &rect, double w, double h, const QString &layer, const QString &labeltext, const QFont &labelfont, bool upside_down, bool diagram = false, bool pinned = false, const QString &providerId = QString() )
83  : featureId( id )
84  , rotation( r )
85  , cornerPoints( corners )
86  , labelRect( rect )
87  , width( w )
88  , height( h )
89  , layerID( layer )
90  , labelText( labeltext )
91  , labelFont( labelfont )
92  , upsideDown( upside_down )
93  , isDiagram( diagram )
94  , isPinned( pinned )
95  , providerID( providerId )
96  {}
97 
99  QgsLabelPosition() = default;
100 
101  int featureId = -1;
102  double rotation = 0;
103  QVector< QgsPointXY > cornerPoints;
105  double width = 0;
106  double height = 0;
107  QString layerID;
108  QString labelText;
109  QFont labelFont;
110  bool upsideDown = false;
111  bool isDiagram = false;
112  bool isPinned = false;
114  QString providerID;
115 };
116 
117 
122 class CORE_EXPORT QgsPalLayerSettings
123 {
124  public:
128 
130  QgsPalLayerSettings &operator=( const QgsPalLayerSettings &s );
131 
132  //TODO QGIS 4.0 - move to QgsLabelingEngine
133 
138  {
147  };
148 
149  //TODO QGIS 4.0 - move to QgsLabelingEngine
152  {
165  };
166 
167  //TODO QGIS 4.0 - move to QgsLabelingEngine
168 
174  {
177  };
178 
179  //TODO QGIS 4.0 - move to QgsLabelingEngine, rename to LinePlacementFlag, use Q_DECLARE_FLAGS to make
180  //LinePlacementFlags type, and replace use of pal::LineArrangementFlag
181 
186  {
187  OnLine = 1,
188  AboveLine = 2,
191  BelowLine = 4,
194  MapOrientation = 8,
197  };
198 
200  {
210  };
211 
213  {
216  ShowAll
217  };
218 
220  {
223  SymbolBelow
224  };
225 
227  {
228  MultiLeft = 0,
231  MultiFollowPlacement
233  };
234 
235  //TODO QGIS 4.0 - Move to QgsLabelingEngine
236 
242  {
243  PolygonInterior,
245  PolygonBoundary,
247  PolygonWhole
251  };
252 
254  enum Property
255  {
256  // text style
257  Size = 0,
258  Bold = 1,
259  Italic = 2,
260  Underline = 3,
261  Color = 4,
262  Strikeout = 5,
263  Family = 6,
264  FontStyle = 21,
265  FontSizeUnit = 22,
266  FontTransp = 18,
267  FontOpacity = 92,
268  FontCase = 27,
269  FontLetterSpacing = 28,
270  FontWordSpacing = 29,
271  FontBlendMode = 30,
272 
273  // text formatting
274  MultiLineWrapChar = 31,
275  AutoWrapLength = 101,
276  MultiLineHeight = 32,
277  MultiLineAlignment = 33,
278  DirSymbDraw = 34,
279  DirSymbLeft = 35,
280  DirSymbRight = 36,
281  DirSymbPlacement = 37,
282  DirSymbReverse = 38,
283  NumFormat = 39,
284  NumDecimals = 40,
285  NumPlusSign = 41,
286 
287  // text buffer
288  BufferDraw = 42,
289  BufferSize = 7,
290  BufferUnit = 43,
291  BufferColor = 8,
292  BufferTransp = 19,
293  BufferOpacity = 94,
294  BufferJoinStyle = 44,
295  BufferBlendMode = 45,
296 
297  // background
298  ShapeDraw = 46,
299  ShapeKind = 47,
300  ShapeSVGFile = 48,
301  ShapeSizeType = 49,
302  ShapeSizeX = 50,
303  ShapeSizeY = 85,
304  ShapeSizeUnits = 51,
305  ShapeRotationType = 52,
306  ShapeRotation = 53,
307  ShapeOffset = 54,
308  ShapeOffsetUnits = 55,
309  ShapeRadii = 56,
310  ShapeRadiiUnits = 57,
311  ShapeTransparency = 63,
312  ShapeOpacity = 93,
313  ShapeBlendMode = 64,
314  ShapeFillColor = 58,
315  ShapeStrokeColor = 59,
316  ShapeStrokeWidth = 60,
317  ShapeStrokeWidthUnits = 61,
318  ShapeJoinStyle = 62,
319 
320  // drop shadow
321  ShadowDraw = 65,
322  ShadowUnder = 66,
323  ShadowOffsetAngle = 67,
324  ShadowOffsetDist = 68,
325  ShadowOffsetUnits = 69,
326  ShadowRadius = 70,
327  ShadowRadiusUnits = 71,
328  ShadowTransparency = 72,
329  ShadowOpacity = 95,
330  ShadowScale = 73,
331  ShadowColor = 74,
332  ShadowBlendMode = 75,
333 
334  // placement
335  CentroidWhole = 76,
336  OffsetQuad = 77,
337  OffsetXY = 78,
338  OffsetUnits = 80,
339  LabelDistance = 13,
340  DistanceUnits = 81,
341  OffsetRotation = 82,
342  CurvedCharAngleInOut = 83,
343  // (data defined only)
344  PositionX = 9,
345  PositionY = 10,
346  Hali = 11,
347  Vali = 12,
348  Rotation = 14,
349  LabelRotation = 96,
350  RepeatDistance = 84,
351  RepeatDistanceUnit = 86,
352  Priority = 87,
353  PredefinedPositionOrder = 91,
354 
355  // rendering
356  ScaleVisibility = 23,
357  MinScale = 16,
358  MinimumScale = 97,
359  MaxScale = 17,
360  MaximumScale = 98,
361  FontLimitPixel = 24,
362  FontMinPixel = 25,
363  FontMaxPixel = 26,
364  IsObstacle = 88,
365  ObstacleFactor = 89,
366  ZIndex = 90,
367 
368  // (data defined only)
369  Show = 15,
370  AlwaysShow = 20
371  };
372 
377  static const QgsPropertiesDefinition &propertyDefinitions();
378 
388 
389  //-- text style
390 
396  QString fieldName;
397 
403 
407  QgsExpression *getLabelExpression();
408 
410 
415 
416  //-- text formatting
417 
422  QString wrapChar;
423 
431  int autoWrapLength = 0;
432 
443  bool useMaxLineLengthForAutoWrap = true;
444 
447 
459 
466 
473 
479 
482 
490 
496  int decimals;
497 
503  bool plusSign;
504 
505  //-- placement
506 
508  unsigned int placementFlags;
509 
515 
522 
529  QVector< PredefinedPointPosition > predefinedPositionOrder SIP_SKIP;
530 
535 
541  double dist;
542 
549 
556 
559 
566 
573 
580 
585 
592  double xOffset;
593 
600  double yOffset;
601 
609 
617 
619  double angleOffset;
620 
623 
629 
635 
640  int priority;
641 
642  //-- rendering
643 
650 
661  double maximumScale;
662 
673  double minimumScale;
674 
681 
688 
695 
698 
700  UpsideDownLabels upsidedownLabels = Upright;
701 
707 
713 
719 
726 
731 
737  bool obstacle;
738 
746 
753 
755  double zIndex;
756 
761  void calculateLabelSize( const QFontMetricsF *fm, const QString &text, double &labelX, double &labelY, const QgsFeature *f = nullptr, QgsRenderContext *context = nullptr );
762 
776  void registerFeature( const QgsFeature &f, QgsRenderContext &context,
777  QgsLabelFeature **labelFeature SIP_PYARGREMOVE = nullptr,
778  QgsGeometry obstacleGeometry SIP_PYARGREMOVE = QgsGeometry() );
779 
784  void readXml( QDomElement &elem, const QgsReadWriteContext &context );
785 
790  QDomElement writeXml( QDomDocument &doc, const QgsReadWriteContext &context );
791 
797  QgsPropertyCollection &dataDefinedProperties() { return mDataDefinedProperties; }
798 
806  const QgsPropertyCollection &dataDefinedProperties() const SIP_SKIP { return mDataDefinedProperties; }
807 
815  void setDataDefinedProperties( const QgsPropertyCollection &collection ) { mDataDefinedProperties = collection; }
816 
822  const QgsTextFormat &format() const { return mFormat; }
823 
830  void setFormat( const QgsTextFormat &format ) { mFormat = format; }
831 
832  // temporary stuff: set when layer gets prepared or labeled
833  const QgsFeature *mCurFeat = nullptr;
836  const QgsMapToPixel *xform = nullptr;
838 
842  int mFeaturesToLabel = 0; // total features that will probably be labeled, may be less (figured before PAL)
843  int mFeatsSendingToPal = 0; // total features tested for sending into PAL (relative to maxNumLabels)
844  int mFeatsRegPal = 0; // number of features registered in PAL, when using limitNumLabels
845  private:
846 
847  friend class QgsVectorLayer; // to allow calling readFromLayerCustomProperties()
848 
853  void readFromLayerCustomProperties( QgsVectorLayer *layer );
854 
858  void readOldDataDefinedPropertyMap( QgsVectorLayer *layer, QDomElement *parentElem );
859 
863  void readOldDataDefinedProperty( QgsVectorLayer *layer, QgsPalLayerSettings::Property p );
864 
865  enum DataDefinedValueType
866  {
867  DDBool,
868  DDInt,
869  DDIntPos,
870  DDDouble,
871  DDDoublePos,
872  DDRotation180,
873  DDOpacity,
874  DDString,
875  DDUnits,
876  DDColor,
877  DDJoinStyle,
878  DDBlendMode,
879  DDPointF,
880  DDSizeF,
881  };
882 
883  // convenience data defined evaluation function
884  bool dataDefinedValEval( DataDefinedValueType valType,
886  QVariant &exprVal, QgsExpressionContext &context, const QVariant &originalValue = QVariant() );
887 
888  void parseTextStyle( QFont &labelFont,
889  QgsUnitTypes::RenderUnit fontunits,
890  QgsRenderContext &context );
891 
892  void parseTextBuffer( QgsRenderContext &context );
893 
894  void parseTextFormatting( QgsRenderContext &context );
895 
896  void parseShapeBackground( QgsRenderContext &context );
897 
898  void parseDropShadow( QgsRenderContext &context );
899 
903  bool checkMinimumSizeMM( const QgsRenderContext &ct, const QgsGeometry &geom, double minSize ) const;
904 
908  void registerObstacleFeature( const QgsFeature &f, QgsRenderContext &context, QgsLabelFeature **obstacleFeature, const QgsGeometry &obstacleGeometry = QgsGeometry() );
909 
910  QMap<Property, QVariant> dataDefinedValues;
911 
913  QgsPropertyCollection mDataDefinedProperties;
914 
915  QgsExpression *expression = nullptr;
916 
917  QFontDatabase mFontDB;
918 
919  QgsTextFormat mFormat;
920 
921  static const QVector< PredefinedPointPosition > DEFAULT_PLACEMENT_ORDER;
922 
923  static void initPropertyDefinitions();
924 
926  static QgsPropertiesDefinition sPropertyDefinitions;
927 
928 };
929 
933 class CORE_EXPORT QgsLabelCandidate
934 {
935  public:
936  QgsLabelCandidate( const QRectF &r, double c ): rect( r ), cost( c ) {}
937 
938  QRectF rect;
939  double cost;
940 };
941 
942 
943 
944 
950 class CORE_EXPORT QgsLabelingResults
951 {
952  public:
955 
957  QgsLabelingResults( const QgsLabelingResults & ) = delete;
959  QgsLabelingResults &operator=( const QgsLabelingResults &rh ) = delete;
960 
962  QList<QgsLabelPosition> labelsAtPosition( const QgsPointXY &p ) const;
964  QList<QgsLabelPosition> labelsWithinRect( const QgsRectangle &r ) const;
965 
966  private:
967 #ifdef SIP_RUN
969 #endif
970 
971  QgsLabelSearchTree *mLabelSearchTree = nullptr;
972 
973  friend class QgsPalLabeling;
976 };
977 
982 class CORE_EXPORT QgsPalLabeling
983 {
984  public:
985 
990  static bool staticWillUseLayer( QgsVectorLayer *layer );
991 
993  static void drawLabelCandidateRect( pal::LabelPosition *lp, QPainter *painter, const QgsMapToPixel *xform, QList<QgsLabelCandidate> *candidates = nullptr ) SIP_SKIP;
994 
1004  static QgsGeometry prepareGeometry( const QgsGeometry &geometry, QgsRenderContext &context, const QgsCoordinateTransform &ct, const QgsGeometry &clipGeometry = QgsGeometry() ) SIP_FACTORY;
1005 
1015  static bool geometryRequiresPreparation( const QgsGeometry &geometry, QgsRenderContext &context, const QgsCoordinateTransform &ct, const QgsGeometry &clipGeometry = QgsGeometry() );
1016 
1029  static QStringList splitToLines( const QString &text, const QString &wrapCharacter, int autoWrapLength = 0, bool useMaxLineLengthWhenAutoWrapping = true );
1030 
1039  static QStringList splitToGraphemes( const QString &text );
1040 
1041  private:
1043  static void dataDefinedTextStyle( QgsPalLayerSettings &tmpLyr,
1044  const QMap< QgsPalLayerSettings::Property, QVariant > &ddValues );
1045 
1047  static void dataDefinedTextFormatting( QgsPalLayerSettings &tmpLyr,
1048  const QMap< QgsPalLayerSettings::Property, QVariant > &ddValues );
1049 
1051  static void dataDefinedTextBuffer( QgsPalLayerSettings &tmpLyr,
1052  const QMap< QgsPalLayerSettings::Property, QVariant > &ddValues );
1053 
1055  static void dataDefinedShapeBackground( QgsPalLayerSettings &tmpLyr,
1056  const QMap< QgsPalLayerSettings::Property, QVariant > &ddValues );
1057 
1059  static void dataDefinedDropShadow( QgsPalLayerSettings &tmpLyr,
1060  const QMap< QgsPalLayerSettings::Property, QVariant > &ddValues );
1061 
1062  friend class QgsVectorLayerLabelProvider; // to allow calling the static methods above
1063  friend class QgsDxfExport; // to allow calling the static methods above
1064 
1073  static bool checkMinimumSizeMM( const QgsRenderContext &context, const QgsGeometry &geom, double minSize );
1074 
1075  friend class QgsPalLayerSettings;
1076 };
1077 
1078 #endif // QGSPALLABELING_H
Label below point, slightly right of center.
QgsRectangle labelRect
Class for parsing and evaluation of expressions (formerly called "search strings").
double xOffset
Horizontal offset of label.
The class is used as a container of context for various read/write operations on other objects...
A rectangle specified with double values.
Definition: qgsrectangle.h:41
Label on bottom-left of point.
double maxCurvedCharAngleOut
Maximum angle between outside curved label characters (valid range -20.0 to -95.0) ...
double maximumScale
The maximum map scale (i.e.
QString leftDirectionSymbol
String to use for left direction arrows.
QgsUnitTypes::RenderUnit repeatDistanceUnit
Units for repeating labels for a single feature.
double angleOffset
Label rotation, in degrees clockwise.
bool formatNumbers
Set to true to format numeric label text as numbers (e.g.
A class to query the labeling structure at a given point (small wrapper around pal RTree class) ...
double obstacleFactor
Obstacle factor, where 1.0 = default, < 1.0 more likely to be covered by labels, 1.0 less likely to be covered
Label on top-left of point.
QgsLabelCandidate(const QRectF &r, double c)
PredefinedPointPosition
Positions for labels when using the QgsPalLabeling::OrderedPositionsAroundPoint placement mode...
A class to represent a 2D point.
Definition: qgspointxy.h:43
bool obstacle
True if features for layer are obstacles to labels of other layers.
int decimals
Number of decimal places to show for numeric labels.
double repeatDistance
Distance for repeating labels for a single feature.
Candidates are placed in predefined positions around a point. Preference is given to positions with g...
QuadrantPosition quadOffset
Sets the quadrant in which to offset labels from feature.
QgsUnitTypes::RenderUnit offsetUnits
Units for offsets of label.
double yOffset
Vertical offset of label.
Class that adds extra information to QgsLabelFeature for text labels.
Container of fields for a vector layer.
Definition: qgsfields.h:42
Label on top of point, slightly right of center.
bool addDirectionSymbol
If true, &#39;<&#39; or &#39;>&#39; (or custom strings set via leftDirectionSymbol and rightDirectionSymbol) will be ...
The QgsVectorLayerLabelProvider class implements a label provider for vector layers.
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:106
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 ...
QgsMapUnitScale repeatDistanceMapUnitScale
Map unit scale for repeating labels for a single feature.
MultiLineAlign multilineAlign
Horizontal alignment of multi-line labels.
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:55
double maxCurvedCharAngleIn
Maximum angle between inside curved label characters (valid range 20.0 to 60.0).
QgsCoordinateTransform ct
bool reverseDirectionSymbol
True if direction symbols should be reversed.
void setFormat(const QgsTextFormat &format)
Sets the label text formatting settings, e.g., font settings, buffer settings, etc.
double zIndex
Z-Index of label, where labels with a higher z-index are rendered on top of labels with a lower z-ind...
QgsStringReplacementCollection substitutions
Substitution collection for automatic text substitution with labels.
Arranges candidates following the curvature of a line feature. Applies to line layers only...
The QgsMapSettings class contains configuration for rendering of the map.
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c
Place direction symbols on left/right of label.
Perform transforms between map coordinates and device coordinates.
Definition: qgsmaptopixel.h:37
Property
Data definable properties.
ObstacleType obstacleType
Controls how features act as obstacles for labels.
const QgsPropertyCollection & dataDefinedProperties() const
Returns a reference to the label&#39;s property collection, used for data defined overrides.
bool displayAll
If true, all features will be labelled even when overlaps occur.
Label on left of point.
Offset distance applies from point geometry.
void setDataDefinedProperties(const QgsPropertyCollection &collection)
Sets the label&#39;s property collection, used for data defined overrides.
int fontMaxPixelSize
Maximum pixel size for showing rendered map unit labels (1 - 10000).
#define SIP_SKIP
Definition: qgis_sip.h:119
The QgsVectorLayerDiagramProvider class implements support for diagrams within the labeling engine...
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
QVector< QgsPointXY > cornerPoints
Arranges candidates in a circle around a point (or centroid of a polygon). Applies to point or polygo...
Upside-down labels (90 <= angle < 270) are shown upright.
OffsetType
Behavior modifier for label offset and distance, only applies in some label placement modes...
#define SIP_FACTORY
Definition: qgis_sip.h:69
Offset distance applies from rendered symbol bounds.
const QgsTextFormat & format() const
Returns the label text formatting settings, e.g., font settings, buffer settings, etc...
QMap< int, QgsPropertyDefinition > QgsPropertiesDefinition
Definition of available properties.
int maxNumLabels
The maximum number of labels which should be drawn for this layer.
Place direction symbols on above label.
Stores the settings for rendering of all diagrams for a layer.
bool plusSign
Whether &#39;+&#39; signs should be prepended to positive numeric labels.
unsigned int placementFlags
QString wrapChar
Wrapping character string.
Placement
Placement modes which determine how label candidates are generated for a feature. ...
#define SIP_PYARGREMOVE
Definition: qgis_sip.h:139
QString rightDirectionSymbol
String to use for right direction arrows.
The QgsLabelingEngine class provides map labeling functionality.
bool preserveRotation
True if label rotation should be preserved during label pin/unpin operations.
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.
bool centroidWhole
True if feature centroid should be calculated from the whole feature, or false if only the visible pa...
bool scaleVisibility
Set to true to limit label visibility to a range of scales.
The QgsLabelFeature class describes a feature that should be used within the labeling engine...
QgsGeometry extentGeom
QgsMapUnitScale distMapUnitScale
Map unit scale for label feature distance.
Struct for storing maximum and minimum scales for measurements in map units.
bool fitInPolygonOnly
True if only labels which completely fit within a polygon are allowed.
A collection of string replacements (specified using QgsStringReplacement objects).
OffsetType offsetType
Offset type for layer (only applies in certain placement modes)
double dist
Distance from feature to the label.
bool useSubstitutions
True if substitutions should be applied.
Label below point, slightly left of center.
Class for doing transforms between two map coordinate systems.
LabelPosition is a candidate feature label position.
Definition: labelposition.h:55
Label on top of point, slightly left of center.
A grouped map of multiple QgsProperty objects, each referenced by a integer key value.
Label on right of point.
bool limitNumLabels
True if the number of labels drawn should be limited.
bool isExpression
True if this label is made from a expression string, e.g., FieldName || &#39;mm&#39;.
Class that stores computed placement from labeling engine.
LinePlacementFlags
Line placement flags, which control how candidates are generated for a linear feature.
Show upside down when rotation is layer- or data-defined.
Container for all settings relating to text rendering.
bool centroidInside
True if centroid positioned labels must be placed inside their corresponding feature polygon...
QgsLabelPosition(int id, double r, const QVector< QgsPointXY > &corners, const QgsRectangle &rect, double w, double h, const QString &layer, const QString &labeltext, const QFont &labelfont, bool upside_down, bool diagram=false, bool pinned=false, const QString &providerId=QString())
Represents a vector layer which manages a vector based data sets.
double minFeatureSize
Minimum feature size (in millimeters) for a feature to be labelled.
int fontMinPixelSize
Minimum pixel size for showing rendered map unit labels (1 - 1000).
int priority
Label priority.
bool labelPerPart
True if every part of a multi-part feature should be labeled.
QgsUnitTypes::RenderUnit distUnits
Units the distance from feature to the label.
QgsMapUnitScale labelOffsetMapUnitScale
Map unit scale for label offset.
RenderUnit
Rendering size units.
Definition: qgsunittypes.h:111
QgsPropertyCollection & dataDefinedProperties()
Returns a reference to the label&#39;s property collection, used for data defined overrides.
double minimumScale
The minimum map scale (i.e.
QString fieldName
Name of field (or an expression) to use for label text.
bool fontLimitPixelSize
True if label sizes should be limited by pixel size.
ObstacleType
Valid obstacle types, which affect how features within the layer will act as obstacles for labels...
DirectionSymbols placeDirectionSymbol
Placement option for direction symbols.
Arranges candidates scattered throughout a polygon feature. Candidates are rotated to respect the pol...