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 " qgssymbol.h"
32
23
#include " qgssymbollayer.h"
33
24
#include " qgsauthmanager.h"
34
25
#include " qgssettings.h"
35
26
#include " qgslinesymbollayer.h"
36
27
#include " qgsfillsymbollayer.h"
37
- #include " qgsmarkersymbollayer.h"
38
28
#include " qgsrenderer.h"
39
29
#include " qgssinglesymbolrenderer.h"
40
30
#include " qgscategorizedsymbolrenderer.h"
@@ -88,7 +78,7 @@ QgsWkbTypes::Type QgsArcGisRestUtils::mapEsriGeometryType( const QString &esriGe
88
78
else if ( esriGeometryType == QLatin1String ( " esriGeometryPolyline" ) )
89
79
return QgsWkbTypes::MultiCurve;
90
80
else if ( esriGeometryType == QLatin1String ( " esriGeometryPolygon" ) )
91
- return QgsWkbTypes::Polygon ;
81
+ return QgsWkbTypes::MultiPolygon ;
92
82
else if ( esriGeometryType == QLatin1String ( " esriGeometryEnvelope" ) )
93
83
return QgsWkbTypes::Polygon;
94
84
// Unsupported (either by qgis, or format unspecified by the specification)
@@ -109,7 +99,7 @@ QgsWkbTypes::Type QgsArcGisRestUtils::mapEsriGeometryType( const QString &esriGe
109
99
return QgsWkbTypes::Unknown;
110
100
}
111
101
112
- static std::unique_ptr< QgsPoint > parsePoint ( const QVariantList &coordList, QgsWkbTypes::Type pointType )
102
+ std::unique_ptr< QgsPoint > QgsArcGisRestUtils:: parsePoint ( const QVariantList &coordList, QgsWkbTypes::Type pointType )
113
103
{
114
104
int nCoords = coordList.size ();
115
105
if ( nCoords < 2 )
@@ -124,7 +114,7 @@ static std::unique_ptr< QgsPoint > parsePoint( const QVariantList &coordList, Qg
124
114
return qgis::make_unique< QgsPoint >( pointType, x, y, z, m );
125
115
}
126
116
127
- static std::unique_ptr< QgsCircularString > parseCircularString ( const QVariantMap &curveData, QgsWkbTypes::Type pointType, const QgsPoint &startPoint )
117
+ std::unique_ptr< QgsCircularString > QgsArcGisRestUtils:: parseCircularString ( const QVariantMap &curveData, QgsWkbTypes::Type pointType, const QgsPoint &startPoint )
128
118
{
129
119
const QVariantList coordsList = curveData[QStringLiteral ( " c" )].toList ();
130
120
if ( coordsList.isEmpty () )
@@ -145,7 +135,7 @@ static std::unique_ptr< QgsCircularString > parseCircularString( const QVariantM
145
135
return curve;
146
136
}
147
137
148
- static std::unique_ptr< QgsCompoundCurve > parseCompoundCurve ( const QVariantList &curvesList, QgsWkbTypes::Type pointType )
138
+ std::unique_ptr< QgsCompoundCurve > QgsArcGisRestUtils:: parseCompoundCurve ( const QVariantList &curvesList, QgsWkbTypes::Type pointType )
149
139
{
150
140
// [[6,3],[5,3],{"b":[[3,2],[6,1],[2,4]]},[1,2],{"c": [[3,3],[1,4]]}]
151
141
std::unique_ptr< QgsCompoundCurve > compoundCurve = qgis::make_unique< QgsCompoundCurve >();
@@ -186,7 +176,7 @@ static std::unique_ptr< QgsCompoundCurve > parseCompoundCurve( const QVariantLis
186
176
return compoundCurve;
187
177
}
188
178
189
- static std::unique_ptr< QgsPoint > parseEsriGeometryPoint ( const QVariantMap &geometryData, QgsWkbTypes::Type pointType )
179
+ std::unique_ptr< QgsPoint > QgsArcGisRestUtils:: parseEsriGeometryPoint ( const QVariantMap &geometryData, QgsWkbTypes::Type pointType )
190
180
{
191
181
// {"x" : <x>, "y" : <y>, "z" : <z>, "m" : <m>}
192
182
bool xok = false , yok = false ;
@@ -199,7 +189,7 @@ static std::unique_ptr< QgsPoint > parseEsriGeometryPoint( const QVariantMap &ge
199
189
return qgis::make_unique< QgsPoint >( pointType, x, y, z, m );
200
190
}
201
191
202
- static std::unique_ptr< QgsMultiPoint > parseEsriGeometryMultiPoint ( const QVariantMap &geometryData, QgsWkbTypes::Type pointType )
192
+ std::unique_ptr< QgsMultiPoint > QgsArcGisRestUtils:: parseEsriGeometryMultiPoint ( const QVariantMap &geometryData, QgsWkbTypes::Type pointType )
203
193
{
204
194
// {"points" : [[ <x1>, <y1>, <z1>, <m1> ] , [ <x2>, <y2>, <z2>, <m2> ], ... ]}
205
195
const QVariantList coordsList = geometryData[QStringLiteral ( " points" )].toList ();
@@ -230,7 +220,7 @@ static std::unique_ptr< QgsMultiPoint > parseEsriGeometryMultiPoint( const QVari
230
220
return multiPoint;
231
221
}
232
222
233
- static std::unique_ptr< QgsMultiCurve > parseEsriGeometryPolyline ( const QVariantMap &geometryData, QgsWkbTypes::Type pointType )
223
+ std::unique_ptr< QgsMultiCurve > QgsArcGisRestUtils:: parseEsriGeometryPolyline ( const QVariantMap &geometryData, QgsWkbTypes::Type pointType )
234
224
{
235
225
// {"curvePaths": [[[0,0], {"c": [[3,3],[1,4]]} ]]}
236
226
QVariantList pathsList;
@@ -253,7 +243,7 @@ static std::unique_ptr< QgsMultiCurve > parseEsriGeometryPolyline( const QVarian
253
243
return multiCurve;
254
244
}
255
245
256
- static std::unique_ptr< QgsCurvePolygon > parseEsriGeometryPolygon ( const QVariantMap &geometryData, QgsWkbTypes::Type pointType )
246
+ std::unique_ptr< QgsMultiSurface > QgsArcGisRestUtils:: parseEsriGeometryPolygon ( const QVariantMap &geometryData, QgsWkbTypes::Type pointType )
257
247
{
258
248
// {"curveRings": [[[0,0], {"c": [[3,3],[1,4]]} ]]}
259
249
QVariantList ringsList;
@@ -263,26 +253,56 @@ static std::unique_ptr< QgsCurvePolygon > parseEsriGeometryPolygon( const QVaria
263
253
ringsList = geometryData[QStringLiteral ( " ringPaths" )].toList ();
264
254
if ( ringsList.isEmpty () )
265
255
return nullptr ;
266
- std::unique_ptr< QgsCurvePolygon > polygon = qgis::make_unique< QgsCurvePolygon >();
267
- std::unique_ptr< QgsCompoundCurve > ext = parseCompoundCurve ( ringsList.front ().toList (), pointType );
268
- if ( !ext )
269
- {
270
- return nullptr ;
271
- }
272
- polygon->setExteriorRing ( ext.release () );
273
- for ( int i = 1 , n = ringsList.size (); i < n; ++i )
256
+
257
+ QList< QgsCompoundCurve * > curves;
258
+ for ( int i = 0 , n = ringsList.size (); i < n; ++i )
274
259
{
275
260
std::unique_ptr< QgsCompoundCurve > curve = parseCompoundCurve ( ringsList[i].toList (), pointType );
276
261
if ( !curve )
277
262
{
278
- return nullptr ;
263
+ continue ;
264
+ }
265
+ curves.append ( curve.release () );
266
+ }
267
+ if ( curves.count () == 0 )
268
+ return nullptr ;
269
+
270
+ 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 ); } );
271
+ std::unique_ptr< QgsMultiSurface > result = qgis::make_unique< QgsMultiSurface >();
272
+ while ( !curves.isEmpty () )
273
+ {
274
+ QgsCompoundCurve *exterior = curves.takeFirst ();
275
+ QgsCurvePolygon *newPolygon = new QgsCurvePolygon ();
276
+ newPolygon->setExteriorRing ( exterior );
277
+ std::unique_ptr<QgsGeometryEngine> engine ( QgsGeometry::createGeometryEngine ( newPolygon ) );
278
+ engine->prepareGeometry ();
279
+
280
+ QMutableListIterator< QgsCompoundCurve * > it ( curves );
281
+ while ( it.hasNext () )
282
+ {
283
+ QgsCompoundCurve *curve = it.next ();
284
+ QgsRectangle boundingBox = newPolygon->boundingBox ();
285
+ if ( boundingBox.intersects ( curve->boundingBox () ) )
286
+ {
287
+ QgsPoint point = curve->startPoint ();
288
+ if ( engine->contains ( &point ) )
289
+ {
290
+ newPolygon->addInteriorRing ( curve );
291
+ it.remove ();
292
+ engine.reset ( QgsGeometry::createGeometryEngine ( newPolygon ) );
293
+ engine->prepareGeometry ();
294
+ }
295
+ }
279
296
}
280
- polygon-> addInteriorRing ( curve. release () );
297
+ result-> addGeometry ( newPolygon );
281
298
}
282
- return polygon;
299
+ if ( result->numGeometries () == 0 )
300
+ return nullptr ;
301
+
302
+ return result;
283
303
}
284
304
285
- static std::unique_ptr< QgsPolygon > parseEsriEnvelope ( const QVariantMap &geometryData )
305
+ std::unique_ptr< QgsPolygon > QgsArcGisRestUtils:: parseEsriEnvelope ( const QVariantMap &geometryData )
286
306
{
287
307
// {"xmin" : -109.55, "ymin" : 25.76, "xmax" : -86.39, "ymax" : 49.94}
288
308
bool xminOk = false , yminOk = false , xmaxOk = false , ymaxOk = false ;
@@ -628,7 +648,7 @@ std::unique_ptr<QgsFillSymbol> QgsArcGisRestUtils::parseEsriFillSymbolJson( cons
628
648
return symbol;
629
649
}
630
650
631
- QgsSimpleMarkerSymbolLayerBase::Shape parseEsriMarkerShape ( const QString &style )
651
+ QgsSimpleMarkerSymbolLayerBase::Shape QgsArcGisRestUtils:: parseEsriMarkerShape ( const QString &style )
632
652
{
633
653
if ( style == QLatin1String ( " esriSMSCircle" ) )
634
654
return QgsSimpleMarkerSymbolLayerBase::Circle;
0 commit comments