QGIS API Documentation 3.41.0-Master (45a0abf3bec)
Loading...
Searching...
No Matches
qgsvectorlayerlabelprovider.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsvectorlayerlabelprovider.cpp
3 --------------------------------------
4 Date : September 2015
5 Copyright : (C) 2015 by Martin Dobias
6 Email : wonder dot sk at gmail dot com
7 ***************************************************************************
8 * *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License as published by *
11 * the Free Software Foundation; either version 2 of the License, or *
12 * (at your option) any later version. *
13 * *
14 ***************************************************************************/
15
17
18#include "qgsgeometry.h"
19#include "qgslabelsearchtree.h"
20#include "qgspallabeling.h"
21#include "qgstextlabelfeature.h"
22#include "qgsvectorlayer.h"
24#include "qgsrenderer.h"
25#include "qgspolygon.h"
26#include "qgslinestring.h"
27#include "qgsmultipolygon.h"
28#include "qgslogger.h"
30#include "qgsmaskidprovider.h"
32#include "qgstextfragment.h"
33#include "qgslabelingresults.h"
34#include "qgstextrenderer.h"
35
36#include "feature.h"
37#include "labelposition.h"
38#include "callouts/qgscallout.h"
39#include "qgssymbol.h"
40#include "qgsmarkersymbol.h"
41
42#include "pal/layer.h"
43
44#include <QPicture>
45#include <QTextDocument>
46#include <QTextFragment>
47
48using namespace pal;
49
50QgsVectorLayerLabelProvider::QgsVectorLayerLabelProvider( QgsVectorLayer *layer, const QString &providerId, bool withFeatureLoop, const QgsPalLayerSettings *settings, const QString &layerName )
51 : QgsAbstractLabelProvider( layer, providerId )
52 , mSettings( settings ? * settings : QgsPalLayerSettings() ) // TODO: all providers should have valid settings?
53 , mLayerGeometryType( layer->geometryType() )
54 , mRenderer( layer->renderer() )
55 , mFields( layer->fields() )
56 , mCrs( layer->crs() )
57{
58 mName = layerName.isEmpty() ? layer->id() : layerName;
59
60 if ( withFeatureLoop )
61 {
62 mSource = std::make_unique<QgsVectorLayerFeatureSource>( layer );
63 }
64
65 init();
66}
67
68QgsVectorLayerLabelProvider::QgsVectorLayerLabelProvider( Qgis::GeometryType geometryType, const QgsFields &fields, const QgsCoordinateReferenceSystem &crs, const QString &providerId, const QgsPalLayerSettings *settings, QgsMapLayer *layer, const QString &layerName )
69 : QgsAbstractLabelProvider( layer, providerId )
70 , mSettings( settings ? * settings : QgsPalLayerSettings() ) // TODO: all providers should have valid settings?
71 , mLayerGeometryType( geometryType )
72 , mRenderer( nullptr )
73 , mFields( fields )
74 , mCrs( crs )
75{
76 mName = layerName.isEmpty() ? layer->id() : layerName;
77
78 init();
79}
80
82{
84
85 mFlags = Flags();
92
93 mPriority = 1 - mSettings.priority / 10.0; // convert 0..10 --> 1..0
94
96 {
97 //override obstacle type to treat any intersection of a label with the point symbol as a high cost conflict
99 }
100 else
101 {
103 }
104
106}
107
108
113
114
115bool QgsVectorLayerLabelProvider::prepare( QgsRenderContext &context, QSet<QString> &attributeNames )
116{
117 const QgsMapSettings &mapSettings = mEngine->mapSettings();
118
119 return mSettings.prepare( context, attributeNames, mFields, mapSettings, mCrs );
120}
121
127
133
135{
136 if ( !mSource )
137 {
138 // we have created the provider with "own feature loop" == false
139 // so it is assumed that prepare() has been already called followed by registerFeature() calls
140 return mLabels;
141 }
142
143 QSet<QString> attrNames;
144 if ( !prepare( ctx, attrNames ) )
145 return QList<QgsLabelFeature *>();
146
147 if ( mRenderer )
149
150 QgsRectangle layerExtent = ctx.extent();
152 {
153 QgsCoordinateTransform extentTransform = mSettings.ct;
154 extentTransform.setBallparkTransformsAreAppropriate( true );
155 layerExtent = extentTransform.transformBoundingBox( ctx.extent(), Qgis::TransformDirection::Reverse );
156 }
157
158 QgsFeatureRequest request;
159 request.setFilterRect( layerExtent );
160 request.setSubsetOfAttributes( attrNames, mFields );
161 QgsFeatureIterator fit = mSource->getFeatures( request );
162
164 ctx.expressionContext().appendScope( symbolScope );
165 QgsFeature fet;
166 while ( fit.nextFeature( fet ) )
167 {
168 QgsGeometry obstacleGeometry;
169 const QgsSymbol *symbol = nullptr;
170 if ( mRenderer )
171 {
173 if ( !symbols.isEmpty() && fet.geometry().type() == Qgis::GeometryType::Point )
174 {
175 //point feature, use symbol bounds as obstacle
176 obstacleGeometry = QgsVectorLayerLabelProvider::getPointObstacleGeometry( fet, ctx, symbols );
177 }
178 if ( !symbols.isEmpty() )
179 {
180 symbol = symbols.at( 0 );
181 symbolScope = QgsExpressionContextUtils::updateSymbolScope( symbol, symbolScope );
182 }
183 }
184 ctx.expressionContext().setFeature( fet );
185 registerFeature( fet, ctx, obstacleGeometry, symbol );
186 }
187
188 if ( ctx.expressionContext().lastScope() == symbolScope )
189 delete ctx.expressionContext().popScope();
190
191 if ( mRenderer )
192 mRenderer->stopRender( ctx );
193
194 return mLabels;
195}
196
197QList< QgsLabelFeature * > QgsVectorLayerLabelProvider::registerFeature( const QgsFeature &feature, QgsRenderContext &context, const QgsGeometry &obstacleGeometry, const QgsSymbol *symbol )
198{
199 std::unique_ptr< QgsLabelFeature > label = mSettings.registerFeatureWithDetails( feature, context, obstacleGeometry, symbol );
200 QList< QgsLabelFeature * > res;
201 if ( label )
202 {
203 res << label.get();
204 mLabels << label.release();
205 }
206 return res;
207}
208
210{
211 if ( !fet.hasGeometry() || fet.geometry().type() != Qgis::GeometryType::Point )
212 return QgsGeometry();
213
214 bool isMultiPoint = fet.geometry().constGet()->nCoordinates() > 1;
215 std::unique_ptr< QgsAbstractGeometry > obstacleGeom;
216 if ( isMultiPoint )
217 obstacleGeom = std::make_unique< QgsMultiPolygon >();
218
219 // for each point
220 for ( int i = 0; i < fet.geometry().constGet()->nCoordinates(); ++i )
221 {
222 QRectF bounds;
223 QgsPoint p = fet.geometry().constGet()->vertexAt( QgsVertexId( i, 0, 0 ) );
224 double x = p.x();
225 double y = p.y();
226 double z = 0; // dummy variable for coordinate transforms
227
228 //transform point to pixels
229 if ( context.coordinateTransform().isValid() )
230 {
231 try
232 {
233 context.coordinateTransform().transformInPlace( x, y, z );
234 }
235 catch ( QgsCsException & )
236 {
237 return QgsGeometry();
238 }
239 }
240 context.mapToPixel().transformInPlace( x, y );
241
242 QPointF pt( x, y );
243 const auto constSymbols = symbols;
244 for ( QgsSymbol *symbol : constSymbols )
245 {
246 if ( symbol->type() == Qgis::SymbolType::Marker )
247 {
248 if ( bounds.isValid() )
249 bounds = bounds.united( static_cast< QgsMarkerSymbol * >( symbol )->bounds( pt, context, fet ) );
250 else
251 bounds = static_cast< QgsMarkerSymbol * >( symbol )->bounds( pt, context, fet );
252 }
253 }
254
255 //convert bounds to a geometry
256 QVector< double > bX;
257 bX << bounds.left() << bounds.right() << bounds.right() << bounds.left();
258 QVector< double > bY;
259 bY << bounds.top() << bounds.top() << bounds.bottom() << bounds.bottom();
260 std::unique_ptr< QgsLineString > boundLineString = std::make_unique< QgsLineString >( bX, bY );
261
262 //then transform back to map units
263 //TODO - remove when labeling is refactored to use screen units
264 for ( int i = 0; i < boundLineString->numPoints(); ++i )
265 {
266 QgsPointXY point = context.mapToPixel().toMapCoordinates( static_cast<int>( boundLineString->xAt( i ) ),
267 static_cast<int>( boundLineString->yAt( i ) ) );
268 boundLineString->setXAt( i, point.x() );
269 boundLineString->setYAt( i, point.y() );
270 }
271 if ( context.coordinateTransform().isValid() )
272 {
273 try
274 {
275 boundLineString->transform( context.coordinateTransform(), Qgis::TransformDirection::Reverse );
276 }
277 catch ( QgsCsException & )
278 {
279 return QgsGeometry();
280 }
281 }
282 boundLineString->close();
283
284 if ( context.coordinateTransform().isValid() )
285 {
286 // coordinate transforms may have resulted in nan coordinates - if so, strip these out
287 boundLineString->filterVertices( []( const QgsPoint & point )->bool
288 {
289 return std::isfinite( point.x() ) && std::isfinite( point.y() );
290 } );
291 if ( !boundLineString->isRing() )
292 return QgsGeometry();
293 }
294
295 std::unique_ptr< QgsPolygon > obstaclePolygon = std::make_unique< QgsPolygon >();
296 obstaclePolygon->setExteriorRing( boundLineString.release() );
297
298 if ( isMultiPoint )
299 {
300 static_cast<QgsMultiPolygon *>( obstacleGeom.get() )->addGeometry( obstaclePolygon.release() );
301 }
302 else
303 {
304 obstacleGeom = std::move( obstaclePolygon );
305 }
306 }
307
308 return QgsGeometry( std::move( obstacleGeom ) );
309}
310
312{
313 if ( !mSettings.drawLabels )
314 return;
315
316 // render callout
318 {
319 drawCallout( context, label );
320 }
321}
322
323void QgsVectorLayerLabelProvider::drawCallout( QgsRenderContext &context, pal::LabelPosition *label ) const
324{
325 bool enabled = mSettings.callout()->enabled();
327 {
328 context.expressionContext().setOriginalValueVariable( enabled );
330 }
331 if ( enabled )
332 {
333 QgsMapToPixel xform = context.mapToPixel();
334 xform.setMapRotation( 0, 0, 0 );
335 QPointF outPt = xform.transform( label->getX(), label->getY() ).toQPointF();
336 QgsPointXY outPt2 = xform.transform( label->getX() + label->getWidth(), label->getY() + label->getHeight() );
337 QRectF rect( outPt.x(), outPt.y(), outPt2.x() - outPt.x(), outPt2.y() - outPt.y() );
338
340 g.transform( xform.transform() );
341 QgsCallout::QgsCalloutContext calloutContext;
342 calloutContext.allFeaturePartsLabeled = label->getFeaturePart()->feature()->labelAllParts();
343 calloutContext.originalFeatureCrs = label->getFeaturePart()->feature()->originalFeatureCrs();
344 mSettings.callout()->render( context, rect, label->getAlpha() * 180 / M_PI, g, calloutContext );
345
346 const QList< QgsCalloutPosition > renderedPositions = calloutContext.positions();
347
348 for ( QgsCalloutPosition position : renderedPositions )
349 {
350 position.layerID = mLayerId;
351 position.featureId = label->getFeaturePart()->featureId();
352 position.providerID = mProviderId;
353 mEngine->results()->mLabelSearchTree->insertCallout( position );
354 }
355 }
356}
357
359{
360 if ( !mSettings.drawLabels )
361 return;
362
363 QgsTextLabelFeature *lf = dynamic_cast<QgsTextLabelFeature *>( label->getFeaturePart()->feature() );
364
365 // Copy to temp, editable layer settings
366 // these settings will be changed by any data defined values, then used for rendering label components
367 // settings may be adjusted during rendering of components
369
370 // apply any previously applied data defined settings for the label
371 const QMap< QgsPalLayerSettings::Property, QVariant > &ddValues = lf->dataDefinedValues();
372
373 //font
374 QFont dFont = lf->definedFont();
375 QgsDebugMsgLevel( QStringLiteral( "PAL font tmpLyr: %1, Style: %2" ).arg( tmpLyr.format().font().toString(), tmpLyr.format().font().styleName() ), 4 );
376 QgsDebugMsgLevel( QStringLiteral( "PAL font definedFont: %1, Style: %2" ).arg( dFont.toString(), dFont.styleName() ), 4 );
377
378 QgsTextFormat format = tmpLyr.format();
379 format.setFont( dFont );
380
381 // size has already been calculated and stored in the defined font - this calculated size
382 // is in pixels
383 format.setSize( dFont.pixelSize() );
385 tmpLyr.setFormat( format );
386
388 {
389 //calculate font alignment based on label quadrant
390 switch ( label->quadrant() )
391 {
396 break;
401 break;
406 break;
407 }
408 }
409
410 // update tmpLyr with any data defined text style values
411 QgsPalLabeling::dataDefinedTextStyle( tmpLyr, ddValues );
412
413 // update tmpLyr with any data defined text buffer values
414 QgsPalLabeling::dataDefinedTextBuffer( tmpLyr, ddValues );
415
416 // update tmpLyr with any data defined text mask values
417 QgsPalLabeling::dataDefinedTextMask( tmpLyr, ddValues );
418
419 // update tmpLyr with any data defined text formatting values
420 QgsPalLabeling::dataDefinedTextFormatting( tmpLyr, ddValues );
421
422 // update tmpLyr with any data defined shape background values
423 QgsPalLabeling::dataDefinedShapeBackground( tmpLyr, ddValues );
424
425 // update tmpLyr with any data defined drop shadow values
426 QgsPalLabeling::dataDefinedDropShadow( tmpLyr, ddValues );
427
428 // Render the components of a label in reverse order
429 // (backgrounds -> text)
430
431 // render callout
433 {
434 drawCallout( context, label );
435 }
436
438 {
439 QgsTextFormat format = tmpLyr.format();
440
441 if ( tmpLyr.format().background().enabled() && tmpLyr.format().background().type() != QgsTextBackgroundSettings::ShapeMarkerSymbol ) // background shadows not compatible with marker symbol backgrounds
442 {
444 }
445 else if ( tmpLyr.format().buffer().enabled() )
446 {
448 }
449 else
450 {
452 }
453
454 tmpLyr.setFormat( format );
455 }
456
457 if ( tmpLyr.format().background().enabled() )
458 {
459 drawLabelPrivate( label, context, tmpLyr, Qgis::TextComponent::Background );
460 }
461
462 if ( tmpLyr.format().buffer().enabled() )
463 {
464 drawLabelPrivate( label, context, tmpLyr, Qgis::TextComponent::Buffer );
465 }
466
467 drawLabelPrivate( label, context, tmpLyr, Qgis::TextComponent::Text );
468
469 // add to the results
470 QString labeltext = label->getFeaturePart()->feature()->labelText();
471 mEngine->results()->mLabelSearchTree->insertLabel( label, label->getFeaturePart()->featureId(), mLayerId, labeltext, dFont, false, lf->hasFixedPosition(), mProviderId );
472}
473
475{
476 QgsTextLabelFeature *lf = dynamic_cast<QgsTextLabelFeature *>( label->getFeaturePart()->feature() );
477
478 QgsTextFormat format = mSettings.format();
482 {
484 format = tmpLyr.format();
486 tmpLyr.setFormat( format );
487 drawLabelPrivate( label, context, tmpLyr, Qgis::TextComponent::Text );
488 }
489
490 // add to the results
491 QString labeltext = label->getFeaturePart()->feature()->labelText();
492 mEngine->results()->mLabelSearchTree->insertLabel( label, label->getFeaturePart()->featureId(), mLayerId, labeltext, format.font(), false, lf->hasFixedPosition(), mProviderId, true );
493}
494
496{
497 // NOTE: this is repeatedly called for multi-part labels
498 QPainter *painter = context.painter();
499
500 Qgis::TextComponents components;
501 switch ( drawType )
502 {
505 break;
506
509 break;
510
513 components = drawType;
514 break;
515 }
516
517 // features are pre-rotated but not scaled/translated,
518 // so we only disable rotation here. Ideally, they'd be
519 // also pre-scaled/translated, as suggested here:
520 // https://github.com/qgis/QGIS/issues/20071
521 QgsMapToPixel xform = context.mapToPixel();
522 xform.setMapRotation( 0, 0, 0 );
523
524 QPointF outPt = xform.transform( label->getX(), label->getY() ).toQPointF();
525
526 if ( mEngine->engineSettings().testFlag( Qgis::LabelingFlag::DrawLabelRectOnly ) ) // TODO: this should get directly to labeling engine
527 {
528 //debugging rect
529 if ( drawType != Qgis::TextComponent::Text )
530 return;
531
532 QgsPointXY outPt2 = xform.transform( label->getX() + label->getWidth(), label->getY() + label->getHeight() );
533 QRectF rect( 0, 0, outPt2.x() - outPt.x(), outPt2.y() - outPt.y() );
534 painter->save();
535 painter->setRenderHint( QPainter::Antialiasing, false );
536 painter->translate( QPointF( outPt.x(), outPt.y() ) );
537 painter->rotate( -label->getAlpha() * 180 / M_PI );
538
539 if ( label->conflictsWithObstacle() )
540 {
541 painter->setBrush( QColor( 255, 0, 0, 100 ) );
542 painter->setPen( QColor( 255, 0, 0, 150 ) );
543 }
544 else
545 {
546 painter->setBrush( QColor( 0, 255, 0, 100 ) );
547 painter->setPen( QColor( 0, 255, 0, 150 ) );
548 }
549
550 painter->drawRect( rect );
551 painter->restore();
552
553 if ( label->nextPart() )
554 drawLabelPrivate( label->nextPart(), context, tmpLyr, drawType, dpiRatio );
555
556 return;
557 }
559 {
560 if ( drawType != Qgis::TextComponent::Text )
561 return;
562
563 QgsPointXY outPt2 = xform.transform( label->getX() + label->getWidth(), label->getY() + label->getHeight() );
564 QRectF rect( 0, 0, outPt2.x() - outPt.x(), outPt2.y() - outPt.y() );
565 painter->save();
566 painter->setRenderHint( QPainter::Antialiasing, false );
567 painter->translate( QPointF( outPt.x(), outPt.y() ) );
568 painter->rotate( -label->getAlpha() * 180 / M_PI );
569
570 painter->setBrush( Qt::NoBrush );
571 painter->setPen( QColor( 255, 0, 0, 220 ) );
572
573 painter->drawRect( rect );
574
575
576 painter->setPen( QColor( 0, 0, 0, 60 ) );
577 const QgsMargins &margins = label->getFeaturePart()->feature()->visualMargin();
578 if ( margins.top() > 0 )
579 {
580 const double topMargin = margins.top() / context.mapToPixel().mapUnitsPerPixel();
581 painter->drawLine( QPointF( rect.left(), rect.top() - topMargin ), QPointF( rect.right(), rect.top() - topMargin ) );
582 }
583 if ( margins.bottom() > 0 )
584 {
585 const double bottomMargin = margins.top() / context.mapToPixel().mapUnitsPerPixel();
586 painter->drawLine( QPointF( rect.left(), rect.bottom() + bottomMargin ), QPointF( rect.right(), rect.bottom() + bottomMargin ) );
587 }
588
589 const QRectF outerBounds = label->getFeaturePart()->feature()->outerBounds();
590 if ( !outerBounds.isNull() )
591 {
592 const QRectF mapOuterBounds = QRectF( label->getX() + outerBounds.left(),
593 label->getY() + outerBounds.top(),
594 outerBounds.width(), outerBounds.height() );
595
596 QgsPointXY outerBoundsPt1 = xform.transform( mapOuterBounds.left(), mapOuterBounds.top() );
597 QgsPointXY outerBoundsPt2 = xform.transform( mapOuterBounds.right(), mapOuterBounds.bottom() );
598
599 const QRectF outerBoundsPixel( outerBoundsPt1.x() - outPt.x(),
600 outerBoundsPt1.y() - outPt.y(),
601 outerBoundsPt2.x() - outerBoundsPt1.x(),
602 outerBoundsPt2.y() - outerBoundsPt1.y() );
603
604 QPen pen( QColor( 255, 0, 255, 140 ) );
605 pen.setCosmetic( true );
606 pen.setWidth( 1 );
607 painter->setPen( pen );
608 painter->drawRect( outerBoundsPixel );
609 }
610
611 if ( QgsTextLabelFeature *textFeature = dynamic_cast< QgsTextLabelFeature * >( label->getFeaturePart()->feature() ) )
612 {
613 const QgsTextDocumentMetrics &metrics = textFeature->documentMetrics();
614 const QgsTextDocument &document = textFeature->document();
615 const int blockCount = document.size();
616
617 double prevBlockBaseline = rect.bottom() - rect.top();
618 const double verticalAlignOffset = -metrics.blockVerticalMargin( document.size() - 1 );
619
620 // draw block baselines
621 for ( int blockIndex = 0; blockIndex < blockCount; ++blockIndex )
622 {
623 const double blockBaseLine = metrics.baselineOffset( blockIndex, Qgis::TextLayoutMode::Labeling );
624
625 const QgsTextBlock &block = document.at( blockIndex );
626 const int fragmentCount = block.size();
627 double left = metrics.blockLeftMargin( blockIndex );
628 for ( int fragmentIndex = 0; fragmentIndex < fragmentCount; ++fragmentIndex )
629 {
630 const double fragmentVerticalOffset = metrics.fragmentVerticalOffset( blockIndex, fragmentIndex, Qgis::TextLayoutMode::Labeling );
631 const double right = left + metrics.fragmentHorizontalAdvance( blockIndex, fragmentIndex, Qgis::TextLayoutMode::Labeling );
632
633 if ( fragmentIndex > 0 )
634 {
635 QPen pen( QColor( 0, 0, 255, 220 ) );
636 pen.setStyle( Qt::PenStyle::DashLine );
637
638 painter->setPen( pen );
639
640 painter->drawLine( QPointF( rect.left() + left, rect.top() + blockBaseLine + fragmentVerticalOffset + verticalAlignOffset ),
641 QPointF( rect.left() + left, rect.top() + prevBlockBaseline + verticalAlignOffset ) );
642
643 }
644
645 painter->setPen( QColor( 0, 0, 255, 220 ) );
646 painter->drawLine( QPointF( rect.left() + left, rect.top() + blockBaseLine + fragmentVerticalOffset + verticalAlignOffset ),
647 QPointF( rect.left() + right, rect.top() + blockBaseLine + fragmentVerticalOffset + verticalAlignOffset ) );
648 left = right;
649 }
650 prevBlockBaseline = blockBaseLine;
651 }
652 }
653
654 painter->restore();
655 }
656
657 QgsTextRenderer::Component component;
658 component.dpiRatio = dpiRatio;
659 component.origin = outPt;
660 component.rotation = label->getAlpha();
661
662 if ( drawType == Qgis::TextComponent::Background )
663 {
664 // get rotated label's center point
665 QPointF centerPt( outPt );
666 QgsPointXY outPt2 = xform.transform( label->getX() + label->getWidth() / 2,
667 label->getY() + label->getHeight() / 2 );
668
669 double xc = outPt2.x() - outPt.x();
670 double yc = outPt2.y() - outPt.y();
671
672 double angle = -component.rotation;
673 double xd = xc * std::cos( angle ) - yc * std::sin( angle );
674 double yd = xc * std::sin( angle ) + yc * std::cos( angle );
675
676 centerPt.setX( centerPt.x() + xd );
677 centerPt.setY( centerPt.y() + yd );
678
679 component.center = centerPt;
680
681 {
682 // label size has already been calculated using any symbology reference scale factor -- we need
683 // to temporarily remove the reference scale here or we'll be applying the scaling twice
684 QgsScopedRenderContextReferenceScaleOverride referenceScaleOverride( context, -1.0 );
685
686 // convert label size to render units
687 double labelWidthPx = context.convertToPainterUnits( label->getWidth(), Qgis::RenderUnit::MapUnits, QgsMapUnitScale() );
688 double labelHeightPx = context.convertToPainterUnits( label->getHeight(), Qgis::RenderUnit::MapUnits, QgsMapUnitScale() );
689
690 component.size = QSizeF( labelWidthPx, labelHeightPx );
691 }
692
693 QgsTextRenderer::drawBackground( context, component, tmpLyr.format(), QgsTextDocumentMetrics(), Qgis::TextLayoutMode::Labeling );
694 }
695
696 else if ( drawType == Qgis::TextComponent::Buffer
697 || drawType == Qgis::TextComponent::Text )
698 {
699 // TODO: optimize access :)
700 QgsTextLabelFeature *lf = static_cast<QgsTextLabelFeature *>( label->getFeaturePart()->feature() );
701 QString txt = lf->text( label->getPartId() );
702
703 if ( auto *lMaskIdProvider = context.maskIdProvider() )
704 {
705 int maskId = lMaskIdProvider->maskId( label->getFeaturePart()->layer()->provider()->layerId(),
706 label->getFeaturePart()->layer()->provider()->providerId() );
707 context.setCurrentMaskId( maskId );
708 }
709
710 const QgsTextDocument &precalculatedDocument = lf->document();
711 const QgsTextDocumentMetrics &precalculatedMetrics = lf->documentMetrics();
712 const QgsTextDocument *document = &precalculatedDocument;
713 const QgsTextDocumentMetrics *documentMetrics = &precalculatedMetrics;
714
715 // add the direction symbol if needed
716 // note that IF we do this, we can no longer use the original text document and metrics
717 // but have to re-calculate these with the newly added text!
718 std::optional< QgsTextDocument > newDocument;
719 std::optional< QgsTextDocumentMetrics > newDocumentMetrics;
720 if ( !txt.isEmpty() && tmpLyr.placement == Qgis::LabelPlacement::Line &&
722 {
723 newDocument.emplace( *document );
724 bool prependSymb = false;
725 QString symb = tmpLyr.lineSettings().rightDirectionSymbol();
726
727 if ( label->isReversedFromLineDirection() )
728 {
729 prependSymb = true;
730 symb = tmpLyr.lineSettings().leftDirectionSymbol();
731 }
732
733 if ( tmpLyr.lineSettings().reverseDirectionSymbol() )
734 {
735 if ( symb == tmpLyr.lineSettings().rightDirectionSymbol() )
736 {
737 prependSymb = true;
738 symb = tmpLyr.lineSettings().leftDirectionSymbol();
739 }
740 else
741 {
742 prependSymb = false;
743 symb = tmpLyr.lineSettings().rightDirectionSymbol();
744 }
745 }
746
747 switch ( tmpLyr.lineSettings().directionSymbolPlacement() )
748 {
750 {
751 newDocument->insert( 0, QgsTextBlock( QgsTextFragment( symb ) ) );
752 break;
753 }
754
756 newDocument->append( QgsTextBlock( QgsTextFragment( symb ) ) );
757 break;
758
760 {
761 QgsTextBlock &block = newDocument.value()[ 0 ];
762 if ( prependSymb )
763 {
764 block.insert( 0, QgsTextFragment( symb ) );
765 }
766 else
767 {
768 block.append( QgsTextFragment( symb ) );
769 }
770 break;
771 }
772 }
773
774 QgsScopedRenderContextReferenceScaleOverride referenceScaleOverride( context, -1.0 );
775 newDocumentMetrics.emplace( QgsTextDocumentMetrics::calculateMetrics( newDocument.value(), tmpLyr.format(), context ) );
776 document = &newDocument.value();
777 documentMetrics = &newDocumentMetrics.value();
778 }
779
787
788 QgsTextRenderer::Component component;
789 component.origin = outPt;
790 component.rotation = label->getAlpha();
791
792 // If we are using non-curved, HTML formatted labels then we've already precalculated the text metrics.
793 // Otherwise we'll need to calculate them now.
794 switch ( tmpLyr.placement )
795 {
798 {
799 QgsTextDocument document;
800 const QgsTextCharacterFormat c = lf->characterFormat( label->getPartId() );
801 const QStringList multiLineList = QgsPalLabeling::splitToLines( txt, tmpLyr.wrapChar, tmpLyr.autoWrapLength, tmpLyr.useMaxLineLengthForAutoWrap );
802 for ( const QString &line : multiLineList )
803 {
804 document.append( QgsTextBlock::fromPlainText( line, c ) );
805 }
806
807 QgsScopedRenderContextReferenceScaleOverride referenceScaleOverride( context, -1.0 );
808 const QgsTextDocumentMetrics metrics = QgsTextDocumentMetrics::calculateMetrics( document, tmpLyr.format(), context );
809 QgsTextRenderer::drawTextInternal( components, context, tmpLyr.format(), component, document,
811 break;
812 }
813
821 {
822 const double verticalAlignOffset = -documentMetrics->blockVerticalMargin( document->size() - 1 );
823
824 component.origin.ry() += verticalAlignOffset;
825
826 QgsTextRenderer::drawTextInternal( components, context, tmpLyr.format(), component, *document,
828 break;
829 }
830 }
831 }
832 if ( label->nextPart() )
833 drawLabelPrivate( label->nextPart(), context, tmpLyr, drawType, dpiRatio );
834}
835
840
842{
843 mFields = fields;
844}
@ OverPoint
Arranges candidates over a point (or centroid of a polygon), or at a preset offset from the point....
@ Curved
Arranges candidates following the curvature of a line feature. Applies to line layers only.
@ AroundPoint
Arranges candidates in a circle around a point (or centroid of a polygon). Applies to point or polygo...
@ Line
Arranges candidates parallel to a generalised line representing the feature or parallel to a polygon'...
@ Free
Arranges candidates scattered throughout a polygon feature. Candidates are rotated to respect the pol...
@ OrderedPositionsAroundPoint
Candidates are placed in predefined positions around a point. Preference is given to positions with g...
@ Horizontal
Arranges horizontal candidates scattered throughout a polygon feature. Applies to polygon layers only...
@ PerimeterCurved
Arranges candidates following the curvature of a polygon's boundary. Applies to polygon layers only.
@ OutsidePolygons
Candidates are placed outside of polygon boundaries. Applies to polygon layers only.
@ Labeling
Labeling-specific layout mode.
@ NeverShow
Never show unplaced labels, regardless of the engine setting.
@ DrawLabelMetrics
Whether to render label metric guides (for debugging)
@ DrawUnplacedLabels
Whether to render unplaced labels as an indicator/warning for users.
@ DrawLabelRectOnly
Whether to only draw the label rect and not the actual label text (used for unit tests)
GeometryType
The geometry types are used to group Qgis::WkbType in a coarse way.
Definition qgis.h:337
@ FollowPlacement
Alignment follows placement of label, e.g., labels to the left of a feature will be drawn with right ...
@ MapUnits
Map units.
@ Marker
Marker symbol.
QFlags< TextComponent > TextComponents
Text components.
Definition qgis.h:2729
TextHorizontalAlignment
Text horizontal alignment.
Definition qgis.h:2740
TextComponent
Text components.
Definition qgis.h:2716
@ Shadow
Drop shadow.
@ Buffer
Buffer component.
@ Text
Text component.
@ Background
Background shape.
@ Reverse
Reverse/inverse transform (from destination to source)
virtual int nCoordinates() const
Returns the number of nodes contained in the geometry.
virtual QgsPoint vertexAt(QgsVertexId id) const =0
Returns the point corresponding to a specified vertex id.
The QgsAbstractLabelProvider class is an interface class.
QgsLabelObstacleSettings::ObstacleType mObstacleType
Type of the obstacle of feature geometries.
QString mName
Name of the layer.
virtual void stopRender(QgsRenderContext &context)
To be called after rendering is complete.
QString mLayerId
Associated layer's ID, if applicable.
double mPriority
Default priority of labels.
const QgsLabelingEngine * mEngine
Associated labeling engine.
QgsMapLayer * layer() const
Returns the associated layer, or nullptr if no layer is associated with the provider.
Flags mFlags
Flags altering drawing and registration of features.
virtual void startRender(QgsRenderContext &context)
To be called before rendering of labels begins.
Qgis::LabelPlacement mPlacement
Placement strategy.
@ MergeConnectedLines
Whether adjacent lines (with the same label text) should be merged.
@ DrawLabels
Whether the labels should be rendered.
@ CentroidMustBeInside
Whether location of centroid must be inside of polygons.
QString layerId() const
Returns ID of associated layer, or empty string if no layer is associated with the provider.
Qgis::UpsideDownLabelHandling mUpsidedownLabels
How to handle labels that would be upside down.
QString providerId() const
Returns provider ID - useful in case there is more than one label provider within a layer (e....
QString mProviderId
Associated provider ID (one layer may have multiple providers, e.g. in rule-based labeling)
bool valueAsBool(int key, const QgsExpressionContext &context, bool defaultValue=false, bool *ok=nullptr) const
Calculates the current value of the property with the specified key and interprets it as an boolean.
Represents the calculated placement of a map label callout line.
Contains additional contextual information about the context in which a callout is being rendered.
Definition qgscallout.h:249
bool allFeaturePartsLabeled
true if all parts of associated feature were labeled
Definition qgscallout.h:252
QList< QgsCalloutPosition > positions() const
Returns the list of rendered callout positions.
Definition qgscallout.h:286
QgsCoordinateReferenceSystem originalFeatureCrs
Contains the CRS of the original feature associated with this callout.
Definition qgscallout.h:259
void render(QgsRenderContext &context, const QRectF &rect, const double angle, const QgsGeometry &anchor, QgsCalloutContext &calloutContext)
Renders the callout onto the specified render context.
@ OrderBelowIndividualLabels
Render callouts below their individual associated labels, some callouts may be drawn over other label...
Definition qgscallout.h:110
@ OrderBelowAllLabels
Render callouts below all labels.
Definition qgscallout.h:109
virtual DrawOrder drawOrder() const
Returns the desired drawing order (stacking) to use while rendering this callout.
bool enabled() const
Returns true if the the callout is enabled.
Definition qgscallout.h:322
This class represents a coordinate reference system (CRS).
Class for doing transforms between two map coordinate systems.
void setBallparkTransformsAreAppropriate(bool appropriate)
Sets whether approximate "ballpark" results are appropriate for this coordinate transform.
void transformInPlace(double &x, double &y, double &z, Qgis::TransformDirection direction=Qgis::TransformDirection::Forward) const
Transforms an array of x, y and z double coordinates in place, from the source CRS to the destination...
bool isShortCircuited() const
Returns true if the transform short circuits because the source and destination are equivalent.
QgsRectangle transformBoundingBox(const QgsRectangle &rectangle, Qgis::TransformDirection direction=Qgis::TransformDirection::Forward, bool handle180Crossover=false) const
Transforms a rectangle from the source CRS to the destination CRS.
bool isValid() const
Returns true if the coordinate transform is valid, ie both the source and destination CRS have been s...
Custom exception class for Coordinate Reference System related exceptions.
Single scope for storing variables and functions for use within a QgsExpressionContext.
static QgsExpressionContextScope * updateSymbolScope(const QgsSymbol *symbol, QgsExpressionContextScope *symbolScope=nullptr)
Updates a symbol scope related to a QgsSymbol to an expression context.
QgsExpressionContextScope * popScope()
Removes the last scope from the expression context and return it.
void setOriginalValueVariable(const QVariant &value)
Sets the original value variable value for the context.
QgsExpressionContextScope * lastScope()
Returns the last scope added to the context.
void appendScope(QgsExpressionContextScope *scope)
Appends a scope to the end of the context.
void setFeature(const QgsFeature &feature)
Convenience function for setting a feature for the context.
Wrapper for iterator of features from vector data provider or vector layer.
bool nextFeature(QgsFeature &f)
Fetch next feature and stores in f, returns true on success.
virtual void stopRender(QgsRenderContext &context)
Must be called when a render cycle has finished, to allow the renderer to clean up.
virtual void startRender(QgsRenderContext &context, const QgsFields &fields)
Must be called when a new render cycle is started.
virtual QgsSymbolList originalSymbolsForFeature(const QgsFeature &feature, QgsRenderContext &context) const
Equivalent of originalSymbolsForFeature() call extended to support renderers that may use more symbol...
This class wraps a request for features to a vector layer (or directly its vector data provider).
QgsFeatureRequest & setSubsetOfAttributes(const QgsAttributeList &attrs)
Set a subset of attributes that will be fetched.
QgsFeatureRequest & setFilterRect(const QgsRectangle &rectangle)
Sets the rectangle from which features will be taken.
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
Definition qgsfeature.h:58
QgsGeometry geometry
Definition qgsfeature.h:69
bool hasGeometry() const
Returns true if the feature has an associated geometry.
Container of fields for a vector layer.
Definition qgsfields.h:46
A geometry is the spatial representation of a feature.
const QgsAbstractGeometry * constGet() const
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
Qgis::GeometryType type
static std::unique_ptr< QgsAbstractGeometry > fromGeos(const GEOSGeometry *geos)
Create a geometry from a GEOSGeometry.
Definition qgsgeos.cpp:1568
QgsCoordinateReferenceSystem originalFeatureCrs() const
Returns the original layer CRS of the feature associated with the label.
GEOSGeometry * geometry() const
Gets access to the associated geometry.
bool hasFixedPosition() const
Whether the label should use a fixed position instead of being automatically placed.
const QgsMargins & visualMargin() const
Returns the visual margin for the label feature.
QString labelText() const
Text of the label.
QRectF outerBounds() const
Returns the extreme outer bounds of the label feature, including any surrounding content like borders...
bool labelAllParts() const
Returns true if all parts of the feature should be labeled.
bool reverseDirectionSymbol() const
Returns true if direction symbols should be reversed.
DirectionSymbolPlacement directionSymbolPlacement() const
Returns the placement for direction symbols.
QString leftDirectionSymbol() const
Returns the string to use for left direction arrows.
@ SymbolLeftRight
Place direction symbols on left/right of label.
@ SymbolAbove
Place direction symbols on above label.
@ SymbolBelow
Place direction symbols on below label.
QString rightDirectionSymbol() const
Returns the string to use for right direction arrows.
bool addDirectionSymbol() const
Returns true if '<' or '>' (or custom strings set via leftDirectionSymbol and rightDirectionSymbol) w...
bool mergeLines() const
Returns true if connected line features with identical label text should be merged prior to generatin...
ObstacleType type() const
Returns how features act as obstacles for labels.
@ PolygonWhole
Avoid placing labels over ANY part of polygon. Where PolygonInterior will prefer to place labels with...
QColor unplacedLabelColor() const
Returns the color to use when rendering unplaced labels.
bool testFlag(Qgis::LabelingFlag f) const
Test whether a particular flag is enabled.
Qgis::LabelingFlags flags() const
Gets flags of the labeling engine.
const QgsLabelingEngineSettings & engineSettings() const
Gets associated labeling engine settings.
const QgsMapSettings & mapSettings() const
Gets associated map settings.
QgsLabelingResults * results() const
For internal use by the providers.
Base class for all map layer types.
Definition qgsmaplayer.h:76
QString id
Definition qgsmaplayer.h:79
The QgsMapSettings class contains configuration for rendering of the map.
Perform transforms between map coordinates and device coordinates.
void setMapRotation(double degrees, double cx, double cy)
Sets map rotation in degrees (clockwise).
double mapUnitsPerPixel() const
Returns the current map units per pixel.
QgsPointXY toMapCoordinates(int x, int y) const
Transforms device coordinates to map (world) coordinates.
QgsPointXY transform(const QgsPointXY &p) const
Transforms a point p from map (world) coordinates to device coordinates.
void transformInPlace(double &x, double &y) const
Transforms map coordinates to device coordinates.
Struct for storing maximum and minimum scales for measurements in map units.
The QgsMargins class defines the four margins of a rectangle.
Definition qgsmargins.h:37
double top() const
Returns the top margin.
Definition qgsmargins.h:77
double bottom() const
Returns the bottom margin.
Definition qgsmargins.h:89
A marker symbol type, for rendering Point and MultiPoint geometries.
QRectF bounds(QPointF point, QgsRenderContext &context, const QgsFeature &feature=QgsFeature()) const
Returns the approximate bounding box of the marker symbol, which includes the bounding box of all sym...
Multi polygon geometry collection.
static QStringList splitToLines(const QString &text, const QString &wrapCharacter, int autoWrapLength=0, bool useMaxLineLengthWhenAutoWrapping=true)
Splits a text string to a list of separate lines, using a specified wrap character (wrapCharacter).
Contains settings for how a map layer will be labeled.
const QgsLabelObstacleSettings & obstacleSettings() const
Returns the label obstacle settings.
std::unique_ptr< QgsLabelFeature > registerFeatureWithDetails(const QgsFeature &feature, QgsRenderContext &context, QgsGeometry obstacleGeometry=QgsGeometry(), const QgsSymbol *symbol=nullptr)
Registers a feature for labeling.
void setFormat(const QgsTextFormat &format)
Sets the label text formatting settings, e.g., font settings, buffer settings, etc.
void startRender(QgsRenderContext &context)
Prepares the label settings for rendering.
QString wrapChar
Wrapping character string.
Qgis::LabelPlacement placement
Label placement mode.
QgsCoordinateTransform ct
bool drawLabels
Whether to draw labels for this layer.
QgsPropertyCollection & dataDefinedProperties()
Returns a reference to the label's property collection, used for data defined overrides.
Qgis::LabelMultiLineAlignment multilineAlign
Horizontal alignment of multi-line labels.
bool centroidInside
true if centroid positioned labels must be placed inside their corresponding feature polygon,...
int priority
Label priority.
QgsCallout * callout() const
Returns the label callout renderer, responsible for drawing label callouts.
bool prepare(QgsRenderContext &context, QSet< QString > &attributeNames, const QgsFields &fields, const QgsMapSettings &mapSettings, const QgsCoordinateReferenceSystem &crs)
Prepare for registration of features.
const QgsLabelLineSettings & lineSettings() const
Returns the label line settings, which contain settings related to how the label engine places and fo...
Qgis::UpsideDownLabelHandling upsidedownLabels
Controls whether upside down labels are displayed and how they are handled.
const QgsTextFormat & format() const
Returns the label text formatting settings, e.g., font settings, buffer settings, etc.
int autoWrapLength
If non-zero, indicates that label text should be automatically wrapped to (ideally) the specified num...
Qgis::UnplacedLabelVisibility unplacedVisibility() const
Returns the layer's unplaced label visibility.
bool useMaxLineLengthForAutoWrap
If true, indicates that when auto wrapping label text the autoWrapLength length indicates the maximum...
void stopRender(QgsRenderContext &context)
Finalises the label settings after use.
A class to represent a 2D point.
Definition qgspointxy.h:60
double y
Definition qgspointxy.h:64
double x
Definition qgspointxy.h:63
QPointF toQPointF() const
Converts a point to a QPointF.
Definition qgspointxy.h:165
Point geometry type, with support for z-dimension and m-values.
Definition qgspoint.h:49
double x
Definition qgspoint.h:52
double y
Definition qgspoint.h:53
bool isActive(int key) const final
Returns true if the collection contains an active property with the specified key.
A rectangle specified with double values.
Contains information about the context of a rendering operation.
const QgsMaskIdProvider * maskIdProvider() const
Returns the mask id provider attached to the context.
double convertToPainterUnits(double size, Qgis::RenderUnit unit, const QgsMapUnitScale &scale=QgsMapUnitScale(), Qgis::RenderSubcomponentProperty property=Qgis::RenderSubcomponentProperty::Generic) const
Converts a size from the specified units to painter units (pixels).
QPainter * painter()
Returns the destination QPainter for the render operation.
QgsExpressionContext & expressionContext()
Gets the expression context.
const QgsRectangle & extent() const
When rendering a map layer, calling this method returns the "clipping" extent for the layer (in the l...
void setCurrentMaskId(int id)
Stores a mask id as the "current" one.
const QgsMapToPixel & mapToPixel() const
Returns the context's map to pixel transform, which transforms between map coordinates and device coo...
QgsCoordinateTransform coordinateTransform() const
Returns the current coordinate transform for the context.
Scoped object for temporary override of the symbologyReferenceScale property of a QgsRenderContext.
Abstract base class for all rendered symbols.
Definition qgssymbol.h:231
bool enabled() const
Returns whether the background is enabled.
ShapeType type() const
Returns the type of background shape (e.g., square, ellipse, SVG).
Represents a block of text consisting of one or more QgsTextFragment objects.
int size() const
Returns the number of fragments in the block.
void insert(int index, const QgsTextFragment &fragment)
Inserts a fragment into the block, at the specified index.
static QgsTextBlock fromPlainText(const QString &text, const QgsTextCharacterFormat &format=QgsTextCharacterFormat())
Constructor for QgsTextBlock consisting of a plain text, and optional character format.
void append(const QgsTextFragment &fragment)
Appends a fragment to the block.
bool enabled() const
Returns whether the buffer is enabled.
Stores information relating to individual character formatting.
Contains pre-calculated metrics of a QgsTextDocument.
double fragmentVerticalOffset(int blockIndex, int fragmentIndex, Qgis::TextLayoutMode mode) const
Returns the vertical offset from a text block's baseline which should be applied to the fragment at t...
static QgsTextDocumentMetrics calculateMetrics(const QgsTextDocument &document, const QgsTextFormat &format, const QgsRenderContext &context, double scaleFactor=1.0, const QgsTextDocumentRenderContext &documentContext=QgsTextDocumentRenderContext())
Returns precalculated text metrics for a text document, when rendered using the given base format and...
double baselineOffset(int blockIndex, Qgis::TextLayoutMode mode) const
Returns the offset from the top of the document to the text baseline for the given block index.
double blockLeftMargin(int blockIndex) const
Returns the margin for the left side of the specified block index.
double fragmentHorizontalAdvance(int blockIndex, int fragmentIndex, Qgis::TextLayoutMode mode) const
Returns the horizontal advance of the fragment at the specified block and fragment index.
double blockVerticalMargin(int blockIndex) const
Returns the vertical margin for the specified block index.
Represents a document consisting of one or more QgsTextBlock objects.
const QgsTextBlock & at(int index) const
Returns the block at the specified index.
int size() const
Returns the number of blocks in the document.
void append(const QgsTextBlock &block)
Appends a block to the document.
Container for all settings relating to text rendering.
void setColor(const QColor &color)
Sets the color that text will be rendered in.
void setSize(double size)
Sets the size for rendered text.
void setFont(const QFont &font)
Sets the font used for rendering text.
void setSizeUnit(Qgis::RenderUnit unit)
Sets the units for the size of rendered text.
QgsTextBackgroundSettings & background()
Returns a reference to the text background settings.
QgsTextShadowSettings & shadow()
Returns a reference to the text drop shadow settings.
QFont font() const
Returns the font used for rendering text.
QgsTextBufferSettings & buffer()
Returns a reference to the text buffer settings.
Stores a fragment of document along with formatting overrides to be used when rendering the fragment.
Class that adds extra information to QgsLabelFeature for text labels.
QFont definedFont() const
Font to be used for rendering.
const QgsTextDocumentMetrics & documentMetrics() const
Returns the document metrics for the label.
const QgsTextDocument & document() const
Returns the document for the label.
QgsTextCharacterFormat characterFormat(int partId) const
Returns the character format corresponding to the specified label part.
const QMap< QgsPalLayerSettings::Property, QVariant > & dataDefinedValues() const
Gets data-defined values.
QString text(int partId) const
Returns the text component corresponding to a specified label part.
bool enabled() const
Returns whether the shadow is enabled.
void setShadowPlacement(QgsTextShadowSettings::ShadowPlacement placement)
Sets the placement for the drop shadow.
@ ShadowBuffer
Draw shadow under buffer.
@ ShadowShape
Draw shadow under background shape.
@ ShadowLowest
Draw shadow below all text components.
@ ShadowText
Draw shadow under text.
QgsTextShadowSettings::ShadowPlacement shadowPlacement() const
Returns the placement for the drop shadow.
void stopRender(QgsRenderContext &context) override
To be called after rendering is complete.
QgsCoordinateReferenceSystem mCrs
Layer's CRS.
virtual bool prepare(QgsRenderContext &context, QSet< QString > &attributeNames)
Prepare for registration of features.
void drawUnplacedLabel(QgsRenderContext &context, pal::LabelPosition *label) const override
Draw an unplaced label.
QList< QgsLabelFeature * > mLabels
List of generated.
QgsVectorLayerLabelProvider(QgsVectorLayer *layer, const QString &providerId, bool withFeatureLoop, const QgsPalLayerSettings *settings, const QString &layerName=QString())
Convenience constructor to initialize the provider from given vector layer.
void startRender(QgsRenderContext &context) override
To be called before rendering of labels begins.
const QgsPalLayerSettings & settings() const
Returns the layer's settings.
void drawLabelPrivate(pal::LabelPosition *label, QgsRenderContext &context, QgsPalLayerSettings &tmpLyr, Qgis::TextComponent drawType, double dpiRatio=1.0) const
Internal label drawing method.
Qgis::GeometryType mLayerGeometryType
Geometry type of layer.
static QgsGeometry getPointObstacleGeometry(QgsFeature &fet, QgsRenderContext &context, const QgsSymbolList &symbols)
Returns the geometry for a point feature which should be used as an obstacle for labels.
QgsPalLayerSettings mSettings
Layer's labeling configuration.
std::unique_ptr< QgsAbstractFeatureSource > mSource
Layer's feature source.
QList< QgsLabelFeature * > labelFeatures(QgsRenderContext &context) override
Returns list of label features (they are owned by the provider and thus deleted on its destruction)
virtual QList< QgsLabelFeature * > registerFeature(const QgsFeature &feature, QgsRenderContext &context, const QgsGeometry &obstacleGeometry=QgsGeometry(), const QgsSymbol *symbol=nullptr)
Register a feature for labeling as one or more QgsLabelFeature objects stored into mLabels.
void init()
initialization method - called from constructors
void setFields(const QgsFields &fields)
Sets fields of this label provider.
void drawLabel(QgsRenderContext &context, pal::LabelPosition *label) const override
Draw this label at the position determined by the labeling engine.
void drawLabelBackground(QgsRenderContext &context, pal::LabelPosition *label) const override
Draw the background for the specified label.
Represents a vector layer which manages a vector based data sets.
QgsFeatureId featureId() const
Returns the unique ID of the feature.
Definition feature.cpp:166
QgsLabelFeature * feature()
Returns the parent feature.
Definition feature.h:94
Layer * layer()
Returns the layer that feature belongs to.
Definition feature.cpp:161
LabelPosition is a candidate feature label position.
double getAlpha() const
Returns the angle to rotate text (in radians).
double getHeight() const
bool conflictsWithObstacle() const
Returns whether the position is marked as conflicting with an obstacle feature.
double getWidth() const
bool isReversedFromLineDirection() const
Returns true if the label direction is the reversed from the line or polygon ring direction.
Qgis::LabelQuadrantPosition quadrant() const
Returns the quadrant associated with this label position.
FeaturePart * getFeaturePart() const
Returns the feature corresponding to this labelposition.
int getPartId() const
double getX(int i=0) const
Returns the down-left x coordinate.
double getY(int i=0) const
Returns the down-left y coordinate.
LabelPosition * nextPart() const
Returns the next part of this label position (i.e.
QgsAbstractLabelProvider * provider() const
Returns pointer to the associated provider.
Definition layer.h:157
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
#define QgsDebugMsgLevel(str, level)
Definition qgslogger.h:39
QList< QgsSymbol * > QgsSymbolList
Definition qgsrenderer.h:47
const QgsCoordinateReferenceSystem & crs
Utility class for identifying a unique vertex within a geometry.
Definition qgsvertexid.h:30