QGIS API Documentation 3.99.0-Master (2fe06baccd8)
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
20#include "qgslogger.h"
21
24 , mDefinition( mappingDefinition )
25 , mSink( sink )
26 , mOwnsSink( ownsSink )
27{}
28
30{
31 if ( mOwnsSink )
32 delete mSink;
33}
34
36{
37 mContext = context;
38}
39
41{
42 mTransform = QgsCoordinateTransform( mDefinition.sourceCrs(), mDefinition.destinationCrs(), context );
43}
44
46{
48
49 mContext.setFeature( feature );
50
51 // remap fields first
52 QgsFeature f;
53 f.setFields( mDefinition.destinationFields(), true );
54 QgsAttributes attributes;
55 const QMap< QString, QgsProperty > fieldMap = mDefinition.fieldMap();
56 for ( const QgsField &field : mDefinition.destinationFields() )
57 {
58 if ( fieldMap.contains( field.name() ) )
59 {
60 attributes.append( fieldMap.value( field.name() ).value( mContext ) );
61 }
62 else
63 {
64 attributes.append( QVariant() );
65 }
66 }
67 f.setAttributes( attributes );
68
69 // make geometries compatible, and reproject if necessary
70 if ( feature.hasGeometry() )
71 {
72 const QVector< QgsGeometry > geometries = feature.geometry().coerceToType( mDefinition.destinationWkbType() );
73 if ( !geometries.isEmpty() )
74 {
75 res.reserve( geometries.size() );
76 for ( const QgsGeometry &geometry : geometries )
77 {
78 QgsFeature featurePart = f;
79
80 QgsGeometry reproject = geometry;
81 try
82 {
83 reproject.transform( mTransform );
84 featurePart.setGeometry( reproject );
85 }
86 catch ( QgsCsException & )
87 {
88 QgsLogger::warning( QObject::tr( "Error reprojecting feature geometry" ) );
89 featurePart.clearGeometry();
90 }
91 res << featurePart;
92 }
93 }
94 else
95 {
96 f.clearGeometry();
97 res << f;
98 }
99 }
100 else
101 {
102 res << f;
103 }
104 return res;
105}
106
108{
109 QgsFeatureList features = remapFeature( feature );
110 return mSink->addFeatures( features, flags );
111}
112
114{
115 bool res = true;
116 for ( QgsFeature &f : features )
117 {
118 res = addFeature( f, flags ) && res;
119 }
120 return res;
121}
122
124{
125 QgsFeature f;
126 bool res = true;
127 while ( iterator.nextFeature( f ) )
128 {
129 res = addFeature( f, flags ) && res;
130 }
131 return res;
132}
133
135{
136 return mSink->lastError();
137}
138
140{
141 QVariantMap map;
142 map.insert( QStringLiteral( "wkb_type" ), static_cast< quint32>( mDestinationWkbType ) );
143 // we only really care about names here
144 QVariantList fieldNames;
145 for ( const QgsField &field : mDestinationFields )
146 fieldNames << field.name();
147 map.insert( QStringLiteral( "destination_field_names" ), fieldNames );
148 map.insert( QStringLiteral( "transform_source" ), mSourceCrs.toWkt( Qgis::CrsWktVariant::Preferred ) );
149 map.insert( QStringLiteral( "transform_dest" ), mDestinationCrs.toWkt( Qgis::CrsWktVariant::Preferred ) );
150
151 QVariantMap fieldMap;
152 for ( auto it = mFieldMap.constBegin(); it != mFieldMap.constEnd(); ++it )
153 {
154 fieldMap.insert( it.key(), it.value().toVariant() );
155 }
156 map.insert( QStringLiteral( "field_map" ), fieldMap );
157
158 return map;
159}
160
161bool QgsRemappingSinkDefinition::loadVariant( const QVariantMap &map )
162{
163 mDestinationWkbType = static_cast< Qgis::WkbType >( map.value( QStringLiteral( "wkb_type" ), static_cast< quint32>( Qgis::WkbType::Unknown ) ).toInt() );
164
165 const QVariantList fieldNames = map.value( QStringLiteral( "destination_field_names" ) ).toList();
166 QgsFields fields;
167 for ( const QVariant &field : fieldNames )
168 {
169 fields.append( QgsField( field.toString() ) );
170 }
171 mDestinationFields = fields;
172
173 mSourceCrs = QgsCoordinateReferenceSystem::fromWkt( map.value( QStringLiteral( "transform_source" ) ).toString() );
174 mDestinationCrs = QgsCoordinateReferenceSystem::fromWkt( map.value( QStringLiteral( "transform_dest" ) ).toString() );
175
176 const QVariantMap fieldMap = map.value( QStringLiteral( "field_map" ) ).toMap();
177 mFieldMap.clear();
178 for ( auto it = fieldMap.constBegin(); it != fieldMap.constEnd(); ++it )
179 {
180 QgsProperty p;
181 p.loadVariant( it.value() );
182 mFieldMap.insert( it.key(), p );
183 }
184
185 return true;
186}
187
189{
190 return mDestinationWkbType == other.mDestinationWkbType
191 && mDestinationFields == other.mDestinationFields
192 && mFieldMap == other.mFieldMap
193 && mSourceCrs == other.mSourceCrs
194 && mDestinationCrs == other.mDestinationCrs;
195}
196
198{
199 return !( *this == other );
200}
WkbType
The WKB type describes the number of dimensions a geometry has.
Definition qgis.h:277
@ Unknown
Unknown.
Definition qgis.h:278
@ Preferred
Preferred format, matching the most recent WKT ISO standard. Currently an alias to WKT2_2019,...
Definition qgis.h:2439
A vector of attributes.
static QgsCoordinateReferenceSystem fromWkt(const QString &wkt)
Creates a CRS from a WKT spatial ref sys definition string.
Contains information about the context in which a coordinate transform is executed.
Handles coordinate transforms between two 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...
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.
QFlags< Flag > Flags
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
Definition qgsfeature.h:58
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: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.
Encapsulate a field in an attribute table or data source.
Definition qgsfield.h:54
Container of fields for a vector layer.
Definition qgsfields.h:46
bool append(const QgsField &field, Qgis::FieldOrigin origin=Qgis::FieldOrigin::Provider, int originIndex=-1)
Appends a field.
Definition qgsfields.cpp:73
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.
QVector< QgsGeometry > coerceToType(Qgis::WkbType type, double defaultZ=0, double defaultM=0, bool avoidDuplicates=true) const
Attempts to coerce this geometry into the specified destination type.
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
QVariant toVariant() const
Saves this remapping definition to a QVariantMap, wrapped in a QVariant.
bool loadVariant(const QVariantMap &map)
Loads this remapping definition from a QVariantMap, wrapped in a QVariant.
QList< QgsFeature > QgsFeatureList