46   : mProvider( provider )
 
   50   , mLabelLayer( toLabel )
 
   51   , mDisplayAll( displayAll )
 
   52   , mCentroidInside( false )
 
   53   , mArrangement( arrangement )
 
   54   , mMergeLines( false )
 
   55   , mUpsidedownLabels( Upright )
 
   57   if ( defaultPriority < 0.0001 )
 
   59   else if ( defaultPriority > 1.0 )
 
   87   if ( lf->
size().width() < 0 || lf->
size().height() < 0 )
 
   90   QMutexLocker locker( &
mMutex );
 
  104   bool addedFeature = 
false;
 
  106   double geom_size = -1, biggest_size = -1;
 
  107   std::unique_ptr<FeaturePart> biggest_part;
 
  110   std::unique_ptr<QLinkedList<const GEOSGeometry *>> simpleGeometries( 
Util::unmulti( lf->
geometry() ) );
 
  111   if ( !simpleGeometries ) 
 
  120   while ( !simpleGeometries->isEmpty() )
 
  122     const GEOSGeometry *geom = simpleGeometries->takeFirst();
 
  125     if ( GEOSisValid_r( geosctxt, geom ) != 1 ) 
 
  130     int type = GEOSGeomTypeId_r( geosctxt, geom );
 
  132     if ( type != GEOS_POINT && type != GEOS_LINESTRING && type != GEOS_POLYGON )
 
  137     std::unique_ptr<FeaturePart> fpart = qgis::make_unique<FeaturePart>( lf, geom );
 
  140     if ( ( type == GEOS_LINESTRING && fpart->nbPoints < 2 ) ||
 
  141          ( type == GEOS_POLYGON && fpart->nbPoints < 3 ) )
 
  153     bool labelWellDefined = ( lf->
size().width() > 0.0000001 && lf->
size().height() > 0.0000001 );
 
  176     if ( !lf->
labelAllParts() && ( type == GEOS_POLYGON || type == GEOS_LINESTRING ) )
 
  178       if ( type == GEOS_LINESTRING )
 
  179         geom_size = fpart->length();
 
  180       else if ( type == GEOS_POLYGON )
 
  181         geom_size = fpart->area();
 
  183       if ( geom_size > biggest_size )
 
  185         biggest_size = geom_size;
 
  186         biggest_part.reset( fpart.release() );
 
  208         QgsDebugMsg( QStringLiteral( 
"Obstacle geometry passed to PAL labeling engine could not be converted to GEOS! %1" ).arg( ( *it )->asWkt() ) );
 
  213       if ( GEOSisValid_r( geosctxt, geom.get() ) != 1 ) 
 
  216         QgsDebugMsg( QStringLiteral( 
"Obstacle geometry passed to PAL labeling engine is not valid! %1" ).arg( ( *it )->asWkt() ) );
 
  220       int type = GEOSGeomTypeId_r( geosctxt, geom.get() );
 
  222       if ( type != GEOS_POINT && type != GEOS_LINESTRING && type != GEOS_POLYGON )
 
  227       std::unique_ptr<FeaturePart> fpart = qgis::make_unique<FeaturePart>( lf, geom.get() );
 
  230       if ( ( type == GEOS_LINESTRING && fpart->nbPoints < 2 ) ||
 
  231            ( type == GEOS_POLYGON && fpart->nbPoints < 3 ) )
 
  286 static FeaturePart *_findConnectedPart( 
FeaturePart *partCheck, 
const QVector<FeaturePart *> &otherParts )
 
  289   auto it = otherParts.constBegin();
 
  290   while ( it != otherParts.constEnd() )
 
  306   int connectedFeaturesId = 0;
 
  309     QVector<FeaturePart *> parts = it.value();
 
  310     connectedFeaturesId++;
 
  316       return a->length() > b->length();
 
  320     while ( parts.count() > 1 )
 
  325       FeaturePart *otherPart = _findConnectedPart( partCheck, parts );
 
  351   QLinkedList<FeaturePart *> newFeatureParts;
 
  354     std::unique_ptr< FeaturePart > fpart( 
mFeatureParts.takeFirst() );
 
  355     const GEOSGeometry *geom = fpart->geos();
 
  356     double chopInterval = fpart->repeatDistance();
 
  359     bool canChop = 
false;
 
  360     double featureLen = 0;
 
  361     if ( chopInterval != 0. && GEOSGeomTypeId_r( geosctxt, geom ) == GEOS_LINESTRING )
 
  363       featureLen = fpart->length();
 
  364       if ( featureLen > chopInterval )
 
  369     bool shouldChop = canChop;
 
  370     int possibleSegments = 0;
 
  374       chopInterval *= std::ceil( fpart->getLabelWidth() / fpart->repeatDistance() );
 
  377       possibleSegments = 
static_cast< int >( std::floor( featureLen / chopInterval ) );
 
  389       chopInterval = featureLen / possibleSegments;
 
  391       shouldChop = possibleSegments > 1;
 
  396       const GEOSCoordSequence *cs = GEOSGeom_getCoordSeq_r( geosctxt, geom );
 
  400       GEOSCoordSeq_getSize_r( geosctxt, cs, &n );
 
  403       std::vector<Point> points( n );
 
  404       for ( 
unsigned int i = 0; i < n; ++i )
 
  406 #if GEOS_VERSION_MAJOR>3 || GEOS_VERSION_MINOR>=8 
  407         GEOSCoordSeq_getXY_r( geosctxt, cs, i, &points[i].x, &points[i].y );
 
  409         GEOSCoordSeq_getX_r( geosctxt, cs, i, &points[i].x );
 
  410         GEOSCoordSeq_getY_r( geosctxt, cs, i, &points[i].y );
 
  415       std::vector<double> len( n, 0 );
 
  416       for ( 
unsigned int i = 1; i < n; ++i )
 
  418         double dx = points[i].x - points[i - 1].x;
 
  419         double dy = points[i].y - points[i - 1].y;
 
  420         len[i] = len[i - 1] + std::sqrt( dx * dx + dy * dy );
 
  424       unsigned int cur = 0;
 
  426       std::vector<Point> part;
 
  428       QList<FeaturePart *> repeatParts;
 
  429       repeatParts.reserve( possibleSegments );
 
  431       for ( 
int segment = 0; segment < possibleSegments; segment++ )
 
  433         lambda += chopInterval;
 
  434         for ( ; cur < n && lambda > len[cur]; ++cur )
 
  436           part.push_back( points[cur] );
 
  441           GEOSCoordSequence *cooSeq = GEOSCoordSeq_create_r( geosctxt, 
static_cast< unsigned int >( part.size() ), 2 );
 
  442           for ( 
unsigned int i = 0; i < part.size(); ++i )
 
  444 #if GEOS_VERSION_MAJOR>3 || GEOS_VERSION_MINOR>=8 
  445             GEOSCoordSeq_setXY_r( geosctxt, cooSeq, i, part[i].x, part[i].y );
 
  447             GEOSCoordSeq_setX_r( geosctxt, cooSeq, i, part[i].x );
 
  448             GEOSCoordSeq_setY_r( geosctxt, cooSeq, i, part[i].y );
 
  451           GEOSGeometry *newgeom = GEOSGeom_createLineString_r( geosctxt, cooSeq );
 
  453           newFeatureParts.append( newfpart );
 
  454           repeatParts.push_back( newfpart );
 
  458         double c = ( lambda - len[cur - 1] ) / ( len[cur] - len[cur - 1] );
 
  460         p.
x = points[cur - 1].x + 
c * ( points[cur].x - points[cur - 1].x );
 
  461         p.
y = points[cur - 1].y + 
c * ( points[cur].y - points[cur - 1].y );
 
  463         GEOSCoordSequence *cooSeq = GEOSCoordSeq_create_r( geosctxt, 
static_cast< unsigned int >( part.size() ), 2 );
 
  464         for ( std::size_t i = 0; i < part.size(); ++i )
 
  466 #if GEOS_VERSION_MAJOR>3 || GEOS_VERSION_MINOR>=8 
  467           GEOSCoordSeq_setXY_r( geosctxt, cooSeq, i, part[i].x, part[i].y );
 
  469           GEOSCoordSeq_setX_r( geosctxt, cooSeq, 
static_cast< unsigned int >( i ), part[i].x );
 
  470           GEOSCoordSeq_setY_r( geosctxt, cooSeq, 
static_cast< unsigned int >( i ), part[i].y );
 
  474         GEOSGeometry *newgeom = GEOSGeom_createLineString_r( geosctxt, cooSeq );
 
  476         newFeatureParts.append( newfpart );
 
  479         repeatParts.push_back( newfpart );
 
  483         partPtr->setTotalRepeats( repeatParts.count() );
 
  487       newFeatureParts.append( fpart.release() );
 
The QgsAbstractLabelProvider class is an interface class.
A generic rtree spatial index based on a libspatialindex backend.
A geometry is the spatial representation of a feature.
QgsAbstractGeometry::const_part_iterator const_parts_begin() const
Returns STL-style const iterator pointing to the first part of the geometry.
QgsAbstractGeometry::const_part_iterator const_parts_end() const
Returns STL-style iterator pointing to the imaginary part after the last part of the geometry.
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...
static GEOSContextHandle_t getGEOSHandler()
The QgsLabelFeature class describes a feature that should be used within the labeling engine.
const QgsLabelObstacleSettings & obstacleSettings() const
Returns the label's obstacle settings.
QSizeF size(double angle=0.0) const
Size of the label (in map units)
void setLayer(pal::Layer *layer)
Assign PAL layer to the label feature. Should be only used internally in PAL.
QgsFeatureId id() const
Identifier of the label (unique within the parent label provider)
bool hasFixedPosition() const
Whether the label should use a fixed position instead of being automatically placed.
QString labelText() const
Text of the label.
GEOSGeometry * geometry() const
Gets access to the associated geometry.
bool labelAllParts() const
Returns true if all parts of the feature should be labeled.
bool isObstacle() const
Returns true if the features are obstacles to labels of other layers.
QgsGeometry obstacleGeometry() const
Returns the label's obstacle geometry, if different to the feature geometry.
Placement
Placement modes which determine how label candidates are generated for a feature.
Main class to handle feature.
QgsFeatureId featureId() const
Returns the unique ID of the feature.
bool mergeWithFeaturePart(FeaturePart *other)
Merge other (connected) part with this one and save the result in this part (other is unchanged).
bool isConnected(FeaturePart *p2)
Check whether this part is connected with some other part.
static int reorderPolygon(int nbPoints, std::vector< double > &x, std::vector< double > &y)
Reorder points to have cross prod ((x,y)[i], (x,y)[i+1), point) > 0 when point is outside.
Thrown when a geometry type is not like expected.
QHash< QString, QVector< FeaturePart * > > mConnectedHashtable
QList< FeaturePart * > mObstacleParts
List of obstacle parts.
bool registerFeature(QgsLabelFeature *label)
Register a feature in the layer.
int connectedFeatureId(QgsFeatureId featureId) const
Returns the connected feature ID for a label feature ID, which is unique for all features which have ...
QHash< QgsFeatureId, int > mConnectedFeaturesIds
void joinConnectedFeatures()
Join connected features with the same label text.
QHash< QgsFeatureId, QgsLabelFeature * > mHashtable
Lookup table of label features (owned by the label feature provider that created them)
QLinkedList< FeaturePart * > mFeatureParts
List of feature parts.
void chopFeaturesAtRepeatDistance()
Chop layer features at the repeat distance.
std::vector< geos::unique_ptr > mGeosObstacleGeometries
void addObstaclePart(FeaturePart *fpart)
Add newly created obstacle part into r tree and to the list.
void setPriority(double priority)
Sets the layer's priority.
void addFeaturePart(FeaturePart *fpart, const QString &labelText=QString())
Add newly created feature part into r tree and to the list.
Layer(QgsAbstractLabelProvider *provider, const QString &name, QgsPalLayerSettings::Placement arrangement, double defaultPriority, bool active, bool toLabel, Pal *pal, bool displayAll=false)
Create a new layer.
double priority() const
Returns the layer's priority, between 0 and 1.
static QLinkedList< const GEOSGeometry * > * unmulti(const GEOSGeometry *the_geom)
std::unique_ptr< GEOSGeometry, GeosDeleter > unique_ptr
Scoped GEOS pointer.
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
qint64 QgsFeatureId
64 bit feature ids negative numbers are used for uncommitted/newly added features