QGIS API Documentation 3.41.0-Master (af5edcb665c)
Loading...
Searching...
No Matches
qgsrasterlabeling.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsrasterlabeling.cpp
3 ---------------
4 begin : December 2024
5 copyright : (C) 2024 by Nyall Dawson
6 email : nyall dot dawson at gmail dot com
7 ***************************************************************************/
8/***************************************************************************
9 * *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 ***************************************************************************/
16
17#include "qgsrasterlabeling.h"
18#include "qgsrasterlayer.h"
19#include "labelposition.h"
20#include "feature.h"
21#include "qgstextrenderer.h"
22#include "qgstextlabelfeature.h"
24#include "qgsstyle.h"
25#include "qgsnumericformat.h"
28#include "qgsapplication.h"
29#include "qgsscaleutils.h"
30#include "qgsmessagelog.h"
31#include "qgsrasterpipe.h"
33
41
46
47void QgsRasterLayerLabelProvider::addLabel( const QgsPoint &mapPoint, const QString &text, QgsRenderContext &context )
48{
49 QgsPoint geom = mapPoint;
50 const QgsTextDocument doc = QgsTextDocument::fromTextAndFormat( { text }, mFormat );
51 QgsTextDocumentMetrics documentMetrics = QgsTextDocumentMetrics::calculateMetrics( doc, mFormat, context );
52 const QSizeF size = documentMetrics.documentSize( Qgis::TextLayoutMode::Point, Qgis::TextOrientation::Horizontal );
53
54
55 // Rotate the geometry if needed, before clipping
56 const QgsMapToPixel &m2p = context.mapToPixel();
57 if ( !qgsDoubleNear( m2p.mapRotation(), 0 ) )
58 {
59 QgsPointXY center = context.mapExtent().center();
60
61 QTransform t = QTransform::fromTranslate( center.x(), center.y() );
62 t.rotate( - m2p.mapRotation() );
63 t.translate( -center.x(), -center.y() );
64 geom.transform( t );
65 }
66
67 const double uPP = m2p.mapUnitsPerPixel();
68 std::unique_ptr< QgsTextLabelFeature > feature = std::make_unique< QgsTextLabelFeature >( mLabels.size(),
69 QgsGeos::asGeos( &geom ),
70 QSizeF( size.width() * uPP,
71 size.height() * uPP ) );
72
73 feature->setDocument( doc, documentMetrics );
74 feature->setFixedAngle( 0 );
75 feature->setHasFixedAngle( true );
76 feature->setQuadOffset( QPointF( 0, 0 ) );
77 feature->setZIndex( mZIndex );
78
79 feature->setOverlapHandling( mPlacementSettings.overlapHandling() );
80
81 mLabels.append( feature.release() );
82}
83
85{
86 mFormat = format;
87}
88
89void QgsRasterLayerLabelProvider::setNumericFormat( std::unique_ptr<QgsNumericFormat> format )
90{
91 mNumericFormat = std::move( format );
92}
93
95{
96 return mNumericFormat.get();
97}
98
100{
101 mResampleMethod = method;
102}
103
105{
106 mResampleOver = pixels;
107}
108
110{
111 return mLabels;
112}
113
115{
116 // as per vector label rendering...
117 QgsMapToPixel xform = context.mapToPixel();
118 xform.setMapRotation( 0, 0, 0 );
119 const QPointF outPt = xform.transform( label->getX(), label->getY() ).toQPointF();
120
121 QgsTextLabelFeature *lf = qgis::down_cast<QgsTextLabelFeature *>( label->getFeaturePart()->feature() );
123 mFormat, lf->document(), lf->documentMetrics(), context, Qgis::TextHorizontalAlignment::Left,
125}
126
133
135// RAII properties restorer for QgsRasterDataProvider
136struct RasterProviderSettingsRestorer
137{
138 QgsRasterDataProvider *mProvider;
139 const bool mProviderResampling;
140 const Qgis::RasterResamplingMethod mZoomedOutMethod;
141 const double mMaxOversampling;
142
143 RasterProviderSettingsRestorer( QgsRasterDataProvider *provider )
144 : mProvider( provider )
145 , mProviderResampling( provider->isProviderResamplingEnabled() )
146 , mZoomedOutMethod( provider->zoomedOutResamplingMethod() )
147 , mMaxOversampling( provider->maxOversampling() ) {}
148
149 ~RasterProviderSettingsRestorer()
150 {
151 mProvider->enableProviderResampling( mProviderResampling );
152 mProvider->setZoomedOutResamplingMethod( mZoomedOutMethod );
153 mProvider->setMaxOversampling( mMaxOversampling );
154 }
155};
157
158void QgsRasterLayerLabelProvider::generateLabels( QgsRenderContext &context, QgsRasterPipe *pipe, QgsRasterViewPort *rasterViewPort, QgsRasterLayerRendererFeedback *feedback )
159{
160 if ( !pipe )
161 return;
162
163 QgsRasterDataProvider *provider = pipe->provider();
164 if ( !provider )
165 return;
166
167 if ( provider->xSize() == 0 || provider->ySize() == 0 )
168 return;
169
170 if ( !rasterViewPort )
171 return;
172
173 // iterate through blocks, directly over the provider.
174 QgsRasterIterator iterator( provider );
175
176 const QSize maxTileSize {provider->maximumTileSize()};
177 iterator.setMaximumTileWidth( maxTileSize.width() );
178 iterator.setMaximumTileHeight( maxTileSize.height() );
179 iterator.setSnapToPixelFactor( mResampleOver );
180
181 // we need to calculate the visible portion of the layer, in the original (layer) CRS:
182 QgsCoordinateTransform layerToMapTransform = context.coordinateTransform();
183 layerToMapTransform.setBallparkTransformsAreAppropriate( true );
184 QgsRectangle layerVisibleExtent;
185 try
186 {
187 layerVisibleExtent = layerToMapTransform.transformBoundingBox( rasterViewPort->mDrawnExtent, Qgis::TransformDirection::Reverse );
188 }
189 catch ( QgsCsException &cs )
190 {
191 QgsMessageLog::logMessage( QObject::tr( "Could not reproject view extent: %1" ).arg( cs.what() ), QObject::tr( "Raster" ) );
192 return;
193 }
194
195 const int maxNumLabels = mThinningSettings.limitNumberOfLabelsEnabled() ? mThinningSettings.maximumNumberLabels() : 0;
196
197 // calculate the portion of the raster which is actually visible in the map
198 int subRegionWidth = 0;
199 int subRegionHeight = 0;
200 int subRegionLeft = 0;
201 int subRegionTop = 0;
203 provider->extent(),
204 provider->xSize(),
205 provider->ySize(),
206 layerVisibleExtent,
207 subRegionWidth,
208 subRegionHeight,
209 subRegionLeft,
210 subRegionTop );
211
212 const double rasterUnitsPerPixelX = provider->extent().width() / provider->xSize() * mResampleOver;
213 const double rasterUnitsPerPixelY = provider->extent().height() / provider->ySize() * mResampleOver;
214
215 const double minPixelSizePainterUnits = context.convertToPainterUnits( mThinningSettings.minimumFeatureSize(), Qgis::RenderUnit::Millimeters );
216 if ( minPixelSizePainterUnits > 0 )
217 {
218 // calculate size in painter units of one raster pixel
219 QgsPointXY p1( rasterSubRegion.xMinimum(), rasterSubRegion.yMinimum() );
220 QgsPointXY p2( rasterSubRegion.xMinimum() + rasterSubRegion.width() / subRegionWidth,
221 rasterSubRegion.yMinimum() + rasterSubRegion.height() / subRegionHeight );
222 try
223 {
224 p1 = context.coordinateTransform().transform( p1 );
225 p2 = context.coordinateTransform().transform( p2 );
226 }
227 catch ( QgsCsException & )
228 {
229 QgsDebugError( QStringLiteral( "Could not transform raster pixel to map crs" ) );
230 return;
231 }
232 const QgsPointXY p1PainterUnits = context.mapToPixel().transform( p1 );
233 const QgsPointXY p2PainterUnits = context.mapToPixel().transform( p2 );
234 const double painterUnitsPerRasterPixel = std::max( std::fabs( p1PainterUnits.x() - p2PainterUnits.x() ),
235 std::fabs( p1PainterUnits.y() - p2PainterUnits.y() ) ) * mResampleOver;
236 if ( painterUnitsPerRasterPixel < minPixelSizePainterUnits )
237 return;
238 }
239
240 iterator.startRasterRead( mBandNumber, subRegionWidth, subRegionHeight, rasterSubRegion, feedback );
241
242 const QgsNumericFormatContext numericContext;
243 QgsNumericFormat *numericFormat = mNumericFormat.get();
244
245 int iterLeft = 0;
246 int iterTop = 0;
247 int iterCols = 0;
248 int iterRows = 0;
249 QgsRectangle blockExtent;
250 std::unique_ptr< QgsRasterBlock > block;
251 bool isNoData = false;
252 int numberLabels = 0;
253
254 RasterProviderSettingsRestorer restorer( provider );
255 if ( mResampleOver > 1 )
256 {
257 provider->enableProviderResampling( true );
258 provider->setZoomedOutResamplingMethod( mResampleMethod );
259 provider->setMaxOversampling( mResampleOver );
260 }
261
262 while ( iterator.next( mBandNumber, iterCols, iterRows, iterLeft, iterTop, blockExtent ) )
263 {
264 if ( feedback && feedback->isCanceled() )
265 return;
266
267 const int resampledColumns = iterCols / mResampleOver;
268 const int resampledRows = iterRows / mResampleOver;
269 block.reset( provider->block( mBandNumber, blockExtent, resampledColumns, resampledRows, feedback ) );
270
271 double currentY = blockExtent.yMaximum() - 0.5 * rasterUnitsPerPixelY;
272
273 for ( int row = 0; row < resampledRows; row++ )
274 {
275 if ( feedback && feedback->isCanceled() )
276 return;
277
278 double currentX = blockExtent.xMinimum() + 0.5 * rasterUnitsPerPixelX;
279
280 for ( int column = 0; column < resampledColumns; column++ )
281 {
282 const double value = block->valueAndNoData( row, column, isNoData );
283 if ( !isNoData )
284 {
285 try
286 {
287 QgsPoint pixelCenter( currentX, currentY );
288 pixelCenter.transform( context.coordinateTransform() );
289
290 addLabel( pixelCenter,
291 numericFormat->formatDouble( value, numericContext ),
292 context );
293 numberLabels++;
294 if ( maxNumLabels > 0 && numberLabels >= maxNumLabels )
295 return;
296 }
297 catch ( QgsCsException & )
298 {
299 QgsDebugError( QStringLiteral( "Could not transform raster pixel center to map crs" ) );
300 }
301 }
302 currentX += rasterUnitsPerPixelX;
303 }
304 currentY -= rasterUnitsPerPixelY;
305 }
306 }
307}
308
309//
310// QgsAbstractRasterLayerLabeling
311//
312
317
319{
320 return true;
321}
322
324{
325 const QString type = element.attribute( QStringLiteral( "type" ) );
326 if ( type == QLatin1String( "simple" ) )
327 {
328 return QgsRasterLayerSimpleLabeling::create( element, context );
329 }
330 else
331 {
332 return nullptr;
333 }
334}
335
336void QgsAbstractRasterLayerLabeling::toSld( QDomNode &parent, const QVariantMap &props ) const
337{
338 Q_UNUSED( parent )
339 Q_UNUSED( props )
340 QDomDocument doc = parent.ownerDocument();
341 parent.appendChild( doc.createComment( QStringLiteral( "SE Export for %1 not implemented yet" ).arg( type() ) ) );
342}
343
348
349//
350// QgsRasterLayerSimpleLabeling
351//
352
353
355 : mNumericFormat( std::make_unique< QgsBasicNumericFormat >() )
356{
357 mThinningSettings.setMaximumNumberLabels( 4000 );
358 mThinningSettings.setLimitNumberLabelsEnabled( true );
359 mThinningSettings.setMinimumFeatureSize( 8 );
360}
361
363
365{
366 return QStringLiteral( "simple" );
367}
368
370{
371 std::unique_ptr< QgsRasterLayerSimpleLabeling > res = std::make_unique< QgsRasterLayerSimpleLabeling >();
372 res->setTextFormat( mTextFormat );
373
374 if ( mNumericFormat )
375 res->mNumericFormat.reset( mNumericFormat->clone() );
376
377 res->setBand( mBandNumber );
378 res->setPriority( mPriority );
379 res->setPlacementSettings( mPlacementSettings );
380 res->setThinningSettings( mThinningSettings );
381 res->setZIndex( mZIndex );
382 res->setScaleBasedVisibility( mScaleVisibility );
383 res->setMaximumScale( mMaximumScale );
384 res->setMinimumScale( mMinimumScale );
385 res->setResampleMethod( mResampleMethod );
386 res->setResampleOver( mResampleOver );
387
388 return res.release();
389}
390
391std::unique_ptr< QgsRasterLayerLabelProvider > QgsRasterLayerSimpleLabeling::provider( QgsRasterLayer *layer ) const
392{
393 std::unique_ptr< QgsRasterLayerLabelProvider > res = std::make_unique< QgsRasterLayerLabelProvider >( layer );
394 res->setTextFormat( mTextFormat );
395 res->setBand( mBandNumber );
396 res->setPriority( mPriority );
397 res->setPlacementSettings( mPlacementSettings );
398 res->setZIndex( mZIndex );
399 res->setThinningSettings( mThinningSettings );
400 res->setResampleMethod( mResampleMethod );
401 res->setResampleOver( mResampleOver );
402 if ( mNumericFormat )
403 {
404 res->setNumericFormat( std::unique_ptr< QgsNumericFormat >( mNumericFormat->clone() ) );
405 }
406 return res;
407}
408
409QDomElement QgsRasterLayerSimpleLabeling::save( QDomDocument &doc, const QgsReadWriteContext &context ) const
410{
411 QDomElement elem = doc.createElement( QStringLiteral( "labeling" ) );
412 elem.setAttribute( QStringLiteral( "type" ), QStringLiteral( "simple" ) );
413 elem.setAttribute( QStringLiteral( "band" ), mBandNumber );
414 elem.setAttribute( QStringLiteral( "priority" ), mPriority );
415 elem.setAttribute( QStringLiteral( "zIndex" ), mZIndex );
416
417 if ( mResampleOver > 1 )
418 {
419 elem.setAttribute( QStringLiteral( "resampleOver" ), mResampleOver );
420 }
421 elem.setAttribute( QStringLiteral( "resampleMethod" ), qgsEnumValueToKey( mResampleMethod ) );
422
423 {
424 QDomElement textFormatElem = doc.createElement( QStringLiteral( "textFormat" ) );
425 textFormatElem.appendChild( mTextFormat.writeXml( doc, context ) );
426 elem.appendChild( textFormatElem );
427 }
428
429 {
430 QDomElement numericFormatElem = doc.createElement( QStringLiteral( "numericFormat" ) );
431 mNumericFormat->writeXml( numericFormatElem, doc, context );
432 elem.appendChild( numericFormatElem );
433 }
434
435 {
436 QDomElement placementElem = doc.createElement( QStringLiteral( "placement" ) );
437 placementElem.setAttribute( QStringLiteral( "overlapHandling" ), qgsEnumValueToKey( mPlacementSettings.overlapHandling() ) );
438 elem.appendChild( placementElem );
439 }
440
441 {
442 QDomElement thinningElem = doc.createElement( QStringLiteral( "thinning" ) );
443 thinningElem.setAttribute( QStringLiteral( "maxNumLabels" ), mThinningSettings.maximumNumberLabels() );
444 thinningElem.setAttribute( QStringLiteral( "limitNumLabels" ), mThinningSettings.limitNumberOfLabelsEnabled() );
445 thinningElem.setAttribute( QStringLiteral( "minFeatureSize" ), mThinningSettings.minimumFeatureSize() );
446 elem.appendChild( thinningElem );
447 }
448
449 {
450 QDomElement renderingElem = doc.createElement( QStringLiteral( "rendering" ) );
451 renderingElem.setAttribute( QStringLiteral( "scaleVisibility" ), mScaleVisibility );
452 // note the element names are "flipped" vs the member -- this is intentional, and done to match vector labeling
453 renderingElem.setAttribute( QStringLiteral( "scaleMin" ), mMaximumScale );
454 renderingElem.setAttribute( QStringLiteral( "scaleMax" ), mMinimumScale );
455 elem.appendChild( renderingElem );
456 }
457
458 return elem;
459}
460
462{
463 QgsStyleTextFormatEntity entity( mTextFormat );
464 if ( !visitor->visit( &entity ) )
465 return false;
466
467 return true;
468}
469
474
476{
477 std::unique_ptr< QgsRasterLayerSimpleLabeling > res = std::make_unique< QgsRasterLayerSimpleLabeling >();
478 res->setBand( element.attribute( QStringLiteral( "band" ), QStringLiteral( "1" ) ).toInt() );
479 res->setPriority( element.attribute( QStringLiteral( "priority" ), QStringLiteral( "0.5" ) ).toDouble() );
480 res->setZIndex( element.attribute( QStringLiteral( "zIndex" ), QStringLiteral( "0" ) ).toDouble() );
481 res->setResampleOver( element.attribute( QStringLiteral( "resampleOver" ), QStringLiteral( "1" ) ).toInt() );
482 res->setResampleMethod( qgsEnumKeyToValue( element.attribute( QStringLiteral( "resampleMethod" ) ), Qgis::RasterResamplingMethod::Average ) );
483
484 const QDomElement textFormatElem = element.firstChildElement( QStringLiteral( "textFormat" ) );
485 if ( !textFormatElem.isNull() )
486 {
487 const QDomNodeList textFormatNodeList = textFormatElem.elementsByTagName( QStringLiteral( "text-style" ) );
488 const QDomElement textFormatElem = textFormatNodeList.at( 0 ).toElement();
489 QgsTextFormat format;
490 format.readXml( textFormatElem, context );
491 res->setTextFormat( format );
492 }
493
494 const QDomNodeList numericFormatNodeList = element.elementsByTagName( QStringLiteral( "numericFormat" ) );
495 if ( !numericFormatNodeList.isEmpty() )
496 {
497 const QDomElement numericFormatElem = numericFormatNodeList.at( 0 ).toElement();
498 res->mNumericFormat.reset( QgsApplication::numericFormatRegistry()->createFromXml( numericFormatElem, context ) );
499 }
500
501 QDomElement placementElem = element.firstChildElement( QStringLiteral( "placement" ) );
502 res->mPlacementSettings.setOverlapHandling( qgsEnumKeyToValue( placementElem.attribute( QStringLiteral( "overlapHandling" ) ), Qgis::LabelOverlapHandling::PreventOverlap ) );
503
504 QDomElement thinningElem = element.firstChildElement( QStringLiteral( "thinning" ) );
505 res->mThinningSettings.setMaximumNumberLabels( thinningElem.attribute( QStringLiteral( "maxNumLabels" ), QStringLiteral( "4000" ) ).toInt() );
506 res->mThinningSettings.setLimitNumberLabelsEnabled( thinningElem.attribute( QStringLiteral( "limitNumLabels" ), QStringLiteral( "1" ) ).toInt() );
507 res->mThinningSettings.setMinimumFeatureSize( thinningElem.attribute( QStringLiteral( "minFeatureSize" ), QStringLiteral( "8" ) ).toDouble() );
508
509 QDomElement renderingElem = element.firstChildElement( QStringLiteral( "rendering" ) );
510 // note the element names are "flipped" vs the member -- this is intentional, and done to match vector labeling
511 res->mMaximumScale = renderingElem.attribute( QStringLiteral( "scaleMin" ), QStringLiteral( "0" ) ).toDouble();
512 res->mMinimumScale = renderingElem.attribute( QStringLiteral( "scaleMax" ), QStringLiteral( "0" ) ).toDouble();
513 res->mScaleVisibility = renderingElem.attribute( QStringLiteral( "scaleVisibility" ) ).toInt();
514
515 return res.release();
516}
517
519{
520 return mTextFormat;
521}
522
524{
525 mTextFormat = format;
526}
527
529{
530 return mNumericFormat.get();
531}
532
534{
535 if ( format != mNumericFormat.get() )
536 mNumericFormat.reset( format );
537}
538
540{
541 return mZIndex;
542}
543
545{
546 mZIndex = index;
547}
548
550{
551 return mMaximumScale;
552}
553
555{
556 mMaximumScale = scale;
557}
558
560{
561 return mMinimumScale;
562}
563
565{
566 mMinimumScale = scale;
567}
568
570{
571 return mScaleVisibility;
572}
573
575{
576 // mMinScale (denominator!) is inclusive ( >= --> In range )
577 // mMaxScale (denominator!) is exclusive ( < --> In range )
578 return !mScaleVisibility
579 || ( ( mMinimumScale == 0 || !QgsScaleUtils::lessThanMaximumScale( scale, mMinimumScale ) )
580 && ( mMaximumScale == 0 || !QgsScaleUtils::equalToOrGreaterThanMinimumScale( scale, mMaximumScale ) ) );
581}
582
587
589{
590 mResampleMethod = method;
591}
592
594{
595 return mResampleOver;
596}
597
599{
600 mResampleOver = pixels;
601}
602
604{
605 mScaleVisibility = enabled;
606}
607
609{
610 mTextFormat.multiplyOpacity( opacityFactor );
611}
612
614{
615 std::unique_ptr< QgsRasterLayerSimpleLabeling > res = std::make_unique< QgsRasterLayerSimpleLabeling >();
616 res->setTextFormat( QgsStyle::defaultTextFormatForProject( layer->project() ) );
617 res->setBand( 1 );
618 return res.release();
619}
@ OverPoint
Arranges candidates over a point (or centroid of a polygon), or at a preset offset from the point....
RasterResamplingMethod
Resampling method for raster provider-level resampling.
Definition qgis.h:1394
@ Average
Average resampling.
@ Labeling
Labeling-specific layout mode.
@ Point
Text at point of origin layout mode.
@ Horizontal
Horizontally oriented text.
@ Millimeters
Millimeters.
@ PreventOverlap
Do not allow labels to overlap other labels.
@ Reverse
Reverse/inverse transform (from destination to source)
The QgsAbstractLabelProvider class is an interface class.
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.
@ DrawLabels
Whether the labels should be rendered.
Abstract base class for labeling settings for raster layers.
virtual QString type() const =0
Unique type string of the labeling configuration implementation.
virtual bool isInScaleRange(double scale) const
Tests whether the labels should be visible at the specified scale.
virtual bool accept(QgsStyleEntityVisitorInterface *visitor) const
Accepts the specified symbology visitor, causing it to visit all symbols associated with the labeling...
virtual void toSld(QDomNode &parent, const QVariantMap &props) const
Writes the SE 1.1 TextSymbolizer element based on the current layer labeling settings.
static QgsAbstractRasterLayerLabeling * createFromElement(const QDomElement &element, const QgsReadWriteContext &context)
Tries to create an instance of an implementation based on the XML data.
virtual void multiplyOpacity(double opacityFactor)
Multiply opacity by opacityFactor.
static QgsAbstractRasterLayerLabeling * defaultLabelingForLayer(QgsRasterLayer *layer)
Creates default labeling for a raster layer.
static QgsNumericFormatRegistry * numericFormatRegistry()
Gets the registry of available numeric formats.
A numeric formatter which returns a simple text representation of a value.
Class for doing transforms between two map coordinate systems.
void setBallparkTransformsAreAppropriate(bool appropriate)
Sets whether approximate "ballpark" results are appropriate for this coordinate transform.
QgsPointXY transform(const QgsPointXY &point, Qgis::TransformDirection direction=Qgis::TransformDirection::Forward) const
Transform the point from the source CRS to the destination CRS.
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.
Custom exception class for Coordinate Reference System related exceptions.
QString what() const
static geos::unique_ptr asGeos(const QgsGeometry &geometry, double precision=0, Qgis::GeosCreationFlags flags=Qgis::GeosCreationFlags())
Returns a geos geometry - caller takes ownership of the object (should be deleted with GEOSGeom_destr...
Definition qgsgeos.cpp:257
Qgis::LabelOverlapHandling overlapHandling() const
Returns the technique used to handle overlapping labels.
void setMaximumNumberLabels(int number)
Sets the maximum number of labels which should be drawn for this layer.
double minimumFeatureSize() const
Returns the minimum feature size (in millimeters) for a feature to be labelled.
int maximumNumberLabels() const
Returns the maximum number of labels which should be drawn for this layer.
void setLimitNumberLabelsEnabled(bool enabled)
Sets whether the the number of labels drawn for the layer should be limited.
bool limitNumberOfLabelsEnabled() const
Returns true if the number of labels drawn for the layer should be limited.
void setMinimumFeatureSize(double size)
Sets the minimum feature size (in millimeters) for a feature to be labelled.
QgsProject * project() const
Returns the parent project if this map layer is added to a project.
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 transform(const QgsPointXY &p) const
Transforms a point p from map (world) coordinates to device coordinates.
double mapRotation() const
Returns the current map rotation in degrees (clockwise).
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::MessageLevel::Warning, bool notifyUser=true)
Adds a message to the log instance (and creates it if necessary).
A context for numeric formats.
A numeric formatter allows for formatting a numeric value for display, using a variety of different f...
virtual QString formatDouble(double value, const QgsNumericFormatContext &context) const =0
Returns a formatted string representation of a numeric double value.
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
void transform(const QgsCoordinateTransform &ct, Qgis::TransformDirection d=Qgis::TransformDirection::Forward, bool transformZ=false) override
Transforms the geometry using a coordinate transform.
Definition qgspoint.cpp:384
bool hasActiveProperties() const final
Returns true if the collection has any active properties, or false if all properties within the colle...
Base class for raster data providers.
virtual QSize maximumTileSize() const
Returns the maximum tile size in pixels for the data provider.
virtual bool setZoomedOutResamplingMethod(Qgis::RasterResamplingMethod method)
Set resampling method to apply for zoomed-out operations.
virtual bool enableProviderResampling(bool enable)
Enable or disable provider-level resampling.
QgsRectangle extent() const override=0
Returns the extent of the layer.
virtual bool setMaxOversampling(double factor)
Sets maximum oversampling factor for zoomed-out operations.
QgsRasterBlock * block(int bandNo, const QgsRectangle &boundingBox, int width, int height, QgsRasterBlockFeedback *feedback=nullptr) override
Read block of data using given extent and size.
virtual int xSize() const
Gets raster size.
virtual int ySize() const
Iterator for sequentially processing raster cells.
void setSnapToPixelFactor(int factor)
Sets the "snap to pixel" factor in pixels.
static QgsRectangle subRegion(const QgsRectangle &rasterExtent, int rasterWidth, int rasterHeight, const QgsRectangle &subRegion, int &subRegionWidth, int &subRegionHeight, int &subRegionLeft, int &subRegionTop, int resamplingFactor=1)
Given an overall raster extent and width and height in pixels, calculates the sub region of the raste...
bool next(int bandNumber, int &columns, int &rows, int &topLeftColumn, int &topLeftRow, QgsRectangle &blockExtent)
Fetches details of the next part of the raster data.
void setMaximumTileWidth(int w)
Sets the maximum tile width returned during iteration.
void startRasterRead(int bandNumber, qgssize nCols, qgssize nRows, const QgsRectangle &extent, QgsRasterBlockFeedback *feedback=nullptr)
Start reading of raster band.
void setMaximumTileHeight(int h)
Sets the minimum tile height returned during iteration.
void setTextFormat(const QgsTextFormat &format)
Sets the text format used for rendering the labels.
QgsRasterLayerLabelProvider(QgsRasterLayer *layer)
Constructor for QgsRasterLayerLabelProvider.
void setResampleMethod(Qgis::RasterResamplingMethod method)
Sets the resampling method to use when the raster labels are being resampled over neighboring pixels.
void addLabel(const QgsPoint &mapPoint, const QString &text, QgsRenderContext &context)
Adds a label at the specified point in map coordinates.
QgsNumericFormat * numericFormat()
Returns the numeric format to be used for the labels.
void generateLabels(QgsRenderContext &context, QgsRasterPipe *pipe, QgsRasterViewPort *rasterViewPort, QgsRasterLayerRendererFeedback *feedback)
Generates the labels, given a render context and input pipe.
void drawLabel(QgsRenderContext &context, pal::LabelPosition *label) const final
Draw this label at the position determined by the labeling engine.
QList< QgsLabelFeature * > labelFeatures(QgsRenderContext &) final
Returns list of label features (they are owned by the provider and thus deleted on its destruction)
void setNumericFormat(std::unique_ptr< QgsNumericFormat > format)
Sets the numeric format used for the labels.
void startRender(QgsRenderContext &context) final
To be called before rendering of labels begins.
void setResampleOver(int pixels)
Sets the number of neighboring pixels to resample over, when labels are showing values resampled over...
Basic implementation of the labeling interface for raster layers.
double maximumScale() const
Returns the maximum map scale (i.e.
int resampleOver() const
Returns the number of neighboring pixels to resample over, when labels are showing values resampled o...
void setTextFormat(const QgsTextFormat &format)
Sets the text format used for rendering the labels.
double zIndex() const
Returns the Z-Index of the labels.
double minimumScale() const
Returns the minimum map scale (i.e.
bool hasScaleBasedVisibility() const
Returns whether scale based visibility is enabled for the labels.
static QgsRasterLayerSimpleLabeling * create(const QDomElement &element, const QgsReadWriteContext &context)
Creates a QgsRasterLayerSimpleLabeling from a DOM element with saved configuration.
void setScaleBasedVisibility(bool enabled)
Sets whether scale based visibility is enabled for the labels.
void setResampleMethod(Qgis::RasterResamplingMethod method)
Sets the resampling method to use when the raster labels are being resampled over neighboring pixels.
void setMinimumScale(double scale)
Sets the minimum map scale (i.e.
void setNumericFormat(QgsNumericFormat *format)
Sets the numeric format used for the labels.
~QgsRasterLayerSimpleLabeling() override
bool accept(QgsStyleEntityVisitorInterface *visitor) const override
Accepts the specified symbology visitor, causing it to visit all symbols associated with the labeling...
std::unique_ptr< QgsRasterLayerLabelProvider > provider(QgsRasterLayer *layer) const override
Creates a raster label provider corresponding to this object's configuration.
QgsTextFormat textFormat() const
Returns the text format used for rendering the labels.
bool isInScaleRange(double scale) const override
Tests whether the labels should be visible at the specified scale.
void setMaximumScale(double scale)
Sets the maximum map scale (i.e.
Qgis::RasterResamplingMethod resampleMethod() const
Returns the resampling method used when the raster labels are being resampled over neighboring pixels...
void setResampleOver(int pixels)
Sets the number of neighboring pixels to resample over, when labels are showing values resampled over...
void multiplyOpacity(double opacityFactor) override
Multiply opacity by opacityFactor.
QString type() const override
Unique type string of the labeling configuration implementation.
QDomElement save(QDomDocument &doc, const QgsReadWriteContext &context) const override
Saves the labeling configuration to an XML element.
QgsRasterLayerSimpleLabeling * clone() const override
Returns a new copy of the object.
const QgsNumericFormat * numericFormat() const
Returns the numeric format used for the labels.
bool requiresAdvancedEffects() const override
Returns true if drawing labels requires advanced effects like composition modes, which could prevent ...
void setZIndex(double index)
Sets the Z-Index of the labels.
Represents a raster layer.
Contains a pipeline of raster interfaces for sequential raster processing.
QgsRasterDataProvider * provider() const
Returns the data provider interface, or nullptr if no data provider is present in the pipe.
The class is used as a container of context for various read/write operations on other objects.
A rectangle specified with double values.
double xMinimum
double yMinimum
double yMaximum
QgsPointXY center
Contains information about the context of a rendering operation.
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).
QgsRectangle mapExtent() const
Returns the original extent of the map being rendered.
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.
static bool equalToOrGreaterThanMinimumScale(const double scale, const double minScale)
Returns whether the scale is equal to or greater than the minScale, taking non-round numbers into acc...
static bool lessThanMaximumScale(const double scale, const double maxScale)
Returns whether the scale is less than the maxScale, taking non-round numbers into account.
An interface for classes which can visit style entity (e.g.
virtual bool visit(const QgsStyleEntityVisitorInterface::StyleLeaf &entity)
Called when the visitor will visit a style entity.
A text format entity for QgsStyle databases.
Definition qgsstyle.h:1459
static QgsTextFormat defaultTextFormatForProject(QgsProject *project, QgsStyle::TextFormatContext context=QgsStyle::TextFormatContext::Labeling)
Returns the default text format to use for new text based objects for the specified project,...
Contains pre-calculated metrics of a QgsTextDocument.
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...
Represents a document consisting of one or more QgsTextBlock objects.
static QgsTextDocument fromTextAndFormat(const QStringList &lines, const QgsTextFormat &format)
Constructor for QgsTextDocument consisting of a set of lines, respecting settings from a text format.
Container for all settings relating to text rendering.
void updateDataDefinedProperties(QgsRenderContext &context)
Updates the format by evaluating current values of data defined properties.
QgsPropertyCollection & dataDefinedProperties()
Returns a reference to the format's property collection, used for data defined overrides.
void multiplyOpacity(double opacityFactor)
Multiply opacity by opacityFactor.
void readXml(const QDomElement &elem, const QgsReadWriteContext &context)
Read settings from a DOM element.
QDomElement writeXml(QDomDocument &doc, const QgsReadWriteContext &context) const
Write settings into a DOM element.
bool containsAdvancedEffects() const
Returns true if any component of the font format requires advanced effects such as blend modes,...
Class that adds extra information to QgsLabelFeature for text labels.
const QgsTextDocumentMetrics & documentMetrics() const
Returns the document metrics for the label.
const QgsTextDocument & document() const
Returns the document for the label.
static void drawDocument(const QRectF &rect, const QgsTextFormat &format, const QgsTextDocument &document, const QgsTextDocumentMetrics &metrics, QgsRenderContext &context, Qgis::TextHorizontalAlignment horizontalAlignment=Qgis::TextHorizontalAlignment::Left, Qgis::TextVerticalAlignment verticalAlignment=Qgis::TextVerticalAlignment::Top, double rotation=0, Qgis::TextLayoutMode mode=Qgis::TextLayoutMode::Rectangle, Qgis::TextRendererFlags flags=Qgis::TextRendererFlags())
Draws a text document within a rectangle using the specified settings.
QgsLabelFeature * feature()
Returns the parent feature.
Definition feature.h:94
LabelPosition is a candidate feature label position.
double getAlpha() const
Returns the angle to rotate text (in radians).
FeaturePart * getFeaturePart() const
Returns the feature corresponding to this labelposition.
double getX(int i=0) const
Returns the down-left x coordinate.
double getY(int i=0) const
Returns the down-left y coordinate.
T qgsEnumKeyToValue(const QString &key, const T &defaultValue, bool tryValueAsKey=true, bool *returnOk=nullptr)
Returns the value corresponding to the given key of an enum.
Definition qgis.h:6276
QString qgsEnumValueToKey(const T &value, bool *returnOk=nullptr)
Returns the value for the given key of an enum.
Definition qgis.h:6257
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
Definition qgis.h:6066
#define QgsDebugError(str)
Definition qgslogger.h:38
This class provides details of the viewable area that a raster will be rendered into.
QgsRectangle mDrawnExtent
Intersection of current map extent and layer extent, in map (destination) CRS.