QGIS API Documentation  3.37.0-Master (a5b4d9743e8)
qgsgml.h
Go to the documentation of this file.
1 /***************************************************************************
2  qgsgml.h
3  ---------------------
4  begin : February 2013
5  copyright : (C) 2013 by Radim Blazek
6  email : radim dot blazek at gmail dot com
7  ***************************************************************************
8  * *
9  * This program is free software; you can redistribute it and/or modify *
10  * it under the terms of the GNU General Public License as published by *
11  * the Free Software Foundation; either version 2 of the License, or *
12  * (at your option) any later version. *
13  * *
14  ***************************************************************************/
15 #ifndef QGSGML_H
16 #define QGSGML_H
17 
18 #include "qgis_core.h"
19 #include <expat.h>
20 #include "qgis_sip.h"
21 #include "qgsfields.h"
22 #include "qgsrectangle.h"
23 #include "qgswkbptr.h"
24 #include "qgsfeature.h"
25 
26 #include <QPair>
27 #include <QByteArray>
28 #include <QDomElement>
29 #include <QStringList>
30 #include <QStack>
31 #include <QVector>
32 
33 #include <string>
34 
35 #ifndef SIP_RUN
36 #include "json.hpp"
37 #endif
38 
40 class QTextCodec;
41 
42 #ifndef SIP_RUN
43 
54 class CORE_EXPORT QgsGmlStreamingParser
55 {
56  public:
57 
58  typedef QPair<QgsFeature *, QString> QgsGmlFeaturePtrGmlIdPair;
59 
65  {
66  public:
68  LayerProperties() = default;
69 
71  QString mName;
74  };
75 
77  typedef enum
78  {
85  } AxisOrientationLogic;
86 
88  QgsGmlStreamingParser( const QString &typeName,
89  const QString &geometryAttribute,
90  const QgsFields &fields,
91  AxisOrientationLogic axisOrientationLogic = Honour_EPSG_if_urn,
92  bool invertAxisOrientation = false );
93 
95  QgsGmlStreamingParser( const QList<LayerProperties> &layerProperties,
96  const QgsFields &fields,
97  const QMap< QString, QPair<QString, QString> > &fieldNameToSrcLayerNameFieldNameMap,
98  AxisOrientationLogic axisOrientationLogic = Honour_EPSG_if_urn,
99  bool invertAxisOrientation = false );
101 
106 
112  void setFieldsXPath(
113  const QMap<QString, QPair<QString, bool>> &fieldNameToSrcLayerNameFieldNameMap,
114  const QMap<QString, QString> &namespacePrefixToURIMap );
115 
120  bool processData( const QByteArray &data, bool atEnd, QString &errorMsg );
121 
126  bool processData( const QByteArray &data, bool atEnd );
127 
134  QVector<QgsGmlFeaturePtrGmlIdPair> getAndStealReadyFeatures();
135 
137  int getEPSGCode() const { return mEpsg; }
138 
140  QString srsName() const { return mSrsName; }
141 
143  const QgsRectangle &layerExtent() const { return mLayerExtent; }
144 
146  Qgis::WkbType wkbType() const { return mWkbType; }
147 
149  int numberMatched() const { return mNumberMatched; }
150 
152  int numberReturned() const { return mNumberReturned; }
153 
155  bool isException() const { return mIsException; }
156 
158  QString exceptionText() const { return mExceptionText; }
159 
161  bool isTruncatedResponse() const { return mTruncatedResponse; }
162 
163  private:
164 
165  enum ParseMode
166  {
167  None,
168  BoundingBox,
169  Null,
170  Envelope,
171  LowerCorner,
172  UpperCorner,
173  Feature, // feature element containing attrs and geo (inside gml:featureMember)
174  Attribute,
175  Tuple, // wfs:Tuple of a join layer
176  FeatureTuple,
177  AttributeTuple,
178  Geometry,
179  Coordinate,
180  PosList,
181  MultiPoint,
182  MultiLine,
183  MultiPolygon,
184  ExceptionReport,
185  ExceptionText
186  };
187 
189  void startElement( const XML_Char *el, const XML_Char **attr );
190  void endElement( const XML_Char *el );
191  void characters( const XML_Char *chars, int len );
192  static void start( void *data, const XML_Char *el, const XML_Char **attr )
193  {
194  static_cast<QgsGmlStreamingParser *>( data )->startElement( el, attr );
195  }
196  static void end( void *data, const XML_Char *el )
197  {
198  static_cast<QgsGmlStreamingParser *>( data )->endElement( el );
199  }
200  static void chars( void *data, const XML_Char *chars, int len )
201  {
202  static_cast<QgsGmlStreamingParser *>( data )->characters( chars, len );
203  }
204 
205  // Add mStringCash to the current json object
206  void addStringContentToJson();
207 
208  // Set current feature attribute
209  void setAttribute( const QString &name, const QString &value );
210 
211  //helper routines
212 
219  int readEpsgFromAttribute( int &epsgNr, const XML_Char **attr );
220 
227  QString readAttribute( const QString &attributeName, const XML_Char **attr ) const;
229  bool createBBoxFromCoordinateString( QgsRectangle &bb, const QString &coordString ) const;
230 
237  int pointsFromCoordinateString( QList<QgsPointXY> &points, const QString &coordString ) const;
238 
246  int pointsFromPosListString( QList<QgsPointXY> &points, const QString &coordString, int dimension ) const;
247 
248  int pointsFromString( QList<QgsPointXY> &points, const QString &coordString ) const;
249  int getPointWKB( QgsWkbPtr &wkbPtr, const QgsPointXY & ) const;
250  int getLineWKB( QgsWkbPtr &wkbPtr, const QList<QgsPointXY> &lineCoordinates ) const;
251  int getRingWKB( QgsWkbPtr &wkbPtr, const QList<QgsPointXY> &ringCoordinates ) const;
252 
259  int createMultiLineFromFragments();
260  int createMultiPointFromFragments();
261  int createPolygonFromFragments();
262  int createMultiPolygonFromFragments();
264  int totalWKBFragmentSize() const;
265 
267  ParseMode modeStackTop() { return mParseModeStack.isEmpty() ? None : mParseModeStack.top(); }
268 
270  ParseMode modeStackPop() { return mParseModeStack.isEmpty() ? None : mParseModeStack.pop(); }
271 
273  void createParser( const QByteArray &encoding = QByteArray() );
274 
276  XML_Parser mParser = nullptr;
277 
279  QVector<QgsGmlFeaturePtrGmlIdPair> mFeatureList;
280 
282  QList<LayerProperties> mLayerProperties;
283  QMap< QString, LayerProperties > mMapTypeNameToProperties;
284 
286  QString mTypeName;
287  QByteArray mTypeNameBA;
288  const char *mTypeNamePtr = nullptr;
289  size_t mTypeNameUTF8Len;
290 
291  Qgis::WkbType mWkbType;
292 
293  //results are members such that handler routines are able to manipulate them
294 
296  QString mGeometryAttribute;
297  QByteArray mGeometryAttributeBA;
298  const char *mGeometryAttributePtr = nullptr;
299  size_t mGeometryAttributeUTF8Len;
300 
301  QgsFields mFields;
302  QMap<QString, QPair<int, QgsField> > mThematicAttributes;
303  QMap<QString, QPair<QString, bool>> mMapXPathToFieldNameAndIsNestedContent;
304  QMap<QString, QString> mMapNamespaceURIToNamespacePrefix;
305 
306  bool mIsException;
307  QString mExceptionText;
308  bool mTruncatedResponse;
310  int mParseDepth;
311  int mFeatureTupleDepth;
312  QString mCurrentTypename;
314  QStack<ParseMode> mParseModeStack;
315  QString mCurrentXPathWithinFeature;
317  QString mStringCash;
318  QgsFeature *mCurrentFeature = nullptr;
319  QVector<QVariant> mCurrentAttributes; //attributes of current feature
320  QString mCurrentFeatureId;
321  int mFeatureCount;
323  QgsWkbPtr mCurrentWKB;
324  QgsRectangle mCurrentExtent;
325  bool mBoundedByNullFound;
326 
333  QList< QList<QgsWkbPtr> > mCurrentWKBFragments;
334  QString mAttributeName;
335  int mAttributeDepth = -1;
336  bool mAttributeValIsNested = false;
338  QMap< QString, QString > mMapFieldNameToJSONContent;
339  nlohmann::json mAttributeJson;
340  QStack<nlohmann::json *> mAttributeJsonCurrentStack;
341  char mEndian;
343  QString mCoordinateSeparator;
345  QString mTupleSeparator;
347  QStack<int> mDimensionStack;
349  int mDimension;
351  ParseMode mCoorMode;
353  int mEpsg;
355  QString mSrsName;
357  QgsRectangle mLayerExtent;
359  QString mGMLNameSpaceURI;
360  const char *mGMLNameSpaceURIPtr = nullptr;
362  AxisOrientationLogic mAxisOrientationLogic;
364  bool mInvertAxisOrientationRequest;
366  bool mInvertAxisOrientation;
368  int mNumberReturned;
370  int mNumberMatched;
372  std::string mGeometryString;
374  bool mFoundUnhandledGeometryElement;
376  QTextCodec *mCodec = nullptr;
377 };
378 
379 #endif
380 
390 class CORE_EXPORT QgsGml : public QObject
391 {
392  Q_OBJECT
393  public:
394  QgsGml(
395  const QString &typeName,
396  const QString &geometryAttribute,
397  const QgsFields &fields );
398 
410  int getFeatures( const QString &uri,
411  Qgis::WkbType *wkbType,
412  QgsRectangle *extent = nullptr,
413  const QString &userName = QString(),
414  const QString &password = QString(),
415  const QString &authcfg = QString() ) SIP_PYNAME( getFeaturesUri );
416 
420  int getFeatures( const QByteArray &data, Qgis::WkbType *wkbType, QgsRectangle *extent = nullptr );
421 
423  QMap<QgsFeatureId, QgsFeature * > featuresMap() const { return mFeatures; }
424 
426  QMap<QgsFeatureId, QString > idsMap() const { return mIdMap; }
427 
432 
433  signals:
434  void dataReadProgress( int progress );
435  void totalStepsUpdate( int totalSteps );
437  void dataProgressAndSteps( int progress, int totalSteps );
438 
439  private slots:
440 
441  void setFinished();
442 
444  void handleProgressEvent( qint64 progress, qint64 totalSteps );
445 
446  private:
447 
454  void calculateExtentFromFeatures();
455 
456  void fillMapsFromParser();
457 
458  QgsGmlStreamingParser mParser;
459 
461  QString mTypeName;
462 
464  bool mFinished;
465 
467  //QMap<QgsFeatureId, QgsFeature* > &mFeatures;
468  QMap<QgsFeatureId, QgsFeature * > mFeatures;
469  //QMap<QString, QMap<QgsFeatureId, QgsFeature* > > mFeatures;
470 
472  //QMap<QgsFeatureId, QString > &mIdMap;
473  QMap<QgsFeatureId, QString > mIdMap;
474  //QMap<QString, QMap<QgsFeatureId, QString > > mIdMap;
475 
477  QgsRectangle mExtent;
478 };
479 
480 #endif
WkbType
The WKB type describes the number of dimensions a geometry has.
Definition: qgis.h:182
This class represents a coordinate reference system (CRS).
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
Definition: qgsfeature.h:56
Container of fields for a vector layer.
Definition: qgsfields.h:45
QString mGeometryAttribute
Geometry attribute name.
Definition: qgsgml.h:73
LayerProperties()=default
Constructor.
This class builds features from GML data in a streaming way.
Definition: qgsgml.h:55
QPair< QgsFeature *, QString > QgsGmlFeaturePtrGmlIdPair
Definition: qgsgml.h:58
bool isException() const
Returns whether the document parser is a OGC exception.
Definition: qgsgml.h:155
int numberReturned() const
Returns WFS 2.0 "numberReturned" or WFS 1.1 "numberOfFeatures" attribute, or -1 if invalid/not found.
Definition: qgsgml.h:152
Qgis::WkbType wkbType() const
Returns the geometry type.
Definition: qgsgml.h:146
@ Ignore_EPSG
Ignore EPSG axis order.
Definition: qgsgml.h:84
@ Honour_EPSG
Honour EPSG axis order.
Definition: qgsgml.h:82
@ Honour_EPSG_if_urn
Honour EPSG axis order only if srsName is of the form urn:ogc:def:crs:EPSG:
Definition: qgsgml.h:80
QgsGmlStreamingParser & operator=(const QgsGmlStreamingParser &other)=delete
QgsGmlStreamingParser cannot be copied.
int numberMatched() const
Returns WFS 2.0 "numberMatched" attribute, or -1 if invalid/not found.
Definition: qgsgml.h:149
QgsGmlStreamingParser(const QgsGmlStreamingParser &other)=delete
QgsGmlStreamingParser cannot be copied.
bool isTruncatedResponse() const
Returns whether a "truncatedResponse" element is found.
Definition: qgsgml.h:161
QString exceptionText() const
Returns the exception text.
Definition: qgsgml.h:158
int getEPSGCode() const
Returns the EPSG code, or 0 if unknown.
Definition: qgsgml.h:137
const QgsRectangle & layerExtent() const
Returns layer bounding box.
Definition: qgsgml.h:143
QString srsName() const
Returns the value of the srsName attribute.
Definition: qgsgml.h:140
This class reads data from a WFS server or alternatively from a GML file.
Definition: qgsgml.h:391
QMap< QgsFeatureId, QgsFeature * > featuresMap() const
Gets parsed features for given type name.
Definition: qgsgml.h:423
void totalStepsUpdate(int totalSteps)
void dataReadProgress(int progress)
QMap< QgsFeatureId, QString > idsMap() const
Gets feature ids map.
Definition: qgsgml.h:426
void dataProgressAndSteps(int progress, int totalSteps)
Also emit signal with progress and totalSteps together (this is better for the status message)
A class to represent a 2D point.
Definition: qgspointxy.h:60
A rectangle specified with double values.
Definition: qgsrectangle.h:42
WKB pointer handler.
Definition: qgswkbptr.h:44
#define SIP_PYNAME(name)
Definition: qgis_sip.h:81
const QgsCoordinateReferenceSystem & crs
const QString & typeName