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