QGIS API Documentation 3.27.0-Master (f261cc1f8b)
qgsinterpolator.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsinterpolator.cpp
3 -------------------
4 begin : Marco 10, 2008
5 copyright : (C) 2008 by Marco Hugentobler
6 email : marco dot hugentobler at karto dot baug dot ethz dot ch
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 ***************************************************************************/
17
18#include "qgsinterpolator.h"
19#include "qgsfeatureiterator.h"
21#include "qgsvectorlayer.h"
22#include "qgsgeometry.h"
23#include "qgsfeedback.h"
24
25QgsInterpolator::QgsInterpolator( const QList<LayerData> &layerData )
26 : mLayerData( layerData )
27{
28
29}
30
32{
33 if ( mLayerData.empty() )
34 {
35 return Success;
36 }
37
38 //reserve initial memory for 100000 vertices
39 mCachedBaseData.clear();
40 mCachedBaseData.reserve( 100000 );
41
42 const QgsCoordinateReferenceSystem crs = !mLayerData.empty() ? mLayerData.at( 0 ).source->sourceCrs() : QgsCoordinateReferenceSystem();
43
44 double layerStep = !mLayerData.empty() ? 100.0 / mLayerData.count() : 1;
45 int layerCount = 0;
46 for ( const LayerData &layer : std::as_const( mLayerData ) )
47 {
48 if ( feedback && feedback->isCanceled() )
49 return Canceled;
50
51 QgsFeatureSource *source = layer.source;
52 if ( !source )
53 {
54 return InvalidSource;
55 }
56
57 QgsAttributeList attList;
58 switch ( layer.valueSource )
59 {
60 case ValueAttribute:
61 attList.push_back( layer.interpolationAttribute );
62 break;
63
64 case ValueZ:
65 case ValueM:
66 break;
67 }
68
69 double attributeValue = 0.0;
70 bool attributeConversionOk = false;
71 double progress = layerCount * layerStep;
72
73 QgsFeatureIterator fit = source->getFeatures( QgsFeatureRequest().setSubsetOfAttributes( attList ).setDestinationCrs( crs, layer.transformContext ) );
74 double featureStep = source->featureCount() > 0 ? layerStep / source->featureCount() : layerStep;
75
76 QgsFeature feature;
77 while ( fit.nextFeature( feature ) )
78 {
79 if ( feedback && feedback->isCanceled() )
80 return Canceled;
81
82 progress += featureStep;
83 if ( feedback )
84 feedback->setProgress( progress );
85
86 switch ( layer.valueSource )
87 {
88 case ValueAttribute:
89 {
90 QVariant attributeVariant = feature.attribute( layer.interpolationAttribute );
91 if ( !attributeVariant.isValid() || attributeVariant.isNull() ) //attribute not found, something must be wrong (e.g. NULL value)
92 {
93 continue;
94 }
95 attributeValue = attributeVariant.toDouble( &attributeConversionOk );
96 if ( !attributeConversionOk || std::isnan( attributeValue ) ) //don't consider vertices with attributes like 'nan' for the interpolation
97 {
98 continue;
99 }
100 break;
101 }
102
103 case ValueZ:
104 case ValueM:
105 break;
106 }
107
108 if ( !addVerticesToCache( feature.geometry(), layer.valueSource, attributeValue ) )
110 }
111 layerCount++;
112 }
113
114 return Success;
115}
116
117bool QgsInterpolator::addVerticesToCache( const QgsGeometry &geom, ValueSource source, double attributeValue )
118{
119 if ( geom.isNull() || geom.isEmpty() )
120 return true; // nothing to do
121
122 //validate source
123 switch ( source )
124 {
125 case ValueAttribute:
126 break;
127
128 case ValueM:
129 if ( !geom.constGet()->isMeasure() )
130 return false;
131 else
132 break;
133
134 case ValueZ:
135 if ( !geom.constGet()->is3D() )
136 return false;
137 else
138 break;
139 }
140
141 for ( auto point = geom.vertices_begin(); point != geom.vertices_end(); ++point )
142 {
143 switch ( source )
144 {
145 case ValueM:
146 mCachedBaseData.push_back( QgsInterpolatorVertexData( ( *point ).x(), ( *point ).y(), ( *point ).m() ) );
147 break;
148
149 case ValueZ:
150 mCachedBaseData.push_back( QgsInterpolatorVertexData( ( *point ).x(), ( *point ).y(), ( *point ).z() ) );
151 break;
152
153 case ValueAttribute:
154 mCachedBaseData.push_back( QgsInterpolatorVertexData( ( *point ).x(), ( *point ).y(), attributeValue ) );
155 break;
156 }
157 }
158 mDataIsCached = true;
159 return true;
160}
bool is3D() const SIP_HOLDGIL
Returns true if the geometry is 3D and contains a z-value.
bool isMeasure() const SIP_HOLDGIL
Returns true if the geometry contains m values.
This class represents a coordinate reference system (CRS).
Wrapper for iterator of features from vector data provider or vector layer.
bool nextFeature(QgsFeature &f)
This class wraps a request for features to a vector layer (or directly its vector data provider).
An interface for objects which provide features via a getFeatures method.
virtual QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) const =0
Returns an iterator for the features in the source.
virtual long long featureCount() const =0
Returns the number of features contained in the source, or -1 if the feature count is unknown.
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
Definition: qgsfeature.h:56
QgsGeometry geometry
Definition: qgsfeature.h:67
QVariant attribute(const QString &name) const
Lookup attribute value by attribute name.
Definition: qgsfeature.cpp:335
Base class for feedback objects to be used for cancellation of something running in a worker thread.
Definition: qgsfeedback.h:45
bool isCanceled() const SIP_HOLDGIL
Tells whether the operation has been canceled already.
Definition: qgsfeedback.h:54
void setProgress(double progress)
Sets the current progress for the feedback object.
Definition: qgsfeedback.h:63
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:125
const QgsAbstractGeometry * constGet() const SIP_HOLDGIL
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
Q_GADGET bool isNull
Definition: qgsgeometry.h:127
bool isEmpty() const
Returns true if the geometry is empty (eg a linestring with no vertices, or a collection with no geom...
QgsAbstractGeometry::vertex_iterator vertices_begin() const
Returns STL-style iterator pointing to the first vertex of the geometry.
QgsAbstractGeometry::vertex_iterator vertices_end() const
Returns STL-style iterator pointing to the imaginary vertex after the last vertex of the geometry.
QVector< QgsInterpolatorVertexData > mCachedBaseData
Cached vertex data for input sources.
@ ValueM
Use feature's geometry M values for interpolation.
@ ValueAttribute
Take value from feature's attribute.
@ ValueZ
Use feature's geometry Z values for interpolation.
QgsInterpolator(const QList< QgsInterpolator::LayerData > &layerData)
Result
Result of an interpolation operation.
@ Canceled
Operation was manually canceled.
@ InvalidSource
Operation failed due to invalid source.
@ FeatureGeometryError
Operation failed due to invalid feature geometry.
@ Success
Operation was successful.
bool mDataIsCached
Flag that tells if the cache already has been filled.
QList< LayerData > mLayerData
Information about the input vector layers and the attributes (or z-values) that are used for interpol...
Result cacheBaseData(QgsFeedback *feedback=nullptr)
Caches the vertex and value data from the provider.
QList< int > QgsAttributeList
Definition: qgsfield.h:26
const QgsCoordinateReferenceSystem & crs
Interpolation data for an individual source vertex.
A source together with the information about interpolation attribute / z-coordinate interpolation and...