QGIS API Documentation 4.1.0-Master (5bf3c20f3c9)
Loading...
Searching...
No Matches
qgsvectorwarper.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsgcptransformer.cpp
3 --------------------------------------
4 Date : February 2022
5 Copyright : (C) 2022 by Nyall Dawson
6 Email : nyall dot dawson at gmail dot com
7 ***************************************************************************
8 * *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License as published by *
11 * the Free Software Foundation; either version 2 of the License, or *
12 * (at your option) any later version. *
13 * *
14 ***************************************************************************/
15
16#include "qgsvectorwarper.h"
17
18#include <memory>
19
20#include "qgsfeaturesink.h"
21#include "qgsfeedback.h"
23#include "qgsvectorfilewriter.h"
24#include "qgsvectorlayer.h"
25
26#include <QFileInfo>
27#include <QObject>
28
29#include "moc_qgsvectorwarper.cpp"
30
32 : mMethod( method )
33 , mPoints( points )
34 , mDestinationCrs( destinationCrs )
35{}
36
38{
39 if ( !sink )
40 return false;
41
42 QVector<QgsPointXY> sourcePoints;
43 sourcePoints.reserve( mPoints.size() );
44 QVector<QgsPointXY> destinationPoints;
45 destinationPoints.reserve( mPoints.size() );
46 for ( const QgsGcpPoint &gcpPoint : mPoints )
47 {
48 sourcePoints << gcpPoint.sourcePoint();
49 destinationPoints << gcpPoint.transformedDestinationPoint( mDestinationCrs, context );
50 }
51
52 if ( feedback && feedback->isCanceled() )
53 return false;
54
55 QgsGcpGeometryTransformer transformer( mMethod, sourcePoints, destinationPoints );
56
57 QgsFeature f;
58
59 long long i = 0;
60 while ( iterator.nextFeature( f ) )
61 {
62 if ( feedback )
63 {
64 if ( feedback->isCanceled() )
65 break;
66
67 feedback->setProcessedCount( i );
68 }
69 i++;
70
71 QgsFeature outputFeature = f;
72 bool ok = false;
73 const QgsGeometry transformed = transformer.transform( f.geometry(), ok, feedback );
74 if ( ok )
75 {
76 outputFeature.setGeometry( transformed );
77 if ( !sink->addFeature( outputFeature, QgsFeatureSink::FastInsert ) )
78 {
79 mError = sink->lastError();
80 return false;
81 }
82 }
83 else
84 {
85 mError = QObject::tr( "An error occurred while transforming a feature" );
86 return false;
87 }
88 }
89 return true;
90}
91
92
93//
94// QgsVectorWarperTask
95//
96
98 QgsGcpTransformerInterface::TransformMethod method, const QList<QgsGcpPoint> &points, const QgsCoordinateReferenceSystem &destinationCrs, QgsVectorLayer *layer, const QString &fileName
99)
100 : QgsTask( tr( "Warping %1" ).arg( fileName ), QgsTask::CanCancel )
101 , mMethod( method )
102 , mPoints( points )
103 , mDestinationCrs( destinationCrs )
104 , mDestFileName( fileName )
105{
106 if ( layer )
107 {
108 mTransformContext = layer->transformContext();
109 mSource = std::make_unique<QgsVectorLayerFeatureSource>( layer );
110 mFeatureCount = layer->featureCount();
111 mFields = layer->fields();
112 mWkbType = layer->wkbType();
113 }
114}
115
117{
118 if ( mFeedback )
119 mFeedback->cancel();
120
122}
123
125{
126 mFeedback = std::make_unique<QgsFeedback>();
127
129
130 const QString fileExtension = QFileInfo( mDestFileName ).completeSuffix();
131 saveOptions.driverName = QgsVectorFileWriter::driverForExtension( fileExtension );
132
133 std::unique_ptr<QgsVectorFileWriter> exporter( QgsVectorFileWriter::create( mDestFileName, mFields, mWkbType, mDestinationCrs, mTransformContext, saveOptions ) );
134 if ( exporter->hasError() )
135 {
136 mErrorMessage = exporter->errorMessage();
137 mResult = Result::Error;
138 return false;
139 }
140
141 QgsVectorWarper warper( mMethod, mPoints, mDestinationCrs );
142
143 connect( mFeedback.get(), &QgsFeedback::processedCountChanged, this, [this]( long long count ) {
144 const double newProgress = 100.0 * count / mFeatureCount;
145 // avoid flooding with too many events
146 if ( static_cast<int>( newProgress * 10 ) != static_cast<int>( mLastProgress * 10 ) )
147 {
148 mLastProgress = newProgress;
149 emit progressChanged( newProgress );
150 }
151 } );
152
153 QgsFeatureIterator iterator = mSource->getFeatures();
154 const bool res = warper.transformFeatures( iterator, exporter.get(), mTransformContext, mFeedback.get() );
155 if ( !res )
156 {
157 mErrorMessage = warper.error();
158 mResult = Result::Error;
159 }
160
161 mResult = mFeedback->isCanceled() ? Result::Canceled : Result::Success;
162 mFeedback.reset();
163 return mResult == Result::Success;
164}
Represents a coordinate reference system (CRS).
Contains information about the context in which a coordinate transform is executed.
Wrapper for iterator of features from vector data provider or vector layer.
bool nextFeature(QgsFeature &f)
Fetch next feature and stores in f, returns true on success.
An interface for objects which accept features via addFeature(s) methods.
virtual bool addFeature(QgsFeature &feature, QgsFeatureSink::Flags flags=QgsFeatureSink::Flags())
Adds a single feature to the sink.
@ FastInsert
Use faster inserts, at the cost of updating the passed features to reflect changes made at the provid...
virtual QString lastError() const
Returns the most recent error encountered by the sink, e.g.
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
Definition qgsfeature.h:60
QgsGeometry geometry
Definition qgsfeature.h:71
void setGeometry(const QgsGeometry &geometry)
Set the feature's geometry.
Base class for feedback objects to be used for cancellation of something running in a worker thread.
Definition qgsfeedback.h:44
bool isCanceled() const
Tells whether the operation has been canceled already.
Definition qgsfeedback.h:56
void setProcessedCount(unsigned long long processedCount)
Sets the current processed objects count for the feedback object.
void processedCountChanged(unsigned long long processedCount)
Emitted when the feedback object reports a change in the number of processed objects.
A geometry transformer which uses an underlying Ground Control Points (GCP) based transformation to m...
QgsGeometry transform(const QgsGeometry &geometry, bool &ok, QgsFeedback *feedback=nullptr)
Transforms the specified input geometry using the GCP based transform.
Contains properties of a ground control point (GCP).
Definition qgsgcppoint.h:31
TransformMethod
Available transformation methods.
A geometry is the spatial representation of a feature.
QgsCoordinateTransformContext transformContext() const
Returns the layer data provider coordinate transform context or a default transform context if the la...
virtual void cancel()
Notifies the task that it should terminate.
QgsTask(const QString &description=QString(), QgsTask::Flags flags=AllFlags)
Constructor for QgsTask.
@ CanCancel
Task can be canceled.
Options to pass to QgsVectorFileWriter::writeAsVectorFormat().
static QString driverForExtension(const QString &extension)
Returns the OGR driver name for a specified file extension.
static QgsVectorFileWriter * create(const QString &fileName, const QgsFields &fields, Qgis::WkbType geometryType, const QgsCoordinateReferenceSystem &srs, const QgsCoordinateTransformContext &transformContext, const QgsVectorFileWriter::SaveVectorOptions &options, QgsFeatureSink::SinkFlags sinkFlags=QgsFeatureSink::SinkFlags(), QString *newFilename=nullptr, QString *newLayer=nullptr)
Create a new vector file writer.
Represents a vector layer which manages a vector based dataset.
long long featureCount(const QString &legendKey) const
Number of features rendered with specified legend key.
Q_INVOKABLE Qgis::WkbType wkbType() const final
Returns the WKBType or WKBUnknown in case of error.
bool run() override
Performs the task's operation.
@ Error
An error occurred while warping.
void cancel() override
Notifies the task that it should terminate.
QgsVectorWarperTask(QgsGcpTransformerInterface::TransformMethod method, const QList< QgsGcpPoint > &points, const QgsCoordinateReferenceSystem &destinationCrs, QgsVectorLayer *layer, const QString &fileName)
Constructor for QgsVectorWarperTask.
Vector layer warper which warps vector layers based on a list of source and destination GCPs.
bool transformFeatures(QgsFeatureIterator &iterator, QgsFeatureSink *sink, const QgsCoordinateTransformContext &context, QgsFeedback *feedback=nullptr) const
Transforms the features from iterator and adds the results to the specified sink.
QgsVectorWarper(QgsGcpTransformerInterface::TransformMethod method, const QList< QgsGcpPoint > &points, const QgsCoordinateReferenceSystem &destinationCrs)
Constructor for QgsVectorWarper.