Skip to content

Commit

Permalink
Fix handling of interpolation layers with differing input coordinate …
Browse files Browse the repository at this point in the history
…reference systems

Fixes #27048
  • Loading branch information
nyalldawson committed Nov 5, 2019
1 parent e455078 commit da853cc
Show file tree
Hide file tree
Showing 10 changed files with 101 additions and 3 deletions.
Expand Up @@ -70,6 +70,8 @@ can be an attribute or the z-coordinates in case of 3D types.
QgsInterpolator::ValueSource valueSource;
int interpolationAttribute;
QgsInterpolator::SourceType sourceType;

QgsCoordinateTransformContext transformContext;
};

QgsInterpolator( const QList<QgsInterpolator::LayerData> &layerData );
Expand Down
1 change: 1 addition & 0 deletions python/plugins/processing/algs/qgis/IdwInterpolation.py
Expand Up @@ -132,6 +132,7 @@ def processAlgorithm(self, parameters, context, feedback):
# need to keep a reference until interpolation is complete
layer = QgsProcessingUtils.variantToSource(v[0], context)
data.source = layer
data.transformContext = context.transformContext()
layers.append(layer)

data.valueSource = int(v[1])
Expand Down
1 change: 1 addition & 0 deletions python/plugins/processing/algs/qgis/TinInterpolation.py
Expand Up @@ -148,6 +148,7 @@ def processAlgorithm(self, parameters, context, feedback):
# need to keep a reference until interpolation is complete
layer = QgsProcessingUtils.variantToSource(v[0], context)
data.source = layer
data.transformContext = context.transformContext()
layers.append(layer)
if not crs.isValid():
crs = layer.sourceCrs()
Expand Down
2 changes: 1 addition & 1 deletion python/plugins/processing/tests/AlgorithmsTestBase.py
Expand Up @@ -178,7 +178,7 @@ def load_param(self, param, id=None):
elif param['type'] == 'interpolation':
prefix = processingTestDataPath()
tmp = ''
for r in param['name'].split(';'):
for r in param['name'].split('::|::'):
v = r.split('::~::')
tmp += '{}::~::{}::~::{}::~::{};'.format(os.path.join(prefix, v[0]),
v[1], v[2], v[3])
Expand Down
20 changes: 20 additions & 0 deletions python/plugins/processing/tests/testdata/custom/breaklines.gml
@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8" ?>
<ogr:FeatureCollection
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://ogr.maptools.org/ breaklines.xsd"
xmlns:ogr="http://ogr.maptools.org/"
xmlns:gml="http://www.opengis.net/gml">
<gml:boundedBy>
<gml:Box>
<gml:coord><gml:X>131913.5965900295</gml:X><gml:Y>140273.865176941</gml:Y></gml:coord>
<gml:coord><gml:X>835452.7784035172</gml:X><gml:Y>302902.8107462598</gml:Y></gml:coord>
</gml:Box>
</gml:boundedBy>

<gml:featureMember>
<ogr:breaklines fid="breaklines.0">
<ogr:geometryProperty><gml:LineString srsName="EPSG:3857"><gml:coordinates>131913.596590029,302902.81074626 199818.485973925,159203.400981573 450287.340258792,140273.865176941 724133.287610245,164771.170880824 835452.778403517,270587.494008943</gml:coordinates></gml:LineString></ogr:geometryProperty>
<ogr:val>1</ogr:val>
</ogr:breaklines>
</gml:featureMember>
</ogr:FeatureCollection>
30 changes: 30 additions & 0 deletions python/plugins/processing/tests/testdata/custom/breaklines.xsd
@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema targetNamespace="http://ogr.maptools.org/" xmlns:ogr="http://ogr.maptools.org/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:gml="http://www.opengis.net/gml" elementFormDefault="qualified" version="1.0">
<xs:import namespace="http://www.opengis.net/gml" schemaLocation="http://schemas.opengis.net/gml/2.1.2/feature.xsd"/>
<xs:element name="FeatureCollection" type="ogr:FeatureCollectionType" substitutionGroup="gml:_FeatureCollection"/>
<xs:complexType name="FeatureCollectionType">
<xs:complexContent>
<xs:extension base="gml:AbstractFeatureCollectionType">
<xs:attribute name="lockId" type="xs:string" use="optional"/>
<xs:attribute name="scope" type="xs:string" use="optional"/>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:element name="breaklines" type="ogr:breaklines_Type" substitutionGroup="gml:_Feature"/>
<xs:complexType name="breaklines_Type">
<xs:complexContent>
<xs:extension base="gml:AbstractFeatureType">
<xs:sequence>
<xs:element name="geometryProperty" type="gml:LineStringPropertyType" nillable="true" minOccurs="0" maxOccurs="1"/>
<xs:element name="val" nillable="true" minOccurs="0" maxOccurs="1">
<xs:simpleType>
<xs:restriction base="xs:integer">
<xs:totalDigits value="10"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:schema>
Expand Up @@ -73,6 +73,22 @@ tests:
# name: expected/triangulation.gml
# type: vector

- algorithm: qgis:tininterpolation
name: TIN interpolation with breaklines
params:
EXTENT: -0.4450000000000012,8.445,-5.2,3.2 [EPSG:4326]
INTERPOLATION_DATA:
name: pointsz.gml::~::1::~::-1::~::0::|::breaklines.gml::~::0::~::1::~::2
type: interpolation
METHOD: 0
PIXEL_SIZE: 0.1
results:
OUTPUT:
hash:
- 34ebe51b4ff75e2eb80746571ac4b72709d200f5d36a1d367d7b0b32
- d2529829631d5b816dba56305736ed7e6961bc63f224f351be719c78
type: rasterhash

- algorithm: qgis:idwinterpolation
name: IDW interpolation using attribute (old parameters)
params:
Expand Down Expand Up @@ -151,6 +167,22 @@ tests:
# name: expected/triangulation.gml
# type: vector

- algorithm: qgis:idwinterpolation
name: IDW interpolation with breakline
params:
DISTANCE_COEFFICIENT: 2.0
EXTENT: -0.4450000000000012,8.445,-5.2,3.2 [EPSG:4326]
INTERPOLATION_DATA:
name: pointsz.gml::~::1::~::-1::~::0::|::breaklines.gml::~::0::~::1::~::2
type: interpolation
PIXEL_SIZE: 0.1
results:
OUTPUT:
hash:
- 56ecc53f6c66a21dd0379170a833c87337932160767cdf9cc47695a8
- f096ffa048892c87eae61ddd4253501f1236ad785a9b084a2badf051
type: rasterhash

- algorithm: native:removenullgeometries
name: Remove null geometries
params:
Expand Down
4 changes: 3 additions & 1 deletion src/analysis/interpolation/qgsinterpolator.cpp
Expand Up @@ -39,6 +39,8 @@ QgsInterpolator::Result QgsInterpolator::cacheBaseData( QgsFeedback *feedback )
mCachedBaseData.clear();
mCachedBaseData.reserve( 100000 );

const QgsCoordinateReferenceSystem crs = !mLayerData.empty() ? mLayerData.at( 0 ).source->sourceCrs() : QgsCoordinateReferenceSystem();

double layerStep = !mLayerData.empty() ? 100.0 / mLayerData.count() : 1;
int layerCount = 0;
for ( const LayerData &layer : qgis::as_const( mLayerData ) )
Expand Down Expand Up @@ -68,7 +70,7 @@ QgsInterpolator::Result QgsInterpolator::cacheBaseData( QgsFeedback *feedback )
bool attributeConversionOk = false;
double progress = layerCount * layerStep;

QgsFeatureIterator fit = source->getFeatures( QgsFeatureRequest().setSubsetOfAttributes( attList ) );
QgsFeatureIterator fit = source->getFeatures( QgsFeatureRequest().setSubsetOfAttributes( attList ).setDestinationCrs( crs, layer.transformContext ) );
double featureStep = source->featureCount() > 0 ? layerStep / source->featureCount() : layerStep;

QgsFeature feature;
Expand Down
8 changes: 8 additions & 0 deletions src/analysis/interpolation/qgsinterpolator.h
Expand Up @@ -22,6 +22,7 @@
#include <QList>
#include "qgis_sip.h"
#include "qgis_analysis.h"
#include "qgscoordinatetransformcontext.h"

class QgsFeatureSource;
class QgsGeometry;
Expand Down Expand Up @@ -101,6 +102,13 @@ class ANALYSIS_EXPORT QgsInterpolator
int interpolationAttribute = -1;
//! Source type
QgsInterpolator::SourceType sourceType = SourcePoints;

/**
* Coordinate transform context.
*
* \since QGIS 3.10.1
*/
QgsCoordinateTransformContext transformContext;
};

QgsInterpolator( const QList<QgsInterpolator::LayerData> &layerData );
Expand Down
4 changes: 3 additions & 1 deletion src/analysis/interpolation/qgstininterpolator.cpp
Expand Up @@ -105,6 +105,8 @@ void QgsTinInterpolator::initialize()
}
}

const QgsCoordinateReferenceSystem crs = !mLayerData.empty() ? mLayerData.at( 0 ).source->sourceCrs() : QgsCoordinateReferenceSystem();

QgsFeature f;
for ( const LayerData &layer : qgis::as_const( mLayerData ) )
{
Expand All @@ -122,7 +124,7 @@ void QgsTinInterpolator::initialize()
break;
}

QgsFeatureIterator fit = layer.source->getFeatures( QgsFeatureRequest().setSubsetOfAttributes( attList ) );
QgsFeatureIterator fit = layer.source->getFeatures( QgsFeatureRequest().setSubsetOfAttributes( attList ).setDestinationCrs( crs, layer.transformContext ) );

while ( fit.nextFeature( f ) )
{
Expand Down

0 comments on commit da853cc

Please sign in to comment.