18
18
#include " qgslogger.h"
19
19
#include " qgsnetworkaccessmanager.h"
20
20
#include " qgsrectangle.h"
21
- #include " geometry/qgsabstractgeometry.h"
22
- #include " geometry/qgscircularstring.h"
23
- #include " geometry/qgscompoundcurve.h"
24
- #include " geometry/qgscurvepolygon.h"
25
- #include " geometry/qgslinestring.h"
26
- #include " geometry/qgsmultipoint.h"
27
- #include " geometry/qgsmulticurve.h"
28
- #include " geometry/qgspolygon.h"
29
- #include " geometry/qgspoint.h"
30
21
#include " qgsfeedback.h"
31
22
#include " qgspallabeling.h"
32
23
#include " qgssymbol.h"
35
26
#include " qgssettings.h"
36
27
#include " qgslinesymbollayer.h"
37
28
#include " qgsfillsymbollayer.h"
38
- #include " qgsmarkersymbollayer.h"
39
29
#include " qgsrenderer.h"
40
30
#include " qgsrulebasedlabeling.h"
41
31
#include " qgssinglesymbolrenderer.h"
@@ -91,7 +81,7 @@ QgsWkbTypes::Type QgsArcGisRestUtils::mapEsriGeometryType( const QString &esriGe
91
81
else if ( esriGeometryType == QLatin1String ( " esriGeometryPolyline" ) )
92
82
return QgsWkbTypes::MultiCurve;
93
83
else if ( esriGeometryType == QLatin1String ( " esriGeometryPolygon" ) )
94
- return QgsWkbTypes::Polygon ;
84
+ return QgsWkbTypes::MultiPolygon ;
95
85
else if ( esriGeometryType == QLatin1String ( " esriGeometryEnvelope" ) )
96
86
return QgsWkbTypes::Polygon;
97
87
// Unsupported (either by qgis, or format unspecified by the specification)
@@ -112,7 +102,7 @@ QgsWkbTypes::Type QgsArcGisRestUtils::mapEsriGeometryType( const QString &esriGe
112
102
return QgsWkbTypes::Unknown;
113
103
}
114
104
115
- static std::unique_ptr< QgsPoint > parsePoint ( const QVariantList &coordList, QgsWkbTypes::Type pointType )
105
+ std::unique_ptr< QgsPoint > QgsArcGisRestUtils:: parsePoint ( const QVariantList &coordList, QgsWkbTypes::Type pointType )
116
106
{
117
107
int nCoords = coordList.size ();
118
108
if ( nCoords < 2 )
@@ -127,7 +117,7 @@ static std::unique_ptr< QgsPoint > parsePoint( const QVariantList &coordList, Qg
127
117
return qgis::make_unique< QgsPoint >( pointType, x, y, z, m );
128
118
}
129
119
130
- static std::unique_ptr< QgsCircularString > parseCircularString ( const QVariantMap &curveData, QgsWkbTypes::Type pointType, const QgsPoint &startPoint )
120
+ std::unique_ptr< QgsCircularString > QgsArcGisRestUtils:: parseCircularString ( const QVariantMap &curveData, QgsWkbTypes::Type pointType, const QgsPoint &startPoint )
131
121
{
132
122
const QVariantList coordsList = curveData[QStringLiteral ( " c" )].toList ();
133
123
if ( coordsList.isEmpty () )
@@ -148,7 +138,7 @@ static std::unique_ptr< QgsCircularString > parseCircularString( const QVariantM
148
138
return curve;
149
139
}
150
140
151
- static std::unique_ptr< QgsCompoundCurve > parseCompoundCurve ( const QVariantList &curvesList, QgsWkbTypes::Type pointType )
141
+ std::unique_ptr< QgsCompoundCurve > QgsArcGisRestUtils:: parseCompoundCurve ( const QVariantList &curvesList, QgsWkbTypes::Type pointType )
152
142
{
153
143
// [[6,3],[5,3],{"b":[[3,2],[6,1],[2,4]]},[1,2],{"c": [[3,3],[1,4]]}]
154
144
std::unique_ptr< QgsCompoundCurve > compoundCurve = qgis::make_unique< QgsCompoundCurve >();
@@ -189,7 +179,7 @@ static std::unique_ptr< QgsCompoundCurve > parseCompoundCurve( const QVariantLis
189
179
return compoundCurve;
190
180
}
191
181
192
- static std::unique_ptr< QgsPoint > parseEsriGeometryPoint ( const QVariantMap &geometryData, QgsWkbTypes::Type pointType )
182
+ std::unique_ptr< QgsPoint > QgsArcGisRestUtils:: parseEsriGeometryPoint ( const QVariantMap &geometryData, QgsWkbTypes::Type pointType )
193
183
{
194
184
// {"x" : <x>, "y" : <y>, "z" : <z>, "m" : <m>}
195
185
bool xok = false , yok = false ;
@@ -202,7 +192,7 @@ static std::unique_ptr< QgsPoint > parseEsriGeometryPoint( const QVariantMap &ge
202
192
return qgis::make_unique< QgsPoint >( pointType, x, y, z, m );
203
193
}
204
194
205
- static std::unique_ptr< QgsMultiPoint > parseEsriGeometryMultiPoint ( const QVariantMap &geometryData, QgsWkbTypes::Type pointType )
195
+ std::unique_ptr< QgsMultiPoint > QgsArcGisRestUtils:: parseEsriGeometryMultiPoint ( const QVariantMap &geometryData, QgsWkbTypes::Type pointType )
206
196
{
207
197
// {"points" : [[ <x1>, <y1>, <z1>, <m1> ] , [ <x2>, <y2>, <z2>, <m2> ], ... ]}
208
198
const QVariantList coordsList = geometryData[QStringLiteral ( " points" )].toList ();
@@ -233,7 +223,7 @@ static std::unique_ptr< QgsMultiPoint > parseEsriGeometryMultiPoint( const QVari
233
223
return multiPoint;
234
224
}
235
225
236
- static std::unique_ptr< QgsMultiCurve > parseEsriGeometryPolyline ( const QVariantMap &geometryData, QgsWkbTypes::Type pointType )
226
+ std::unique_ptr< QgsMultiCurve > QgsArcGisRestUtils:: parseEsriGeometryPolyline ( const QVariantMap &geometryData, QgsWkbTypes::Type pointType )
237
227
{
238
228
// {"curvePaths": [[[0,0], {"c": [[3,3],[1,4]]} ]]}
239
229
QVariantList pathsList;
@@ -256,7 +246,7 @@ static std::unique_ptr< QgsMultiCurve > parseEsriGeometryPolyline( const QVarian
256
246
return multiCurve;
257
247
}
258
248
259
- static std::unique_ptr< QgsCurvePolygon > parseEsriGeometryPolygon ( const QVariantMap &geometryData, QgsWkbTypes::Type pointType )
249
+ std::unique_ptr< QgsMultiSurface > QgsArcGisRestUtils:: parseEsriGeometryPolygon ( const QVariantMap &geometryData, QgsWkbTypes::Type pointType )
260
250
{
261
251
// {"curveRings": [[[0,0], {"c": [[3,3],[1,4]]} ]]}
262
252
QVariantList ringsList;
@@ -266,26 +256,56 @@ static std::unique_ptr< QgsCurvePolygon > parseEsriGeometryPolygon( const QVaria
266
256
ringsList = geometryData[QStringLiteral ( " ringPaths" )].toList ();
267
257
if ( ringsList.isEmpty () )
268
258
return nullptr ;
269
- std::unique_ptr< QgsCurvePolygon > polygon = qgis::make_unique< QgsCurvePolygon >();
270
- std::unique_ptr< QgsCompoundCurve > ext = parseCompoundCurve ( ringsList.front ().toList (), pointType );
271
- if ( !ext )
272
- {
273
- return nullptr ;
274
- }
275
- polygon->setExteriorRing ( ext.release () );
276
- for ( int i = 1 , n = ringsList.size (); i < n; ++i )
259
+
260
+ QList< QgsCompoundCurve * > curves;
261
+ for ( int i = 0 , n = ringsList.size (); i < n; ++i )
277
262
{
278
263
std::unique_ptr< QgsCompoundCurve > curve = parseCompoundCurve ( ringsList[i].toList (), pointType );
279
264
if ( !curve )
280
265
{
281
- return nullptr ;
266
+ continue ;
282
267
}
283
- polygon-> addInteriorRing ( curve.release () );
268
+ curves. append ( curve.release () );
284
269
}
285
- return polygon;
270
+ if ( curves.count () == 0 )
271
+ return nullptr ;
272
+
273
+ std::sort ( curves.begin (), curves.end (), []( const QgsCompoundCurve * a, const QgsCompoundCurve * b )->bool { double a_area = 0.0 ; double b_area = 0.0 ; a->sumUpArea ( a_area ); b->sumUpArea ( b_area ); return std::abs ( a_area ) > std::abs ( b_area ); } );
274
+ std::unique_ptr< QgsMultiSurface > result = qgis::make_unique< QgsMultiSurface >();
275
+ while ( !curves.isEmpty () )
276
+ {
277
+ QgsCompoundCurve *exterior = curves.takeFirst ();
278
+ QgsCurvePolygon *newPolygon = new QgsCurvePolygon ();
279
+ newPolygon->setExteriorRing ( exterior );
280
+ std::unique_ptr<QgsGeometryEngine> engine ( QgsGeometry::createGeometryEngine ( newPolygon ) );
281
+ engine->prepareGeometry ();
282
+
283
+ QMutableListIterator< QgsCompoundCurve * > it ( curves );
284
+ while ( it.hasNext () )
285
+ {
286
+ QgsCompoundCurve *curve = it.next ();
287
+ QgsRectangle boundingBox = newPolygon->boundingBox ();
288
+ if ( boundingBox.intersects ( curve->boundingBox () ) )
289
+ {
290
+ QgsPoint point = curve->startPoint ();
291
+ if ( engine->contains ( &point ) )
292
+ {
293
+ newPolygon->addInteriorRing ( curve );
294
+ it.remove ();
295
+ engine.reset ( QgsGeometry::createGeometryEngine ( newPolygon ) );
296
+ engine->prepareGeometry ();
297
+ }
298
+ }
299
+ }
300
+ result->addGeometry ( newPolygon );
301
+ }
302
+ if ( result->numGeometries () == 0 )
303
+ return nullptr ;
304
+
305
+ return result;
286
306
}
287
307
288
- static std::unique_ptr< QgsPolygon > parseEsriEnvelope ( const QVariantMap &geometryData )
308
+ std::unique_ptr< QgsPolygon > QgsArcGisRestUtils:: parseEsriEnvelope ( const QVariantMap &geometryData )
289
309
{
290
310
// {"xmin" : -109.55, "ymin" : 25.76, "xmax" : -86.39, "ymax" : 49.94}
291
311
bool xminOk = false , yminOk = false , xmaxOk = false , ymaxOk = false ;
@@ -651,7 +671,7 @@ std::unique_ptr<QgsFillSymbol> QgsArcGisRestUtils::parseEsriPictureFillSymbolJso
651
671
return symbol;
652
672
}
653
673
654
- QgsSimpleMarkerSymbolLayerBase::Shape parseEsriMarkerShape ( const QString &style )
674
+ QgsSimpleMarkerSymbolLayerBase::Shape QgsArcGisRestUtils:: parseEsriMarkerShape ( const QString &style )
655
675
{
656
676
if ( style == QLatin1String ( " esriSMSCircle" ) )
657
677
return QgsSimpleMarkerSymbolLayerBase::Circle;
0 commit comments