53   mGlobalCandidatesLimitPoint = settings.
value( QStringLiteral( 
"rendering/label_candidates_limit_points" ), 0, 
QgsSettings::Core ).toInt();
    54   mGlobalCandidatesLimitLine = settings.
value( QStringLiteral( 
"rendering/label_candidates_limit_lines" ), 0, 
QgsSettings::Core ).toInt();
    55   mGlobalCandidatesLimitPolygon = settings.
value( QStringLiteral( 
"rendering/label_candidates_limit_polygons" ), 0, 
QgsSettings::Core ).toInt();
    67   for ( 
auto it = mLayers.begin(); it != mLayers.end(); ++it )
    69     if ( it->second.get() == layer )
    82   Q_ASSERT( mLayers.find( provider ) == mLayers.end() );
    84   std::unique_ptr< Layer > layer = qgis::make_unique< Layer >( provider, layerName, arrangement, defaultPriority, active, toLabel, 
this, displayAll );
    85   Layer *res = layer.get();
   102   std::vector< FeaturePart * > allObstacleParts;
   103   std::unique_ptr< Problem > prob = qgis::make_unique< Problem >( maxCoordinateExtentForSpatialIndices );
   108   bbx[0] = bbx[3] = prob->mMapExtentBounds[0] = extent.
xMinimum();
   109   bby[0] = bby[1] = prob->mMapExtentBounds[1] = extent.
yMinimum();
   110   bbx[1] = bbx[2] = prob->mMapExtentBounds[2] = extent.
xMaximum();
   111   bby[2] = bby[3] = prob->mMapExtentBounds[3] = extent.
yMaximum();
   115   std::list< std::unique_ptr< Feats > > features;
   121   int obstacleCount = 0;
   125   std::size_t previousFeatureCount = 0;
   126   int previousObstacleCount = 0;
   128   QStringList layersWithFeaturesInBBox;
   130   QMutexLocker palLocker( &mMutex );
   131   for ( 
const auto &it : mLayers )
   133     Layer *layer = it.second.get();
   156     QMutexLocker locker( &layer->
mMutex );
   165       for ( 
int i = 0; i < featurePart->getNumSelfObstacles(); i++ )
   169         allObstacleParts.emplace_back( selfObstacle );
   171         if ( !featurePart->getSelfObstacle( i )->getHoleOf() )
   178       std::vector< std::unique_ptr< LabelPosition > > candidates = featurePart->createCandidates( 
this );
   184       candidates.erase( std::remove_if( candidates.begin(), candidates.end(), [&mapBoundaryPrepared, 
this]( std::unique_ptr< LabelPosition > &candidate )
   187           return !candidate->intersects( mapBoundaryPrepared.get() );
   189           return !candidate->within( mapBoundaryPrepared.get() );
   190       } ), candidates.end() );
   195       if ( !candidates.empty() )
   197         for ( std::unique_ptr< LabelPosition > &candidate : candidates )
   199           candidate->insertIntoIndex( allCandidatesFirstRound );
   205         std::unique_ptr< Feats > ft = qgis::make_unique< Feats >();
   206         ft->feature = featurePart;
   208         ft->candidates = std::move( candidates );
   209         ft->priority = featurePart->calculatePriority();
   210         features.emplace_back( std::move( ft ) );
   215         std::unique_ptr< LabelPosition > unplacedPosition = featurePart->createCandidatePointOnSurface( featurePart );
   216         if ( unplacedPosition )
   217           prob->positionsWithNoCandidates()->emplace_back( std::move( unplacedPosition ) );
   230       obstacles.
insert( obstaclePart, obstaclePart->boundingBox() );
   231       allObstacleParts.emplace_back( obstaclePart );
   240     if ( features.size() - previousFeatureCount > 0 || obstacleCount > previousObstacleCount )
   242       layersWithFeaturesInBBox << layer->
name();
   244     previousFeatureCount = features.size();
   245     previousObstacleCount = obstacleCount;
   252   prob->mLayerCount = layersWithFeaturesInBBox.size();
   253   prob->labelledLayersName = layersWithFeaturesInBBox;
   255   prob->mFeatureCount = features.size();
   256   prob->mTotalCandidates = 0;
   257   prob->mFeatNbLp.resize( prob->mFeatureCount );
   258   prob->mFeatStartId.resize( prob->mFeatureCount );
   259   prob->mInactiveCost.resize( prob->mFeatureCount );
   261   if ( !features.empty() )
   264     for ( 
FeaturePart *obstaclePart : allObstacleParts )
   269       allCandidatesFirstRound.
intersects( obstaclePart->boundingBox(), [obstaclePart, 
this]( 
const LabelPosition * candidatePosition ) -> 
bool   276         if ( ( !obstaclePart->getHoleOf() && candidatePosition->getFeaturePart()->hasSameLabelFeatureAs( obstaclePart ) )
   277              || ( obstaclePart->getHoleOf() && !candidatePosition->getFeaturePart()->hasSameLabelFeatureAs( dynamic_cast< FeaturePart * >( obstaclePart->getHoleOf() ) ) ) )
   294     for ( std::size_t i = 0; i < prob->mFeatureCount; i++ ) 
   296       std::unique_ptr< Feats > feat = std::move( features.front() );
   297       features.pop_front();
   299       prob->mFeatStartId[i] = idlp;
   300       prob->mInactiveCost[i] = std::pow( 2, 10 - 10 * feat->priority );
   302       std::size_t maxCandidates = 0;
   303       switch ( feat->feature->getGeosType() )
   307           maxCandidates = feat->feature->maximumPointCandidates();
   310         case GEOS_LINESTRING:
   311           maxCandidates = feat->feature->maximumLineCandidates();
   315           maxCandidates = feat->feature->maximumPolygonCandidates();
   322       switch ( mPlacementVersion )
   333           feat->candidates.erase( std::remove_if( feat->candidates.begin() + 1, feat->candidates.end(), [ & ]( std::unique_ptr< LabelPosition > &candidate )
   335             if ( candidate->hasHardObstacleConflict() )
   340           } ), feat->candidates.end() );
   342           if ( feat->candidates.size() == 1 && feat->candidates[ 0 ]->hasHardObstacleConflict() )
   346             prob->positionsWithNoCandidates()->emplace_back( std::move( feat->candidates.front() ) );
   347             feat->candidates.clear();
   352       if ( feat->candidates.empty() )
   362       if ( maxCandidates > 0 && feat->candidates.size() > maxCandidates )
   364         feat->candidates.resize( maxCandidates );
   371       prob->mFeatNbLp[i] = 
static_cast< int >( feat->candidates.size() );
   372       prob->mTotalCandidates += 
static_cast< int >( feat->candidates.size() );
   375       for ( std::unique_ptr< LabelPosition > &candidate : feat->candidates )
   377         candidate->insertIntoIndex( prob->allCandidatesIndex() );
   378         candidate->setProblemIds( static_cast< int >( i ), idlp++ );
   380       features.emplace_back( std::move( feat ) );
   387     while ( !features.empty() ) 
   392       std::unique_ptr< Feats > feat = std::move( features.front() );
   393       features.pop_front();
   395       for ( std::unique_ptr< LabelPosition > &candidate : feat->candidates )
   397         std::unique_ptr< LabelPosition > lp = std::move( candidate );
   399         lp->resetNumOverlaps();
   407         lp->getBoundingBox( amin, amax );
   408         prob->allCandidatesIndex().intersects( 
QgsRectangle( amin[0], amin[1], amax[0], amax[1] ), [&lp]( 
const LabelPosition * lp2 )->
bool   410           if ( lp->isInConflict( lp2 ) )
   412             lp->incrementNumOverlaps();
   419         nbOverlaps += lp->getNumOverlaps();
   421         prob->addCandidatePosition( std::move( lp ) );
   428     prob->mAllNblp = prob->mTotalCandidates;
   429     prob->mNbOverlap = nbOverlaps;
   437   fnIsCanceled = fnCanceled;
   438   fnIsCanceledContext = context;
   443   return extract( extent, mapBoundary );
   449     return QList<LabelPosition *>();
   459     return QList<LabelPosition *>();
   465 void Pal::setMinIt( 
int min_it )
   471 void Pal::setMaxIt( 
int max_it )
   477 void Pal::setPopmusicR( 
int r )
   483 void Pal::setEjChainDeg( 
int degree )
   485   this->mEjChainDeg = degree;
   488 void Pal::setTenure( 
int tenure )
   490   this->mTenure = tenure;
   493 void Pal::setCandListSize( 
double fact )
   495   this->mCandListSize = fact;
   500   this->mShowPartialLabels = show;
   505   return mPlacementVersion;
   525   return mShowPartialLabels;
 static void addObstacleCostPenalty(pal::LabelPosition *lp, pal::FeaturePart *obstacle, Pal *pal)
Increase candidate's cost according to its collision with passed feature. 
 
Layer * addLayer(QgsAbstractLabelProvider *provider, const QString &layerName, QgsPalLayerSettings::Placement arrangement, double defaultPriority, bool active, bool toLabel, bool displayAll=false)
add a new layer 
 
QList< FeaturePart * > mObstacleParts
List of obstacle parts. 
 
static bool candidateSortGrow(const std::unique_ptr< pal::LabelPosition > &c1, const std::unique_ptr< pal::LabelPosition > &c2)
Sorts label candidates in ascending order of cost. 
 
A rectangle specified with double values. 
 
bool mergeConnectedLines() const
Returns whether connected lines will be merged before labeling. 
 
bool showPartialLabels() const
Returns whether partial labels should be allowed. 
 
This class is a composition of two QSettings instances: 
 
Version 1, matches placement from QGIS <= 3.10.1. 
 
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key. 
 
std::unique_ptr< const GEOSPreparedGeometry, GeosDeleter > prepared_unique_ptr
Scoped GEOS prepared geometry pointer. 
 
void registerCancellationCallback(FnIsCanceled fnCanceled, void *context)
Register a function that returns whether this job has been canceled - PAL calls it during the computa...
 
A set of features which influence the labeling process. 
 
void chopFeaturesAtRepeatDistance()
Chop layer features at the repeat distance *. 
 
A geometry is the spatial representation of a feature. 
 
void setPlacementVersion(QgsLabelingEngineSettings::PlacementEngineVersion placementVersion)
Sets the placement engine version, which dictates how the label placement problem is solved...
 
A rtree spatial index for use in the pal labeling engine. 
 
static GEOSContextHandle_t getGEOSHandler()
 
void removeLayer(Layer *layer)
remove a layer 
 
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...
 
bool intersects(const QgsRectangle &bounds, const std::function< bool(T *data)> &callback) const
Performs an intersection check against the index, for data intersecting the specified bounds...
 
QgsRectangle buffered(double width) const
Gets rectangle enlarged by buffer. 
 
Version 2 (default for new projects since QGIS 3.12) 
 
void chain_search()
Test with very-large scale neighborhood. 
 
bool(* FnIsCanceled)(void *ctx)
 
void joinConnectedFeatures()
Join connected features with the same label text. 
 
double width() const
Returns the width of the rectangle. 
 
QgsLabelingEngineSettings::PlacementEngineVersion placementVersion() const
Returns the placement engine version, which dictates how the label placement problem is solved...
 
bool isCanceled()
Check whether the job has been canceled. 
 
std::unique_ptr< GEOSGeometry, GeosDeleter > unique_ptr
Scoped GEOS pointer. 
 
Main class to handle feature. 
 
The QgsAbstractLabelProvider class is an interface class. 
 
Pal()
Create an new pal instance. 
 
double yMinimum() const
Returns the y minimum value (bottom side of rectangle). 
 
double xMaximum() const
Returns the x maximum value (right side of rectangle). 
 
Placement
Placement modes which determine how label candidates are generated for a feature. ...
 
QgsRectangle boundingBox() const
Returns the point set bounding box. 
 
static geos::unique_ptr asGeos(const QgsGeometry &geometry, double precision=0)
Returns a geos geometry - caller takes ownership of the object (should be deleted with GEOSGeom_destr...
 
QLinkedList< FeaturePart * > mFeatureParts
List of feature parts. 
 
FeaturePart * getSelfObstacle(int i)
Gets hole (inner ring) - considered as obstacle. 
 
QString name() const
Returns the layer's name. 
 
bool active() const
Returns whether the layer is currently active. 
 
LabelPosition is a candidate feature label position. 
 
double xMinimum() const
Returns the x minimum value (left side of rectangle). 
 
Representation of a labeling problem. 
 
double yMaximum() const
Returns the y maximum value (top side of rectangle). 
 
QList< LabelPosition * > solveProblem(Problem *prob, bool displayAll, QList< pal::LabelPosition *> *unlabeled=nullptr)
Solves the labeling problem, selecting the best candidate locations for all labels and returns a list...
 
QList< LabelPosition * > getSolution(bool returnInactive, QList< LabelPosition *> *unlabeled=nullptr)
Solves the labeling problem, selecting the best candidate locations for all labels and returns a list...
 
void insert(T *data, const QgsRectangle &bounds)
Inserts new data into the spatial index, with the specified bounds. 
 
PlacementEngineVersion
Placement engine version. 
 
static void finalizeCandidatesCosts(Feats *feat, double bbx[4], double bby[4])
Sort candidates by costs, skip the worse ones, evaluate polygon candidates. 
 
Thrown when trying to access an empty data set. 
 
double height() const
Returns the height of the rectangle. 
 
void setShowPartialLabels(bool show)
Sets whether partial labels show be allowed.