32 static bool _palIsCanceled(
void *ctx )
34 return ( reinterpret_cast< QgsRenderContext * >( ctx ) )->renderingStopped();
47 : mMapSettings( mapSettings )
59 QStringList layerIds = mMapSettings.
layerIds();
62 if ( layer1Pos != layer2Pos && layer1Pos >= 0 && layer2Pos >= 0 )
63 return layer1Pos > layer2Pos;
66 return lf1->
size().width() * lf1->
size().height() > lf2->
size().width() * lf2->
size().height();
89 mResults->setMapSettings( mapSettings );
94 QSet< QgsMapLayer * > layers;
97 if ( provider->layer() )
98 layers << provider->layer();
102 if ( provider->layer() )
103 layers << provider->layer();
105 return layers.toList();
125 QgsAbstractLabelProvider::Flags flags = provider->
flags();
165 const QList<QgsLabelFeature *> features = provider->
labelFeatures( context );
173 catch ( std::exception &e )
176 QgsDebugMsgLevel( QStringLiteral(
"Ignoring feature %1 due PAL exception:" ).arg( feature->id() ) + QString::fromLatin1( e.what() ), 4 );
218 int candPoint, candLine, candPolygon;
230 bool appendedLayerScope =
false;
233 appendedLayerScope =
true;
237 if ( appendedLayerScope )
244 QPainter *painter = context.
painter();
248 visiblePoly.append( visiblePoly.at( 0 ) );
257 mapBoundaryGeom = mapBoundaryGeom.
difference( region.geometry );
266 properties.insert( QStringLiteral(
"style" ), QStringLiteral(
"no" ) );
267 properties.insert( QStringLiteral(
"style_border" ), QStringLiteral(
"solid" ) );
268 properties.insert( QStringLiteral(
"color_border" ), QStringLiteral(
"#0000ff" ) );
269 properties.insert( QStringLiteral(
"width_border" ), QStringLiteral(
"0.3" ) );
270 properties.insert( QStringLiteral(
"joinstyle" ), QStringLiteral(
"miter" ) );
272 boundarySymbol->startRender( context );
273 boundarySymbol->renderFeature( f, context );
274 boundarySymbol->stopRender( context );
293 std::unique_ptr< pal::Problem > problem;
298 catch ( std::exception &e )
301 QgsDebugMsgLevel(
"PAL EXCEPTION :-( " + QString::fromLatin1( e.what() ), 4 );
327 painter->setBrush( Qt::NoBrush );
328 for (
int i = 0; i < problem->getNumFeatures(); i++ )
330 for (
int j = 0; j < problem->getFeatureCandidateCount( i ); j++ )
342 QgsDebugMsgLevel( QStringLiteral(
"LABELING work: %1 ms ... labels# %2" ).arg( t.elapsed() ).arg( labels.size() ), 4 );
349 painter->setRenderHint( QPainter::Antialiasing );
370 painter->setCompositionMode( QPainter::CompositionMode_SourceOver );
372 QgsDebugMsgLevel( QStringLiteral(
"LABELING draw: %1 ms" ).arg( t.elapsed() ), 4 );
385 return mLayer ? mLayer->provider() :
nullptr;
390 : mLayerId( layer ? layer->id() : QString() )
392 , mProviderId( providerId )
393 , mFlags( DrawLabels )
408 QStringList predefinedOrderString;
409 const auto constPositions = positions;
415 predefinedOrderString << QStringLiteral(
"TL" );
418 predefinedOrderString << QStringLiteral(
"TSL" );
421 predefinedOrderString << QStringLiteral(
"T" );
424 predefinedOrderString << QStringLiteral(
"TSR" );
427 predefinedOrderString << QStringLiteral(
"TR" );
430 predefinedOrderString << QStringLiteral(
"L" );
433 predefinedOrderString << QStringLiteral(
"R" );
436 predefinedOrderString << QStringLiteral(
"BL" );
439 predefinedOrderString << QStringLiteral(
"BSL" );
442 predefinedOrderString << QStringLiteral(
"B" );
445 predefinedOrderString << QStringLiteral(
"BSR" );
448 predefinedOrderString << QStringLiteral(
"BR" );
452 return predefinedOrderString.join(
',' );
457 QVector<QgsPalLayerSettings::PredefinedPointPosition> result;
458 const QStringList predefinedOrderList = positionString.split(
',' );
459 result.reserve( predefinedOrderList.size() );
460 for (
const QString &position : predefinedOrderList )
462 QString cleaned = position.trimmed().toUpper();
463 if ( cleaned == QLatin1String(
"TL" ) )
465 else if ( cleaned == QLatin1String(
"TSL" ) )
467 else if ( cleaned == QLatin1String(
"T" ) )
469 else if ( cleaned == QLatin1String(
"TSR" ) )
471 else if ( cleaned == QLatin1String(
"TR" ) )
473 else if ( cleaned == QLatin1String(
"L" ) )
475 else if ( cleaned == QLatin1String(
"R" ) )
477 else if ( cleaned == QLatin1String(
"BL" ) )
479 else if ( cleaned == QLatin1String(
"BSL" ) )
481 else if ( cleaned == QLatin1String(
"B" ) )
483 else if ( cleaned == QLatin1String(
"BSR" ) )
485 else if ( cleaned == QLatin1String(
"BR" ) )
495 parts << QStringLiteral(
"OL" );
497 parts << QStringLiteral(
"AL" );
499 parts << QStringLiteral(
"BL" );
501 parts << QStringLiteral(
"LO" );
502 return parts.join(
',' );
507 pal::LineArrangementFlags
flags =
nullptr;
508 const QStringList flagList =
string.split(
',' );
509 bool foundLineOrientationFlag =
false;
510 for (
const QString &flag : flagList )
512 QString cleaned = flag.trimmed().toUpper();
513 if ( cleaned == QLatin1String(
"OL" ) )
515 else if ( cleaned == QLatin1String(
"AL" ) )
517 else if ( cleaned == QLatin1String(
"BL" ) )
519 else if ( cleaned == QLatin1String(
"LO" ) )
520 foundLineOrientationFlag =
true;
522 if ( !foundLineOrientationFlag )
Label on bottom right of point.
void processProvider(QgsAbstractLabelProvider *provider, QgsRenderContext &context, pal::Pal &p)
Layer * addLayer(QgsAbstractLabelProvider *provider, const QString &layerName, QgsPalLayerSettings::Placement arrangement, double defaultPriority, bool active, bool toLabel, bool displayAll=false)
add a new layer
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.
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.
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 registerCancellationCallback(FnIsCanceled fnCanceled, void *context)
Register a function that returns whether this job has been canceled - PAL calls it during the computa...
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...
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.
QgsPalLayerSettings::ObstacleType obstacleType() const
How the feature geometries will work as obstacles.
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...
Is slower and best than TABU, worse and faster than TABU_CHAIN.
Label on top-right of point.
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.
void setShowPartial(bool show)
Set flag show partial label.
Whether to label each part of multi-part features separately.
FeaturePart * getFeaturePart()
Returns the feature corresponding to this labelposition.
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) ...
void setObstacleType(QgsPalLayerSettings::ObstacleType obstacleType)
Sets the obstacle type, which controls how features within the layer act as obstacles for labels...
QMap< QString, QString > QgsStringMap
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...
Is a little bit better than CHAIN but slower.
Whether adjacent lines (with the same label text) should be merged.
std::unique_ptr< Problem > extractProblem(const QgsRectangle &extent, const QgsGeometry &mapBoundary)
Extracts the labeling problem for the specified map extent - only features within this extent will be...
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...
static pal::LineArrangementFlags decodeLinePlacementFlags(const QString &string)
Decodes a string to set of line placement flags.
double zIndex() const
Returns the label's z-index.
#define QgsDebugMsgLevel(str, level)
Show upside down for all labels, including dynamic ones.
bool operator()(pal::LabelPosition *lp1, pal::LabelPosition *lp2) const
void setPointP(int point_p)
set # candidates to generate for points features Higher the value is, longer Pal::labeller will spend...
Whether location of centroid must be inside of polygons.
void setLineP(int line_p)
set maximum # candidates to generate for lines features Higher the value is, longer Pal::labeller wil...
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).
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)
static QString encodeLinePlacementFlags(pal::LineArrangementFlags flags)
Encodes line placement flags to a string.
QString layerId() const
Returns ID of associated layer, or empty string if no layer is associated with the provider...
QSizeF size() const
Size of the label (in map units)
QgsPalLayerSettings::UpsideDownLabels upsidedownLabels() const
How to handle labels that would be upside down.
void numCandidatePositions(int &candPoint, int &candLine, int &candPolygon) const
Gets number of candidate positions that will be generated for each label feature (default to 8) ...
QgsLabelSorter(const QgsMapSettings &mapSettings)
QgsExpressionContext & expressionContext()
Gets the expression context.
~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.
void run(QgsRenderContext &context)
compute the labeling with given map settings and providers
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.
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.
void setPolyP(int poly_p)
set maximum # candidates to generate for polygon features Higher the value is, longer Pal::labeller w...
Label below point, slightly left of center.
QgsMapSettings mMapSettings
Associated map settings instance.
QgsLabelingResults * takeResults()
Returns pointer to recently computed results and pass the ownership of results to the caller...
void appendScope(QgsExpressionContextScope *scope)
Appends a scope to the end of the context.
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.
QList< LabelPosition * > solveProblem(Problem *prob, bool displayAll)
void setLabelMode(LabelMode mode)
Sets the layer's labeling mode.
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)
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.
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.
SearchMethod
Search method to use.
QgsExpressionContextScope * popScope()
Removes the last scope from the expression context and return it.
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
Is the worst but fastest method.
QList< QgsLabelBlockingRegion > labelBlockingRegions() const
Returns the list of regions to avoid placing labels within.
void setSearch(SearchMethod method)
Select the search method to use.
void setEngine(const QgsLabelingEngine *engine)
Associate provider with a labeling engine (should be only called internally from QgsLabelingEngine) ...
Search searchMethod() const
Which search method to use for removal collisions between labels.
const QgsLabelingEngineSettings & labelingEngineSettings() const
Returns the global configuration of the labeling engine.
Flags flags() const
Gets flags of the labeling engine.
void setMergeConnectedLines(bool merge)
Sets whether connected lines should be merged before labeling.
QgsGeometry difference(const QgsGeometry &geometry) const
Returns a geometry representing the points making up this geometry that do not make up other...