QGIS API Documentation 3.99.0-Master (2fe06baccd8)
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
19#include "feature.h"
20#include "labelposition.h"
21#include "qgsapplication.h"
23#include "qgsmessagelog.h"
24#include "qgsnumericformat.h"
26#include "qgsrasterlayer.h"
28#include "qgsrasterpipe.h"
29#include "qgsscaleutils.h"
30#include "qgsstyle.h"
32#include "qgstextlabelfeature.h"
33#include "qgstextrenderer.h"
34
42
47
48void QgsRasterLayerLabelProvider::addLabel( const QgsPoint &mapPoint, const QString &text, QgsRenderContext &context )
49{
50 QgsPoint geom = mapPoint;
51 const QgsTextDocument doc = QgsTextDocument::fromTextAndFormat( text.split( "\n" ), mFormat );
52 QgsTextDocumentMetrics documentMetrics = QgsTextDocumentMetrics::calculateMetrics( doc, mFormat, context );
54
55
56 // Rotate the geometry if needed, before clipping
57 const QgsMapToPixel &m2p = context.mapToPixel();
58 if ( !qgsDoubleNear( m2p.mapRotation(), 0 ) )
59 {
60 QgsPointXY center = context.mapExtent().center();
61
62 QTransform t = QTransform::fromTranslate( center.x(), center.y() );
63 t.rotate( - m2p.mapRotation() );
64 t.translate( -center.x(), -center.y() );
65 geom.transform( t );
66 }
67
68 const double uPP = m2p.mapUnitsPerPixel();
69 auto feature = std::make_unique< QgsTextLabelFeature >( mLabels.size(),
70 QgsGeos::asGeos( &geom ),
71 QSizeF( size.width() * uPP,
72 size.height() * uPP ) );
73
74 feature->setDocument( doc, documentMetrics );
75 feature->setFixedAngle( 0 );
76 feature->setHasFixedAngle( true );
77 feature->setQuadOffset( QPointF( 0, 0 ) );
78 feature->setZIndex( mZIndex );
79
80 feature->setOverlapHandling( mPlacementSettings.overlapHandling() );
81
82 mLabels.append( feature.release() );
83}
84
86{
87 mFormat = format;
88}
89
90void QgsRasterLayerLabelProvider::setNumericFormat( std::unique_ptr<QgsNumericFormat> format )
91{
92 mNumericFormat = std::move( format );
93}
94
96{
97 return mNumericFormat.get();
98}
99
101{
102 mResampleMethod = method;
103}
104
106{
107 mResampleOver = pixels;
108}
109
111{
112 return mLabels;
113}
114
116{
117 // as per vector label rendering...
118 QgsMapToPixel xform = context.mapToPixel();
119 xform.setMapRotation( 0, 0, 0 );
120 const QPointF outPt = xform.transform( label->getX(), label->getY() ).toQPointF();
121
122 QgsTextLabelFeature *lf = qgis::down_cast<QgsTextLabelFeature *>( label->getFeaturePart()->feature() );
124 mFormat, lf->document(), lf->documentMetrics(), context, Qgis::TextHorizontalAlignment::Left,
126}
127
129{
130 if ( mFormat.dataDefinedProperties().hasActiveProperties() )
131 mFormat.updateDataDefinedProperties( context );
133}
134
136// RAII properties restorer for QgsRasterDataProvider
137struct RasterProviderSettingsRestorer
138{
139 QgsRasterDataProvider *mProvider;
140 const bool mProviderResampling;
141 const Qgis::RasterResamplingMethod mZoomedOutMethod;
142 const double mMaxOversampling;
143
144 RasterProviderSettingsRestorer( QgsRasterDataProvider *provider )
145 : mProvider( provider )
146 , mProviderResampling( provider->isProviderResamplingEnabled() )
147 , mZoomedOutMethod( provider->zoomedOutResamplingMethod() )
148 , mMaxOversampling( provider->maxOversampling() ) {}
149
150 ~RasterProviderSettingsRestorer()
151 {
152 mProvider->enableProviderResampling( mProviderResampling );
153 mProvider->setZoomedOutResamplingMethod( mZoomedOutMethod );
154 mProvider->setMaxOversampling( mMaxOversampling );
155 }
156};
158
159void QgsRasterLayerLabelProvider::generateLabels( QgsRenderContext &context, QgsRasterPipe *pipe, QgsRasterViewPort *rasterViewPort, QgsRasterLayerRendererFeedback *feedback )
160{
161 if ( !pipe )
162 return;
163
164 QgsRasterDataProvider *provider = pipe->provider();
165 if ( !provider )
166 return;
167
168 if ( provider->xSize() == 0 || provider->ySize() == 0 )
169 return;
170
171 if ( !rasterViewPort )
172 return;
173
174 // iterate through blocks, directly over the provider.
175 QgsRasterIterator iterator( provider );
176
177 const QSize maxTileSize {provider->maximumTileSize()};
178 iterator.setMaximumTileWidth( maxTileSize.width() );
179 iterator.setMaximumTileHeight( maxTileSize.height() );
180 iterator.setSnapToPixelFactor( mResampleOver );
181
182 // we need to calculate the visible portion of the layer, in the original (layer) CRS:
183 QgsCoordinateTransform layerToMapTransform = context.coordinateTransform();
184 layerToMapTransform.setBallparkTransformsAreAppropriate( true );
185 QgsRectangle layerVisibleExtent;
186 try
187 {
188 layerVisibleExtent = layerToMapTransform.transformBoundingBox( rasterViewPort->mDrawnExtent, Qgis::TransformDirection::Reverse );
189 }
190 catch ( QgsCsException &cs )
191 {
192 QgsMessageLog::logMessage( QObject::tr( "Could not reproject view extent: %1" ).arg( cs.what() ), QObject::tr( "Raster" ) );
193 return;
194 }
195
196 const int maxNumLabels = mThinningSettings.limitNumberOfLabelsEnabled() ? mThinningSettings.maximumNumberLabels() : 0;
197
198 // calculate the portion of the raster which is actually visible in the map
199 int subRegionWidth = 0;
200 int subRegionHeight = 0;
201 int subRegionLeft = 0;
202 int subRegionTop = 0;
204 provider->extent(),
205 provider->xSize(),
206 provider->ySize(),
207 layerVisibleExtent,
208 subRegionWidth,
209 subRegionHeight,
210 subRegionLeft,
211 subRegionTop );
212
213 const double rasterUnitsPerPixelX = provider->extent().width() / provider->xSize() * mResampleOver;
214 const double rasterUnitsPerPixelY = provider->extent().height() / provider->ySize() * mResampleOver;
215
216 const double minPixelSizePainterUnits = context.convertToPainterUnits( mThinningSettings.minimumFeatureSize(), Qgis::RenderUnit::Millimeters );
217 if ( minPixelSizePainterUnits > 0 )
218 {
219 // calculate size in painter units of one raster pixel
220 QgsPointXY p1( rasterSubRegion.xMinimum(), rasterSubRegion.yMinimum() );
221 QgsPointXY p2( rasterSubRegion.xMinimum() + rasterSubRegion.width() / subRegionWidth,
222 rasterSubRegion.yMinimum() + rasterSubRegion.height() / subRegionHeight );
223 try
224 {
225 p1 = context.coordinateTransform().transform( p1 );
226 p2 = context.coordinateTransform().transform( p2 );
227 }
228 catch ( QgsCsException & )
229 {
230 QgsDebugError( QStringLiteral( "Could not transform raster pixel to map crs" ) );
231 return;
232 }
233 const QgsPointXY p1PainterUnits = context.mapToPixel().transform( p1 );
234 const QgsPointXY p2PainterUnits = context.mapToPixel().transform( p2 );
235 const double painterUnitsPerRasterPixel = std::max( std::fabs( p1PainterUnits.x() - p2PainterUnits.x() ),
236 std::fabs( p1PainterUnits.y() - p2PainterUnits.y() ) ) * mResampleOver;
237 if ( painterUnitsPerRasterPixel < minPixelSizePainterUnits )
238 return;
239 }
240
241 iterator.startRasterRead( mBandNumber, subRegionWidth, subRegionHeight, rasterSubRegion, feedback );
242
243 QgsNumericFormatContext numericContext;
244 numericContext.setExpressionContext( context.expressionContext() );
245 QgsNumericFormat *numericFormat = mNumericFormat.get();
246
247 int iterLeft = 0;
248 int iterTop = 0;
249 int iterCols = 0;
250 int iterRows = 0;
251 QgsRectangle blockExtent;
252 std::unique_ptr< QgsRasterBlock > block;
253 bool isNoData = false;
254 int numberLabels = 0;
255
256 RasterProviderSettingsRestorer restorer( provider );
257 if ( mResampleOver > 1 )
258 {
259 provider->enableProviderResampling( true );
260 provider->setZoomedOutResamplingMethod( mResampleMethod );
261 provider->setMaxOversampling( mResampleOver );
262 }
263
264 while ( iterator.next( mBandNumber, iterCols, iterRows, iterLeft, iterTop, blockExtent ) )
265 {
266 if ( feedback && feedback->isCanceled() )
267 return;
268
269 const int resampledColumns = iterCols / mResampleOver;
270 const int resampledRows = iterRows / mResampleOver;
271 block.reset( provider->block( mBandNumber, blockExtent, resampledColumns, resampledRows, feedback ) );
272
273 double currentY = blockExtent.yMaximum() - 0.5 * rasterUnitsPerPixelY;
274
275 for ( int row = 0; row < resampledRows; row++ )
276 {
277 if ( feedback && feedback->isCanceled() )
278 return;
279
280 double currentX = blockExtent.xMinimum() + 0.5 * rasterUnitsPerPixelX;
281
282 for ( int column = 0; column < resampledColumns; column++ )
283 {
284 const double value = block->valueAndNoData( row, column, isNoData );
285 if ( !isNoData )
286 {
287 try
288 {
289 QgsPoint pixelCenter( currentX, currentY );
290 pixelCenter.transform( context.coordinateTransform() );
291
292 addLabel( pixelCenter,
293 numericFormat->formatDouble( value, numericContext ),
294 context );
295 numberLabels++;
296 if ( maxNumLabels > 0 && numberLabels >= maxNumLabels )
297 return;
298 }
299 catch ( QgsCsException & )
300 {
301 QgsDebugError( QStringLiteral( "Could not transform raster pixel center to map crs" ) );
302 }
303 }
304 currentX += rasterUnitsPerPixelX;
305 }
306 currentY -= rasterUnitsPerPixelY;
307 }
308 }
309}
310
311//
312// QgsAbstractRasterLayerLabeling
313//
314
319
321{
322 return true;
323}
324
326{
327 const QString type = element.attribute( QStringLiteral( "type" ) );
328 if ( type == QLatin1String( "simple" ) )
329 {
330 return QgsRasterLayerSimpleLabeling::create( element, context );
331 }
332 else
333 {
334 return nullptr;
335 }
336}
337
338void QgsAbstractRasterLayerLabeling::toSld( QDomNode &parent, const QVariantMap &props ) const
339{
340 Q_UNUSED( parent )
341 Q_UNUSED( props )
342 QDomDocument doc = parent.ownerDocument();
343 parent.appendChild( doc.createComment( QStringLiteral( "SE Export for %1 not implemented yet" ).arg( type() ) ) );
344}
345
350
351//
352// QgsRasterLayerSimpleLabeling
353//
354
355
357 : mNumericFormat( std::make_unique< QgsBasicNumericFormat >() )
358{
359 mThinningSettings.setMaximumNumberLabels( 4000 );
360 mThinningSettings.setLimitNumberLabelsEnabled( true );
361 mThinningSettings.setMinimumFeatureSize( 8 );
362}
363
365
367{
368 return QStringLiteral( "simple" );
369}
370
372{
373 auto res = std::make_unique< QgsRasterLayerSimpleLabeling >();
374 res->setTextFormat( mTextFormat );
375
376 if ( mNumericFormat )
377 res->mNumericFormat.reset( mNumericFormat->clone() );
378
379 res->setBand( mBandNumber );
380 res->setPriority( mPriority );
381 res->setPlacementSettings( mPlacementSettings );
382 res->setThinningSettings( mThinningSettings );
383 res->setZIndex( mZIndex );
384 res->setScaleBasedVisibility( mScaleVisibility );
385 res->setMaximumScale( mMaximumScale );
386 res->setMinimumScale( mMinimumScale );
387 res->setResampleMethod( mResampleMethod );
388 res->setResampleOver( mResampleOver );
389
390 return res.release();
391}
392
393std::unique_ptr< QgsRasterLayerLabelProvider > QgsRasterLayerSimpleLabeling::provider( QgsRasterLayer *layer ) const
394{
395 auto res = std::make_unique< QgsRasterLayerLabelProvider >( layer );
396 res->setTextFormat( mTextFormat );
397 res->setBand( mBandNumber );
398 res->setPriority( mPriority );
399 res->setPlacementSettings( mPlacementSettings );
400 res->setZIndex( mZIndex );
401 res->setThinningSettings( mThinningSettings );
402 res->setResampleMethod( mResampleMethod );
403 res->setResampleOver( mResampleOver );
404 if ( mNumericFormat )
405 {
406 res->setNumericFormat( std::unique_ptr< QgsNumericFormat >( mNumericFormat->clone() ) );
407 }
408 return res;
409}
410
411QDomElement QgsRasterLayerSimpleLabeling::save( QDomDocument &doc, const QgsReadWriteContext &context ) const
412{
413 QDomElement elem = doc.createElement( QStringLiteral( "labeling" ) );
414 elem.setAttribute( QStringLiteral( "type" ), QStringLiteral( "simple" ) );
415 elem.setAttribute( QStringLiteral( "band" ), mBandNumber );
416 elem.setAttribute( QStringLiteral( "priority" ), mPriority );
417 elem.setAttribute( QStringLiteral( "zIndex" ), mZIndex );
418
419 if ( mResampleOver > 1 )
420 {
421 elem.setAttribute( QStringLiteral( "resampleOver" ), mResampleOver );
422 }
423 elem.setAttribute( QStringLiteral( "resampleMethod" ), qgsEnumValueToKey( mResampleMethod ) );
424
425 {
426 QDomElement textFormatElem = doc.createElement( QStringLiteral( "textFormat" ) );
427 textFormatElem.appendChild( mTextFormat.writeXml( doc, context ) );
428 elem.appendChild( textFormatElem );
429 }
430
431 {
432 QDomElement numericFormatElem = doc.createElement( QStringLiteral( "numericFormat" ) );
433 mNumericFormat->writeXml( numericFormatElem, doc, context );
434 elem.appendChild( numericFormatElem );
435 }
436
437 {
438 QDomElement placementElem = doc.createElement( QStringLiteral( "placement" ) );
439 placementElem.setAttribute( QStringLiteral( "overlapHandling" ), qgsEnumValueToKey( mPlacementSettings.overlapHandling() ) );
440 elem.appendChild( placementElem );
441 }
442
443 {
444 QDomElement thinningElem = doc.createElement( QStringLiteral( "thinning" ) );
445 thinningElem.setAttribute( QStringLiteral( "maxNumLabels" ), mThinningSettings.maximumNumberLabels() );
446 thinningElem.setAttribute( QStringLiteral( "limitNumLabels" ), mThinningSettings.limitNumberOfLabelsEnabled() );
447 thinningElem.setAttribute( QStringLiteral( "minFeatureSize" ), mThinningSettings.minimumFeatureSize() );
448 elem.appendChild( thinningElem );
449 }
450
451 {
452 QDomElement renderingElem = doc.createElement( QStringLiteral( "rendering" ) );
453 renderingElem.setAttribute( QStringLiteral( "scaleVisibility" ), mScaleVisibility );
454 // note the element names are "flipped" vs the member -- this is intentional, and done to match vector labeling
455 renderingElem.setAttribute( QStringLiteral( "scaleMin" ), mMaximumScale );
456 renderingElem.setAttribute( QStringLiteral( "scaleMax" ), mMinimumScale );
457 elem.appendChild( renderingElem );
458 }
459
460 return elem;
461}
462
464{
465 QgsStyleTextFormatEntity entity( mTextFormat );
466 if ( !visitor->visit( &entity ) )
467 return false;
468
469 return true;
470}
471
473{
474 return mTextFormat.containsAdvancedEffects();
475}
476
478{
479 return mTextFormat.hasNonDefaultCompositionMode();
480}
481
483{
484 auto res = std::make_unique< QgsRasterLayerSimpleLabeling >();
485 res->setBand( element.attribute( QStringLiteral( "band" ), QStringLiteral( "1" ) ).toInt() );
486 res->setPriority( element.attribute( QStringLiteral( "priority" ), QStringLiteral( "0.5" ) ).toDouble() );
487 res->setZIndex( element.attribute( QStringLiteral( "zIndex" ), QStringLiteral( "0" ) ).toDouble() );
488 res->setResampleOver( element.attribute( QStringLiteral( "resampleOver" ), QStringLiteral( "1" ) ).toInt() );
489 res->setResampleMethod( qgsEnumKeyToValue( element.attribute( QStringLiteral( "resampleMethod" ) ), Qgis::RasterResamplingMethod::Average ) );
490
491 const QDomElement textFormatElem = element.firstChildElement( QStringLiteral( "textFormat" ) );
492 if ( !textFormatElem.isNull() )
493 {
494 const QDomNodeList textFormatNodeList = textFormatElem.elementsByTagName( QStringLiteral( "text-style" ) );
495 const QDomElement textFormatElem = textFormatNodeList.at( 0 ).toElement();
496 QgsTextFormat format;
497 format.readXml( textFormatElem, context );
498 res->setTextFormat( format );
499 }
500
501 const QDomNodeList numericFormatNodeList = element.elementsByTagName( QStringLiteral( "numericFormat" ) );
502 if ( !numericFormatNodeList.isEmpty() )
503 {
504 const QDomElement numericFormatElem = numericFormatNodeList.at( 0 ).toElement();
505 res->mNumericFormat.reset( QgsApplication::numericFormatRegistry()->createFromXml( numericFormatElem, context ) );
506 }
507
508 QDomElement placementElem = element.firstChildElement( QStringLiteral( "placement" ) );
509 res->mPlacementSettings.setOverlapHandling( qgsEnumKeyToValue( placementElem.attribute( QStringLiteral( "overlapHandling" ) ), Qgis::LabelOverlapHandling::PreventOverlap ) );
510
511 QDomElement thinningElem = element.firstChildElement( QStringLiteral( "thinning" ) );
512 res->mThinningSettings.setMaximumNumberLabels( thinningElem.attribute( QStringLiteral( "maxNumLabels" ), QStringLiteral( "4000" ) ).toInt() );
513 res->mThinningSettings.setLimitNumberLabelsEnabled( thinningElem.attribute( QStringLiteral( "limitNumLabels" ), QStringLiteral( "1" ) ).toInt() );
514 res->mThinningSettings.setMinimumFeatureSize( thinningElem.attribute( QStringLiteral( "minFeatureSize" ), QStringLiteral( "8" ) ).toDouble() );
515
516 QDomElement renderingElem = element.firstChildElement( QStringLiteral( "rendering" ) );
517 // note the element names are "flipped" vs the member -- this is intentional, and done to match vector labeling
518 res->mMaximumScale = renderingElem.attribute( QStringLiteral( "scaleMin" ), QStringLiteral( "0" ) ).toDouble();
519 res->mMinimumScale = renderingElem.attribute( QStringLiteral( "scaleMax" ), QStringLiteral( "0" ) ).toDouble();
520 res->mScaleVisibility = renderingElem.attribute( QStringLiteral( "scaleVisibility" ) ).toInt();
521
522 return res.release();
523}
524
526{
527 return mTextFormat;
528}
529
531{
532 mTextFormat = format;
533}
534
536{
537 return mNumericFormat.get();
538}
539
541{
542 if ( format != mNumericFormat.get() )
543 mNumericFormat.reset( format );
544}
545
547{
548 return mZIndex;
549}
550
552{
553 mZIndex = index;
554}
555
557{
558 return mMaximumScale;
559}
560
562{
563 mMaximumScale = scale;
564}
565
567{
568 return mMinimumScale;
569}
570
572{
573 mMinimumScale = scale;
574}
575
577{
578 return mScaleVisibility;
579}
580
582{
583 // mMinScale (denominator!) is inclusive ( >= --> In range )
584 // mMaxScale (denominator!) is exclusive ( < --> In range )
585 return !mScaleVisibility
586 || ( ( mMinimumScale == 0 || !QgsScaleUtils::lessThanMaximumScale( scale, mMinimumScale ) )
587 && ( mMaximumScale == 0 || !QgsScaleUtils::equalToOrGreaterThanMinimumScale( scale, mMaximumScale ) ) );
588}
589
594
596{
597 mResampleMethod = method;
598}
599
601{
602 return mResampleOver;
603}
604
606{
607 mResampleOver = pixels;
608}
609
611{
612 mScaleVisibility = enabled;
613}
614
616{
617 mTextFormat.multiplyOpacity( opacityFactor );
618}
619
621{
622 auto res = std::make_unique< QgsRasterLayerSimpleLabeling >();
623 res->setTextFormat( QgsStyle::defaultTextFormatForProject( layer->project() ) );
624 res->setBand( 1 );
625 return res.release();
626}
@ OverPoint
Arranges candidates over a point (or centroid of a polygon), or at a preset offset from the point....
Definition qgis.h:1196
RasterResamplingMethod
Resampling method for raster provider-level resampling.
Definition qgis.h:1484
@ Average
Average resampling.
Definition qgis.h:1490
@ Labeling
Labeling-specific layout mode.
Definition qgis.h:2904
@ Point
Text at point of origin layout mode.
Definition qgis.h:2903
@ Horizontal
Horizontally oriented text.
Definition qgis.h:2887
@ Millimeters
Millimeters.
Definition qgis.h:5184
@ PreventOverlap
Do not allow labels to overlap other labels.
Definition qgis.h:1168
@ Reverse
Reverse/inverse transform (from destination to source).
Definition qgis.h:2673
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.
@ DrawLabels
Whether the labels should be rendered.
QgsAbstractLabelProvider(QgsMapLayer *layer, const QString &providerId=QString())
Construct the provider with default values.
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.
Handles coordinate transforms between two 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:260
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, const char *file=__builtin_FILE(), const char *function=__builtin_FUNCTION(), int line=__builtin_LINE())
Adds a message to the log instance (and creates it if necessary).
A context for numeric formats.
void setExpressionContext(const QgsExpressionContext &context)
Sets the expression context to use when evaluating QgsExpressions.
Abstract base class for numeric formatters, which allow for formatting a numeric value for display.
Represents 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:387
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...
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.
bool hasNonDefaultCompositionMode() const override
Returns true the labeling requires a non-default composition mode.
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.
A container for the context for various read/write operations on 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).
QgsExpressionContext & expressionContext()
Gets the expression context.
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:1460
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.
QSizeF documentSize(Qgis::TextLayoutMode mode, Qgis::TextOrientation orientation) const
Returns the overall size of the document.
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 readXml(const QDomElement &elem, const QgsReadWriteContext &context)
Read settings from a DOM element.
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:89
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:6817
QString qgsEnumValueToKey(const T &value, bool *returnOk=nullptr)
Returns the value for the given key of an enum.
Definition qgis.h:6798
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference).
Definition qgis.h:6607
#define QgsDebugError(str)
Definition qgslogger.h:57
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.