QGIS API Documentation 3.43.0-Master (e01d6d7c4c0)
qgsalgorithmtransform.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsalgorithmtransform.cpp
3 ---------------------
4 begin : April 2017
5 copyright : (C) 2017 by Nyall Dawson
6 email : nyall dot dawson at gmail dot com
7 ***************************************************************************/
8
9/***************************************************************************
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 ***************************************************************************/
17
19
21
22
23void QgsTransformAlgorithm::initParameters( const QVariantMap & )
24{
25 addParameter( new QgsProcessingParameterCrs( QStringLiteral( "TARGET_CRS" ), QObject::tr( "Target CRS" ), QStringLiteral( "EPSG:4326" ) ) );
26
27 // Convert curves to straight segments
28 auto convertCurvesParam = std::make_unique<QgsProcessingParameterBoolean>( QStringLiteral( "CONVERT_CURVED_GEOMETRIES" ), QObject::tr( "Convert curved geometries to straight segments" ), false );
29 convertCurvesParam->setHelp( QObject::tr( "If checked, curved geometries will be converted to straight segments. Otherwise, they will be kept as curves. This can fix distortion issues." ) );
30 addParameter( convertCurvesParam.release() );
31
32 // Optional coordinate operation
33 auto crsOpParam = std::make_unique<QgsProcessingParameterCoordinateOperation>( QStringLiteral( "OPERATION" ), QObject::tr( "Coordinate operation" ), QVariant(), QStringLiteral( "INPUT" ), QStringLiteral( "TARGET_CRS" ), QVariant(), QVariant(), true );
34 crsOpParam->setFlags( crsOpParam->flags() | Qgis::ProcessingParameterFlag::Advanced );
35 addParameter( crsOpParam.release() );
36}
37
38QgsCoordinateReferenceSystem QgsTransformAlgorithm::outputCrs( const QgsCoordinateReferenceSystem & ) const
39{
40 return mDestCrs;
41}
42
43QString QgsTransformAlgorithm::outputName() const
44{
45 return QObject::tr( "Reprojected" );
46}
47
48Qgis::ProcessingFeatureSourceFlags QgsTransformAlgorithm::sourceFlags() const
49{
51}
52
53QString QgsTransformAlgorithm::name() const
54{
55 return QStringLiteral( "reprojectlayer" );
56}
57
58QString QgsTransformAlgorithm::displayName() const
59{
60 return QObject::tr( "Reproject layer" );
61}
62
63QStringList QgsTransformAlgorithm::tags() const
64{
65 return QObject::tr( "transform,reprojection,crs,srs,warp" ).split( ',' );
66}
67
68QString QgsTransformAlgorithm::group() const
69{
70 return QObject::tr( "Vector general" );
71}
72
73QString QgsTransformAlgorithm::groupId() const
74{
75 return QStringLiteral( "vectorgeneral" );
76}
77
78QString QgsTransformAlgorithm::shortHelpString() const
79{
80 return QObject::tr( "This algorithm reprojects a vector layer. It creates a new layer with the same features "
81 "as the input one, but with geometries reprojected to a new CRS.\n\n"
82 "Attributes are not modified by this algorithm." );
83}
84
85QString QgsTransformAlgorithm::shortDescription() const
86{
87 return QObject::tr( "Creates a vector layer with geometries transformed to a new CRS." );
88}
89
90QgsTransformAlgorithm *QgsTransformAlgorithm::createInstance() const
91{
92 return new QgsTransformAlgorithm();
93}
94
95bool QgsTransformAlgorithm::prepareAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback * )
96{
97 prepareSource( parameters, context );
98 mDestCrs = parameterAsCrs( parameters, QStringLiteral( "TARGET_CRS" ), context );
99 mTransformContext = context.transformContext();
100 mConvertCurveToSegments = parameterAsBoolean( parameters, QStringLiteral( "CONVERT_CURVED_GEOMETRIES" ), context );
101 mCoordOp = parameterAsString( parameters, QStringLiteral( "OPERATION" ), context );
102 return true;
103}
104
105QgsFeatureList QgsTransformAlgorithm::processFeature( const QgsFeature &f, QgsProcessingContext &, QgsProcessingFeedback *feedback )
106{
107 QgsFeature feature = f;
108 if ( !mCreatedTransform )
109 {
110 mCreatedTransform = true;
111 if ( !mCoordOp.isEmpty() )
112 mTransformContext.addCoordinateOperation( sourceCrs(), mDestCrs, mCoordOp, false );
113 mTransform = QgsCoordinateTransform( sourceCrs(), mDestCrs, mTransformContext );
114
115 mTransform.disableFallbackOperationHandler( true );
116 }
117
118 if ( feature.hasGeometry() )
119 {
120 QgsGeometry g = feature.geometry();
121
122 if ( !mTransform.isShortCircuited() && mConvertCurveToSegments )
123 {
124 // convert to straight segments to avoid issues with distorted curves
126 }
127 try
128 {
129 if ( g.transform( mTransform ) == Qgis::GeometryOperationResult::Success )
130 {
131 feature.setGeometry( g );
132 }
133 else
134 {
135 feature.clearGeometry();
136 }
137
138 if ( !mWarnedAboutFallbackTransform && mTransform.fallbackOperationOccurred() )
139 {
140 feedback->reportError( QObject::tr( "An alternative, ballpark-only transform was used when transforming coordinates for one or more features. "
141 "(Possibly an incorrect choice of operation was made for transformations between these reference systems - check "
142 "that the selected operation is valid for the full extent of the input layer.)" ) );
143 mWarnedAboutFallbackTransform = true; // only warn once to avoid flooding the log
144 }
145 }
146 catch ( QgsCsException & )
147 {
148 if ( feedback )
149 feedback->reportError( QObject::tr( "Encountered a transform error when reprojecting feature with id %1." ).arg( f.id() ) );
150 feature.clearGeometry();
151 }
152 }
153 return QgsFeatureList() << feature;
154}
155
@ Success
Operation succeeded.
@ SkipGeometryValidityChecks
Invalid geometry checks should always be skipped. This flag can be useful for algorithms which always...
@ Advanced
Parameter is an advanced parameter which should be hidden from users by default.
QFlags< ProcessingFeatureSourceFlag > ProcessingFeatureSourceFlags
Flags which control how QgsProcessingFeatureSource fetches features.
Definition qgis.h:3588
Represents a coordinate reference system (CRS).
Handles coordinate transforms between two coordinate systems.
Custom exception class for Coordinate Reference System related exceptions.
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
Definition qgsfeature.h:58
QgsFeatureId id
Definition qgsfeature.h:66
QgsGeometry geometry
Definition qgsfeature.h:69
void clearGeometry()
Removes any geometry associated with the feature.
bool hasGeometry() const
Returns true if the feature has an associated geometry.
void setGeometry(const QgsGeometry &geometry)
Set the feature's geometry.
A geometry is the spatial representation of a feature.
Qgis::GeometryOperationResult transform(const QgsCoordinateTransform &ct, Qgis::TransformDirection direction=Qgis::TransformDirection::Forward, bool transformZ=false)
Transforms this geometry as described by the coordinate transform ct.
void convertToStraightSegment(double tolerance=M_PI/180., QgsAbstractGeometry::SegmentationToleranceType toleranceType=QgsAbstractGeometry::MaximumAngle)
Converts the geometry to straight line segments, if it is a curved geometry type.
Contains information about the context in which a processing algorithm is executed.
QgsCoordinateTransformContext transformContext() const
Returns the coordinate transform context.
Base class for providing feedback from a processing algorithm.
virtual void reportError(const QString &error, bool fatalError=false)
Reports that the algorithm encountered an error while executing.
A coordinate reference system parameter for processing algorithms.
QList< QgsFeature > QgsFeatureList