QGIS API Documentation  3.14.0-Pi (9f7028fd23)
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 
36 
37 #ifndef SIP_RUN
38 
48 class CORE_EXPORT QgsGmlStreamingParser
49 {
50  public:
51 
52  typedef QPair<QgsFeature *, QString> QgsGmlFeaturePtrGmlIdPair;
53 
59  {
60  public:
62  LayerProperties() = default;
63 
65  QString mName;
68  };
69 
71  typedef enum
72  {
79  } AxisOrientationLogic;
80 
82  QgsGmlStreamingParser( const QString &typeName,
83  const QString &geometryAttribute,
84  const QgsFields &fields,
85  AxisOrientationLogic axisOrientationLogic = Honour_EPSG_if_urn,
86  bool invertAxisOrientation = false );
87 
89  QgsGmlStreamingParser( const QList<LayerProperties> &layerProperties,
90  const QgsFields &fields,
91  const QMap< QString, QPair<QString, QString> > &mapFieldNameToSrcLayerNameFieldName,
92  AxisOrientationLogic axisOrientationLogic = Honour_EPSG_if_urn,
93  bool invertAxisOrientation = false );
95 
97  QgsGmlStreamingParser( const QgsGmlStreamingParser &other ) = delete;
99  QgsGmlStreamingParser &operator=( const QgsGmlStreamingParser &other ) = delete;
100 
104  bool processData( const QByteArray &data, bool atEnd, QString &errorMsg );
105 
109  bool processData( const QByteArray &data, bool atEnd );
110 
116  QVector<QgsGmlFeaturePtrGmlIdPair> getAndStealReadyFeatures();
117 
119  int getEPSGCode() const { return mEpsg; }
120 
122  QString srsName() const { return mSrsName; }
123 
125  const QgsRectangle &layerExtent() const { return mLayerExtent; }
126 
128  QgsWkbTypes::Type wkbType() const { return mWkbType; }
129 
131  int numberMatched() const { return mNumberMatched; }
132 
134  int numberReturned() const { return mNumberReturned; }
135 
137  bool isException() const { return mIsException; }
138 
140  QString exceptionText() const { return mExceptionText; }
141 
143  bool isTruncatedResponse() const { return mTruncatedResponse; }
144 
145  private:
146 
147  enum ParseMode
148  {
149  None,
150  BoundingBox,
151  Null,
152  Envelope,
153  LowerCorner,
154  UpperCorner,
155  Feature, // feature element containing attrs and geo (inside gml:featureMember)
156  Attribute,
157  Tuple, // wfs:Tuple of a join layer
158  FeatureTuple,
159  AttributeTuple,
160  Geometry,
161  Coordinate,
162  PosList,
163  MultiPoint,
164  MultiLine,
165  MultiPolygon,
166  ExceptionReport,
167  ExceptionText
168  };
169 
171  void startElement( const XML_Char *el, const XML_Char **attr );
172  void endElement( const XML_Char *el );
173  void characters( const XML_Char *chars, int len );
174  static void start( void *data, const XML_Char *el, const XML_Char **attr )
175  {
176  static_cast<QgsGmlStreamingParser *>( data )->startElement( el, attr );
177  }
178  static void end( void *data, const XML_Char *el )
179  {
180  static_cast<QgsGmlStreamingParser *>( data )->endElement( el );
181  }
182  static void chars( void *data, const XML_Char *chars, int len )
183  {
184  static_cast<QgsGmlStreamingParser *>( data )->characters( chars, len );
185  }
186 
187  // Set current feature attribute
188  void setAttribute( const QString &name, const QString &value );
189 
190  //helper routines
191 
198  int readEpsgFromAttribute( int &epsgNr, const XML_Char **attr );
199 
206  QString readAttribute( const QString &attributeName, const XML_Char **attr ) const;
208  bool createBBoxFromCoordinateString( QgsRectangle &bb, const QString &coordString ) const;
209 
216  int pointsFromCoordinateString( QList<QgsPointXY> &points, const QString &coordString ) const;
217 
225  int pointsFromPosListString( QList<QgsPointXY> &points, const QString &coordString, int dimension ) const;
226 
227  int pointsFromString( QList<QgsPointXY> &points, const QString &coordString ) const;
228  int getPointWKB( QgsWkbPtr &wkbPtr, const QgsPointXY & ) const;
229  int getLineWKB( QgsWkbPtr &wkbPtr, const QList<QgsPointXY> &lineCoordinates ) const;
230  int getRingWKB( QgsWkbPtr &wkbPtr, const QList<QgsPointXY> &ringCoordinates ) const;
231 
238  int createMultiLineFromFragments();
239  int createMultiPointFromFragments();
240  int createPolygonFromFragments();
241  int createMultiPolygonFromFragments();
243  int totalWKBFragmentSize() const;
244 
246  ParseMode modeStackTop() { return mParseModeStack.isEmpty() ? None : mParseModeStack.top(); }
247 
249  ParseMode modeStackPop() { return mParseModeStack.isEmpty() ? None : mParseModeStack.pop(); }
250 
252  XML_Parser mParser;
253 
255  QVector<QgsGmlFeaturePtrGmlIdPair> mFeatureList;
256 
258  QList<LayerProperties> mLayerProperties;
259  QMap< QString, LayerProperties > mMapTypeNameToProperties;
260 
262  QString mTypeName;
263  QByteArray mTypeNameBA;
264  const char *mTypeNamePtr = nullptr;
265  size_t mTypeNameUTF8Len;
266 
267  QgsWkbTypes::Type mWkbType;
268 
269  //results are members such that handler routines are able to manipulate them
270 
272  QString mGeometryAttribute;
273  QByteArray mGeometryAttributeBA;
274  const char *mGeometryAttributePtr = nullptr;
275  size_t mGeometryAttributeUTF8Len;
276 
277  QgsFields mFields;
278  QMap<QString, QPair<int, QgsField> > mThematicAttributes;
279 
280  bool mIsException;
281  QString mExceptionText;
282  bool mTruncatedResponse;
284  int mParseDepth;
285  int mFeatureTupleDepth;
286  QString mCurrentTypename;
287  QStack<ParseMode> mParseModeStack;
290  QString mStringCash;
291  QgsFeature *mCurrentFeature = nullptr;
292  QVector<QVariant> mCurrentAttributes; //attributes of current feature
293  QString mCurrentFeatureId;
294  int mFeatureCount;
296  QgsWkbPtr mCurrentWKB;
297  QgsRectangle mCurrentExtent;
298  bool mBoundedByNullFound;
299 
305  QList< QList<QgsWkbPtr> > mCurrentWKBFragments;
306  QString mAttributeName;
307  char mEndian;
309  QString mCoordinateSeparator;
311  QString mTupleSeparator;
313  QStack<int> mDimensionStack;
315  int mDimension;
317  ParseMode mCoorMode;
319  int mEpsg;
321  QString mSrsName;
323  QgsRectangle mLayerExtent;
325  QString mGMLNameSpaceURI;
326  const char *mGMLNameSpaceURIPtr = nullptr;
328  AxisOrientationLogic mAxisOrientationLogic;
330  bool mInvertAxisOrientationRequest;
332  bool mInvertAxisOrientation;
334  int mNumberReturned;
336  int mNumberMatched;
338  std::string mGeometryString;
340  bool mFoundUnhandledGeometryElement;
341 };
342 
343 #endif
344 
352 class CORE_EXPORT QgsGml : public QObject
353 {
354  Q_OBJECT
355  public:
356  QgsGml(
357  const QString &typeName,
358  const QString &geometryAttribute,
359  const QgsFields &fields );
360 
373  int getFeatures( const QString &uri,
374  QgsWkbTypes::Type *wkbType,
375  QgsRectangle *extent = nullptr,
376  const QString &userName = QString(),
377  const QString &password = QString(),
378  const QString &authcfg = QString() ) SIP_PYNAME( getFeaturesUri );
379 
384  int getFeatures( const QByteArray &data, QgsWkbTypes::Type *wkbType, QgsRectangle *extent = nullptr );
385 
387  QMap<QgsFeatureId, QgsFeature * > featuresMap() const { return mFeatures; }
388 
390  QMap<QgsFeatureId, QString > idsMap() const { return mIdMap; }
391 
396 
397  signals:
398  void dataReadProgress( int progress );
399  void totalStepsUpdate( int totalSteps );
401  void dataProgressAndSteps( int progress, int totalSteps );
402 
403  private slots:
404 
405  void setFinished();
406 
408  void handleProgressEvent( qint64 progress, qint64 totalSteps );
409 
410  private:
411 
418  void calculateExtentFromFeatures();
419 
420  void fillMapsFromParser();
421 
422  QgsGmlStreamingParser mParser;
423 
425  QString mTypeName;
426 
428  bool mFinished;
429 
431  //QMap<QgsFeatureId, QgsFeature* > &mFeatures;
432  QMap<QgsFeatureId, QgsFeature * > mFeatures;
433  //QMap<QString, QMap<QgsFeatureId, QgsFeature* > > mFeatures;
434 
436  //QMap<QgsFeatureId, QString > &mIdMap;
437  QMap<QgsFeatureId, QString > mIdMap;
438  //QMap<QString, QMap<QgsFeatureId, QString > > mIdMap;
439 
441  QgsRectangle mExtent;
442 };
443 
444 #endif
SIP_PYNAME
#define SIP_PYNAME(name)
Definition: qgis_sip.h:81
QgsGmlStreamingParser::LayerProperties::mName
QString mName
Layer name.
Definition: qgsgml.h:65
qgsfields.h
QgsGmlStreamingParser::srsName
QString srsName() const
Returns the value of the srsName attribute.
Definition: qgsgml.h:122
QgsGmlStreamingParser::exceptionText
QString exceptionText() const
Returns the exception text.
Definition: qgsgml.h:140
QgsGmlStreamingParser::Honour_EPSG
@ Honour_EPSG
Honour EPSG axis order.
Definition: qgsgml.h:76
qgsrectangle.h
qgswkbptr.h
QgsGmlStreamingParser
Definition: qgsgml.h:48
crs
const QgsCoordinateReferenceSystem & crs
Definition: qgswfsgetfeature.cpp:105
QgsGmlStreamingParser::isException
bool isException() const
Returns whether the document parser is a OGC exception.
Definition: qgsgml.h:137
QgsFields
Definition: qgsfields.h:44
qgsfeature.h
QgsGmlStreamingParser::Honour_EPSG_if_urn
@ Honour_EPSG_if_urn
Honour EPSG axis order only if srsName is of the form urn:ogc:def:crs:EPSG: *.
Definition: qgsgml.h:74
QgsWkbTypes::Type
Type
The WKB type describes the number of dimensions a geometry has.
Definition: qgswkbtypes.h:68
QgsRectangle
Definition: qgsrectangle.h:41
QgsGmlStreamingParser::getEPSGCode
int getEPSGCode() const
Returns the EPSG code, or 0 if unknown.
Definition: qgsgml.h:119
qgis_sip.h
QgsGml::featuresMap
QMap< QgsFeatureId, QgsFeature * > featuresMap() const
Gets parsed features for given type name.
Definition: qgsgml.h:387
typeName
const QString & typeName
Definition: qgswfsgetfeature.cpp:109
QgsGmlStreamingParser::isTruncatedResponse
bool isTruncatedResponse() const
Returns whether a "truncatedResponse" element is found.
Definition: qgsgml.h:143
QgsWkbPtr
Definition: qgswkbptr.h:42
QgsCoordinateReferenceSystem
Definition: qgscoordinatereferencesystem.h:206
QgsPointXY
Definition: qgspointxy.h:43
QgsGmlStreamingParser::Ignore_EPSG
@ Ignore_EPSG
Ignore EPSG axis order.
Definition: qgsgml.h:78
QgsGml
Definition: qgsgml.h:352
QgsGmlStreamingParser::QgsGmlFeaturePtrGmlIdPair
QPair< QgsFeature *, QString > QgsGmlFeaturePtrGmlIdPair
Definition: qgsgml.h:52
QgsGmlStreamingParser::numberMatched
int numberMatched() const
Returns WFS 2.0 "numberMatched" attribute, or -1 if invalid/not found.
Definition: qgsgml.h:131
QgsGmlStreamingParser::numberReturned
int numberReturned() const
Returns WFS 2.0 "numberReturned" or WFS 1.1 "numberOfFeatures" attribute, or -1 if invalid/not found.
Definition: qgsgml.h:134
QgsGmlStreamingParser::LayerProperties
Definition: qgsgml.h:58
QgsGmlStreamingParser::layerExtent
const QgsRectangle & layerExtent() const
Returns layer bounding box.
Definition: qgsgml.h:125
QgsFeature
Definition: qgsfeature.h:55
QgsGmlStreamingParser::wkbType
QgsWkbTypes::Type wkbType() const
Returns the geometry type.
Definition: qgsgml.h:128
QgsGml::idsMap
QMap< QgsFeatureId, QString > idsMap() const
Gets feature ids map.
Definition: qgsgml.h:390
QgsGmlStreamingParser::LayerProperties::mGeometryAttribute
QString mGeometryAttribute
Geometry attribute name.
Definition: qgsgml.h:67