Skip to content

Commit

Permalink
Cleanup interpolation code
Browse files Browse the repository at this point in the history
  • Loading branch information
nyalldawson committed Nov 2, 2017
1 parent cb292c1 commit f200d9c
Show file tree
Hide file tree
Showing 4 changed files with 104 additions and 54 deletions.
37 changes: 29 additions & 8 deletions python/analysis/interpolation/qgsidwinterpolator.sip
Original file line number Diff line number Diff line change
Expand Up @@ -11,25 +11,46 @@

class QgsIDWInterpolator: QgsInterpolator
{
%Docstring
Inverse distance weight interpolator.
%End

%TypeHeaderCode
#include "qgsidwinterpolator.h"
%End
public:

QgsIDWInterpolator( const QList<QgsInterpolator::LayerData> &layerData );
%Docstring
Constructor for QgsIDWInterpolator, with the specified ``layerData`` sources.
%End

virtual int interpolatePoint( double x, double y, double &result, QgsFeedback *feedback = 0 );

virtual int interpolatePoint( double x, double y, double &result );

void setDistanceCoefficient( double coefficient );
%Docstring
Calculates interpolation value for map coordinates x, y
\param x x-coordinate (in map units)
\param y y-coordinate (in map units)
\param result out: interpolation result
:return: 0 in case of success*
:rtype: int
Sets the distance ``coefficient``, the parameter that sets how the values are
weighted with distance. Smaller values mean sharper peaks at the data points.

Point values are weighted by 1 / ( distance ^ coefficient ).

.. seealso:: distanceCoefficient()
.. versionadded:: 3.0
%End

void setDistanceCoefficient( double p );
double distanceCoefficient() const;
%Docstring
Returns the distance coefficient, the parameter that sets how the values are
weighted with distance. Smaller values mean sharper peaks at the data points.
The default is a coefficient of 2.

Point values are weighted by 1 / ( distance ^ coefficient ).

.. seealso:: setDistanceCoefficient()
.. versionadded:: 3.0
:rtype: float
%End

};

Expand Down
85 changes: 66 additions & 19 deletions python/analysis/interpolation/qgsinterpolator.sip
Original file line number Diff line number Diff line change
Expand Up @@ -10,63 +10,110 @@



struct vertexData
struct QgsInterpolatorVertexData
{

QgsInterpolatorVertexData( double x, double y, double z );
%Docstring
Constructor for QgsInterpolatorVertexData with the specified
``x``, ``y``, and ``z`` coordinate.
%End

QgsInterpolatorVertexData();
%Docstring
Constructor for QgsInterpolatorVertexData
%End

double x;
%Docstring
X-coordinate
%End
double y;
%Docstring
Y-coordinate
%End
double z;
%Docstring
Z-coordinate
%End
};

class QgsInterpolator
{
%Docstring
Interface class for interpolations. Interpolators take
the vertices of a vector layer as base data. The z-Value
can be an attribute or the z-coordinates in case of 25D types*
the vertices of a vector layer as base data. The z-Value
can be an attribute or the z-coordinates in case of 3D types.
%End

%TypeHeaderCode
#include "qgsinterpolator.h"
%End
public:
enum InputType

enum SourceType
{
POINTS,
STRUCTURE_LINES,
BREAK_LINES
SourcePoints,
SourceStructureLines,
SourceBreakLines,
};

enum Result
{
Success,
Canceled,
InvalidSource,
FeatureGeometryError,
};

struct LayerData
{
QgsVectorLayer *vectorLayer;
bool zCoordInterpolation;
QgsFeatureSource *source;
%Docstring
Feature source
%End
bool useZValue;
%Docstring
True if feature geometry z values should be used for interpolation
%End
int interpolationAttribute;
QgsInterpolator::InputType mInputType;
%Docstring
Index of feature attribute to use for interpolation
%End
QgsInterpolator::SourceType sourceType;
%Docstring
Source type
%End
};

QgsInterpolator( const QList<QgsInterpolator::LayerData> &layerData );

virtual ~QgsInterpolator();

virtual int interpolatePoint( double x, double y, double &result ) = 0;
virtual int interpolatePoint( double x, double y, double &result, QgsFeedback *feedback = 0 ) = 0;
%Docstring
Calculates interpolation value for map coordinates x, y
\param x x-coordinate (in map units)
\param y y-coordinate (in map units)
\param result out: interpolation result
:return: 0 in case of success*
\param x x-coordinate (in map units)
\param y y-coordinate (in map units)
\param result out: interpolation result
\param feedback optional feedback object for progress and cancelation support
:return: 0 in case of success*
:rtype: int
%End


protected:

int cacheBaseData();
Result cacheBaseData( QgsFeedback *feedback = 0 );
%Docstring
Caches the vertex and value data from the provider. All the vertex data
will be held in virtual memory
:return: 0 in case of success*
:rtype: int
will be held in virtual memory.

An optional ``feedback`` argument may be specified to allow cancelation and
progress reports from the cache operation.

:return: Success in case of success
:rtype: Result
%End


Expand Down
10 changes: 1 addition & 9 deletions python/analysis/interpolation/qgstininterpolator.sip
Original file line number Diff line number Diff line change
Expand Up @@ -34,16 +34,8 @@ class QgsTINInterpolator: QgsInterpolator
%End
~QgsTINInterpolator();

virtual int interpolatePoint( double x, double y, double &result );
virtual int interpolatePoint( double x, double y, double &result, QgsFeedback *feedback );

%Docstring
Calculates interpolation value for map coordinates x, y
\param x x-coordinate (in map units)
\param y y-coordinate (in map units)
\param result out: interpolation result
:return: 0 in case of success*
:rtype: int
%End

static QgsFields triangulationFields();
%Docstring
Expand Down
26 changes: 8 additions & 18 deletions src/analysis/interpolation/qgsidwinterpolator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,20 +16,13 @@
***************************************************************************/

#include "qgsidwinterpolator.h"
#include "qgis.h"
#include <cmath>
#include <limits>

QgsIDWInterpolator::QgsIDWInterpolator( const QList<LayerData> &layerData )
: QgsInterpolator( layerData )
{

}

QgsIDWInterpolator::QgsIDWInterpolator()
: QgsInterpolator( QList<LayerData>() )
{

}
{}

int QgsIDWInterpolator::interpolatePoint( double x, double y, double &result, QgsFeedback *feedback )
{
Expand All @@ -38,22 +31,19 @@ int QgsIDWInterpolator::interpolatePoint( double x, double y, double &result, Qg
cacheBaseData( feedback );
}

double currentWeight;
double distance;

double sumCounter = 0;
double sumDenominator = 0;

Q_FOREACH ( const vertexData &vertex_it, mCachedBaseData )
for ( const QgsInterpolatorVertexData &vertex : qgis::as_const( mCachedBaseData ) )
{
distance = std::sqrt( ( vertex_it.x - x ) * ( vertex_it.x - x ) + ( vertex_it.y - y ) * ( vertex_it.y - y ) );
if ( ( distance - 0 ) < std::numeric_limits<double>::min() )
double distance = std::sqrt( ( vertex.x - x ) * ( vertex.x - x ) + ( vertex.y - y ) * ( vertex.y - y ) );
if ( qgsDoubleNear( distance, 0.0 ) )
{
result = vertex_it.z;
result = vertex.z;
return 0;
}
currentWeight = 1 / ( std::pow( distance, mDistanceCoefficient ) );
sumCounter += ( currentWeight * vertex_it.z );
double currentWeight = 1 / ( std::pow( distance, mDistanceCoefficient ) );
sumCounter += ( currentWeight * vertex.z );
sumDenominator += currentWeight;
}

Expand Down

0 comments on commit f200d9c

Please sign in to comment.