32
32
#include < QSettings>
33
33
#include < QUrl>
34
34
35
+ #include " ogr_api.h"
36
+
35
37
#include < limits>
36
38
37
39
static const char NS_SEPARATOR = ' ?' ;
@@ -288,6 +290,7 @@ QgsGmlStreamingParser::QgsGmlStreamingParser( const QString& typeName,
288
290
, mInvertAxisOrientation( invertAxisOrientation )
289
291
, mNumberReturned( -1 )
290
292
, mNumberMatched( -1 )
293
+ , mFoundUnhandledGeometryElement( false )
291
294
{
292
295
mThematicAttributes .clear ();
293
296
for ( int i = 0 ; i < fields.size (); i++ )
@@ -348,6 +351,7 @@ QgsGmlStreamingParser::QgsGmlStreamingParser( const QList<LayerProperties>& laye
348
351
, mInvertAxisOrientation( invertAxisOrientation )
349
352
, mNumberReturned( -1 )
350
353
, mNumberMatched( -1 )
354
+ , mFoundUnhandledGeometryElement( false )
351
355
{
352
356
mThematicAttributes .clear ();
353
357
for ( int i = 0 ; i < fields.size (); i++ )
@@ -478,6 +482,24 @@ void QgsGmlStreamingParser::startElement( const XML_Char* el, const XML_Char** a
478
482
479
483
const bool isGMLNS = ( nsLen == mGMLNameSpaceURI .size () && mGMLNameSpaceURIPtr && memcmp ( el, mGMLNameSpaceURIPtr , nsLen ) == 0 );
480
484
bool isGeom = false ;
485
+
486
+ if ( theParseMode == geometry || theParseMode == coordinate || theParseMode == posList ||
487
+ theParseMode == multiPoint || theParseMode == multiLine || theParseMode == multiPolygon )
488
+ {
489
+ mGeometryString .append ( " <" , 1 );
490
+ mGeometryString .append ( pszLocalName, localNameLen );
491
+ mGeometryString .append ( " " , 1 );
492
+ for ( const XML_Char** attrIter = attr; attrIter && *attrIter; attrIter += 2 )
493
+ {
494
+ mGeometryString .append ( attrIter[0 ] );
495
+ mGeometryString .append ( " =\" " , 2 );
496
+ mGeometryString .append ( attrIter[1 ] );
497
+ mGeometryString .append ( " \" " , 2 );
498
+
499
+ }
500
+ mGeometryString .append ( " >" , 1 );
501
+ }
502
+
481
503
if ( isGMLNS && LOCALNAME_EQUALS ( " coordinates" ) )
482
504
{
483
505
mParseModeStack .push ( coordinate );
@@ -515,6 +537,8 @@ void QgsGmlStreamingParser::startElement( const XML_Char* el, const XML_Char** a
515
537
memcmp ( pszLocalName, mGeometryAttributePtr , localNameLen ) == 0 )
516
538
{
517
539
mParseModeStack .push ( QgsGmlStreamingParser::geometry );
540
+ mFoundUnhandledGeometryElement = false ;
541
+ mGeometryString .clear ();
518
542
}
519
543
// else if ( mParseModeStack.size() == 0 && elementName == mGMLNameSpaceURI + NS_SEPARATOR + "boundedBy" )
520
544
else if ( isGMLNS && LOCALNAME_EQUALS ( " boundedBy" ) )
@@ -739,6 +763,27 @@ void QgsGmlStreamingParser::startElement( const XML_Char* el, const XML_Char** a
739
763
// e.g: http://services.cuzk.cz/wfs/inspire-cp-wfs.asp?SERVICE=WFS&REQUEST=GetFeature&VERSION=2.0.0&TYPENAMES=cp:CadastralParcel
740
764
mTruncatedResponse = true ;
741
765
}
766
+ else if ( !mGeometryString .empty () &&
767
+ !LOCALNAME_EQUALS ( " exterior" ) &&
768
+ !LOCALNAME_EQUALS ( " interior" ) &&
769
+ !LOCALNAME_EQUALS ( " innerBoundaryIs" ) &&
770
+ !LOCALNAME_EQUALS ( " outerBoundaryIs" ) &&
771
+ !LOCALNAME_EQUALS ( " LinearRing" ) &&
772
+ !LOCALNAME_EQUALS ( " pointMember" ) &&
773
+ !LOCALNAME_EQUALS ( " curveMember" ) &&
774
+ !LOCALNAME_EQUALS ( " lineStringMember" ) &&
775
+ !LOCALNAME_EQUALS ( " polygonMember" ) &&
776
+ !LOCALNAME_EQUALS ( " surfaceMember" ) &&
777
+ !LOCALNAME_EQUALS ( " Curve" ) &&
778
+ !LOCALNAME_EQUALS ( " segments" ) &&
779
+ !LOCALNAME_EQUALS ( " LineStringSegment" ) )
780
+ {
781
+ // QgsDebugMsg( "Found unhandled geometry element " + QString::fromUtf8( pszLocalName, localNameLen ) );
782
+ mFoundUnhandledGeometryElement = true ;
783
+ }
784
+
785
+ if ( !mGeometryString .empty () )
786
+ isGeom = true ;
742
787
743
788
if ( mDimension == 0 && isGeom )
744
789
{
@@ -807,6 +852,29 @@ void QgsGmlStreamingParser::endElement( const XML_Char* el )
807
852
memcmp ( pszLocalName, mGeometryAttributePtr , localNameLen ) == 0 )
808
853
{
809
854
mParseModeStack .pop ();
855
+ if ( mFoundUnhandledGeometryElement )
856
+ {
857
+ OGRGeometryH hGeom = OGR_G_CreateFromGML ( mGeometryString .c_str () );
858
+ if ( hGeom )
859
+ {
860
+ const int wkbSize = OGR_G_WkbSize ( hGeom );
861
+ unsigned char * pabyBuffer = new unsigned char [ wkbSize ];
862
+ #if GDAL_VERSION_MAJOR >= 2
863
+ OGR_G_ExportToIsoWkb ( hGeom, wkbNDR, pabyBuffer );
864
+ #else
865
+ OGR_G_ExportToWkb ( hGeom, wkbNDR, pabyBuffer );
866
+ #endif
867
+ QgsGeometry *g = new QgsGeometry ();
868
+ g->fromWkb ( pabyBuffer, wkbSize );
869
+ if ( mInvertAxisOrientation )
870
+ {
871
+ g->transform ( QTransform ( 0 , 1 , 1 , 0 , 0 , 0 ) );
872
+ }
873
+ mCurrentFeature ->setGeometry ( g );
874
+ OGR_G_DestroyGeometry ( hGeom );
875
+ }
876
+ }
877
+ mGeometryString .clear ();
810
878
}
811
879
else if ( theParseMode == boundingBox && isGMLNS && LOCALNAME_EQUALS ( " boundedBy" ) )
812
880
{
@@ -861,20 +929,19 @@ void QgsGmlStreamingParser::endElement( const XML_Char* el )
861
929
memcmp ( pszLocalName, mTypeNamePtr , mTypeName .size () ) == 0 ) )
862
930
{
863
931
Q_ASSERT ( mCurrentFeature );
864
- if ( mCurrentWKB . size () > 0 )
932
+ if ( ! mCurrentFeature -> geometry () )
865
933
{
866
- QgsGeometry *g = new QgsGeometry ();
867
- g->fromWkb ( mCurrentWKB , mCurrentWKB .size () );
868
- mCurrentFeature ->setGeometry ( g );
869
- mCurrentWKB = QgsWkbPtr ( nullptr , 0 );
870
- }
871
- else if ( !mCurrentExtent .isEmpty () )
872
- {
873
- mCurrentFeature ->setGeometry ( QgsGeometry::fromRect ( mCurrentExtent ) );
874
- }
875
- else
876
- {
877
- mCurrentFeature ->setGeometry ( nullptr );
934
+ if ( mCurrentWKB .size () > 0 )
935
+ {
936
+ QgsGeometry *g = new QgsGeometry ();
937
+ g->fromWkb ( mCurrentWKB , mCurrentWKB .size () );
938
+ mCurrentFeature ->setGeometry ( g );
939
+ mCurrentWKB = QgsWkbPtr ( nullptr , 0 );
940
+ }
941
+ else if ( !mCurrentExtent .isEmpty () )
942
+ {
943
+ mCurrentFeature ->setGeometry ( QgsGeometry::fromRect ( mCurrentExtent ) );
944
+ }
878
945
}
879
946
mCurrentFeature ->setValid ( true );
880
947
@@ -1033,6 +1100,14 @@ void QgsGmlStreamingParser::endElement( const XML_Char* el )
1033
1100
mExceptionText = mStringCash ;
1034
1101
mParseModeStack .pop ();
1035
1102
}
1103
+
1104
+ if ( !mGeometryString .empty () )
1105
+ {
1106
+ mGeometryString .append ( " </" , 2 );
1107
+ mGeometryString .append ( pszLocalName, localNameLen );
1108
+ mGeometryString .append ( " >" , 1 );
1109
+ }
1110
+
1036
1111
}
1037
1112
1038
1113
void QgsGmlStreamingParser::characters ( const XML_Char* chars, int len )
@@ -1043,6 +1118,11 @@ void QgsGmlStreamingParser::characters( const XML_Char* chars, int len )
1043
1118
return ;
1044
1119
}
1045
1120
1121
+ if ( !mGeometryString .empty () )
1122
+ {
1123
+ mGeometryString .append ( chars, len );
1124
+ }
1125
+
1046
1126
QgsGmlStreamingParser::ParseMode theParseMode = mParseModeStack .top ();
1047
1127
if ( theParseMode == QgsGmlStreamingParser::attribute ||
1048
1128
theParseMode == QgsGmlStreamingParser::attributeTuple ||
0 commit comments