33 static bool _palIsCanceled(
void *ctx )
35 return ( reinterpret_cast< QgsRenderContext * >( ctx ) )->renderingStopped();
48 : mMapSettings( mapSettings )
60 QStringList layerIds = mMapSettings.
layerIds();
63 if ( layer1Pos != layer2Pos && layer1Pos >= 0 && layer2Pos >= 0 )
64 return layer1Pos > layer2Pos;
67 return lf1->
size().width() * lf1->
size().height() > lf2->
size().width() * lf2->
size().height();
93 mResults->setMapSettings( mapSettings );
98 QList< QgsMapLayer * > layers;
101 QList< QgsAbstractLabelProvider * > providersByZ =
mProviders;
102 std::sort( providersByZ.begin(), providersByZ.end(),
108 if ( providerA && providerB )
115 QList< QgsAbstractLabelProvider * > subProvidersByZ =
mSubProviders;
116 std::sort( subProvidersByZ.begin(), subProvidersByZ.end(),
122 if ( providerA && providerB )
131 if ( provider->layer() && !layers.contains( provider->layer() ) )
132 layers << provider->layer();
136 if ( provider->layer() && !layers.contains( provider->layer() ) )
137 layers << provider->layer();
147 QList< QgsAbstractLabelProvider * > providersByZ =
mProviders;
148 std::sort( providersByZ.begin(), providersByZ.end(),
154 if ( providerA && providerB )
161 QList< QgsAbstractLabelProvider * > subProvidersByZ =
mSubProviders;
162 std::sort( subProvidersByZ.begin(), subProvidersByZ.end(),
168 if ( providerA && providerB )
177 if ( !layers.contains( provider->layerId() ) )
178 layers << provider->layerId();
182 if ( !layers.contains( provider->layerId() ) )
183 layers << provider->layerId();
205 QgsAbstractLabelProvider::Flags flags = provider->
flags();
242 const QList<QgsLabelFeature *> features = provider->
labelFeatures( context );
250 catch ( std::exception &e )
253 QgsDebugMsgLevel( QStringLiteral(
"Ignoring feature %1 due PAL exception:" ).arg( feature->id() ) + QString::fromLatin1( e.what() ), 4 );
271 mPal = qgis::make_unique< pal::Pal >();
282 std::unique_ptr< QgsExpressionContextScopePopper > layerScopePopper;
293 Q_ASSERT(
mPal.get() );
298 QPainter *painter = context.
painter();
302 visiblePoly.append( visiblePoly.at( 0 ) );
311 mapBoundaryGeom = mapBoundaryGeom.
difference( region.geometry );
320 properties.insert( QStringLiteral(
"style" ), QStringLiteral(
"no" ) );
321 properties.insert( QStringLiteral(
"style_border" ), QStringLiteral(
"solid" ) );
322 properties.insert( QStringLiteral(
"color_border" ), QStringLiteral(
"#0000ff" ) );
323 properties.insert( QStringLiteral(
"width_border" ), QStringLiteral(
"0.3" ) );
324 properties.insert( QStringLiteral(
"joinstyle" ), QStringLiteral(
"miter" ) );
326 boundarySymbol->startRender( context );
327 boundarySymbol->renderFeature( f, context );
328 boundarySymbol->stopRender( context );
341 mPal->registerCancellationCallback( &_palIsCanceled, reinterpret_cast< void * >( &context ) );
349 mProblem =
mPal->extractProblem( extent, mapBoundaryGeom );
351 catch ( std::exception &e )
354 QgsDebugMsgLevel(
"PAL EXCEPTION :-( " + QString::fromLatin1( e.what() ), 4 );
380 painter->setBrush( Qt::NoBrush );
381 for (
int i = 0; i < static_cast< int >(
mProblem->featureCount() ); i++ )
383 for (
int j = 0; j <
mProblem->featureCandidateCount( i ); j++ )
398 QgsDebugMsgLevel( QStringLiteral(
"LABELING work: %1 ms ... labels# %2" ).arg( t.elapsed() ).arg(
mLabels.size() ), 4 );
407 QPainter *painter = context.
painter();
408 painter->setRenderHint( QPainter::Antialiasing );
413 if ( !layerId.isEmpty() && provider->layerId() != layerId )
419 provider->startRender( context );
423 std::unique_ptr< QgsExpressionContextScopePopper > symbolScopePopper = qgis::make_unique< QgsExpressionContextScopePopper >( context.
expressionContext(), symbolScope );
503 symbolScopePopper.reset();
508 if ( !layerId.isEmpty() && provider->layerId() != layerId )
511 provider->stopRender( context );
515 painter->setCompositionMode( QPainter::CompositionMode_SourceOver );
517 QgsDebugMsgLevel( QStringLiteral(
"LABELING draw: %1 ms" ).arg( t.elapsed() ), 4 );
608 return mLayer ? mLayer->provider() :
nullptr;
613 : mLayerId( layer ? layer->id() : QString() )
615 , mProviderId( providerId )
616 , mFlags( DrawLabels )
638 subProvider->startRender( context );
647 subProvider->stopRender( context );
657 QStringList predefinedOrderString;
658 const auto constPositions = positions;
664 predefinedOrderString << QStringLiteral(
"TL" );
667 predefinedOrderString << QStringLiteral(
"TSL" );
670 predefinedOrderString << QStringLiteral(
"T" );
673 predefinedOrderString << QStringLiteral(
"TSR" );
676 predefinedOrderString << QStringLiteral(
"TR" );
679 predefinedOrderString << QStringLiteral(
"L" );
682 predefinedOrderString << QStringLiteral(
"R" );
685 predefinedOrderString << QStringLiteral(
"BL" );
688 predefinedOrderString << QStringLiteral(
"BSL" );
691 predefinedOrderString << QStringLiteral(
"B" );
694 predefinedOrderString << QStringLiteral(
"BSR" );
697 predefinedOrderString << QStringLiteral(
"BR" );
701 return predefinedOrderString.join(
',' );
706 QVector<QgsPalLayerSettings::PredefinedPointPosition> result;
707 const QStringList predefinedOrderList = positionString.split(
',' );
708 result.reserve( predefinedOrderList.size() );
709 for (
const QString &position : predefinedOrderList )
711 QString cleaned = position.trimmed().toUpper();
712 if ( cleaned == QLatin1String(
"TL" ) )
714 else if ( cleaned == QLatin1String(
"TSL" ) )
716 else if ( cleaned == QLatin1String(
"T" ) )
718 else if ( cleaned == QLatin1String(
"TSR" ) )
720 else if ( cleaned == QLatin1String(
"TR" ) )
722 else if ( cleaned == QLatin1String(
"L" ) )
724 else if ( cleaned == QLatin1String(
"R" ) )
726 else if ( cleaned == QLatin1String(
"BL" ) )
728 else if ( cleaned == QLatin1String(
"BSL" ) )
730 else if ( cleaned == QLatin1String(
"B" ) )
732 else if ( cleaned == QLatin1String(
"BSR" ) )
734 else if ( cleaned == QLatin1String(
"BR" ) )
744 parts << QStringLiteral(
"OL" );
746 parts << QStringLiteral(
"AL" );
748 parts << QStringLiteral(
"BL" );
750 parts << QStringLiteral(
"LO" );
751 return parts.join(
',' );
756 QgsLabeling::LinePlacementFlags
flags =
nullptr;
757 const QStringList flagList =
string.split(
',' );
758 bool foundLineOrientationFlag =
false;
759 for (
const QString &flag : flagList )
761 QString cleaned = flag.trimmed().toUpper();
762 if ( cleaned == QLatin1String(
"OL" ) )
764 else if ( cleaned == QLatin1String(
"AL" ) )
766 else if ( cleaned == QLatin1String(
"BL" ) )
768 else if ( cleaned == QLatin1String(
"LO" ) )
769 foundLineOrientationFlag =
true;
771 if ( !foundLineOrientationFlag )
Label on bottom right of point.
void setSymbol(const QgsSymbol *symbol)
Sets the feature symbol associated with this label.
void processProvider(QgsAbstractLabelProvider *provider, QgsRenderContext &context, pal::Pal &p)
static QgsExpressionContextScope * updateSymbolScope(const QgsSymbol *symbol, QgsExpressionContextScope *symbolScope=nullptr)
Updates a symbol scope related to a QgsSymbol to an expression context.
QList< pal::LabelPosition * > mLabels
Layer * addLayer(QgsAbstractLabelProvider *provider, const QString &layerName, QgsPalLayerSettings::Placement arrangement, double defaultPriority, bool active, bool toLabel, bool displayAll=false)
add a new layer
std::unique_ptr< pal::Pal > mPal
double convertToMapUnits(double size, QgsUnitTypes::RenderUnit unit, const QgsMapUnitScale &scale=QgsMapUnitScale()) const
Converts a size from the specified units to map units.
A rectangle specified with double values.
Base class for all map layer types.
Label on bottom-left of point.
Label on top of point, slightly left of center.
virtual void drawLabelBackground(QgsRenderContext &context, pal::LabelPosition *label) const
Draw the background for the specified label.
void setMapRotation(double degrees, double cx, double cy)
Set map rotation in degrees (clockwise)
void addProvider(QgsAbstractLabelProvider *provider)
Add provider of label features. Takes ownership of the provider.
QList< QgsAbstractLabelProvider * > mProviders
List of providers (the are owned by the labeling engine)
void removeProvider(QgsAbstractLabelProvider *provider)
Remove provider if the provider's initialization failed. Provider instance is deleted.
QgsLabelFeature * feature()
Returns the parent feature.
double rotation() const
Returns the rotation of the resulting map image, in degrees clockwise.
QgsDefaultLabelingEngine()
Construct the labeling engine with default settings.
QStringList layerIds() const
Gets list of layer IDs for map rendering The layers are stored in the reverse order of how they are r...
QgsAbstractLabelProvider * provider() const
Returns provider of this instance.
Label on top-left of point.
QgsAbstractLabelProvider(QgsMapLayer *layer, const QString &providerId=QString())
Construct the provider with default values.
void setFeature(const QgsFeature &feature)
Convenience function for setting a feature for the context.
QStringList participatingLayerIds() const
Returns a list of layer IDs for layers with providers in the engine.
static void drawLabelCandidateRect(pal::LabelPosition *lp, QPainter *painter, const QgsMapToPixel *xform, QList< QgsLabelCandidate > *candidates=nullptr)
A set of features which influence the labeling process.
PredefinedPointPosition
Positions for labels when using the QgsPalLabeling::OrderedPositionsAroundPoint placement mode...
void drawLabels(QgsRenderContext &context, const QString &layerId=QString())
Draws labels to the specified render context.
static QgsFillSymbol * createSimple(const QgsStringMap &properties)
Create a fill symbol with one symbol layer: SimpleFill with specified properties. ...
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
OperationResult rotate(double rotation, const QgsPointXY ¢er)
Rotate this geometry around the Z axis.
const QgsSymbol * symbol()
Returns the feature symbol associated with this label.
Whether to use also label candidates that are partially outside of the map view.
QgsLabelingEngine()
Construct the labeling engine with default settings.
QList< QgsAbstractLabelProvider * > mSubProviders
bool renderingStopped() const
Returns true if the rendering operation has been stopped and any ongoing rendering should be canceled...
static QgsLabeling::LinePlacementFlags decodeLinePlacementFlags(const QString &string)
Decodes a string to set of line placement flags.
Label on top-right of point.
The QgsVectorLayerLabelProvider class implements a label provider for vector layers.
void setMapSettings(const QgsMapSettings &mapSettings)
Associate map settings instance.
A geometry is the spatial representation of a feature.
void setUpsidedownLabels(UpsideDownLabels ud)
Sets how upside down labels will be handled within the layer.
QList< pal::LabelPosition * > mUnlabeled
QgsFeature feature() const
Returns the original feature associated with this label.
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
virtual QList< QgsLabelFeature * > labelFeatures(QgsRenderContext &context)=0
Returns list of label features (they are owned by the provider and thus deleted on its destruction) ...
QMap< QString, QString > QgsStringMap
Labels can be placed directly over a line feature.
QgsRectangle visibleExtent() const
Returns the actual extent derived from requested extent that takes takes output image size into accou...
void setCentroidInside(bool forceInside)
Sets whether labels placed at the centroid of features within the layer are forced to be placed insid...
Labels can be placed above a line feature. Unless MapOrientation is also specified this mode respects...
double zIndex
Z-Index of label, where labels with a higher z-index are rendered on top of labels with a lower z-ind...
void finalize()
Finalizes and cleans up the engine following the rendering of labels for the last layer to be labeled...
Whether adjacent lines (with the same label text) should be merged.
The QgsMapSettings class contains configuration for rendering of the map.
Perform transforms between map coordinates and device coordinates.
Whether to draw all labels even if there would be collisions.
static QgsGeometry fromRect(const QgsRectangle &rect)
Creates a new geometry from a QgsRectangle.
QgsGeometry labelBoundaryGeometry() const
Returns the label boundary geometry, which restricts where in the rendered map labels are permitted t...
double zIndex() const
Returns the label's z-index.
Whether to render unplaced labels as an indicator/warning for users.
void renderLabelsForLayer(QgsRenderContext &context, const QString &layerId)
Renders all the labels which belong only to the layer with matching layerId to the specified render c...
double maximumPolygonCandidatesPerCmSquared() const
Returns the maximum number of polygon label candidate positions per centimeter squared.
FeaturePart * getFeaturePart() const
Returns the feature corresponding to this labelposition.
QgsStagedRenderLabelingEngine()
Construct the labeling engine with default settings.
#define QgsDebugMsgLevel(str, level)
Show upside down for all labels, including dynamic ones.
double maximumLineCandidatesPerCm() const
Returns the maximum number of line label candidate positions per centimeter.
virtual void drawUnplacedLabel(QgsRenderContext &context, pal::LabelPosition *label) const
Draw an unplaced label.
bool operator()(pal::LabelPosition *lp1, pal::LabelPosition *lp2) const
const QgsPalLayerSettings & settings() const
Returns the layer's settings.
Whether location of centroid must be inside of polygons.
void setObstacleType(QgsLabelObstacleSettings::ObstacleType obstacleType)
Sets the obstacle type, which controls how features within the layer act as obstacles for labels...
Upside-down labels (90 <= angle < 270) are shown upright.
QList< QgsMapLayer *> participatingLayers() const
Returns a list of layers with providers in the engine.
Label below point, slightly right of center.
Whether all features will be labelled even though overlaps occur.
Label blocking region (in map coordinates and CRS).
Single scope for storing variables and functions for use within a QgsExpressionContext.
void cleanup()
Cleans up the engine following a call to registerLabels() or solve().
QgsPalLayerSettings::Placement placement() const
What placement strategy to use for the labels.
const QgsMapToPixel & mapToPixel() const
The QgsAbstractLabelProvider class is an interface class.
Whether to draw rectangles of generated candidates (good for debugging)
void setFields(const QgsFields &fields)
Convenience function for setting a fields for the context.
QString layerId() const
Returns ID of associated layer, or empty string if no layer is associated with the provider...
QgsPalLayerSettings::UpsideDownLabels upsidedownLabels() const
How to handle labels that would be upside down.
QgsLabelObstacleSettings::ObstacleType obstacleType() const
How the feature geometries will work as obstacles.
QgsLabelSorter(const QgsMapSettings &mapSettings)
QgsExpressionContext & expressionContext()
Gets the expression context.
virtual ~QgsLabelingEngine()
Clean up everything (especially the registered providers)
bool registerFeature(QgsLabelFeature *label)
Register a feature in the layer.
Flags flags() const
Flags associated with the provider.
static QString encodePredefinedPositionOrder(const QVector< QgsPalLayerSettings::PredefinedPointPosition > &positions)
Encodes an ordered list of predefined point label positions to a string.
The QgsLabelingEngine class provides map labeling functionality.
virtual QList< QgsAbstractLabelProvider * > subProviders()
Returns list of child providers - useful if the provider needs to put labels into more layers with di...
Contains information about the context of a rendering operation.
Signifies that the AboveLine and BelowLine flags should respect the map's orientation rather than the...
std::unique_ptr< pal::Problem > mProblem
void run(QgsRenderContext &context) override
Runs the labeling job.
QPainter * painter()
Returns the destination QPainter for the render operation.
The QgsLabelFeature class describes a feature that should be used within the labeling engine...
QString name() const
Name of the layer (for statistics, debugging etc.) - does not need to be unique.
std::unique_ptr< QgsLabelingResults > mResults
Resulting labeling layout.
Label below point, slightly left of center.
PlacementEngineVersion placementVersion() const
Returns the placement engine version, which dictates how the label placement problem is solved...
QgsMapSettings mMapSettings
Associated map settings instance.
QgsLabelingResults * takeResults()
Returns pointer to recently computed results and pass the ownership of results to the caller...
Stores global configuration for labeling engine.
Label on top of point, slightly right of center.
const QgsMapSettings & mapSettings() const
Gets associated map settings.
QgsRectangle boundingBox() const
Returns the bounding box of the geometry.
Label directly below point.
Helper class for sorting labels into correct draw order.
void setGeometry(const QgsGeometry &geometry)
Set the feature's geometry.
double priority() const
Default priority of labels (may be overridden by individual labels)
QSizeF size(double angle=0.0) const
Size of the label (in map units)
bool testFlag(Flag f) const
Test whether a particular flag is enabled.
static QgsGeometry fromQPolygonF(const QPolygonF &polygon)
Construct geometry from a QPolygonF.
LabelPosition is a candidate feature label position.
virtual void startRender(QgsRenderContext &context)
To be called before rendering of labels begins.
Label directly above point.
Whether the labels should be rendered.
Class that stores computed placement from labeling engine.
QPolygonF visiblePolygon() const
Returns the visible area as a polygon (may be rotated)
static QVector< QgsPalLayerSettings::PredefinedPointPosition > decodePredefinedPositionOrder(const QString &positionString)
Decodes a string to an ordered list of predefined point label positions.
QgsPointXY center() const
Returns the center point of the rectangle.
static QgsExpressionContextScope * layerScope(const QgsMapLayer *layer)
Creates a new scope which contains variables and functions relating to a QgsMapLayer.
Show upside down when rotation is layer- or data-defined.
virtual void drawLabel(QgsRenderContext &context, pal::LabelPosition *label) const =0
Draw this label at the position determined by the labeling engine.
virtual void stopRender(QgsRenderContext &context)
To be called after rendering is complete.
void solve(QgsRenderContext &context)
Solves the label problem.
Labels can be placed below a line feature. Unless MapOrientation is also specified this mode respects...
QList< QgsLabelBlockingRegion > labelBlockingRegions() const
Returns the list of regions to avoid placing labels within.
RAII class to pop scope from an expression context on destruction.
void registerLabels(QgsRenderContext &context)
Runs the label registration step.
void setEngine(const QgsLabelingEngine *engine)
Associate provider with a labeling engine (should be only called internally from QgsLabelingEngine) ...
void run(QgsRenderContext &context) override
Runs the labeling job.
const QgsLabelingEngineSettings & labelingEngineSettings() const
Returns the global configuration of the labeling engine.
void setMergeConnectedLines(bool merge)
Sets whether connected lines should be merged before labeling.
static QString encodeLinePlacementFlags(QgsLabeling::LinePlacementFlags flags)
Encodes line placement flags to a string.
QgsGeometry difference(const QgsGeometry &geometry) const
Returns a geometry representing the points making up this geometry that do not make up other...