QGIS API Documentation  3.26.3-Buenos Aires (65e4edfdad)
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 #include "qgsfeaturesink.h"
18 #include "qgsfeedback.h"
20 #include "qgsfeaturesource.h"
21 #include "qgsvectorlayer.h"
22 
23 #include <QObject>
24 #include <QFileInfo>
25 
26 QgsVectorWarper::QgsVectorWarper( QgsGcpTransformerInterface::TransformMethod method, const QList<QgsGcpPoint> &points, const QgsCoordinateReferenceSystem &destinationCrs )
27  : mMethod( method )
28  , mPoints( points )
29  , mDestinationCrs( destinationCrs )
30 {
31 
32 }
33 
35 {
36  if ( !sink )
37  return false;
38 
39  QVector<QgsPointXY> sourcePoints;
40  sourcePoints.reserve( mPoints.size() );
41  QVector<QgsPointXY> destinationPoints;
42  destinationPoints.reserve( mPoints.size() );
43  for ( const QgsGcpPoint &gcpPoint : mPoints )
44  {
45  sourcePoints << gcpPoint.sourcePoint();
46  destinationPoints << gcpPoint.transformedDestinationPoint( mDestinationCrs, context );
47  }
48 
49  if ( feedback && feedback->isCanceled() )
50  return false;
51 
52  QgsGcpGeometryTransformer transformer( mMethod, sourcePoints, destinationPoints );
53 
54  QgsFeature f;
55 
56  long long i = 0;
57  while ( iterator.nextFeature( f ) )
58  {
59  if ( feedback )
60  {
61  if ( feedback->isCanceled() )
62  break;
63 
64  feedback->setProcessedCount( i );
65  }
66  i++;
67 
68  QgsFeature outputFeature = f;
69  bool ok = false;
70  const QgsGeometry transformed = transformer.transform( f.geometry(), ok, feedback );
71  if ( ok )
72  {
73  outputFeature.setGeometry( transformed );
74  if ( !sink->addFeature( outputFeature, QgsFeatureSink::FastInsert ) )
75  {
76  mError = sink->lastError();
77  return false;
78  }
79  }
80  else
81  {
82  mError = QObject::tr( "An error occurred while transforming a feature" );
83  return false;
84  }
85  }
86  return true;
87 }
88 
89 
90 
91 //
92 // QgsVectorWarperTask
93 //
94 
96  const QgsCoordinateReferenceSystem &destinationCrs,
97  QgsVectorLayer *layer, const QString &fileName )
98  : QgsTask( tr( "Warping %1" ).arg( fileName ), QgsTask::CanCancel )
99  , mMethod( method )
100  , mPoints( points )
101  , mDestinationCrs( destinationCrs )
102  , mDestFileName( fileName )
103 {
104  if ( layer )
105  {
106  mTransformContext = layer->transformContext();
107  mSource.reset( new QgsVectorLayerFeatureSource( layer ) );
108  mFeatureCount = layer->featureCount();
109  mFields = layer->fields();
110  mWkbType = layer->wkbType();
111  }
112 }
113 
115 {
116  if ( mFeedback )
117  mFeedback->cancel();
118 
119  QgsTask::cancel();
120 }
121 
123 {
124  mFeedback = std::make_unique< QgsFeedback >();
125 
127 
128  const QString fileExtension = QFileInfo( mDestFileName ).completeSuffix();
129  saveOptions.driverName = QgsVectorFileWriter::driverForExtension( fileExtension );
130 
131  std::unique_ptr< QgsVectorFileWriter > exporter( QgsVectorFileWriter::create( mDestFileName, mFields, mWkbType, mDestinationCrs, mTransformContext, saveOptions ) );
132  if ( exporter->hasError() )
133  {
134  mErrorMessage = exporter->errorMessage();
135  mResult = Result::Error;
136  return false;
137  }
138 
139  QgsVectorWarper warper( mMethod, mPoints, mDestinationCrs );
140 
141  connect( mFeedback.get(), &QgsFeedback::processedCountChanged, this, [ = ]( long long count )
142  {
143  const double newProgress = 100.0 * count / mFeatureCount;
144  // avoid flooding with too many events
145  if ( static_cast< int >( newProgress * 10 ) != static_cast< int >( mLastProgress * 10 ) )
146  {
147  mLastProgress = newProgress;
148  emit progressChanged( newProgress );
149  }
150  } );
151 
152  QgsFeatureIterator iterator = mSource->getFeatures();
153  const bool res = warper.transformFeatures( iterator, exporter.get(), mTransformContext, mFeedback.get() );
154  if ( !res )
155  {
156  mErrorMessage = warper.error();
157  mResult = Result::Error;
158  }
159 
160  mResult = mFeedback->isCanceled() ? Result::Canceled : Result::Success;
161  mFeedback.reset();
162  return mResult == Result::Success;
163 }
164 
qgsgcpgeometrytransformer.h
QgsVectorWarper::transformFeatures
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.
Definition: qgsvectorwarper.cpp:34
QgsVectorFileWriter::create
static QgsVectorFileWriter * create(const QString &fileName, const QgsFields &fields, QgsWkbTypes::Type 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.
Definition: qgsvectorfilewriter.cpp:133
QgsCoordinateTransformContext
Contains information about the context in which a coordinate transform is executed.
Definition: qgscoordinatetransformcontext.h:57
QgsVectorLayer::wkbType
Q_INVOKABLE QgsWkbTypes::Type wkbType() const FINAL
Returns the WKBType or WKBUnknown in case of error.
Definition: qgsvectorlayer.cpp:725
QgsVectorFileWriter::SaveVectorOptions
Options to pass to writeAsVectorFormat()
Definition: qgsvectorfilewriter.h:458
QgsGcpPoint
Contains properties of a ground control point (GCP).
Definition: qgsgcppoint.h:30
QgsGcpGeometryTransformer
A geometry transformer which uses an underlying Ground Control Points (GCP) based transformation to m...
Definition: qgsgcpgeometrytransformer.h:35
QgsVectorWarperTask::QgsVectorWarperTask
QgsVectorWarperTask(QgsGcpTransformerInterface::TransformMethod method, const QList< QgsGcpPoint > &points, const QgsCoordinateReferenceSystem &destinationCrs, QgsVectorLayer *layer, const QString &fileName)
Constructor for QgsVectorWarperTask.
Definition: qgsvectorwarper.cpp:95
QgsFeedback::setProcessedCount
void setProcessedCount(unsigned long long processedCount)
Sets the current processed objects count for the feedback object.
Definition: qgsfeedback.h:112
QgsVectorLayer::featureCount
long long featureCount(const QString &legendKey) const
Number of features rendered with specified legend key.
Definition: qgsvectorlayer.cpp:812
QgsFeedback::processedCountChanged
void processedCountChanged(unsigned long long processedCount)
Emitted when the feedback object reports a change in the number of processed objects.
QgsFeatureSink::addFeature
virtual bool addFeature(QgsFeature &feature, QgsFeatureSink::Flags flags=QgsFeatureSink::Flags())
Adds a single feature to the sink.
Definition: qgsfeaturesink.cpp:20
qgsfeaturesink.h
QgsFeature::geometry
QgsGeometry geometry
Definition: qgsfeature.h:71
QgsFeedback::isCanceled
bool isCanceled() const SIP_HOLDGIL
Tells whether the operation has been canceled already.
Definition: qgsfeedback.h:67
QgsVectorWarper::QgsVectorWarper
QgsVectorWarper(QgsGcpTransformerInterface::TransformMethod method, const QList< QgsGcpPoint > &points, const QgsCoordinateReferenceSystem &destinationCrs)
Constructor for QgsVectorWarper.
Definition: qgsvectorwarper.cpp:26
QgsTask::cancel
virtual void cancel()
Notifies the task that it should terminate.
Definition: qgstaskmanager.cpp:91
QgsVectorLayer::fields
QgsFields fields() const FINAL
Returns the list of fields of this layer.
Definition: qgsvectorlayer.cpp:3436
QgsFeature::setGeometry
void setGeometry(const QgsGeometry &geometry)
Set the feature's geometry.
Definition: qgsfeature.cpp:170
QgsFeedback
Base class for feedback objects to be used for cancellation of something running in a worker thread.
Definition: qgsfeedback.h:44
qgsfeaturesource.h
qgsvectorwarper.h
QgsVectorWarper
Vector layer warper which warps vector layers based on a list of source and destination GCPs.
Definition: qgsvectorwarper.h:38
QgsVectorFileWriter::driverForExtension
static QString driverForExtension(const QString &extension)
Returns the OGR driver name for a specified file extension.
Definition: qgsvectorfilewriter.cpp:3716
QgsCoordinateReferenceSystem
This class represents a coordinate reference system (CRS).
Definition: qgscoordinatereferencesystem.h:211
qgsvectorlayer.h
QgsMapLayer::transformContext
QgsCoordinateTransformContext transformContext() const
Returns the layer data provider coordinate transform context or a default transform context if the la...
Definition: qgsmaplayer.cpp:951
QgsVectorWarperTask::cancel
void cancel() override
Notifies the task that it should terminate.
Definition: qgsvectorwarper.cpp:114
QgsFeatureIterator::nextFeature
bool nextFeature(QgsFeature &f)
Definition: qgsfeatureiterator.h:399
QgsFeatureSink::lastError
virtual QString lastError() const
Returns the most recent error encountered by the sink, e.g.
Definition: qgsfeaturesink.h:115
QgsGeometry
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:124
QgsVectorLayer
Represents a vector layer which manages a vector based data sets.
Definition: qgsvectorlayer.h:391
QgsVectorLayerFeatureSource
Partial snapshot of vector layer's state (only the members necessary for access to features)
Definition: qgsvectorlayerfeatureiterator.h:52
QgsGcpTransformerInterface::TransformMethod
TransformMethod
Available transformation methods.
Definition: qgsgcptransformer.h:55
QgsFeature
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
Definition: qgsfeature.h:55
QgsGcpGeometryTransformer::transform
QgsGeometry transform(const QgsGeometry &geometry, bool &ok, QgsFeedback *feedback=nullptr)
Transforms the specified input geometry using the GCP based transform.
Definition: qgsgcpgeometrytransformer.cpp:43
QgsVectorWarperTask::run
bool run() override
Performs the task's operation.
Definition: qgsvectorwarper.cpp:122
QgsVectorFileWriter::SaveVectorOptions::driverName
QString driverName
OGR driver to use.
Definition: qgsvectorfilewriter.h:467
QgsFeatureIterator
Wrapper for iterator of features from vector data provider or vector layer.
Definition: qgsfeatureiterator.h:289
qgsfeedback.h
QgsFeatureSink
An interface for objects which accept features via addFeature(s) methods.
Definition: qgsfeaturesink.h:33
QgsVectorWarperTask::Result::Error
@ Error
An error occurred while warping.
QgsFeatureSink::FastInsert
@ FastInsert
Use faster inserts, at the cost of updating the passed features to reflect changes made at the provid...
Definition: qgsfeaturesink.h:70
QgsTask
Abstract base class for long running background tasks. Tasks can be controlled directly,...
Definition: qgstaskmanager.h:54