QGIS API Documentation  3.21.0-Master (5b68dc587e)
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 class QTextCodec;
37 
38 #ifndef SIP_RUN
39 
51 class CORE_EXPORT QgsGmlStreamingParser
52 {
53  public:
54 
55  typedef QPair<QgsFeature *, QString> QgsGmlFeaturePtrGmlIdPair;
56 
62  {
63  public:
65  LayerProperties() = default;
66 
68  QString mName;
71  };
72 
74  typedef enum
75  {
82  } AxisOrientationLogic;
83 
85  QgsGmlStreamingParser( const QString &typeName,
86  const QString &geometryAttribute,
87  const QgsFields &fields,
88  AxisOrientationLogic axisOrientationLogic = Honour_EPSG_if_urn,
89  bool invertAxisOrientation = false );
90 
92  QgsGmlStreamingParser( const QList<LayerProperties> &layerProperties,
93  const QgsFields &fields,
94  const QMap< QString, QPair<QString, QString> > &mapFieldNameToSrcLayerNameFieldName,
95  AxisOrientationLogic axisOrientationLogic = Honour_EPSG_if_urn,
96  bool invertAxisOrientation = false );
98 
103 
108  bool processData( const QByteArray &data, bool atEnd, QString &errorMsg );
109 
114  bool processData( const QByteArray &data, bool atEnd );
115 
122  QVector<QgsGmlFeaturePtrGmlIdPair> getAndStealReadyFeatures();
123 
125  int getEPSGCode() const { return mEpsg; }
126 
128  QString srsName() const { return mSrsName; }
129 
131  const QgsRectangle &layerExtent() const { return mLayerExtent; }
132 
134  QgsWkbTypes::Type wkbType() const { return mWkbType; }
135 
137  int numberMatched() const { return mNumberMatched; }
138 
140  int numberReturned() const { return mNumberReturned; }
141 
143  bool isException() const { return mIsException; }
144 
146  QString exceptionText() const { return mExceptionText; }
147 
149  bool isTruncatedResponse() const { return mTruncatedResponse; }
150 
151  private:
152 
153  enum ParseMode
154  {
155  None,
156  BoundingBox,
157  Null,
158  Envelope,
159  LowerCorner,
160  UpperCorner,
161  Feature, // feature element containing attrs and geo (inside gml:featureMember)
162  Attribute,
163  Tuple, // wfs:Tuple of a join layer
164  FeatureTuple,
165  AttributeTuple,
166  Geometry,
167  Coordinate,
168  PosList,
169  MultiPoint,
170  MultiLine,
171  MultiPolygon,
172  ExceptionReport,
173  ExceptionText
174  };
175 
177  void startElement( const XML_Char *el, const XML_Char **attr );
178  void endElement( const XML_Char *el );
179  void characters( const XML_Char *chars, int len );
180  static void start( void *data, const XML_Char *el, const XML_Char **attr )
181  {
182  static_cast<QgsGmlStreamingParser *>( data )->startElement( el, attr );
183  }
184  static void end( void *data, const XML_Char *el )
185  {
186  static_cast<QgsGmlStreamingParser *>( data )->endElement( el );
187  }
188  static void chars( void *data, const XML_Char *chars, int len )
189  {
190  static_cast<QgsGmlStreamingParser *>( data )->characters( chars, len );
191  }
192 
193  // Set current feature attribute
194  void setAttribute( const QString &name, const QString &value );
195 
196  //helper routines
197 
204  int readEpsgFromAttribute( int &epsgNr, const XML_Char **attr );
205 
212  QString readAttribute( const QString &attributeName, const XML_Char **attr ) const;
214  bool createBBoxFromCoordinateString( QgsRectangle &bb, const QString &coordString ) const;
215 
222  int pointsFromCoordinateString( QList<QgsPointXY> &points, const QString &coordString ) const;
223 
231  int pointsFromPosListString( QList<QgsPointXY> &points, const QString &coordString, int dimension ) const;
232 
233  int pointsFromString( QList<QgsPointXY> &points, const QString &coordString ) const;
234  int getPointWKB( QgsWkbPtr &wkbPtr, const QgsPointXY & ) const;
235  int getLineWKB( QgsWkbPtr &wkbPtr, const QList<QgsPointXY> &lineCoordinates ) const;
236  int getRingWKB( QgsWkbPtr &wkbPtr, const QList<QgsPointXY> &ringCoordinates ) const;
237 
244  int createMultiLineFromFragments();
245  int createMultiPointFromFragments();
246  int createPolygonFromFragments();
247  int createMultiPolygonFromFragments();
249  int totalWKBFragmentSize() const;
250 
252  ParseMode modeStackTop() { return mParseModeStack.isEmpty() ? None : mParseModeStack.top(); }
253 
255  ParseMode modeStackPop() { return mParseModeStack.isEmpty() ? None : mParseModeStack.pop(); }
256 
258  void createParser( const QByteArray &encoding = QByteArray() );
259 
261  XML_Parser mParser = nullptr;
262 
264  QVector<QgsGmlFeaturePtrGmlIdPair> mFeatureList;
265 
267  QList<LayerProperties> mLayerProperties;
268  QMap< QString, LayerProperties > mMapTypeNameToProperties;
269 
271  QString mTypeName;
272  QByteArray mTypeNameBA;
273  const char *mTypeNamePtr = nullptr;
274  size_t mTypeNameUTF8Len;
275 
276  QgsWkbTypes::Type mWkbType;
277 
278  //results are members such that handler routines are able to manipulate them
279 
281  QString mGeometryAttribute;
282  QByteArray mGeometryAttributeBA;
283  const char *mGeometryAttributePtr = nullptr;
284  size_t mGeometryAttributeUTF8Len;
285 
286  QgsFields mFields;
287  QMap<QString, QPair<int, QgsField> > mThematicAttributes;
288 
289  bool mIsException;
290  QString mExceptionText;
291  bool mTruncatedResponse;
293  int mParseDepth;
294  int mFeatureTupleDepth;
295  QString mCurrentTypename;
297  QStack<ParseMode> mParseModeStack;
299  QString mStringCash;
300  QgsFeature *mCurrentFeature = nullptr;
301  QVector<QVariant> mCurrentAttributes; //attributes of current feature
302  QString mCurrentFeatureId;
303  int mFeatureCount;
305  QgsWkbPtr mCurrentWKB;
306  QgsRectangle mCurrentExtent;
307  bool mBoundedByNullFound;
308 
315  QList< QList<QgsWkbPtr> > mCurrentWKBFragments;
316  QString mAttributeName;
317  char mEndian;
319  QString mCoordinateSeparator;
321  QString mTupleSeparator;
323  QStack<int> mDimensionStack;
325  int mDimension;
327  ParseMode mCoorMode;
329  int mEpsg;
331  QString mSrsName;
333  QgsRectangle mLayerExtent;
335  QString mGMLNameSpaceURI;
336  const char *mGMLNameSpaceURIPtr = nullptr;
338  AxisOrientationLogic mAxisOrientationLogic;
340  bool mInvertAxisOrientationRequest;
342  bool mInvertAxisOrientation;
344  int mNumberReturned;
346  int mNumberMatched;
348  std::string mGeometryString;
350  bool mFoundUnhandledGeometryElement;
352  QTextCodec *mCodec = nullptr;
353 };
354 
355 #endif
356 
366 class CORE_EXPORT QgsGml : public QObject
367 {
368  Q_OBJECT
369  public:
370  QgsGml(
371  const QString &typeName,
372  const QString &geometryAttribute,
373  const QgsFields &fields );
374 
386  int getFeatures( const QString &uri,
387  QgsWkbTypes::Type *wkbType,
388  QgsRectangle *extent = nullptr,
389  const QString &userName = QString(),
390  const QString &password = QString(),
391  const QString &authcfg = QString() ) SIP_PYNAME( getFeaturesUri );
392 
396  int getFeatures( const QByteArray &data, QgsWkbTypes::Type *wkbType, QgsRectangle *extent = nullptr );
397 
399  QMap<QgsFeatureId, QgsFeature * > featuresMap() const { return mFeatures; }
400 
402  QMap<QgsFeatureId, QString > idsMap() const { return mIdMap; }
403 
409 
410  signals:
411  void dataReadProgress( int progress );
412  void totalStepsUpdate( int totalSteps );
414  void dataProgressAndSteps( int progress, int totalSteps );
415 
416  private slots:
417 
418  void setFinished();
419 
421  void handleProgressEvent( qint64 progress, qint64 totalSteps );
422 
423  private:
424 
431  void calculateExtentFromFeatures();
432 
433  void fillMapsFromParser();
434 
435  QgsGmlStreamingParser mParser;
436 
438  QString mTypeName;
439 
441  bool mFinished;
442 
444  //QMap<QgsFeatureId, QgsFeature* > &mFeatures;
445  QMap<QgsFeatureId, QgsFeature * > mFeatures;
446  //QMap<QString, QMap<QgsFeatureId, QgsFeature* > > mFeatures;
447 
449  //QMap<QgsFeatureId, QString > &mIdMap;
450  QMap<QgsFeatureId, QString > mIdMap;
451  //QMap<QString, QMap<QgsFeatureId, QString > > mIdMap;
452 
454  QgsRectangle mExtent;
455 };
456 
457 #endif
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:70
LayerProperties()=default
Constructor.
This class builds features from GML data in a streaming way.
Definition: qgsgml.h:52
QgsWkbTypes::Type wkbType() const
Returns the geometry type.
Definition: qgsgml.h:134
QPair< QgsFeature *, QString > QgsGmlFeaturePtrGmlIdPair
Definition: qgsgml.h:55
bool isException() const
Returns whether the document parser is a OGC exception.
Definition: qgsgml.h:143
int numberReturned() const
Returns WFS 2.0 "numberReturned" or WFS 1.1 "numberOfFeatures" attribute, or -1 if invalid/not found.
Definition: qgsgml.h:140
@ Ignore_EPSG
Ignore EPSG axis order.
Definition: qgsgml.h:81
@ Honour_EPSG
Honour EPSG axis order.
Definition: qgsgml.h:79
@ Honour_EPSG_if_urn
Honour EPSG axis order only if srsName is of the form urn:ogc:def:crs:EPSG:
Definition: qgsgml.h:77
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:137
QgsGmlStreamingParser(const QgsGmlStreamingParser &other)=delete
QgsGmlStreamingParser cannot be copied.
bool isTruncatedResponse() const
Returns whether a "truncatedResponse" element is found.
Definition: qgsgml.h:149
QString exceptionText() const
Returns the exception text.
Definition: qgsgml.h:146
int getEPSGCode() const
Returns the EPSG code, or 0 if unknown.
Definition: qgsgml.h:125
const QgsRectangle & layerExtent() const
Returns layer bounding box.
Definition: qgsgml.h:131
QString srsName() const
Returns the value of the srsName attribute.
Definition: qgsgml.h:128
This class reads data from a WFS server or alternatively from a GML file.
Definition: qgsgml.h:367
QMap< QgsFeatureId, QgsFeature * > featuresMap() const
Gets parsed features for given type name.
Definition: qgsgml.h:399
void totalStepsUpdate(int totalSteps)
void dataReadProgress(int progress)
QMap< QgsFeatureId, QString > idsMap() const
Gets feature ids map.
Definition: qgsgml.h:402
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:59
A rectangle specified with double values.
Definition: qgsrectangle.h:42
WKB pointer handler.
Definition: qgswkbptr.h:44
Type
The WKB type describes the number of dimensions a geometry has.
Definition: qgswkbtypes.h:70
#define SIP_PYNAME(name)
Definition: qgis_sip.h:81
const QgsCoordinateReferenceSystem & crs
const QString & typeName