LCOV - code coverage report
Current view: top level - core - qgsgml.h (source / functions) Hit Total Coverage
Test: coverage.info.cleaned Lines: 0 13 0.0 %
Date: 2021-04-10 08:29:14 Functions: 0 0 -
Branches: 0 0 -

           Branch data     Line data    Source code
       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                 :            : class QgsCoordinateReferenceSystem;
      36                 :            : 
      37                 :            : #ifndef SIP_RUN
      38                 :            : 
      39                 :            : /**
      40                 :            :  * \ingroup core
      41                 :            :  * \brief This class builds features from GML data in a streaming way.
      42                 :            :  *
      43                 :            :  * The caller must call processData()
      44                 :            :  * as soon it has new content from the source. At any point, it can call
      45                 :            :  * getAndStealReadyFeatures() to collect the features that have been completely
      46                 :            :  * parsed.
      47                 :            :  * \note not available in Python bindings
      48                 :            :  * \since QGIS 2.16
      49                 :            :  */
      50                 :            : class CORE_EXPORT QgsGmlStreamingParser
      51                 :            : {
      52                 :            :   public:
      53                 :            : 
      54                 :            :     typedef QPair<QgsFeature *, QString> QgsGmlFeaturePtrGmlIdPair;
      55                 :            : 
      56                 :            :     /**
      57                 :            :      * \ingroup core
      58                 :            :      * \brief Layer properties
      59                 :            :     */
      60                 :          0 :     class LayerProperties
      61                 :            :     {
      62                 :            :       public:
      63                 :            :         //! Constructor
      64                 :            :         LayerProperties() = default;
      65                 :            : 
      66                 :            :         //! Layer name
      67                 :            :         QString mName;
      68                 :            :         //! Geometry attribute name
      69                 :            :         QString mGeometryAttribute;
      70                 :            :     };
      71                 :            : 
      72                 :            :     //! Axis orientation logic.
      73                 :            :     typedef enum
      74                 :            :     {
      75                 :            :       //! Honour EPSG axis order only if srsName is of the form urn:ogc:def:crs:EPSG:
      76                 :            :       Honour_EPSG_if_urn,
      77                 :            :       //! Honour EPSG axis order
      78                 :            :       Honour_EPSG,
      79                 :            :       //! Ignore EPSG axis order
      80                 :            :       Ignore_EPSG,
      81                 :            :     } AxisOrientationLogic;
      82                 :            : 
      83                 :            :     //! Constructor
      84                 :            :     QgsGmlStreamingParser( const QString &typeName,
      85                 :            :                            const QString &geometryAttribute,
      86                 :            :                            const QgsFields &fields,
      87                 :            :                            AxisOrientationLogic axisOrientationLogic = Honour_EPSG_if_urn,
      88                 :            :                            bool invertAxisOrientation = false );
      89                 :            : 
      90                 :            :     //! Constructor for a join layer, or dealing with renamed fields
      91                 :            :     QgsGmlStreamingParser( const QList<LayerProperties> &layerProperties,
      92                 :            :                            const QgsFields &fields,
      93                 :            :                            const QMap< QString, QPair<QString, QString> > &mapFieldNameToSrcLayerNameFieldName,
      94                 :            :                            AxisOrientationLogic axisOrientationLogic = Honour_EPSG_if_urn,
      95                 :            :                            bool invertAxisOrientation = false );
      96                 :            :     ~QgsGmlStreamingParser();
      97                 :            : 
      98                 :            :     //! QgsGmlStreamingParser cannot be copied.
      99                 :            :     QgsGmlStreamingParser( const QgsGmlStreamingParser &other ) = delete;
     100                 :            :     //! QgsGmlStreamingParser cannot be copied.
     101                 :            :     QgsGmlStreamingParser &operator=( const QgsGmlStreamingParser &other ) = delete;
     102                 :            : 
     103                 :            :     /**
     104                 :            :      * Process a new chunk of data. atEnd must be set to TRUE when this is
     105                 :            :      * the last chunk of data.
     106                 :            :     */
     107                 :            :     bool processData( const QByteArray &data, bool atEnd, QString &errorMsg );
     108                 :            : 
     109                 :            :     /**
     110                 :            :      * Process a new chunk of data. atEnd must be set to TRUE when this is
     111                 :            :      * the last chunk of data.
     112                 :            :     */
     113                 :            :     bool processData( const QByteArray &data, bool atEnd );
     114                 :            : 
     115                 :            :     /**
     116                 :            :      * Returns the list of features that have been completely parsed. This
     117                 :            :      * can be called at any point. This will empty the list maintained internally
     118                 :            :      * by the parser, so that features already returned will no longer be returned
     119                 :            :      * by later calls.
     120                 :            :     */
     121                 :            :     QVector<QgsGmlFeaturePtrGmlIdPair> getAndStealReadyFeatures();
     122                 :            : 
     123                 :            :     //! Returns the EPSG code, or 0 if unknown
     124                 :          0 :     int getEPSGCode() const { return mEpsg; }
     125                 :            : 
     126                 :            :     //! Returns the value of the srsName attribute
     127                 :            :     QString srsName() const { return mSrsName; }
     128                 :            : 
     129                 :            :     //! Returns layer bounding box
     130                 :            :     const QgsRectangle &layerExtent() const { return mLayerExtent; }
     131                 :            : 
     132                 :            :     //! Returns the geometry type
     133                 :          0 :     QgsWkbTypes::Type wkbType() const { return mWkbType; }
     134                 :            : 
     135                 :            :     //! Returns WFS 2.0 "numberMatched" attribute, or -1 if invalid/not found
     136                 :            :     int numberMatched() const { return mNumberMatched; }
     137                 :            : 
     138                 :            :     //! Returns WFS 2.0 "numberReturned" or WFS 1.1 "numberOfFeatures" attribute, or -1 if invalid/not found
     139                 :            :     int numberReturned() const { return mNumberReturned; }
     140                 :            : 
     141                 :            :     //! Returns whether the document parser is a OGC exception
     142                 :            :     bool isException() const { return mIsException; }
     143                 :            : 
     144                 :            :     //! Returns the exception text.
     145                 :            :     QString exceptionText() const { return mExceptionText; }
     146                 :            : 
     147                 :            :     //! Returns whether a "truncatedResponse" element is found
     148                 :            :     bool isTruncatedResponse() const { return mTruncatedResponse; }
     149                 :            : 
     150                 :            :   private:
     151                 :            : 
     152                 :            :     enum ParseMode
     153                 :            :     {
     154                 :            :       None,
     155                 :            :       BoundingBox,
     156                 :            :       Null,
     157                 :            :       Envelope,
     158                 :            :       LowerCorner,
     159                 :            :       UpperCorner,
     160                 :            :       Feature,  // feature element containing attrs and geo (inside gml:featureMember)
     161                 :            :       Attribute,
     162                 :            :       Tuple, // wfs:Tuple of a join layer
     163                 :            :       FeatureTuple,
     164                 :            :       AttributeTuple,
     165                 :            :       Geometry,
     166                 :            :       Coordinate,
     167                 :            :       PosList,
     168                 :            :       MultiPoint,
     169                 :            :       MultiLine,
     170                 :            :       MultiPolygon,
     171                 :            :       ExceptionReport,
     172                 :            :       ExceptionText
     173                 :            :     };
     174                 :            : 
     175                 :            :     //! XML handler methods
     176                 :            :     void startElement( const XML_Char *el, const XML_Char **attr );
     177                 :            :     void endElement( const XML_Char *el );
     178                 :            :     void characters( const XML_Char *chars, int len );
     179                 :          0 :     static void start( void *data, const XML_Char *el, const XML_Char **attr )
     180                 :            :     {
     181                 :          0 :       static_cast<QgsGmlStreamingParser *>( data )->startElement( el, attr );
     182                 :          0 :     }
     183                 :          0 :     static void end( void *data, const XML_Char *el )
     184                 :            :     {
     185                 :          0 :       static_cast<QgsGmlStreamingParser *>( data )->endElement( el );
     186                 :          0 :     }
     187                 :          0 :     static void chars( void *data, const XML_Char *chars, int len )
     188                 :            :     {
     189                 :          0 :       static_cast<QgsGmlStreamingParser *>( data )->characters( chars, len );
     190                 :          0 :     }
     191                 :            : 
     192                 :            :     // Set current feature attribute
     193                 :            :     void setAttribute( const QString &name, const QString &value );
     194                 :            : 
     195                 :            :     //helper routines
     196                 :            : 
     197                 :            :     /**
     198                 :            :      * Reads attribute srsName="EpsgCrsId:..."
     199                 :            :      * \param epsgNr result
     200                 :            :      * \param attr attribute strings
     201                 :            :      * \returns 0 in case of success
     202                 :            :       */
     203                 :            :     int readEpsgFromAttribute( int &epsgNr, const XML_Char **attr );
     204                 :            : 
     205                 :            :     /**
     206                 :            :      * Reads attribute as string
     207                 :            :      * \param attributeName
     208                 :            :      * \param attr
     209                 :            :      * \returns attribute value or an empty string if no such attribute
     210                 :            :       */
     211                 :            :     QString readAttribute( const QString &attributeName, const XML_Char **attr ) const;
     212                 :            :     //! Creates a rectangle from a coordinate string.
     213                 :            :     bool createBBoxFromCoordinateString( QgsRectangle &bb, const QString &coordString ) const;
     214                 :            : 
     215                 :            :     /**
     216                 :            :      * Creates a set of points from a coordinate string.
     217                 :            :      * \param points list that will contain the created points
     218                 :            :      * \param coordString the text containing the coordinates
     219                 :            :      * \returns 0 in case of success
     220                 :            :      */
     221                 :            :     int pointsFromCoordinateString( QList<QgsPointXY> &points, const QString &coordString ) const;
     222                 :            : 
     223                 :            :     /**
     224                 :            :      * Creates a set of points from a gml:posList or gml:pos coordinate string.
     225                 :            :      * \param points list that will contain the created points
     226                 :            :      * \param coordString the text containing the coordinates
     227                 :            :      * \param dimension number of dimensions
     228                 :            :      * \returns 0 in case of success
     229                 :            :       */
     230                 :            :     int pointsFromPosListString( QList<QgsPointXY> &points, const QString &coordString, int dimension ) const;
     231                 :            : 
     232                 :            :     int pointsFromString( QList<QgsPointXY> &points, const QString &coordString ) const;
     233                 :            :     int getPointWKB( QgsWkbPtr &wkbPtr, const QgsPointXY & ) const;
     234                 :            :     int getLineWKB( QgsWkbPtr &wkbPtr, const QList<QgsPointXY> &lineCoordinates ) const;
     235                 :            :     int getRingWKB( QgsWkbPtr &wkbPtr, const QList<QgsPointXY> &ringCoordinates ) const;
     236                 :            : 
     237                 :            :     /**
     238                 :            :      * Creates a multiline from the information in mCurrentWKBFragments and
     239                 :            :      * mCurrentWKBFragmentSizes. Assign the result. The multiline is in
     240                 :            :      * mCurrentWKB. The function deletes the memory in
     241                 :            :      * mCurrentWKBFragments. Returns 0 in case of success.
     242                 :            :      */
     243                 :            :     int createMultiLineFromFragments();
     244                 :            :     int createMultiPointFromFragments();
     245                 :            :     int createPolygonFromFragments();
     246                 :            :     int createMultiPolygonFromFragments();
     247                 :            :     //! Adds all the integers contained in mCurrentWKBFragmentSizes
     248                 :            :     int totalWKBFragmentSize() const;
     249                 :            : 
     250                 :            :     //! Gets safely (if empty) top from mode stack
     251                 :            :     ParseMode modeStackTop() { return mParseModeStack.isEmpty() ? None : mParseModeStack.top(); }
     252                 :            : 
     253                 :            :     //! Safely (if empty) pop from mode stack
     254                 :            :     ParseMode modeStackPop() { return mParseModeStack.isEmpty() ? None : mParseModeStack.pop(); }
     255                 :            : 
     256                 :            :     //! Expat parser
     257                 :            :     XML_Parser mParser;
     258                 :            : 
     259                 :            :     //! List of (feature, gml_id) pairs
     260                 :            :     QVector<QgsGmlFeaturePtrGmlIdPair> mFeatureList;
     261                 :            : 
     262                 :            :     //! Describe the various feature types of a join layer
     263                 :            :     QList<LayerProperties> mLayerProperties;
     264                 :            :     QMap< QString, LayerProperties > mMapTypeNameToProperties;
     265                 :            : 
     266                 :            :     //! Typename without namespace prefix
     267                 :            :     QString mTypeName;
     268                 :            :     QByteArray mTypeNameBA;
     269                 :            :     const char *mTypeNamePtr = nullptr;
     270                 :            :     size_t mTypeNameUTF8Len;
     271                 :            : 
     272                 :            :     QgsWkbTypes::Type mWkbType;
     273                 :            : 
     274                 :            :     //results are members such that handler routines are able to manipulate them
     275                 :            : 
     276                 :            :     //! Name of geometry attribute
     277                 :            :     QString mGeometryAttribute;
     278                 :            :     QByteArray mGeometryAttributeBA;
     279                 :            :     const char *mGeometryAttributePtr = nullptr;
     280                 :            :     size_t mGeometryAttributeUTF8Len;
     281                 :            : 
     282                 :            :     QgsFields mFields;
     283                 :            :     QMap<QString, QPair<int, QgsField> > mThematicAttributes;
     284                 :            : 
     285                 :            :     bool mIsException;
     286                 :            :     QString mExceptionText;
     287                 :            :     bool mTruncatedResponse;
     288                 :            :     //! Parsing depth
     289                 :            :     int mParseDepth;
     290                 :            :     int mFeatureTupleDepth;
     291                 :            :     QString mCurrentTypename; //!< Used to track the current (unprefixed) typename for wfs:Member in join layer
     292                 :            :     //! Keep track about the most important nested elements
     293                 :            :     QStack<ParseMode> mParseModeStack;
     294                 :            :     //! This contains the character data if an important element has been encountered
     295                 :            :     QString mStringCash;
     296                 :            :     QgsFeature *mCurrentFeature = nullptr;
     297                 :            :     QVector<QVariant> mCurrentAttributes; //attributes of current feature
     298                 :            :     QString mCurrentFeatureId;
     299                 :            :     int mFeatureCount;
     300                 :            :     //! The total WKB for a feature
     301                 :            :     QgsWkbPtr mCurrentWKB;
     302                 :            :     QgsRectangle mCurrentExtent;
     303                 :            :     bool mBoundedByNullFound;
     304                 :            : 
     305                 :            :     /**
     306                 :            :      * WKB intermediate storage during parsing. For points and lines, no
     307                 :            :      * intermediate WKB is stored at all. For multipoints and multilines and
     308                 :            :      * polygons, only one nested list is used. For multipolygons, both nested lists
     309                 :            :      * are used
     310                 :            :     */
     311                 :            :     QList< QList<QgsWkbPtr> > mCurrentWKBFragments;
     312                 :            :     QString mAttributeName;
     313                 :            :     char mEndian;
     314                 :            :     //! Coordinate separator for coordinate strings. Usually ","
     315                 :            :     QString mCoordinateSeparator;
     316                 :            :     //! Tuple separator for coordinate strings. Usually " "
     317                 :            :     QString mTupleSeparator;
     318                 :            :     //! Keep track about number of dimensions in pos or posList
     319                 :            :     QStack<int> mDimensionStack;
     320                 :            :     //! Number of dimensions in pos or posList for the current geometry
     321                 :            :     int mDimension;
     322                 :            :     //! Coordinates mode, coordinate or posList
     323                 :            :     ParseMode mCoorMode;
     324                 :            :     //! EPSG of parsed features geometries
     325                 :            :     int mEpsg;
     326                 :            :     //! Literal srsName attribute
     327                 :            :     QString mSrsName;
     328                 :            :     //! Layer bounding box
     329                 :            :     QgsRectangle mLayerExtent;
     330                 :            :     //! GML namespace URI
     331                 :            :     QString mGMLNameSpaceURI;
     332                 :            :     const char *mGMLNameSpaceURIPtr = nullptr;
     333                 :            :     //! Axis orientation logic
     334                 :            :     AxisOrientationLogic mAxisOrientationLogic;
     335                 :            :     //! Whether to invert axis orientation. This value is immutable, but combined with what is inferred from data and mAxisOrientationLogic, is used to compute mInvertAxisOrientation
     336                 :            :     bool mInvertAxisOrientationRequest;
     337                 :            :     //! Whether to invert axis orientation: result of mAxisOrientationLogic, mInvertAxisOrientationRequest and what is inferred from data and mAxisOrientationLogic
     338                 :            :     bool mInvertAxisOrientation;
     339                 :            :     //! WFS 2.0 "numberReturned" or WFS 1.1 "numberOfFeatures" attribute, or -1 if invalid/not found
     340                 :            :     int mNumberReturned;
     341                 :            :     //! WFS 2.0 "numberMatched" attribute, or -1 if invalid/not found
     342                 :            :     int mNumberMatched;
     343                 :            :     //! XML blob containing geometry
     344                 :            :     std::string mGeometryString;
     345                 :            :     //! Whether we found a unhandled geometry element
     346                 :            :     bool mFoundUnhandledGeometryElement;
     347                 :            : };
     348                 :            : 
     349                 :            : #endif
     350                 :            : 
     351                 :            : /**
     352                 :            :  * \ingroup core
     353                 :            :  * \brief This class reads data from a WFS server or alternatively from a GML file.
     354                 :            :  *
     355                 :            :  * It
     356                 :            :  * uses the expat XML parser and an event based model to keep performance high.
     357                 :            :  * The parsing starts when the first data arrives, it does not wait until the
     358                 :            :  * request is finished
     359                 :            : */
     360                 :            : class CORE_EXPORT QgsGml : public QObject
     361                 :            : {
     362                 :          0 :     Q_OBJECT
     363                 :            :   public:
     364                 :            :     QgsGml(
     365                 :            :       const QString &typeName,
     366                 :            :       const QString &geometryAttribute,
     367                 :            :       const QgsFields &fields );
     368                 :            : 
     369                 :            :     /**
     370                 :            :      * Does the Http GET request to the wfs server
     371                 :            :      *  Supports only UTF-8, UTF-16, ISO-8859-1, ISO-8859-1 XML encodings.
     372                 :            :      *  \param uri GML URL
     373                 :            :      *  \param wkbType wkbType to retrieve
     374                 :            :      *  \param extent retrieved extents
     375                 :            :      *  \param userName username for authentication
     376                 :            :      *  \param password password for authentication
     377                 :            :      *  \param authcfg authentication configuration id
     378                 :            :      *  \returns 0 in case of success
     379                 :            :      *  \note available in Python as getFeaturesUri
     380                 :            :      */
     381                 :            :     int getFeatures( const QString &uri,
     382                 :            :                      QgsWkbTypes::Type *wkbType,
     383                 :            :                      QgsRectangle *extent = nullptr,
     384                 :            :                      const QString &userName = QString(),
     385                 :            :                      const QString &password = QString(),
     386                 :            :                      const QString &authcfg = QString() ) SIP_PYNAME( getFeaturesUri );
     387                 :            : 
     388                 :            :     /**
     389                 :            :      * Read from GML data. Constructor uri param is ignored
     390                 :            :      *  Supports only UTF-8, UTF-16, ISO-8859-1, ISO-8859-1 XML encodings.
     391                 :            :      */
     392                 :            :     int getFeatures( const QByteArray &data, QgsWkbTypes::Type *wkbType, QgsRectangle *extent = nullptr );
     393                 :            : 
     394                 :            :     //! Gets parsed features for given type name
     395                 :            :     QMap<QgsFeatureId, QgsFeature * > featuresMap() const { return mFeatures; }
     396                 :            : 
     397                 :            :     //! Gets feature ids map
     398                 :            :     QMap<QgsFeatureId, QString > idsMap() const { return mIdMap; }
     399                 :            : 
     400                 :            :     /**
     401                 :            :      * Returns features spatial reference system
     402                 :            :      * \since QGIS 2.1
     403                 :            :      */
     404                 :            :     QgsCoordinateReferenceSystem crs() const;
     405                 :            : 
     406                 :            :   signals:
     407                 :            :     void dataReadProgress( int progress );
     408                 :            :     void totalStepsUpdate( int totalSteps );
     409                 :            :     //! Also emit signal with progress and totalSteps together (this is better for the status message)
     410                 :            :     void dataProgressAndSteps( int progress, int totalSteps );
     411                 :            : 
     412                 :            :   private slots:
     413                 :            : 
     414                 :            :     void setFinished();
     415                 :            : 
     416                 :            :     //! Takes progress value and total steps and emit signals 'dataReadProgress' and 'totalStepUpdate'
     417                 :            :     void handleProgressEvent( qint64 progress, qint64 totalSteps );
     418                 :            : 
     419                 :            :   private:
     420                 :            : 
     421                 :            :     /**
     422                 :            :      * This function evaluates the layer bounding box from the features and
     423                 :            :      * sets it to mExtent.  Less efficient compared to reading the bbox from
     424                 :            :      * the provider, so it is only done if the wfs server does not provider
     425                 :            :      * extent information.
     426                 :            :      */
     427                 :            :     void calculateExtentFromFeatures();
     428                 :            : 
     429                 :            :     void fillMapsFromParser();
     430                 :            : 
     431                 :            :     QgsGmlStreamingParser mParser;
     432                 :            : 
     433                 :            :     //! Typename without namespace prefix
     434                 :            :     QString mTypeName;
     435                 :            : 
     436                 :            :     //! True if the request is finished
     437                 :            :     bool mFinished;
     438                 :            : 
     439                 :            :     //! The features of the layer, map of feature maps for each feature type
     440                 :            :     //QMap<QgsFeatureId, QgsFeature* > &mFeatures;
     441                 :            :     QMap<QgsFeatureId, QgsFeature * > mFeatures;
     442                 :            :     //QMap<QString, QMap<QgsFeatureId, QgsFeature* > > mFeatures;
     443                 :            : 
     444                 :            :     //! Stores the relation between provider ids and WFS server ids
     445                 :            :     //QMap<QgsFeatureId, QString > &mIdMap;
     446                 :            :     QMap<QgsFeatureId, QString > mIdMap;
     447                 :            :     //QMap<QString, QMap<QgsFeatureId, QString > > mIdMap;
     448                 :            : 
     449                 :            :     //! Bounding box of the layer
     450                 :            :     QgsRectangle mExtent;
     451                 :            : };
     452                 :            : 
     453                 :            : #endif

Generated by: LCOV version 1.14