Skip to content

Commit 9ca57bd

Browse files
committedAug 29, 2017
Use a QgsFeatureSink instead of path to shapefile in QgsTinInterpolator
Instead of just forcing writing the triangulation to a shapefile (boo!) change the parameter to use a QgsFeatureSink, so that anything which implements the QgsFeatureSink interface can be used for storing the triangulation.
1 parent d5e63bc commit 9ca57bd

File tree

11 files changed

+116
-61
lines changed

11 files changed

+116
-61
lines changed
 

‎doc/api_break.dox

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2338,6 +2338,7 @@ QgsTINInterpolator {#qgis_api_break_3_0_QgsTINInterpolator}
23382338
------------------
23392339

23402340
- The constructor takes a QgsFeedback argument instead of using a QProgressDialog.
2341+
- setExportTriangulationToFile() and setTriangulationFilePath() were removed. Use setTriangulationSink() instead.
23412342

23422343
QgsTolerance {#qgis_api_break_3_0_QgsTolerance}
23432344
------------

‎python/analysis/interpolation/qgstininterpolator.sip

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,26 @@ class QgsTINInterpolator: QgsInterpolator
4545
:rtype: int
4646
%End
4747

48-
void setExportTriangulationToFile( bool e );
49-
void setTriangulationFilePath( const QString &filepath );
48+
static QgsFields triangulationFields();
49+
%Docstring
50+
Returns the fields output by features when saving the triangulation.
51+
These fields should be used when creating
52+
a suitable feature sink for setTriangulationSink()
53+
.. seealso:: setTriangulationSink()
54+
.. versionadded:: 3.0
55+
:rtype: QgsFields
56+
%End
57+
58+
void setTriangulationSink( QgsFeatureSink *sink );
59+
%Docstring
60+
Sets the optional ``sink`` for saving the triangulation features.
61+
62+
The sink must be setup to accept LineString features, with fields matching
63+
those returned by triangulationFields().
64+
65+
.. seealso:: triangulationFields()
66+
.. versionadded:: 3.0
67+
%End
5068

5169
};
5270

‎python/plugins/processing/algs/qgis/TinInterpolation.py

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,16 @@
3030
from qgis.PyQt.QtGui import QIcon
3131

3232
from qgis.core import (QgsProcessingUtils,
33+
QgsProcessing,
3334
QgsProcessingParameterDefinition,
3435
QgsProcessingParameterEnum,
3536
QgsProcessingParameterNumber,
3637
QgsProcessingParameterExtent,
3738
QgsProcessingParameterRasterDestination,
38-
QgsProcessingParameterFileDestination,
39-
QgsProcessingException)
39+
QgsWkbTypes,
40+
QgsProcessingParameterFeatureSink,
41+
QgsProcessingException,
42+
QgsCoordinateReferenceSystem)
4043
from qgis.analysis import (QgsInterpolator,
4144
QgsTINInterpolator,
4245
QgsGridFileWriter)
@@ -85,7 +88,6 @@ def dataToString(data):
8588

8689

8790
class TinInterpolation(QgisAlgorithm):
88-
8991
INTERPOLATION_DATA = 'INTERPOLATION_DATA'
9092
METHOD = 'METHOD'
9193
COLUMNS = 'COLUMNS'
@@ -94,7 +96,7 @@ class TinInterpolation(QgisAlgorithm):
9496
CELLSIZE_Y = 'CELLSIZE_Y'
9597
EXTENT = 'EXTENT'
9698
OUTPUT = 'OUTPUT'
97-
TRIANGULATION_FILE = 'TRIANGULATION_FILE'
99+
TRIANGULATION = 'TRIANGULATION'
98100

99101
def icon(self):
100102
return QIcon(os.path.join(pluginPath, 'images', 'interpolation.png'))
@@ -134,10 +136,10 @@ def initAlgorithm(self, config=None):
134136
self.addParameter(QgsProcessingParameterRasterDestination(self.OUTPUT,
135137
self.tr('Interpolated')))
136138

137-
triangulation_file_param = QgsProcessingParameterFileDestination(self.TRIANGULATION_FILE,
138-
self.tr('Triangulation'),
139-
self.tr('SHP files (*.shp)'),
140-
optional=True)
139+
triangulation_file_param = QgsProcessingParameterFeatureSink(self.TRIANGULATION,
140+
self.tr('Triangulation'),
141+
type=QgsProcessing.TypeVectorLine,
142+
optional=True)
141143
triangulation_file_param.setCreateByDefault(False)
142144
self.addParameter(triangulation_file_param)
143145

@@ -156,7 +158,6 @@ def processAlgorithm(self, parameters, context, feedback):
156158
cellsizeY = self.parameterAsDouble(parameters, self.CELLSIZE_Y, context)
157159
bbox = self.parameterAsExtent(parameters, self.EXTENT, context)
158160
output = self.parameterAsOutputLayer(parameters, self.OUTPUT, context)
159-
triangulation = self.parameterAsFileOutput(parameters, self.TRIANGULATION_FILE, context)
160161

161162
if interpolationData is None:
162163
raise QgsProcessingException(
@@ -168,6 +169,7 @@ def processAlgorithm(self, parameters, context, feedback):
168169

169170
layerData = []
170171
layers = []
172+
crs = QgsCoordinateReferenceSystem()
171173
for row in interpolationData.split(';'):
172174
v = row.split(',')
173175
data = QgsInterpolator.LayerData()
@@ -176,6 +178,8 @@ def processAlgorithm(self, parameters, context, feedback):
176178
layer = QgsProcessingUtils.mapLayerFromString(v[0], context)
177179
data.vectorLayer = layer
178180
layers.append(layer)
181+
if not crs.isValid():
182+
crs = layer.crs()
179183

180184
data.zCoordInterpolation = bool(v[1])
181185
data.interpolationAttribute = int(v[2])
@@ -192,10 +196,12 @@ def processAlgorithm(self, parameters, context, feedback):
192196
else:
193197
interpolationMethod = QgsTINInterpolator.CloughTocher
194198

199+
(triangulation_sink, triangulation_dest_id) = self.parameterAsSink(parameters, self.TRIANGULATION, context,
200+
QgsTINInterpolator.triangulationFields(), QgsWkbTypes.LineString, crs)
201+
195202
interpolator = QgsTINInterpolator(layerData, interpolationMethod, feedback)
196-
if triangulation is not None and triangulation != '':
197-
interpolator.setExportTriangulationToFile(True)
198-
interpolator.setTriangulationFilePath(triangulation)
203+
if triangulation_sink is not None:
204+
interpolator.setTriangulationSink(triangulation_sink)
199205

200206
writer = QgsGridFileWriter(interpolator,
201207
output,
@@ -206,4 +212,4 @@ def processAlgorithm(self, parameters, context, feedback):
206212
cellsizeY)
207213

208214
writer.writeFile(feedback)
209-
return {self.OUTPUT: output}
215+
return {self.OUTPUT: output, self.TRIANGULATION: triangulation_dest_id}

‎src/analysis/interpolation/DualEdgeTriangulation.cpp

Lines changed: 7 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -3081,30 +3081,9 @@ QList<int> *DualEdgeTriangulation::getPointsAroundEdge( double x, double y )
30813081
}
30823082
}
30833083

3084-
bool DualEdgeTriangulation::saveAsShapefile( const QString &fileName ) const
3084+
bool DualEdgeTriangulation::saveTriangulation( QgsFeatureSink *sink, QgsFeedback *feedback ) const
30853085
{
3086-
QString shapeFileName = fileName;
3087-
3088-
QgsFields fields;
3089-
fields.append( QgsField( QStringLiteral( "type" ), QVariant::String, QStringLiteral( "String" ) ) );
3090-
3091-
// add the extension if not present
3092-
if ( shapeFileName.indexOf( QLatin1String( ".shp" ) ) == -1 )
3093-
{
3094-
shapeFileName += QLatin1String( ".shp" );
3095-
}
3096-
3097-
//delete already existing files
3098-
if ( QFile::exists( shapeFileName ) )
3099-
{
3100-
if ( !QgsVectorFileWriter::deleteShapeFile( shapeFileName ) )
3101-
{
3102-
return false;
3103-
}
3104-
}
3105-
3106-
QgsVectorFileWriter writer( shapeFileName, QStringLiteral( "Utf-8" ), fields, QgsWkbTypes::LineString );
3107-
if ( writer.hasError() != QgsVectorFileWriter::NoError )
3086+
if ( !sink )
31083087
{
31093088
return false;
31103089
}
@@ -3123,6 +3102,9 @@ bool DualEdgeTriangulation::saveAsShapefile( const QString &fileName ) const
31233102

31243103
for ( int i = 0; i < mHalfEdge.size(); ++i )
31253104
{
3105+
if ( feedback && feedback->isCanceled() )
3106+
break;
3107+
31263108
HalfEdge *currentEdge = mHalfEdge[i];
31273109
if ( currentEdge->getPoint() != -1 && mHalfEdge[currentEdge->getDual()]->getPoint() != -1 && !alreadyVisitedEdges[currentEdge->getDual()] )
31283110
{
@@ -3152,14 +3134,14 @@ bool DualEdgeTriangulation::saveAsShapefile( const QString &fileName ) const
31523134
}
31533135
edgeLineFeature.setAttribute( 0, attributeString );
31543136

3155-
writer.addFeature( edgeLineFeature );
3137+
sink->addFeature( edgeLineFeature, QgsFeatureSink::FastInsert );
31563138
}
31573139
alreadyVisitedEdges[i] = true;
31583140
}
31593141

31603142
delete [] alreadyVisitedEdges;
31613143

3162-
return true;
3144+
return !feedback || !feedback->isCanceled();
31633145
}
31643146

31653147
double DualEdgeTriangulation::swapMinAngle( int edge ) const

‎src/analysis/interpolation/DualEdgeTriangulation.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -103,9 +103,7 @@ class ANALYSIS_EXPORT DualEdgeTriangulation: public Triangulation
103103
//! Returns a value list with the numbers of the four points, which would be affected by an edge swap. This function is e.g. needed by NormVecDecorator to know the points, for which the normals have to be recalculated. The returned ValueList has to be deleted by the code which calls the method
104104
virtual QList<int> *getPointsAroundEdge( double x, double y ) override;
105105

106-
/** Saves the triangulation as a (line) shapefile
107-
\returns true in case of success*/
108-
virtual bool saveAsShapefile( const QString &fileName ) const override;
106+
virtual bool saveTriangulation( QgsFeatureSink *sink, QgsFeedback *feedback = nullptr ) const override;
109107

110108
protected:
111109
//! X-coordinate of the upper right corner of the bounding box

‎src/analysis/interpolation/NormVecDecorator.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "NormVecDecorator.h"
1818
#include "qgsfeedback.h"
1919
#include "qgslogger.h"
20+
#include "qgsfields.h"
2021
#include <QApplication>
2122

2223
NormVecDecorator::~NormVecDecorator()
@@ -590,13 +591,12 @@ bool NormVecDecorator::swapEdge( double x, double y )
590591
}
591592
}
592593

593-
bool NormVecDecorator::saveAsShapefile( const QString &fileName ) const
594+
bool NormVecDecorator::saveTriangulation( QgsFeatureSink *sink, QgsFeedback *feedback ) const
594595
{
595596
if ( !mTIN )
596597
{
597598
return false;
598599
}
599-
return mTIN->saveAsShapefile( fileName );
600+
return mTIN->saveTriangulation( sink, feedback );
600601
}
601602

602-

‎src/analysis/interpolation/NormVecDecorator.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,7 @@ class ANALYSIS_EXPORT NormVecDecorator: public TriDecorator
6868
//! Swaps the edge which is closest to the point with x and y coordinates (if this is possible) and forces recalculation of the concerned normals (if alreadyestimated is true)
6969
virtual bool swapEdge( double x, double y ) override;
7070

71-
/** Saves the triangulation as a (line) shapefile
72-
\returns true in case of success*/
73-
virtual bool saveAsShapefile( const QString &fileName ) const override;
71+
virtual bool saveTriangulation( QgsFeatureSink *sink, QgsFeedback *feedback = nullptr ) const override;
7472

7573
protected:
7674
//! Is true, if the normals already have been estimated

‎src/analysis/interpolation/Triangulation.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,11 @@
1313
* *
1414
***************************************************************************/
1515
#include "Triangulation.h"
16+
#include "qgsfields.h"
1617

17-
//empty file (abstract class)
18+
QgsFields Triangulation::triangulationFields()
19+
{
20+
QgsFields fields;
21+
fields.append( QgsField( QStringLiteral( "type" ), QVariant::String, QStringLiteral( "String" ) ) );
22+
return fields;
23+
}

‎src/analysis/interpolation/Triangulation.h

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,10 @@
2323
#include "TriangleInterpolator.h"
2424
#include "qgis_analysis.h"
2525

26+
class QgsFeatureSink;
2627
class Line3D;
28+
class QgsFields;
29+
class QgsFeedback;
2730

2831
#define SIP_NO_FILE
2932

@@ -152,10 +155,26 @@ class ANALYSIS_EXPORT Triangulation
152155
virtual bool swapEdge( double x, double y ) = 0;
153156

154157
/**
155-
* Saves the triangulation as a (line) shapefile
158+
* Returns the fields output by features when calling
159+
* saveTriangulation(). These fields should be used when creating
160+
* a suitable feature sink for saveTriangulation()
161+
* \see saveTriangulation()
162+
* \since QGIS 3.0
163+
*/
164+
static QgsFields triangulationFields();
165+
166+
/**
167+
* Saves the triangulation features to a feature \a sink.
168+
*
169+
* The sink must be setup to accept LineString features, with fields matching
170+
* those returned by triangulationFields().
171+
*
156172
* \returns true in case of success
173+
*
174+
* \see triangulationFields()
175+
* \since QGIS 3.0
157176
*/
158-
virtual bool saveAsShapefile( const QString &fileName ) const = 0;
177+
virtual bool saveTriangulation( QgsFeatureSink *sink, QgsFeedback *feedback = nullptr ) const = 0;
159178
};
160179

161180
#ifndef SIP_RUN

‎src/analysis/interpolation/qgstininterpolator.cpp

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ QgsTINInterpolator::QgsTINInterpolator( const QList<LayerData> &inputData, TINIn
3535
, mTriangleInterpolator( nullptr )
3636
, mIsInitialized( false )
3737
, mFeedback( feedback )
38-
, mExportTriangulationToFile( false )
3938
, mInterpolation( interpolation )
4039
{
4140
}
@@ -67,6 +66,16 @@ int QgsTINInterpolator::interpolatePoint( double x, double y, double &result )
6766
return 0;
6867
}
6968

69+
QgsFields QgsTINInterpolator::triangulationFields()
70+
{
71+
return Triangulation::triangulationFields();
72+
}
73+
74+
void QgsTINInterpolator::setTriangulationSink( QgsFeatureSink *sink )
75+
{
76+
mTriangulationSink = sink;
77+
}
78+
7079
void QgsTINInterpolator::initialize()
7180
{
7281
DualEdgeTriangulation *dualEdgeTriangulation = new DualEdgeTriangulation( 100000, nullptr );
@@ -143,9 +152,9 @@ void QgsTINInterpolator::initialize()
143152
mIsInitialized = true;
144153

145154
//debug
146-
if ( mExportTriangulationToFile )
155+
if ( mTriangulationSink )
147156
{
148-
dualEdgeTriangulation->saveAsShapefile( mTriangulationFilePath );
157+
dualEdgeTriangulation->saveTriangulation( mTriangulationSink, mFeedback );
149158
}
150159
}
151160

‎src/analysis/interpolation/qgstininterpolator.h

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,12 @@
2222
#include <QString>
2323
#include "qgis_analysis.h"
2424

25+
class QgsFeatureSink;
2526
class Triangulation;
2627
class TriangleInterpolator;
2728
class QgsFeature;
2829
class QgsFeedback;
30+
class QgsFields;
2931

3032
/** \ingroup analysis
3133
* Interpolation in a triangular irregular network*/
@@ -54,18 +56,34 @@ class ANALYSIS_EXPORT QgsTINInterpolator: public QgsInterpolator
5456
\returns 0 in case of success*/
5557
int interpolatePoint( double x, double y, double &result ) override;
5658

57-
void setExportTriangulationToFile( bool e ) {mExportTriangulationToFile = e;}
58-
void setTriangulationFilePath( const QString &filepath ) {mTriangulationFilePath = filepath;}
59+
/**
60+
* Returns the fields output by features when saving the triangulation.
61+
* These fields should be used when creating
62+
* a suitable feature sink for setTriangulationSink()
63+
* \see setTriangulationSink()
64+
* \since QGIS 3.0
65+
*/
66+
static QgsFields triangulationFields();
67+
68+
/**
69+
* Sets the optional \a sink for saving the triangulation features.
70+
*
71+
* The sink must be setup to accept LineString features, with fields matching
72+
* those returned by triangulationFields().
73+
*
74+
* \see triangulationFields()
75+
* \since QGIS 3.0
76+
*/
77+
void setTriangulationSink( QgsFeatureSink *sink );
5978

6079
private:
6180
Triangulation *mTriangulation = nullptr;
6281
TriangleInterpolator *mTriangleInterpolator = nullptr;
6382
bool mIsInitialized;
6483
QgsFeedback *mFeedback = nullptr;
65-
//! If true: export triangulation to shapefile after initialization
66-
bool mExportTriangulationToFile;
67-
//! File path to export the triangulation
68-
QString mTriangulationFilePath;
84+
85+
//! Feature sink for triangulation
86+
QgsFeatureSink *mTriangulationSink = nullptr;
6987
//! Type of interpolation
7088
TINInterpolation mInterpolation;
7189

0 commit comments

Comments
 (0)
Please sign in to comment.