LCOV - code coverage report
Current view: top level - ogr/ogrsf_frmts/wfs - ogr_wfs.h (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 66 83 79.5 %
Date: 2024-05-03 15:49:35 Functions: 31 37 83.8 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  * $Id$
       3             :  *
       4             :  * Project:  WFS Translator
       5             :  * Purpose:  Definition of classes for OGR WFS driver.
       6             :  * Author:   Even Rouault, even dot rouault at spatialys.com
       7             :  *
       8             :  ******************************************************************************
       9             :  * Copyright (c) 2010-2013, Even Rouault <even dot rouault at spatialys.com>
      10             :  *
      11             :  * Permission is hereby granted, free of charge, to any person obtaining a
      12             :  * copy of this software and associated documentation files (the "Software"),
      13             :  * to deal in the Software without restriction, including without limitation
      14             :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      15             :  * and/or sell copies of the Software, and to permit persons to whom the
      16             :  * Software is furnished to do so, subject to the following conditions:
      17             :  *
      18             :  * The above copyright notice and this permission notice shall be included
      19             :  * in all copies or substantial portions of the Software.
      20             :  *
      21             :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      22             :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      23             :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      24             :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      25             :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      26             :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      27             :  * DEALINGS IN THE SOFTWARE.
      28             :  ****************************************************************************/
      29             : 
      30             : #ifndef OGR_WFS_H_INCLUDED
      31             : #define OGR_WFS_H_INCLUDED
      32             : 
      33             : #include <vector>
      34             : #include <set>
      35             : #include <map>
      36             : 
      37             : #include "cpl_minixml.h"
      38             : #include "ogrsf_frmts.h"
      39             : #include "gmlreader.h"
      40             : #include "cpl_http.h"
      41             : #include "ogr_swq.h"
      42             : 
      43             : const CPLXMLNode *WFSFindNode(const CPLXMLNode *psXML, const char *pszRootName);
      44             : void OGRWFSRecursiveUnlink(const char *pszName);
      45             : CPLString
      46             : WFS_TurnSQLFilterToOGCFilter(const swq_expr_node *poExpr, OGRDataSource *poDS,
      47             :                              OGRFeatureDefn *poFDefn, int nVersion,
      48             :                              int bPropertyIsNotEqualToSupported,
      49             :                              int bUseFeatureId, int bGmlObjectIdNeedsGMLPrefix,
      50             :                              const char *pszNSPrefix, int *pbOutNeedsNullCheck);
      51             : swq_custom_func_registrar *WFSGetCustomFuncRegistrar();
      52             : 
      53             : const char *FindSubStringInsensitive(const char *pszStr, const char *pszSubStr);
      54             : 
      55             : CPLString WFS_EscapeURL(const char *pszURL);
      56             : CPLString WFS_DecodeURL(const CPLString &osSrc);
      57             : 
      58             : class OGRWFSSortDesc
      59             : {
      60             :   public:
      61             :     CPLString osColumn;
      62             :     bool bAsc;
      63             : 
      64           0 :     OGRWFSSortDesc(const CPLString &osColumnIn, int bAscIn)
      65           0 :         : osColumn(osColumnIn), bAsc(CPL_TO_BOOL(bAscIn))
      66             :     {
      67           0 :     }
      68             : };
      69             : 
      70             : /************************************************************************/
      71             : /*                             OGRWFSLayer                              */
      72             : /************************************************************************/
      73             : 
      74             : class OGRWFSDataSource;
      75             : 
      76             : class OGRWFSLayer final : public OGRLayer
      77             : {
      78             :     OGRWFSDataSource *poDS;
      79             : 
      80             :     OGRFeatureDefn *poFeatureDefn;
      81             :     bool bGotApproximateLayerDefn;
      82             :     GMLFeatureClass *poGMLFeatureClass;
      83             : 
      84             :     int bAxisOrderAlreadyInverted;
      85             :     OGRSpatialReference *m_poSRS;
      86             :     std::string m_osSRSName{};
      87             : 
      88             :     char *pszBaseURL;
      89             :     char *pszName;
      90             :     char *pszNS;
      91             :     char *pszNSVal;
      92             : 
      93             :     bool bStreamingDS;
      94             :     GDALDataset *poBaseDS;
      95             :     OGRLayer *poBaseLayer;
      96             :     bool bHasFetched;
      97             :     bool bReloadNeeded;
      98             : 
      99             :     CPLString osGeometryColumnName;
     100             :     OGRwkbGeometryType eGeomType;
     101             :     GIntBig nFeatures;
     102             :     GIntBig m_nNumberMatched = -1;
     103             :     bool m_bHasReadAtLeastOneFeatureInThisPage = false;
     104             :     bool bCountFeaturesInGetNextFeature;
     105             : 
     106             :     int CanRunGetFeatureCountAndGetExtentTogether();
     107             : 
     108             :     CPLString MakeGetFeatureURL(int nMaxFeatures, int bRequestHits);
     109             :     bool MustRetryIfNonCompliantServer(const char *pszServerAnswer);
     110             :     GDALDataset *FetchGetFeature(int nMaxFeatures);
     111             :     OGRFeatureDefn *DescribeFeatureType();
     112             :     GIntBig ExecuteGetFeatureResultTypeHits();
     113             : 
     114             :     OGREnvelope m_oWGS84Extents{};
     115             :     OGREnvelope m_oExtents{};
     116             : 
     117             :     OGRGeometry *poFetchedFilterGeom;
     118             : 
     119             :     CPLString osSQLWhere;
     120             :     CPLString osWFSWhere;
     121             : 
     122             :     CPLString osTargetNamespace;
     123             :     CPLString GetDescribeFeatureTypeURL(int bWithNS);
     124             : 
     125             :     int nExpectedInserts;
     126             :     CPLString osGlobalInsert;
     127             :     std::vector<CPLString> aosFIDList;
     128             : 
     129             :     bool bInTransaction;
     130             : 
     131             :     CPLString GetPostHeader();
     132             : 
     133             :     bool bUseFeatureIdAtLayerLevel;
     134             : 
     135             :     bool bPagingActive;
     136             :     int nPagingStartIndex;
     137             :     int nFeatureRead;
     138             : 
     139             :     OGRFeatureDefn *BuildLayerDefnFromFeatureClass(GMLFeatureClass *poClass);
     140             : 
     141             :     char *pszRequiredOutputFormat;
     142             : 
     143             :     std::vector<OGRWFSSortDesc> aoSortColumns;
     144             : 
     145             :     std::vector<std::string> m_aosSupportedCRSList{};
     146             :     OGRLayer::GetSupportedSRSListRetType m_apoSupportedCRSList{};
     147             : 
     148             :   public:
     149             :     OGRWFSLayer(OGRWFSDataSource *poDS, OGRSpatialReference *poSRS,
     150             :                 int bAxisOrderAlreadyInverted, const char *pszBaseURL,
     151             :                 const char *pszName, const char *pszNS, const char *pszNSVal);
     152             : 
     153             :     virtual ~OGRWFSLayer();
     154             : 
     155             :     OGRWFSLayer *Clone();
     156             : 
     157        1832 :     const char *GetName() override
     158             :     {
     159        1832 :         return pszName;
     160             :     }
     161             : 
     162             :     virtual void ResetReading() override;
     163             :     virtual OGRFeature *GetNextFeature() override;
     164             :     virtual OGRFeature *GetFeature(GIntBig nFID) override;
     165             : 
     166             :     virtual OGRFeatureDefn *GetLayerDefn() override;
     167             : 
     168             :     virtual int TestCapability(const char *) override;
     169             : 
     170             :     virtual void SetSpatialFilter(OGRGeometry *) override;
     171             : 
     172          12 :     virtual void SetSpatialFilter(int iGeomField, OGRGeometry *poGeom) override
     173             :     {
     174          12 :         OGRLayer::SetSpatialFilter(iGeomField, poGeom);
     175          12 :     }
     176             : 
     177             :     virtual OGRErr SetAttributeFilter(const char *) override;
     178             : 
     179             :     virtual GIntBig GetFeatureCount(int bForce = TRUE) override;
     180             : 
     181             :     void SetExtents(double dfMinX, double dfMinY, double dfMaxX, double dfMaxY);
     182             :     void SetWGS84Extents(double dfMinX, double dfMinY, double dfMaxX,
     183             :                          double dfMaxY);
     184             :     virtual OGRErr GetExtent(OGREnvelope *psExtent, int bForce = TRUE) override;
     185             : 
     186          15 :     virtual OGRErr GetExtent(int iGeomField, OGREnvelope *psExtent,
     187             :                              int bForce) override
     188             :     {
     189          15 :         return OGRLayer::GetExtent(iGeomField, psExtent, bForce);
     190             :     }
     191             : 
     192             :     virtual OGRErr ICreateFeature(OGRFeature *poFeature) override;
     193             :     virtual OGRErr ISetFeature(OGRFeature *poFeature) override;
     194             :     virtual OGRErr DeleteFeature(GIntBig nFID) override;
     195             : 
     196             :     virtual OGRErr StartTransaction() override;
     197             :     virtual OGRErr CommitTransaction() override;
     198             :     virtual OGRErr RollbackTransaction() override;
     199             : 
     200             :     virtual OGRErr SetIgnoredFields(CSLConstList papszFields) override;
     201             : 
     202         138 :     int HasLayerDefn()
     203             :     {
     204         138 :         return poFeatureDefn != nullptr;
     205             :     }
     206             : 
     207             :     OGRFeatureDefn *ParseSchema(const CPLXMLNode *psSchema);
     208             :     OGRFeatureDefn *BuildLayerDefn(OGRFeatureDefn *poSrcFDefn = nullptr);
     209             : 
     210             :     OGRErr DeleteFromFilter(const std::string &osOGCFilter);
     211             : 
     212           4 :     const std::vector<CPLString> &GetLastInsertedFIDList()
     213             :     {
     214           4 :         return aosFIDList;
     215             :     }
     216             : 
     217             :     const char *GetShortName();
     218             : 
     219             :     void SetRequiredOutputFormat(const char *pszRequiredOutputFormatIn);
     220             : 
     221         122 :     const char *GetRequiredOutputFormat()
     222             :     {
     223         122 :         return pszRequiredOutputFormat;
     224             :     }
     225             : 
     226             :     void SetOrderBy(const std::vector<OGRWFSSortDesc> &aoSortColumnsIn);
     227             : 
     228           0 :     bool HasGotApproximateLayerDefn()
     229             :     {
     230           0 :         GetLayerDefn();
     231           0 :         return bGotApproximateLayerDefn;
     232             :     }
     233             : 
     234         168 :     const char *GetNamespacePrefix()
     235             :     {
     236         168 :         return pszNS;
     237             :     }
     238             : 
     239         168 :     const char *GetNamespaceName()
     240             :     {
     241         168 :         return pszNSVal;
     242             :     }
     243             : 
     244         205 :     void SetSupportedSRSList(
     245             :         std::vector<std::string> &&aosSupportedCRSList,
     246             :         OGRLayer::GetSupportedSRSListRetType &&apoSupportedCRSList)
     247             :     {
     248         205 :         m_aosSupportedCRSList = std::move(aosSupportedCRSList);
     249         205 :         m_apoSupportedCRSList = std::move(apoSupportedCRSList);
     250         205 :     }
     251             : 
     252             :     const OGRLayer::GetSupportedSRSListRetType &
     253           1 :     GetSupportedSRSList(int /*iGeomField*/) override
     254             :     {
     255           1 :         return m_apoSupportedCRSList;
     256             :     }
     257             : 
     258             :     OGRErr SetActiveSRS(int iGeomField,
     259             :                         const OGRSpatialReference *poSRS) override;
     260             : };
     261             : 
     262             : /************************************************************************/
     263             : /*                          OGRWFSJoinLayer                             */
     264             : /************************************************************************/
     265             : 
     266             : class OGRWFSJoinLayer final : public OGRLayer
     267             : {
     268             :     OGRWFSDataSource *poDS;
     269             :     OGRFeatureDefn *poFeatureDefn;
     270             : 
     271             :     CPLString osGlobalFilter;
     272             :     CPLString osSortBy;
     273             :     int bDistinct;
     274             :     std::set<CPLString> aoSetMD5;
     275             : 
     276             :     std::vector<OGRWFSLayer *> apoLayers;
     277             : 
     278             :     GDALDataset *poBaseDS;
     279             :     OGRLayer *poBaseLayer;
     280             :     bool bReloadNeeded;
     281             :     bool bHasFetched;
     282             : 
     283             :     bool bPagingActive;
     284             :     int nPagingStartIndex;
     285             :     int nFeatureRead;
     286             :     int nFeatureCountRequested;
     287             : 
     288             :     std::vector<CPLString> aoSrcFieldNames;
     289             :     std::vector<CPLString> aoSrcGeomFieldNames;
     290             : 
     291             :     CPLString osFeatureTypes;
     292             : 
     293             :     OGRWFSJoinLayer(OGRWFSDataSource *poDS, const swq_select *psSelectInfo,
     294             :                     const CPLString &osGlobalFilter);
     295             :     CPLString MakeGetFeatureURL(int bRequestHits = FALSE);
     296             :     GDALDataset *FetchGetFeature();
     297             :     GIntBig ExecuteGetFeatureResultTypeHits();
     298             : 
     299             :   public:
     300             :     static OGRWFSJoinLayer *Build(OGRWFSDataSource *poDS,
     301             :                                   const swq_select *psSelectInfo);
     302             :     virtual ~OGRWFSJoinLayer();
     303             : 
     304             :     virtual void ResetReading() override;
     305             :     virtual OGRFeature *GetNextFeature() override;
     306             : 
     307             :     virtual OGRFeatureDefn *GetLayerDefn() override;
     308             : 
     309             :     virtual int TestCapability(const char *) override;
     310             : 
     311             :     virtual GIntBig GetFeatureCount(int bForce = TRUE) override;
     312             : 
     313             :     virtual void SetSpatialFilter(OGRGeometry *) override;
     314             : 
     315           0 :     virtual void SetSpatialFilter(int iGeomField, OGRGeometry *poGeom) override
     316             :     {
     317           0 :         OGRLayer::SetSpatialFilter(iGeomField, poGeom);
     318           0 :     }
     319             : 
     320             :     virtual OGRErr SetAttributeFilter(const char *) override;
     321             : };
     322             : 
     323             : /************************************************************************/
     324             : /*                           OGRWFSDataSource                           */
     325             : /************************************************************************/
     326             : 
     327             : class OGRWFSDataSource final : public OGRDataSource
     328             : {
     329             :     char *pszName;
     330             :     bool bRewriteFile;
     331             :     CPLXMLNode *psFileXML;
     332             : 
     333             :     OGRWFSLayer **papoLayers;
     334             :     int nLayers;
     335             :     std::map<OGRLayer *, OGRLayer *> oMap;
     336             : 
     337             :     bool bUpdate;
     338             : 
     339             :     bool bGetFeatureSupportHits;
     340             :     CPLString osVersion;
     341             :     bool bNeedNAMESPACE;
     342             :     bool bHasMinOperators;
     343             :     bool bHasNullCheck;
     344             :     bool bPropertyIsNotEqualToSupported;
     345             :     bool bUseFeatureId;
     346             :     bool bGmlObjectIdNeedsGMLPrefix;
     347             :     bool bRequiresEnvelopeSpatialFilter;
     348             :     static bool DetectRequiresEnvelopeSpatialFilter(const CPLXMLNode *psRoot);
     349             : 
     350             :     bool bTransactionSupport;
     351             :     char **papszIdGenMethods;
     352             :     bool DetectTransactionSupport(const CPLXMLNode *psRoot);
     353             : 
     354             :     CPLString osBaseURL;
     355             :     CPLString osPostTransactionURL;
     356             : 
     357             :     CPLXMLNode *LoadFromFile(const char *pszFilename);
     358             : 
     359             :     bool bUseHttp10;
     360             : 
     361             :     char **papszHttpOptions;
     362             : 
     363             :     bool bPagingAllowed;
     364             :     int nPageSize;
     365             :     int nBaseStartIndex;
     366             :     bool DetectSupportPagingWFS2(const CPLXMLNode *psGetCapabilitiesResponse,
     367             :                                  const CPLXMLNode *psConfigurationRoot);
     368             : 
     369             :     bool bStandardJoinsWFS2;
     370             :     bool DetectSupportStandardJoinsWFS2(const CPLXMLNode *psRoot);
     371             : 
     372             :     bool bLoadMultipleLayerDefn;
     373             :     std::set<CPLString> aoSetAlreadyTriedLayers;
     374             : 
     375             :     CPLString osLayerMetadataCSV;
     376             :     CPLString osLayerMetadataTmpFileName;
     377             :     OGRDataSource *poLayerMetadataDS;
     378             :     OGRLayer *poLayerMetadataLayer;
     379             : 
     380             :     CPLString osGetCapabilities;
     381             :     const char *apszGetCapabilities[2];
     382             :     GDALDataset *poLayerGetCapabilitiesDS;
     383             :     OGRLayer *poLayerGetCapabilitiesLayer;
     384             : 
     385             :     bool bKeepLayerNamePrefix;
     386             : 
     387             :     bool bEmptyAsNull;
     388             : 
     389             :     bool bInvertAxisOrderIfLatLong;
     390             :     CPLString osConsiderEPSGAsURN;
     391             :     bool bExposeGMLId;
     392             : 
     393             :     CPLHTTPResult *SendGetCapabilities(const char *pszBaseURL,
     394             :                                        CPLString &osTypeName);
     395             : 
     396             :     int GetLayerIndex(const char *pszName);
     397             : 
     398             :   public:
     399             :     OGRWFSDataSource();
     400             :     virtual ~OGRWFSDataSource();
     401             : 
     402             :     int Open(const char *pszFilename, int bUpdate, char **papszOpenOptions);
     403             : 
     404           0 :     virtual const char *GetName() override
     405             :     {
     406           0 :         return pszName;
     407             :     }
     408             : 
     409         126 :     virtual int GetLayerCount() override
     410             :     {
     411         126 :         return nLayers;
     412             :     }
     413             : 
     414             :     virtual OGRLayer *GetLayer(int) override;
     415             :     virtual OGRLayer *GetLayerByName(const char *pszLayerName) override;
     416             : 
     417             :     virtual int TestCapability(const char *) override;
     418             : 
     419             :     virtual OGRLayer *ExecuteSQL(const char *pszSQLCommand,
     420             :                                  OGRGeometry *poSpatialFilter,
     421             :                                  const char *pszDialect) override;
     422             :     virtual void ReleaseResultSet(OGRLayer *poResultsSet) override;
     423             : 
     424         128 :     bool UpdateMode() const
     425             :     {
     426         128 :         return bUpdate;
     427             :     }
     428             : 
     429         128 :     bool SupportTransactions() const
     430             :     {
     431         128 :         return bTransactionSupport;
     432             :     }
     433             : 
     434           1 :     void DisableSupportHits()
     435             :     {
     436           1 :         bGetFeatureSupportHits = false;
     437           1 :     }
     438             : 
     439          10 :     bool GetFeatureSupportHits() const
     440             :     {
     441          10 :         return bGetFeatureSupportHits;
     442             :     }
     443             : 
     444         934 :     const char *GetVersion()
     445             :     {
     446         934 :         return osVersion.c_str();
     447             :     }
     448             : 
     449             :     bool IsOldDeegree(const char *pszErrorString);
     450             : 
     451           6 :     bool GetNeedNAMESPACE() const
     452             :     {
     453           6 :         return bNeedNAMESPACE;
     454             :     }
     455             : 
     456          62 :     bool HasMinOperators() const
     457             :     {
     458          62 :         return bHasMinOperators;
     459             :     }
     460             : 
     461           2 :     bool HasNullCheck() const
     462             :     {
     463           2 :         return bHasNullCheck;
     464             :     }
     465             : 
     466          44 :     bool UseFeatureId() const
     467             :     {
     468          44 :         return bUseFeatureId;
     469             :     }
     470             : 
     471           5 :     bool RequiresEnvelopeSpatialFilter() const
     472             :     {
     473           5 :         return bRequiresEnvelopeSpatialFilter;
     474             :     }
     475             : 
     476           0 :     void SetGmlObjectIdNeedsGMLPrefix()
     477             :     {
     478           0 :         bGmlObjectIdNeedsGMLPrefix = true;
     479           0 :     }
     480             : 
     481          43 :     int DoesGmlObjectIdNeedGMLPrefix() const
     482             :     {
     483          43 :         return bGmlObjectIdNeedsGMLPrefix;
     484             :     }
     485             : 
     486           0 :     void SetPropertyIsNotEqualToUnSupported()
     487             :     {
     488           0 :         bPropertyIsNotEqualToSupported = false;
     489           0 :     }
     490             : 
     491          43 :     bool PropertyIsNotEqualToSupported() const
     492             :     {
     493          43 :         return bPropertyIsNotEqualToSupported;
     494             :     }
     495             : 
     496             :     CPLString GetPostTransactionURL();
     497             : 
     498             :     void SaveLayerSchema(const char *pszLayerName, const CPLXMLNode *psSchema);
     499             : 
     500             :     CPLHTTPResult *HTTPFetch(const char *pszURL, char **papszOptions);
     501             : 
     502         219 :     bool IsPagingAllowed() const
     503             :     {
     504         219 :         return bPagingAllowed;
     505             :     }
     506             : 
     507          90 :     int GetPageSize() const
     508             :     {
     509          90 :         return nPageSize;
     510             :     }
     511             : 
     512          88 :     int GetBaseStartIndex() const
     513             :     {
     514          88 :         return nBaseStartIndex;
     515             :     }
     516             : 
     517             :     void LoadMultipleLayerDefn(const char *pszLayerName, char *pszNS,
     518             :                                char *pszNSVal);
     519             : 
     520             :     bool GetKeepLayerNamePrefix() const
     521             :     {
     522             :         return bKeepLayerNamePrefix;
     523             :     }
     524             : 
     525          84 :     const CPLString &GetBaseURL()
     526             :     {
     527          84 :         return osBaseURL;
     528             :     }
     529             : 
     530         589 :     bool IsEmptyAsNull() const
     531             :     {
     532         589 :         return bEmptyAsNull;
     533             :     }
     534             : 
     535          89 :     bool InvertAxisOrderIfLatLong() const
     536             :     {
     537          89 :         return bInvertAxisOrderIfLatLong;
     538             :     }
     539             : 
     540          89 :     const CPLString &GetConsiderEPSGAsURN() const
     541             :     {
     542          89 :         return osConsiderEPSGAsURN;
     543             :     }
     544             : 
     545         227 :     bool ExposeGMLId() const
     546             :     {
     547         227 :         return bExposeGMLId;
     548             :     }
     549             : 
     550             :     virtual char **GetMetadataDomainList() override;
     551             :     virtual char **GetMetadata(const char *pszDomain = "") override;
     552             : };
     553             : 
     554             : #endif /* ndef OGR_WFS_H_INCLUDED */

Generated by: LCOV version 1.14