QGIS API Documentation  3.26.3-Buenos Aires (65e4edfdad)
qgsrasterlayerprofilegenerator.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsrasterlayerprofilegenerator.cpp
3  ---------------
4  begin : March 2022
5  copyright : (C) 2022 by Nyall Dawson
6  email : nyall dot dawson at gmail dot com
7  ***************************************************************************/
8 
9 /***************************************************************************
10  * *
11  * This program is free software; you can redistribute it and/or modify *
12  * it under the terms of the GNU General Public License as published by *
13  * the Free Software Foundation; either version 2 of the License, or *
14  * (at your option) any later version. *
15  * *
16  ***************************************************************************/
18 #include "qgsprofilerequest.h"
19 #include "qgscurve.h"
20 #include "qgsrasterlayer.h"
22 #include "qgsrasteriterator.h"
23 #include "qgsgeometryengine.h"
24 #include "qgsgeos.h"
25 #include "qgslinesymbol.h"
26 #include "qgsgeometryutils.h"
27 #include "qgsprofilepoint.h"
28 #include "qgsfillsymbol.h"
29 
30 #include <QPolygonF>
31 
32 //
33 // QgsRasterLayerProfileResults
34 //
35 
37 {
38  return QStringLiteral( "raster" );
39 }
40 
41 QVector<QgsProfileIdentifyResults> QgsRasterLayerProfileResults::identify( const QgsProfilePoint &point, const QgsProfileIdentifyContext &context )
42 {
43  const QVector<QgsProfileIdentifyResults> noLayerResults = QgsAbstractProfileSurfaceResults::identify( point, context );
44 
45  // we have to make a new list, with the correct layer reference set
46  QVector<QgsProfileIdentifyResults> res;
47  res.reserve( noLayerResults.size() );
48  for ( const QgsProfileIdentifyResults &result : noLayerResults )
49  {
50  res.append( QgsProfileIdentifyResults( mLayer, result.results() ) );
51  }
52  return res;
53 }
54 
55 
56 
57 //
58 // QgsRasterLayerProfileGenerator
59 //
60 
62  : mId( layer->id() )
63  , mFeedback( std::make_unique< QgsRasterBlockFeedback >() )
64  , mProfileCurve( request.profileCurve() ? request.profileCurve()->clone() : nullptr )
65  , mSourceCrs( layer->crs() )
66  , mTargetCrs( request.crs() )
67  , mTransformContext( request.transformContext() )
68  , mOffset( layer->elevationProperties()->zOffset() )
69  , mScale( layer->elevationProperties()->zScale() )
70  , mLayer( layer )
71  , mBand( qgis::down_cast< QgsRasterLayerElevationProperties * >( layer->elevationProperties() )->bandNumber() )
72  , mRasterUnitsPerPixelX( layer->rasterUnitsPerPixelX() )
73  , mRasterUnitsPerPixelY( layer->rasterUnitsPerPixelY() )
74  , mStepDistance( request.stepDistance() )
75 {
76  mRasterProvider.reset( layer->dataProvider()->clone() );
77 
78  mSymbology = qgis::down_cast< QgsRasterLayerElevationProperties * >( layer->elevationProperties() )->profileSymbology();
79  mLineSymbol.reset( qgis::down_cast< QgsRasterLayerElevationProperties * >( layer->elevationProperties() )->profileLineSymbol()->clone() );
80  mFillSymbol.reset( qgis::down_cast< QgsRasterLayerElevationProperties * >( layer->elevationProperties() )->profileFillSymbol()->clone() );
81 }
82 
84 {
85  return mId;
86 }
87 
88 Qgis::ProfileGeneratorFlags QgsRasterLayerProfileGenerator::flags() const
89 {
91 }
92 
94 
96 {
97  if ( !mProfileCurve || mFeedback->isCanceled() )
98  return false;
99 
100  const double startDistanceOffset = std::max( !context.distanceRange().isInfinite() ? context.distanceRange().lower() : 0, 0.0 );
101  const double endDistance = context.distanceRange().upper();
102 
103  std::unique_ptr< QgsCurve > trimmedCurve;
104  QgsCurve *sourceCurve = nullptr;
105  if ( startDistanceOffset > 0 || endDistance < mProfileCurve->length() )
106  {
107  trimmedCurve.reset( mProfileCurve->curveSubstring( startDistanceOffset, endDistance ) );
108  sourceCurve = trimmedCurve.get();
109  }
110  else
111  {
112  sourceCurve = mProfileCurve.get();
113  }
114 
115  // we need to transform the profile curve to the raster's CRS
116  std::unique_ptr< QgsCurve > transformedCurve( sourceCurve->clone() );
117  const QgsCoordinateTransform rasterToTargetTransform( mSourceCrs, mTargetCrs, mTransformContext );
118  try
119  {
120  transformedCurve->transform( rasterToTargetTransform, Qgis::TransformDirection::Reverse );
121  }
122  catch ( QgsCsException & )
123  {
124  QgsDebugMsg( QStringLiteral( "Error transforming profile line to raster CRS" ) );
125  return false;
126  }
127 
128  if ( mFeedback->isCanceled() )
129  return false;
130 
131  const QgsRectangle profileCurveBoundingBox = transformedCurve->boundingBox();
132  if ( !profileCurveBoundingBox.intersects( mRasterProvider->extent() ) )
133  return false;
134 
135  if ( mFeedback->isCanceled() )
136  return false;
137 
138  mResults = std::make_unique< QgsRasterLayerProfileResults >();
139  mResults->mLayer = mLayer;
140  mResults->copyPropertiesFromGenerator( this );
141 
142  std::unique_ptr< QgsGeometryEngine > curveEngine( QgsGeometry::createGeometryEngine( transformedCurve.get() ) );
143  curveEngine->prepareGeometry();
144 
145  if ( mFeedback->isCanceled() )
146  return false;
147 
148  double stepDistance = mStepDistance;
149  if ( !std::isnan( context.maximumErrorMapUnits() ) )
150  {
151  // convert the maximum error in curve units to a step distance
152  // TODO -- there's no point in this being << pixel size!
153  if ( std::isnan( stepDistance ) || context.maximumErrorMapUnits() > stepDistance )
154  {
155  stepDistance = context.maximumErrorMapUnits();
156  }
157  }
158 
159  QSet< QgsPointXY > profilePoints;
160  if ( !std::isnan( stepDistance ) )
161  {
162  // if specific step distance specified, use this to generate points along the curve
163  QgsGeometry densifiedCurve( sourceCurve->clone() );
164  densifiedCurve = densifiedCurve.densifyByDistance( stepDistance );
165  densifiedCurve.transform( rasterToTargetTransform, Qgis::TransformDirection::Reverse );
166  profilePoints.reserve( densifiedCurve.constGet()->nCoordinates() );
167  for ( auto it = densifiedCurve.vertices_begin(); it != densifiedCurve.vertices_end(); ++it )
168  {
169  profilePoints.insert( *it );
170  }
171  }
172 
173  if ( mFeedback->isCanceled() )
174  return false;
175 
176  // calculate the portion of the raster which actually covers the curve
177  int subRegionWidth = 0;
178  int subRegionHeight = 0;
179  int subRegionLeft = 0;
180  int subRegionTop = 0;
181  const QgsRectangle rasterSubRegion = mRasterProvider->xSize() > 0 && mRasterProvider->ySize() > 0 ?
183  mRasterProvider->extent(),
184  mRasterProvider->xSize(),
185  mRasterProvider->ySize(),
186  transformedCurve->boundingBox(),
187  subRegionWidth,
188  subRegionHeight,
189  subRegionLeft,
190  subRegionTop ) : transformedCurve->boundingBox();
191 
192  if ( mRasterProvider->xSize() == 0 || mRasterProvider->ySize() == 0 )
193  {
194  // e.g. XYZ tile source -- this is a rough hack for https://github.com/qgis/QGIS/issues/48806, which results
195  // in pretty poor curves ;)
196  const double curveLengthInPixels = sourceCurve->length() / context.mapUnitsPerDistancePixel();
197  const double conversionFactor = curveLengthInPixels / transformedCurve->length();
198  subRegionWidth = 2 * conversionFactor * rasterSubRegion.width();
199  subRegionHeight = 2 * conversionFactor * rasterSubRegion.height();
200  }
201 
202  // iterate over the raster blocks, throwing away any which don't intersect the profile curve
203  QgsRasterIterator it( mRasterProvider.get() );
204  // we use smaller tile sizes vs the default, as we will be skipping over tiles which don't intersect the curve at all,
205  // and we expect that to be the VAST majority of the tiles in the raster.
206  // => Smaller tile sizes = more regions we can shortcut over = less pixels to iterate over = faster runtime
207  it.setMaximumTileHeight( 64 );
208  it.setMaximumTileWidth( 64 );
209 
210  it.startRasterRead( mBand, subRegionWidth, subRegionHeight, rasterSubRegion );
211 
212  const double halfPixelSizeX = mRasterUnitsPerPixelX / 2.0;
213  const double halfPixelSizeY = mRasterUnitsPerPixelY / 2.0;
214  int blockColumns = 0;
215  int blockRows = 0;
216  int blockTopLeftColumn = 0;
217  int blockTopLeftRow = 0;
218  QgsRectangle blockExtent;
219 
220  while ( it.next( mBand, blockColumns, blockRows, blockTopLeftColumn, blockTopLeftRow, blockExtent ) )
221  {
222  if ( mFeedback->isCanceled() )
223  return false;
224 
225  const QgsGeometry blockExtentGeom = QgsGeometry::fromRect( blockExtent );
226  if ( !curveEngine->intersects( blockExtentGeom.constGet() ) )
227  continue;
228 
229  std::unique_ptr< QgsRasterBlock > block( mRasterProvider->block( mBand, blockExtent, blockColumns, blockRows, mFeedback.get() ) );
230  if ( mFeedback->isCanceled() )
231  return false;
232 
233  if ( !block )
234  continue;
235 
236  bool isNoData = false;
237 
238  // there's two potential code paths we use here, depending on if we want to sample at every pixel, or if we only want to
239  // sample at specific points
240  if ( !std::isnan( stepDistance ) )
241  {
242  auto it = profilePoints.begin();
243  while ( it != profilePoints.end() )
244  {
245  if ( mFeedback->isCanceled() )
246  return false;
247 
248  // convert point to a pixel and sample, if it's in this block
249  if ( blockExtent.contains( *it ) )
250  {
251  const int row = std::clamp( static_cast< int >( std::round( ( blockExtent.yMaximum() - it->y() ) / mRasterUnitsPerPixelY ) ), 0, blockRows - 1 );
252  const int col = std::clamp( static_cast< int >( std::round( ( it->x() - blockExtent.xMinimum() ) / mRasterUnitsPerPixelX ) ), 0, blockColumns - 1 );
253  double val = block->valueAndNoData( row, col, isNoData );
254  if ( !isNoData )
255  {
256  val = val * mScale + mOffset;
257  }
258  else
259  {
260  val = std::numeric_limits<double>::quiet_NaN();
261  }
262 
263  QgsPoint pixel( it->x(), it->y(), val );
264  try
265  {
266  pixel.transform( rasterToTargetTransform );
267  }
268  catch ( QgsCsException & )
269  {
270  continue;
271  }
272  mResults->mRawPoints.append( pixel );
273 
274  it = profilePoints.erase( it );
275  }
276  else
277  {
278  it++;
279  }
280  }
281 
282  if ( profilePoints.isEmpty() )
283  break; // all done!
284  }
285  else
286  {
287  double currentY = blockExtent.yMaximum() - 0.5 * mRasterUnitsPerPixelY;
288  for ( int row = 0; row < blockRows; ++row )
289  {
290  if ( mFeedback->isCanceled() )
291  return false;
292 
293  double currentX = blockExtent.xMinimum() + 0.5 * mRasterUnitsPerPixelX;
294  for ( int col = 0; col < blockColumns; ++col, currentX += mRasterUnitsPerPixelX )
295  {
296  const double val = block->valueAndNoData( row, col, isNoData );
297 
298  // does pixel intersect curve?
299  QgsGeometry pixelRectGeometry = QgsGeometry::fromRect( QgsRectangle( currentX - halfPixelSizeX,
300  currentY - halfPixelSizeY,
301  currentX + halfPixelSizeX,
302  currentY + halfPixelSizeY ) );
303  if ( !curveEngine->intersects( pixelRectGeometry.constGet() ) )
304  continue;
305 
306  QgsPoint pixel( currentX, currentY, isNoData ? std::numeric_limits<double>::quiet_NaN() : val * mScale + mOffset );
307  try
308  {
309  pixel.transform( rasterToTargetTransform );
310  }
311  catch ( QgsCsException & )
312  {
313  continue;
314  }
315  mResults->mRawPoints.append( pixel );
316  }
317  currentY -= mRasterUnitsPerPixelY;
318  }
319  }
320  }
321 
322  if ( mFeedback->isCanceled() )
323  return false;
324 
325  // convert x/y values back to distance/height values
326  QgsGeos originalCurveGeos( sourceCurve );
327  originalCurveGeos.prepareGeometry();
328  QString lastError;
329  for ( const QgsPoint &pixel : std::as_const( mResults->mRawPoints ) )
330  {
331  if ( mFeedback->isCanceled() )
332  return false;
333 
334  const double distance = originalCurveGeos.lineLocatePoint( pixel, &lastError ) + startDistanceOffset;
335 
336  if ( !std::isnan( pixel.z() ) )
337  {
338  mResults->minZ = std::min( pixel.z(), mResults->minZ );
339  mResults->maxZ = std::max( pixel.z(), mResults->maxZ );
340  }
341  mResults->mDistanceToHeightMap.insert( distance, pixel.z() );
342  }
343 
344  return true;
345 }
346 
348 {
349  return mResults.release();
350 }
351 
353 {
354  return mFeedback.get();
355 }
QgsRectangle::intersects
bool intersects(const QgsRectangle &rect) const SIP_HOLDGIL
Returns true when rectangle intersects with other rectangle.
Definition: qgsrectangle.h:349
QgsProfileIdentifyContext
Encapsulates the context of identifying profile results.
Definition: qgsabstractprofilegenerator.h:125
QgsCurve
Abstract base class for curved geometry type.
Definition: qgscurve.h:35
QgsRectangle::height
double height() const SIP_HOLDGIL
Returns the height of the rectangle.
Definition: qgsrectangle.h:230
qgsrasterlayer.h
qgsrasterlayerprofilegenerator.h
QgsPoint
Point geometry type, with support for z-dimension and m-values.
Definition: qgspoint.h:48
QgsGeometry::transform
Qgis::GeometryOperationResult transform(const QgsCoordinateTransform &ct, Qgis::TransformDirection direction=Qgis::TransformDirection::Forward, bool transformZ=false) SIP_THROW(QgsCsException)
Transforms this geometry as described by the coordinate transform ct.
Definition: qgsgeometry.cpp:3128
QgsAbstractProfileSurfaceGenerator::mFillSymbol
std::unique_ptr< QgsFillSymbol > mFillSymbol
Definition: qgsabstractprofilesurfacegenerator.h:94
crs
const QgsCoordinateReferenceSystem & crs
Definition: qgswfsgetfeature.cpp:105
QgsRasterLayerProfileGenerator::takeResults
QgsAbstractProfileResults * takeResults() override
Takes results from the generator.
Definition: qgsrasterlayerprofilegenerator.cpp:347
QgsRasterIterator::subRegion
static QgsRectangle subRegion(const QgsRectangle &rasterExtent, int rasterWidth, int rasterHeight, const QgsRectangle &subRegion, int &subRegionWidth, int &subRegionHeight, int &subRegionLeft, int &subRegionTop)
Given an overall raster extent and width and height in pixels, calculates the sub region of the raste...
Definition: qgsrasteriterator.cpp:38
QgsAbstractGeometry::length
virtual double length() const
Returns the planar, 2-dimensional length of the geometry.
Definition: qgsabstractgeometry.cpp:166
QgsDebugMsg
#define QgsDebugMsg(str)
Definition: qgslogger.h:38
Qgis::ProfileGeneratorFlag::RespectsMaximumErrorMapUnit
@ RespectsMaximumErrorMapUnit
Generated profile respects the QgsProfileGenerationContext::maximumErrorMapUnits() property.
QgsRectangle
A rectangle specified with double values.
Definition: qgsrectangle.h:41
QgsProfilePoint
Encapsulates a point on a distance-elevation profile.
Definition: qgsprofilepoint.h:30
QgsRasterDataProvider::clone
QgsRasterDataProvider * clone() const override=0
Clone itself, create deep copy.
QgsRasterIterator::next
bool next(int bandNumber, int &columns, int &rows, int &topLeftColumn, int &topLeftRow, QgsRectangle &blockExtent)
Fetches details of the next part of the raster data.
Definition: qgsrasteriterator.cpp:99
QgsProfileGenerationContext
Encapsulates the context in which an elevation profile is to be generated.
Definition: qgsabstractprofilegenerator.h:262
qgsrasteriterator.h
QgsRasterLayerProfileGenerator::sourceId
QString sourceId() const override
Returns a unique identifier representing the source of the profile.
Definition: qgsrasterlayerprofilegenerator.cpp:83
QgsProfileIdentifyResults
Stores identify results generated by a QgsAbstractProfileResults object.
Definition: qgsabstractprofilegenerator.h:158
QgsAbstractProfileSurfaceGenerator::mSymbology
Qgis::ProfileSurfaceSymbology mSymbology
Definition: qgsabstractprofilesurfacegenerator.h:92
QgsRasterLayerProfileGenerator::feedback
QgsFeedback * feedback() const override
Access to feedback object of the generator (may be nullptr)
Definition: qgsrasterlayerprofilegenerator.cpp:352
qgsgeometryengine.h
QgsCsException
Custom exception class for Coordinate Reference System related exceptions.
Definition: qgsexception.h:65
QgsRange::lower
T lower() const
Returns the lower bound of the range.
Definition: qgsrange.h:66
QgsRasterLayerProfileGenerator::QgsRasterLayerProfileGenerator
QgsRasterLayerProfileGenerator(QgsRasterLayer *layer, const QgsProfileRequest &request)
Constructor for QgsRasterLayerProfileGenerator.
Definition: qgsrasterlayerprofilegenerator.cpp:61
qgsprofilepoint.h
qgsrasterlayerelevationproperties.h
QgsAbstractProfileSurfaceGenerator::mLineSymbol
std::unique_ptr< QgsLineSymbol > mLineSymbol
Definition: qgsabstractprofilesurfacegenerator.h:93
QgsPoint::transform
void transform(const QgsCoordinateTransform &ct, Qgis::TransformDirection d=Qgis::TransformDirection::Forward, bool transformZ=false) override SIP_THROW(QgsCsException)
Transforms the geometry using a coordinate transform.
Definition: qgspoint.cpp:382
QgsRasterLayerElevationProperties
Raster layer specific subclass of QgsMapLayerElevationProperties.
Definition: qgsrasterlayerelevationproperties.h:34
QgsFeedback
Base class for feedback objects to be used for cancellation of something running in a worker thread.
Definition: qgsfeedback.h:44
QgsRange::upper
T upper() const
Returns the upper bound of the range.
Definition: qgsrange.h:73
qgsprofilerequest.h
QgsProfileGenerationContext::distanceRange
QgsDoubleRange distanceRange() const
Returns the range of distances to include in the generation.
Definition: qgsabstractprofilegenerator.h:307
QgsRectangle::contains
bool contains(const QgsRectangle &rect) const SIP_HOLDGIL
Returns true when rectangle contains other rectangle.
Definition: qgsrectangle.h:363
QgsGeos
Does vector analysis using the geos library and handles import, export, exception handling*.
Definition: qgsgeos.h:103
QgsRasterIterator::startRasterRead
void startRasterRead(int bandNumber, qgssize nCols, qgssize nRows, const QgsRectangle &extent, QgsRasterBlockFeedback *feedback=nullptr)
Start reading of raster band.
Definition: qgsrasteriterator.cpp:77
QgsGeometry::densifyByDistance
QgsGeometry densifyByDistance(double distance) const
Densifies the geometry by adding regularly placed extra nodes inside each segment so that the maximum...
Definition: qgsgeometry.cpp:2270
QgsProfileRequest
Encapsulates properties and constraints relating to fetching elevation profiles from different source...
Definition: qgsprofilerequest.h:37
QgsAbstractProfileSurfaceResults::identify
QVector< QgsProfileIdentifyResults > identify(const QgsProfilePoint &point, const QgsProfileIdentifyContext &context) override
Identify results visible at the specified profile point.
Definition: qgsabstractprofilesurfacegenerator.cpp:85
QgsAbstractGeometry::nCoordinates
virtual int nCoordinates() const
Returns the number of nodes contained in the geometry.
Definition: qgsabstractgeometry.cpp:150
QgsRectangle::xMinimum
double xMinimum() const SIP_HOLDGIL
Returns the x minimum value (left side of rectangle).
Definition: qgsrectangle.h:188
QgsRasterLayer
Represents a raster layer.
Definition: qgsrasterlayer.h:76
QgsRasterIterator
Iterator for sequentially processing raster cells.
Definition: qgsrasteriterator.h:34
QgsGeometry::constGet
const QgsAbstractGeometry * constGet() const SIP_HOLDGIL
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
Definition: qgsgeometry.cpp:136
QgsProfileGenerationContext::mapUnitsPerDistancePixel
double mapUnitsPerDistancePixel() const
Returns the number of map units per pixel in the distance dimension.
Definition: qgsabstractprofilegenerator.h:291
qgsgeometryutils.h
QgsDoubleRange::isInfinite
bool isInfinite() const
Returns true if the range consists of all possible values.
Definition: qgsrange.h:247
QgsRasterIterator::setMaximumTileHeight
void setMaximumTileHeight(int h)
Sets the minimum tile height returned during iteration.
Definition: qgsrasteriterator.h:157
QgsRasterLayer::elevationProperties
QgsMapLayerElevationProperties * elevationProperties() override
Returns the layer's elevation properties.
Definition: qgsrasterlayer.cpp:1087
QgsCurve::clone
QgsCurve * clone() const override=0
Clones the geometry by performing a deep copy.
QgsRasterLayerProfileResults::type
QString type() const override
Returns the unique string identifier for the results type.
Definition: qgsrasterlayerprofilegenerator.cpp:36
QgsGeometry::createGeometryEngine
static QgsGeometryEngine * createGeometryEngine(const QgsAbstractGeometry *geometry)
Creates and returns a new geometry engine representing the specified geometry.
Definition: qgsgeometry.cpp:3972
QgsRectangle::yMaximum
double yMaximum() const SIP_HOLDGIL
Returns the y maximum value (top side of rectangle).
Definition: qgsrectangle.h:193
Qgis::ProfileGeneratorFlag::RespectsDistanceRange
@ RespectsDistanceRange
Generated profile respects the QgsProfileGenerationContext::distanceRange() property.
QgsRasterIterator::setMaximumTileWidth
void setMaximumTileWidth(int w)
Sets the maximum tile width returned during iteration.
Definition: qgsrasteriterator.h:143
qgscurve.h
QgsGeometry
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:124
QgsRectangle::width
double width() const SIP_HOLDGIL
Returns the width of the rectangle.
Definition: qgsrectangle.h:223
QgsRasterBlockFeedback
Feedback object tailored for raster block reading.
Definition: qgsrasterinterface.h:41
QgsGeometry::fromRect
static QgsGeometry fromRect(const QgsRectangle &rect) SIP_HOLDGIL
Creates a new geometry from a QgsRectangle.
Definition: qgsgeometry.cpp:241
QgsProfileGenerationContext::maximumErrorMapUnits
double maximumErrorMapUnits() const
Returns the maximum allowed error in the generated result, in profile curve map units.
Definition: qgsabstractprofilegenerator.h:274
QgsGeos::lineLocatePoint
double lineLocatePoint(const QgsPoint &point, QString *errorMsg=nullptr) const
Returns a distance representing the location along this linestring of the closest point on this lines...
Definition: qgsgeos.cpp:2733
QgsRasterLayerProfileGenerator::flags
Qgis::ProfileGeneratorFlags flags() const override
Returns flags which reflect how the profile generator operates.
Definition: qgsrasterlayerprofilegenerator.cpp:88
QgsAbstractProfileResults
Abstract base class for storage of elevation profiles.
Definition: qgsabstractprofilegenerator.h:193
QgsGeometry::vertices_end
QgsAbstractGeometry::vertex_iterator vertices_end() const
Returns STL-style iterator pointing to the imaginary vertex after the last vertex of the geometry.
Definition: qgsgeometry.cpp:1989
QgsGeometry::vertices_begin
QgsAbstractGeometry::vertex_iterator vertices_begin() const
Returns STL-style iterator pointing to the first vertex of the geometry.
Definition: qgsgeometry.cpp:1982
QgsCoordinateTransform
Class for doing transforms between two map coordinate systems.
Definition: qgscoordinatetransform.h:57
qgsfillsymbol.h
QgsGeos::prepareGeometry
void prepareGeometry() override
Prepares the geometry, so that subsequent calls to spatial relation methods are much faster.
Definition: qgsgeos.cpp:213
QgsRasterLayerProfileGenerator::~QgsRasterLayerProfileGenerator
~QgsRasterLayerProfileGenerator() override
QgsRasterLayer::dataProvider
QgsRasterDataProvider * dataProvider() override
Returns the source data provider.
Definition: qgsrasterlayer.cpp:257
qgsgeos.h
qgslinesymbol.h
QgsRasterLayerProfileGenerator::generateProfile
bool generateProfile(const QgsProfileGenerationContext &context=QgsProfileGenerationContext()) override
Generate the profile (based on data stored in the class).
Definition: qgsrasterlayerprofilegenerator.cpp:95
QgsRasterLayerProfileResults::identify
QVector< QgsProfileIdentifyResults > identify(const QgsProfilePoint &point, const QgsProfileIdentifyContext &context) override
Identify results visible at the specified profile point.
Definition: qgsrasterlayerprofilegenerator.cpp:41