@@ -18,6 +18,10 @@ email : a.furieri@lqt.it
18
18
#include " qgsfeature.h"
19
19
#include " qgsfields.h"
20
20
#include " qgsgeometry.h"
21
+ #include " qgsgeometryfactory.h"
22
+ #include " qgsgeometrycollection.h"
23
+ #include " qgscompoundcurve.h"
24
+ #include " qgscircularstring.h"
21
25
#include " qgsrectangle.h"
22
26
#include " qgscoordinatereferencesystem.h"
23
27
#include " qgslogger.h"
@@ -127,6 +131,125 @@ bool QgsSpatiaLiteProvider::convertField( QgsField &field )
127
131
return true ;
128
132
}
129
133
134
+ QgsGeometry QgsSpatiaLiteProvider::convertToProviderType ( const QgsGeometry &geom ) const
135
+ {
136
+ if ( geom.isNull () )
137
+ {
138
+ return QgsGeometry ();
139
+ }
140
+
141
+ const QgsAbstractGeometry *geometry = geom.constGet ();
142
+ if ( !geometry )
143
+ {
144
+ return QgsGeometry ();
145
+ }
146
+
147
+ const Qgis::WkbType providerGeomType = wkbType ();
148
+
149
+ // geom is already in the provider geometry type
150
+ if ( geometry->wkbType () == providerGeomType )
151
+ {
152
+ return QgsGeometry ();
153
+ }
154
+
155
+ std::unique_ptr< QgsAbstractGeometry > outputGeom;
156
+
157
+ // convert compoundcurve to circularstring (possible if compoundcurve consists of one circular string)
158
+ if ( QgsWkbTypes::flatType ( providerGeomType ) == Qgis::WkbType::CircularString )
159
+ {
160
+ QgsCompoundCurve *compoundCurve = qgsgeometry_cast<QgsCompoundCurve *>( geometry );
161
+ if ( compoundCurve )
162
+ {
163
+ if ( compoundCurve->nCurves () == 1 )
164
+ {
165
+ const QgsCircularString *circularString = qgsgeometry_cast<const QgsCircularString *>( compoundCurve->curveAt ( 0 ) );
166
+ if ( circularString )
167
+ {
168
+ outputGeom.reset ( circularString->clone () );
169
+ }
170
+ }
171
+ }
172
+ }
173
+
174
+ // convert to curved type if necessary
175
+ if ( !QgsWkbTypes::isCurvedType ( geometry->wkbType () ) && QgsWkbTypes::isCurvedType ( providerGeomType ) )
176
+ {
177
+ QgsAbstractGeometry *curveGeom = outputGeom ? outputGeom->toCurveType () : geometry->toCurveType ();
178
+ if ( curveGeom )
179
+ {
180
+ outputGeom.reset ( curveGeom );
181
+ }
182
+ }
183
+
184
+ // convert to linear type from curved type
185
+ if ( QgsWkbTypes::isCurvedType ( geometry->wkbType () ) && !QgsWkbTypes::isCurvedType ( providerGeomType ) )
186
+ {
187
+ QgsAbstractGeometry *segmentizedGeom = outputGeom ? outputGeom->segmentize () : geometry->segmentize ();
188
+ if ( segmentizedGeom )
189
+ {
190
+ outputGeom.reset ( segmentizedGeom );
191
+ }
192
+ }
193
+
194
+ // convert to multitype if necessary
195
+ if ( QgsWkbTypes::isMultiType ( providerGeomType ) && !QgsWkbTypes::isMultiType ( geometry->wkbType () ) )
196
+ {
197
+ std::unique_ptr< QgsAbstractGeometry > collGeom ( QgsGeometryFactory::geomFromWkbType ( providerGeomType ) );
198
+ QgsGeometryCollection *geomCollection = qgsgeometry_cast<QgsGeometryCollection *>( collGeom.get () );
199
+ if ( geomCollection )
200
+ {
201
+ if ( geomCollection->addGeometry ( outputGeom ? outputGeom->clone () : geometry->clone () ) )
202
+ {
203
+ outputGeom.reset ( collGeom.release () );
204
+ }
205
+ }
206
+ }
207
+
208
+ // convert to single type if there's a single part of compatible type
209
+ if ( !QgsWkbTypes::isMultiType ( providerGeomType ) && QgsWkbTypes::isMultiType ( geometry->wkbType () ) )
210
+ {
211
+ const QgsGeometryCollection *collection = qgsgeometry_cast<const QgsGeometryCollection *>( geometry );
212
+ if ( collection )
213
+ {
214
+ if ( collection->numGeometries () == 1 )
215
+ {
216
+ const QgsAbstractGeometry *firstGeom = collection->geometryN ( 0 );
217
+ if ( firstGeom && firstGeom->wkbType () == providerGeomType )
218
+ {
219
+ outputGeom.reset ( firstGeom->clone () );
220
+ }
221
+ }
222
+ }
223
+ }
224
+
225
+ // set z/m types
226
+ if ( QgsWkbTypes::hasZ ( providerGeomType ) )
227
+ {
228
+ if ( !outputGeom )
229
+ {
230
+ outputGeom.reset ( geometry->clone () );
231
+ }
232
+ outputGeom->addZValue ();
233
+ }
234
+
235
+ if ( QgsWkbTypes::hasM ( providerGeomType ) )
236
+ {
237
+ if ( !outputGeom )
238
+ {
239
+ outputGeom.reset ( geometry->clone () );
240
+ }
241
+ outputGeom->addMValue ();
242
+ }
243
+
244
+ if ( outputGeom )
245
+ {
246
+ return QgsGeometry ( outputGeom.release () );
247
+ }
248
+
249
+ return QgsGeometry ();
250
+
251
+ }
252
+
130
253
131
254
Qgis::VectorExportResult QgsSpatiaLiteProvider::createEmptyLayer ( const QString &uri,
132
255
const QgsFields &fields,
@@ -4230,7 +4353,8 @@ bool QgsSpatiaLiteProvider::addFeatures( QgsFeatureList &flist, Flags flags )
4230
4353
{
4231
4354
unsigned char *wkb = nullptr ;
4232
4355
int wkb_size;
4233
- QByteArray featureWkb = feature->geometry ().asWkb ();
4356
+ const QgsGeometry convertedGeom ( convertToProviderType ( feature->geometry () ) );
4357
+ const QByteArray featureWkb{ !convertedGeom.isNull () ? convertedGeom.asWkb () : feature->geometry ().asWkb () };
4234
4358
convertFromGeosWKB ( reinterpret_cast <const unsigned char *>( featureWkb.constData () ),
4235
4359
featureWkb.length (),
4236
4360
&wkb, &wkb_size, nDims );
0 commit comments