QGIS API Documentation 3.34.0-Prizren (ffbdd678812)
Loading...
Searching...
No Matches
qgsremappingproxyfeaturesink.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsremappingproxyfeaturesink.cpp
3 ----------------------
4 begin : April 2020
5 copyright : (C) 2020 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#include "qgslogger.h"
20
23 , mDefinition( mappingDefinition )
24 , mSink( sink )
25 , mOwnsSink( ownsSink )
26{}
27
29{
30 if ( mOwnsSink )
31 delete mSink;
32}
33
35{
36 mContext = context;
37}
38
40{
41 mTransform = QgsCoordinateTransform( mDefinition.sourceCrs(), mDefinition.destinationCrs(), context );
42}
43
45{
47
48 mContext.setFeature( feature );
49
50 // remap fields first
51 QgsFeature f;
52 f.setFields( mDefinition.destinationFields(), true );
53 QgsAttributes attributes;
54 const QMap< QString, QgsProperty > fieldMap = mDefinition.fieldMap();
55 for ( const QgsField &field : mDefinition.destinationFields() )
56 {
57 if ( fieldMap.contains( field.name() ) )
58 {
59 attributes.append( fieldMap.value( field.name() ).value( mContext ) );
60 }
61 else
62 {
63 attributes.append( QVariant() );
64 }
65 }
66 f.setAttributes( attributes );
67
68 // make geometries compatible, and reproject if necessary
69 if ( feature.hasGeometry() )
70 {
71 const QVector< QgsGeometry > geometries = feature.geometry().coerceToType( mDefinition.destinationWkbType() );
72 if ( !geometries.isEmpty() )
73 {
74 res.reserve( geometries.size() );
75 for ( const QgsGeometry &geometry : geometries )
76 {
77 QgsFeature featurePart = f;
78
79 QgsGeometry reproject = geometry;
80 try
81 {
82 reproject.transform( mTransform );
83 featurePart.setGeometry( reproject );
84 }
85 catch ( QgsCsException & )
86 {
87 QgsLogger::warning( QObject::tr( "Error reprojecting feature geometry" ) );
88 featurePart.clearGeometry();
89 }
90 res << featurePart;
91 }
92 }
93 else
94 {
95 f.clearGeometry();
96 res << f;
97 }
98 }
99 else
100 {
101 res << f;
102 }
103 return res;
104}
105
106bool QgsRemappingProxyFeatureSink::addFeature( QgsFeature &feature, QgsFeatureSink::Flags flags )
107{
108 QgsFeatureList features = remapFeature( feature );
109 return mSink->addFeatures( features, flags );
110}
111
112bool QgsRemappingProxyFeatureSink::addFeatures( QgsFeatureList &features, QgsFeatureSink::Flags flags )
113{
114 bool res = true;
115 for ( QgsFeature &f : features )
116 {
117 res = addFeature( f, flags ) && res;
118 }
119 return res;
120}
121
122bool QgsRemappingProxyFeatureSink::addFeatures( QgsFeatureIterator &iterator, QgsFeatureSink::Flags flags )
123{
124 QgsFeature f;
125 bool res = true;
126 while ( iterator.nextFeature( f ) )
127 {
128 res = addFeature( f, flags ) && res;
129 }
130 return res;
131}
132
134{
135 return mSink->lastError();
136}
137
139{
140 QVariantMap map;
141 map.insert( QStringLiteral( "wkb_type" ), static_cast< quint32>( mDestinationWkbType ) );
142 // we only really care about names here
143 QVariantList fieldNames;
144 for ( const QgsField &field : mDestinationFields )
145 fieldNames << field.name();
146 map.insert( QStringLiteral( "destination_field_names" ), fieldNames );
147 map.insert( QStringLiteral( "transform_source" ), mSourceCrs.toWkt( QgsCoordinateReferenceSystem::WKT_PREFERRED ) );
148 map.insert( QStringLiteral( "transform_dest" ), mDestinationCrs.toWkt( QgsCoordinateReferenceSystem::WKT_PREFERRED ) );
149
150 QVariantMap fieldMap;
151 for ( auto it = mFieldMap.constBegin(); it != mFieldMap.constEnd(); ++it )
152 {
153 fieldMap.insert( it.key(), it.value().toVariant() );
154 }
155 map.insert( QStringLiteral( "field_map" ), fieldMap );
156
157 return map;
158}
159
160bool QgsRemappingSinkDefinition::loadVariant( const QVariantMap &map )
161{
162 mDestinationWkbType = static_cast< Qgis::WkbType >( map.value( QStringLiteral( "wkb_type" ), static_cast< quint32>( Qgis::WkbType::Unknown ) ).toInt() );
163
164 const QVariantList fieldNames = map.value( QStringLiteral( "destination_field_names" ) ).toList();
165 QgsFields fields;
166 for ( const QVariant &field : fieldNames )
167 {
168 fields.append( QgsField( field.toString() ) );
169 }
170 mDestinationFields = fields;
171
172 mSourceCrs = QgsCoordinateReferenceSystem::fromWkt( map.value( QStringLiteral( "transform_source" ) ).toString() );
173 mDestinationCrs = QgsCoordinateReferenceSystem::fromWkt( map.value( QStringLiteral( "transform_dest" ) ).toString() );
174
175 const QVariantMap fieldMap = map.value( QStringLiteral( "field_map" ) ).toMap();
176 mFieldMap.clear();
177 for ( auto it = fieldMap.constBegin(); it != fieldMap.constEnd(); ++it )
178 {
179 QgsProperty p;
180 p.loadVariant( it.value() );
181 mFieldMap.insert( it.key(), p );
182 }
183
184 return true;
185}
186
188{
189 return mDestinationWkbType == other.mDestinationWkbType
190 && mDestinationFields == other.mDestinationFields
191 && mFieldMap == other.mFieldMap
192 && mSourceCrs == other.mSourceCrs
193 && mDestinationCrs == other.mDestinationCrs;
194}
195
197{
198 return !( *this == other );
199}
WkbType
The WKB type describes the number of dimensions a geometry has.
Definition qgis.h:182
@ Unknown
Unknown.
A vector of attributes.
@ WKT_PREFERRED
Preferred format, matching the most recent WKT ISO standard. Currently an alias to WKT2_2019,...
static QgsCoordinateReferenceSystem fromWkt(const QString &wkt)
Creates a CRS from a WKT spatial ref sys definition string.
QString toWkt(WktVariant variant=WKT1_GDAL, bool multiline=false, int indentationWidth=4) const
Returns a WKT representation of this CRS.
Contains information about the context in which a coordinate transform is executed.
Class for doing transforms between two map coordinate systems.
Custom exception class for Coordinate Reference System related exceptions.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
void setFeature(const QgsFeature &feature)
Convenience function for setting a feature for the context.
Wrapper for iterator of features from vector data provider or vector layer.
bool nextFeature(QgsFeature &f)
An interface for objects which accept features via addFeature(s) methods.
virtual QString lastError() const
Returns the most recent error encountered by the sink, e.g.
virtual bool addFeatures(QgsFeatureList &features, QgsFeatureSink::Flags flags=QgsFeatureSink::Flags())=0
Adds a list of features to the sink.
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
Definition qgsfeature.h:56
void setAttributes(const QgsAttributes &attrs)
Sets the feature's attributes.
void setFields(const QgsFields &fields, bool initAttributes=false)
Assigns a field map with the feature to allow attribute access by attribute name.
QgsGeometry geometry
Definition qgsfeature.h:67
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.
Encapsulate a field in an attribute table or data source.
Definition qgsfield.h:53
Container of fields for a vector layer.
Definition qgsfields.h:45
bool append(const QgsField &field, FieldOrigin origin=OriginProvider, int originIndex=-1)
Appends a field. The field must have unique name, otherwise it is rejected (returns false)
Definition qgsfields.cpp:59
A geometry is the spatial representation of a feature.
QVector< QgsGeometry > coerceToType(Qgis::WkbType type, double defaultZ=0, double defaultM=0) const
Attempts to coerce this geometry into the specified destination type.
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.
static void warning(const QString &msg)
Goes to qWarning.
A store for object properties.
bool loadVariant(const QVariant &property)
Loads this property from a QVariantMap, wrapped in a QVariant.
void setTransformContext(const QgsCoordinateTransformContext &context)
Sets the transform context to use when reprojecting features.
void setExpressionContext(const QgsExpressionContext &context) const
Sets the expression context to use when evaluating mapped field values.
bool addFeatures(QgsFeatureList &features, QgsFeatureSink::Flags flags=QgsFeatureSink::Flags()) override
Adds a list of features to the sink.
QString lastError() const override
Returns the most recent error encountered by the sink, e.g.
QgsRemappingProxyFeatureSink(const QgsRemappingSinkDefinition &mappingDefinition, QgsFeatureSink *sink, bool ownsSink=false)
Constructor for QgsRemappingProxyFeatureSink, using the specified mappingDefinition to manipulate fea...
bool addFeature(QgsFeature &feature, QgsFeatureSink::Flags flags=QgsFeatureSink::Flags()) override
Adds a single feature to the sink.
QgsFeatureList remapFeature(const QgsFeature &feature) const
Remaps a feature to a set of features compatible with the destination sink.
Defines the parameters used to remap features when creating a QgsRemappingProxyFeatureSink.
bool operator==(const QgsRemappingSinkDefinition &other) const
QMap< QString, QgsProperty > fieldMap() const
Returns the field mapping, which defines how to map the values from incoming features to destination ...
bool operator!=(const QgsRemappingSinkDefinition &other) const
QgsCoordinateReferenceSystem sourceCrs() const
Returns the source CRS used for reprojecting incoming features to the sink's destination CRS.
QVariant toVariant() const
Saves this remapping definition to a QVariantMap, wrapped in a QVariant.
QgsCoordinateReferenceSystem destinationCrs() const
Returns the destination CRS used for reprojecting incoming features to the sink's destination CRS.
bool loadVariant(const QVariantMap &map)
Loads this remapping definition from a QVariantMap, wrapped in a QVariant.
QgsFields destinationFields() const
Returns the fields for the destination sink.
Qgis::WkbType destinationWkbType() const
Returns the WKB geometry type for the destination.
QList< QgsFeature > QgsFeatureList
Definition qgsfeature.h:920