mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-13 00:03:09 -04:00
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.
This commit is contained in:
parent
d5e63bc84f
commit
9ca57bd62c
@ -2338,6 +2338,7 @@ QgsTINInterpolator {#qgis_api_break_3_0_QgsTINInterpolator}
|
||||
------------------
|
||||
|
||||
- The constructor takes a QgsFeedback argument instead of using a QProgressDialog.
|
||||
- setExportTriangulationToFile() and setTriangulationFilePath() were removed. Use setTriangulationSink() instead.
|
||||
|
||||
QgsTolerance {#qgis_api_break_3_0_QgsTolerance}
|
||||
------------
|
||||
|
@ -45,8 +45,26 @@ class QgsTINInterpolator: QgsInterpolator
|
||||
:rtype: int
|
||||
%End
|
||||
|
||||
void setExportTriangulationToFile( bool e );
|
||||
void setTriangulationFilePath( const QString &filepath );
|
||||
static QgsFields triangulationFields();
|
||||
%Docstring
|
||||
Returns the fields output by features when saving the triangulation.
|
||||
These fields should be used when creating
|
||||
a suitable feature sink for setTriangulationSink()
|
||||
.. seealso:: setTriangulationSink()
|
||||
.. versionadded:: 3.0
|
||||
:rtype: QgsFields
|
||||
%End
|
||||
|
||||
void setTriangulationSink( QgsFeatureSink *sink );
|
||||
%Docstring
|
||||
Sets the optional ``sink`` for saving the triangulation features.
|
||||
|
||||
The sink must be setup to accept LineString features, with fields matching
|
||||
those returned by triangulationFields().
|
||||
|
||||
.. seealso:: triangulationFields()
|
||||
.. versionadded:: 3.0
|
||||
%End
|
||||
|
||||
};
|
||||
|
||||
|
@ -30,13 +30,16 @@ import os
|
||||
from qgis.PyQt.QtGui import QIcon
|
||||
|
||||
from qgis.core import (QgsProcessingUtils,
|
||||
QgsProcessing,
|
||||
QgsProcessingParameterDefinition,
|
||||
QgsProcessingParameterEnum,
|
||||
QgsProcessingParameterNumber,
|
||||
QgsProcessingParameterExtent,
|
||||
QgsProcessingParameterRasterDestination,
|
||||
QgsProcessingParameterFileDestination,
|
||||
QgsProcessingException)
|
||||
QgsWkbTypes,
|
||||
QgsProcessingParameterFeatureSink,
|
||||
QgsProcessingException,
|
||||
QgsCoordinateReferenceSystem)
|
||||
from qgis.analysis import (QgsInterpolator,
|
||||
QgsTINInterpolator,
|
||||
QgsGridFileWriter)
|
||||
@ -85,7 +88,6 @@ class ParameterInterpolationData(QgsProcessingParameterDefinition):
|
||||
|
||||
|
||||
class TinInterpolation(QgisAlgorithm):
|
||||
|
||||
INTERPOLATION_DATA = 'INTERPOLATION_DATA'
|
||||
METHOD = 'METHOD'
|
||||
COLUMNS = 'COLUMNS'
|
||||
@ -94,7 +96,7 @@ class TinInterpolation(QgisAlgorithm):
|
||||
CELLSIZE_Y = 'CELLSIZE_Y'
|
||||
EXTENT = 'EXTENT'
|
||||
OUTPUT = 'OUTPUT'
|
||||
TRIANGULATION_FILE = 'TRIANGULATION_FILE'
|
||||
TRIANGULATION = 'TRIANGULATION'
|
||||
|
||||
def icon(self):
|
||||
return QIcon(os.path.join(pluginPath, 'images', 'interpolation.png'))
|
||||
@ -134,10 +136,10 @@ class TinInterpolation(QgisAlgorithm):
|
||||
self.addParameter(QgsProcessingParameterRasterDestination(self.OUTPUT,
|
||||
self.tr('Interpolated')))
|
||||
|
||||
triangulation_file_param = QgsProcessingParameterFileDestination(self.TRIANGULATION_FILE,
|
||||
self.tr('Triangulation'),
|
||||
self.tr('SHP files (*.shp)'),
|
||||
optional=True)
|
||||
triangulation_file_param = QgsProcessingParameterFeatureSink(self.TRIANGULATION,
|
||||
self.tr('Triangulation'),
|
||||
type=QgsProcessing.TypeVectorLine,
|
||||
optional=True)
|
||||
triangulation_file_param.setCreateByDefault(False)
|
||||
self.addParameter(triangulation_file_param)
|
||||
|
||||
@ -156,7 +158,6 @@ class TinInterpolation(QgisAlgorithm):
|
||||
cellsizeY = self.parameterAsDouble(parameters, self.CELLSIZE_Y, context)
|
||||
bbox = self.parameterAsExtent(parameters, self.EXTENT, context)
|
||||
output = self.parameterAsOutputLayer(parameters, self.OUTPUT, context)
|
||||
triangulation = self.parameterAsFileOutput(parameters, self.TRIANGULATION_FILE, context)
|
||||
|
||||
if interpolationData is None:
|
||||
raise QgsProcessingException(
|
||||
@ -168,6 +169,7 @@ class TinInterpolation(QgisAlgorithm):
|
||||
|
||||
layerData = []
|
||||
layers = []
|
||||
crs = QgsCoordinateReferenceSystem()
|
||||
for row in interpolationData.split(';'):
|
||||
v = row.split(',')
|
||||
data = QgsInterpolator.LayerData()
|
||||
@ -176,6 +178,8 @@ class TinInterpolation(QgisAlgorithm):
|
||||
layer = QgsProcessingUtils.mapLayerFromString(v[0], context)
|
||||
data.vectorLayer = layer
|
||||
layers.append(layer)
|
||||
if not crs.isValid():
|
||||
crs = layer.crs()
|
||||
|
||||
data.zCoordInterpolation = bool(v[1])
|
||||
data.interpolationAttribute = int(v[2])
|
||||
@ -192,10 +196,12 @@ class TinInterpolation(QgisAlgorithm):
|
||||
else:
|
||||
interpolationMethod = QgsTINInterpolator.CloughTocher
|
||||
|
||||
(triangulation_sink, triangulation_dest_id) = self.parameterAsSink(parameters, self.TRIANGULATION, context,
|
||||
QgsTINInterpolator.triangulationFields(), QgsWkbTypes.LineString, crs)
|
||||
|
||||
interpolator = QgsTINInterpolator(layerData, interpolationMethod, feedback)
|
||||
if triangulation is not None and triangulation != '':
|
||||
interpolator.setExportTriangulationToFile(True)
|
||||
interpolator.setTriangulationFilePath(triangulation)
|
||||
if triangulation_sink is not None:
|
||||
interpolator.setTriangulationSink(triangulation_sink)
|
||||
|
||||
writer = QgsGridFileWriter(interpolator,
|
||||
output,
|
||||
@ -206,4 +212,4 @@ class TinInterpolation(QgisAlgorithm):
|
||||
cellsizeY)
|
||||
|
||||
writer.writeFile(feedback)
|
||||
return {self.OUTPUT: output}
|
||||
return {self.OUTPUT: output, self.TRIANGULATION: triangulation_dest_id}
|
||||
|
@ -3081,30 +3081,9 @@ QList<int> *DualEdgeTriangulation::getPointsAroundEdge( double x, double y )
|
||||
}
|
||||
}
|
||||
|
||||
bool DualEdgeTriangulation::saveAsShapefile( const QString &fileName ) const
|
||||
bool DualEdgeTriangulation::saveTriangulation( QgsFeatureSink *sink, QgsFeedback *feedback ) const
|
||||
{
|
||||
QString shapeFileName = fileName;
|
||||
|
||||
QgsFields fields;
|
||||
fields.append( QgsField( QStringLiteral( "type" ), QVariant::String, QStringLiteral( "String" ) ) );
|
||||
|
||||
// add the extension if not present
|
||||
if ( shapeFileName.indexOf( QLatin1String( ".shp" ) ) == -1 )
|
||||
{
|
||||
shapeFileName += QLatin1String( ".shp" );
|
||||
}
|
||||
|
||||
//delete already existing files
|
||||
if ( QFile::exists( shapeFileName ) )
|
||||
{
|
||||
if ( !QgsVectorFileWriter::deleteShapeFile( shapeFileName ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
QgsVectorFileWriter writer( shapeFileName, QStringLiteral( "Utf-8" ), fields, QgsWkbTypes::LineString );
|
||||
if ( writer.hasError() != QgsVectorFileWriter::NoError )
|
||||
if ( !sink )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@ -3123,6 +3102,9 @@ bool DualEdgeTriangulation::saveAsShapefile( const QString &fileName ) const
|
||||
|
||||
for ( int i = 0; i < mHalfEdge.size(); ++i )
|
||||
{
|
||||
if ( feedback && feedback->isCanceled() )
|
||||
break;
|
||||
|
||||
HalfEdge *currentEdge = mHalfEdge[i];
|
||||
if ( currentEdge->getPoint() != -1 && mHalfEdge[currentEdge->getDual()]->getPoint() != -1 && !alreadyVisitedEdges[currentEdge->getDual()] )
|
||||
{
|
||||
@ -3152,14 +3134,14 @@ bool DualEdgeTriangulation::saveAsShapefile( const QString &fileName ) const
|
||||
}
|
||||
edgeLineFeature.setAttribute( 0, attributeString );
|
||||
|
||||
writer.addFeature( edgeLineFeature );
|
||||
sink->addFeature( edgeLineFeature, QgsFeatureSink::FastInsert );
|
||||
}
|
||||
alreadyVisitedEdges[i] = true;
|
||||
}
|
||||
|
||||
delete [] alreadyVisitedEdges;
|
||||
|
||||
return true;
|
||||
return !feedback || !feedback->isCanceled();
|
||||
}
|
||||
|
||||
double DualEdgeTriangulation::swapMinAngle( int edge ) const
|
||||
|
@ -103,9 +103,7 @@ class ANALYSIS_EXPORT DualEdgeTriangulation: public Triangulation
|
||||
//! 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
|
||||
virtual QList<int> *getPointsAroundEdge( double x, double y ) override;
|
||||
|
||||
/** Saves the triangulation as a (line) shapefile
|
||||
\returns true in case of success*/
|
||||
virtual bool saveAsShapefile( const QString &fileName ) const override;
|
||||
virtual bool saveTriangulation( QgsFeatureSink *sink, QgsFeedback *feedback = nullptr ) const override;
|
||||
|
||||
protected:
|
||||
//! X-coordinate of the upper right corner of the bounding box
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "NormVecDecorator.h"
|
||||
#include "qgsfeedback.h"
|
||||
#include "qgslogger.h"
|
||||
#include "qgsfields.h"
|
||||
#include <QApplication>
|
||||
|
||||
NormVecDecorator::~NormVecDecorator()
|
||||
@ -590,13 +591,12 @@ bool NormVecDecorator::swapEdge( double x, double y )
|
||||
}
|
||||
}
|
||||
|
||||
bool NormVecDecorator::saveAsShapefile( const QString &fileName ) const
|
||||
bool NormVecDecorator::saveTriangulation( QgsFeatureSink *sink, QgsFeedback *feedback ) const
|
||||
{
|
||||
if ( !mTIN )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return mTIN->saveAsShapefile( fileName );
|
||||
return mTIN->saveTriangulation( sink, feedback );
|
||||
}
|
||||
|
||||
|
||||
|
@ -68,9 +68,7 @@ class ANALYSIS_EXPORT NormVecDecorator: public TriDecorator
|
||||
//! 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)
|
||||
virtual bool swapEdge( double x, double y ) override;
|
||||
|
||||
/** Saves the triangulation as a (line) shapefile
|
||||
\returns true in case of success*/
|
||||
virtual bool saveAsShapefile( const QString &fileName ) const override;
|
||||
virtual bool saveTriangulation( QgsFeatureSink *sink, QgsFeedback *feedback = nullptr ) const override;
|
||||
|
||||
protected:
|
||||
//! Is true, if the normals already have been estimated
|
||||
|
@ -13,5 +13,11 @@
|
||||
* *
|
||||
***************************************************************************/
|
||||
#include "Triangulation.h"
|
||||
#include "qgsfields.h"
|
||||
|
||||
//empty file (abstract class)
|
||||
QgsFields Triangulation::triangulationFields()
|
||||
{
|
||||
QgsFields fields;
|
||||
fields.append( QgsField( QStringLiteral( "type" ), QVariant::String, QStringLiteral( "String" ) ) );
|
||||
return fields;
|
||||
}
|
||||
|
@ -23,7 +23,10 @@
|
||||
#include "TriangleInterpolator.h"
|
||||
#include "qgis_analysis.h"
|
||||
|
||||
class QgsFeatureSink;
|
||||
class Line3D;
|
||||
class QgsFields;
|
||||
class QgsFeedback;
|
||||
|
||||
#define SIP_NO_FILE
|
||||
|
||||
@ -152,10 +155,26 @@ class ANALYSIS_EXPORT Triangulation
|
||||
virtual bool swapEdge( double x, double y ) = 0;
|
||||
|
||||
/**
|
||||
* Saves the triangulation as a (line) shapefile
|
||||
* \returns true in case of success
|
||||
* Returns the fields output by features when calling
|
||||
* saveTriangulation(). These fields should be used when creating
|
||||
* a suitable feature sink for saveTriangulation()
|
||||
* \see saveTriangulation()
|
||||
* \since QGIS 3.0
|
||||
*/
|
||||
virtual bool saveAsShapefile( const QString &fileName ) const = 0;
|
||||
static QgsFields triangulationFields();
|
||||
|
||||
/**
|
||||
* Saves the triangulation features to a feature \a sink.
|
||||
*
|
||||
* The sink must be setup to accept LineString features, with fields matching
|
||||
* those returned by triangulationFields().
|
||||
*
|
||||
* \returns true in case of success
|
||||
*
|
||||
* \see triangulationFields()
|
||||
* \since QGIS 3.0
|
||||
*/
|
||||
virtual bool saveTriangulation( QgsFeatureSink *sink, QgsFeedback *feedback = nullptr ) const = 0;
|
||||
};
|
||||
|
||||
#ifndef SIP_RUN
|
||||
|
@ -35,7 +35,6 @@ QgsTINInterpolator::QgsTINInterpolator( const QList<LayerData> &inputData, TINIn
|
||||
, mTriangleInterpolator( nullptr )
|
||||
, mIsInitialized( false )
|
||||
, mFeedback( feedback )
|
||||
, mExportTriangulationToFile( false )
|
||||
, mInterpolation( interpolation )
|
||||
{
|
||||
}
|
||||
@ -67,6 +66,16 @@ int QgsTINInterpolator::interpolatePoint( double x, double y, double &result )
|
||||
return 0;
|
||||
}
|
||||
|
||||
QgsFields QgsTINInterpolator::triangulationFields()
|
||||
{
|
||||
return Triangulation::triangulationFields();
|
||||
}
|
||||
|
||||
void QgsTINInterpolator::setTriangulationSink( QgsFeatureSink *sink )
|
||||
{
|
||||
mTriangulationSink = sink;
|
||||
}
|
||||
|
||||
void QgsTINInterpolator::initialize()
|
||||
{
|
||||
DualEdgeTriangulation *dualEdgeTriangulation = new DualEdgeTriangulation( 100000, nullptr );
|
||||
@ -143,9 +152,9 @@ void QgsTINInterpolator::initialize()
|
||||
mIsInitialized = true;
|
||||
|
||||
//debug
|
||||
if ( mExportTriangulationToFile )
|
||||
if ( mTriangulationSink )
|
||||
{
|
||||
dualEdgeTriangulation->saveAsShapefile( mTriangulationFilePath );
|
||||
dualEdgeTriangulation->saveTriangulation( mTriangulationSink, mFeedback );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -22,10 +22,12 @@
|
||||
#include <QString>
|
||||
#include "qgis_analysis.h"
|
||||
|
||||
class QgsFeatureSink;
|
||||
class Triangulation;
|
||||
class TriangleInterpolator;
|
||||
class QgsFeature;
|
||||
class QgsFeedback;
|
||||
class QgsFields;
|
||||
|
||||
/** \ingroup analysis
|
||||
* Interpolation in a triangular irregular network*/
|
||||
@ -54,18 +56,34 @@ class ANALYSIS_EXPORT QgsTINInterpolator: public QgsInterpolator
|
||||
\returns 0 in case of success*/
|
||||
int interpolatePoint( double x, double y, double &result ) override;
|
||||
|
||||
void setExportTriangulationToFile( bool e ) {mExportTriangulationToFile = e;}
|
||||
void setTriangulationFilePath( const QString &filepath ) {mTriangulationFilePath = filepath;}
|
||||
/**
|
||||
* Returns the fields output by features when saving the triangulation.
|
||||
* These fields should be used when creating
|
||||
* a suitable feature sink for setTriangulationSink()
|
||||
* \see setTriangulationSink()
|
||||
* \since QGIS 3.0
|
||||
*/
|
||||
static QgsFields triangulationFields();
|
||||
|
||||
/**
|
||||
* Sets the optional \a sink for saving the triangulation features.
|
||||
*
|
||||
* The sink must be setup to accept LineString features, with fields matching
|
||||
* those returned by triangulationFields().
|
||||
*
|
||||
* \see triangulationFields()
|
||||
* \since QGIS 3.0
|
||||
*/
|
||||
void setTriangulationSink( QgsFeatureSink *sink );
|
||||
|
||||
private:
|
||||
Triangulation *mTriangulation = nullptr;
|
||||
TriangleInterpolator *mTriangleInterpolator = nullptr;
|
||||
bool mIsInitialized;
|
||||
QgsFeedback *mFeedback = nullptr;
|
||||
//! If true: export triangulation to shapefile after initialization
|
||||
bool mExportTriangulationToFile;
|
||||
//! File path to export the triangulation
|
||||
QString mTriangulationFilePath;
|
||||
|
||||
//! Feature sink for triangulation
|
||||
QgsFeatureSink *mTriangulationSink = nullptr;
|
||||
//! Type of interpolation
|
||||
TINInterpolation mInterpolation;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user