1 /******************************************************************************
2  * $Id: ogr_wfs.h 2818ff0a49f65741a55b9cea79df496cc05f85e3 2020-05-22 19:10:11 +0200 Even Rouault $
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 CPLXMLNode* WFSFindNode(CPLXMLNode* psXML, const char* pszRootName);
44 void OGRWFSRecursiveUnlink( const char *pszName );
45 CPLString WFS_TurnSQLFilterToOGCFilter( const swq_expr_node* poExpr,
46                                         OGRDataSource* poDS,
47                                         OGRFeatureDefn* poFDefn,
48                                         int nVersion,
49                                         int bPropertyIsNotEqualToSupported,
50                                         int bUseFeatureId,
51                                         int bGmlObjectIdNeedsGMLPrefix,
52                                         const char* pszNSPrefix,
53                                         int* pbOutNeedsNullCheck);
54 swq_custom_func_registrar* WFSGetCustomFuncRegistrar();
55 
56 const char* FindSubStringInsensitive(const char* pszStr,
57                                      const char* pszSubStr);
58 
59 CPLString WFS_EscapeURL(const char* pszURL);
60 CPLString WFS_DecodeURL(const CPLString &osSrc);
61 
62 class OGRWFSSortDesc
63 {
64     public:
65         CPLString osColumn;
66         bool      bAsc;
67 
OGRWFSSortDesc(const CPLString & osColumnIn,int bAscIn)68         OGRWFSSortDesc( const CPLString& osColumnIn, int bAscIn ) :
69             osColumn(osColumnIn),
70             bAsc(CPL_TO_BOOL(bAscIn)) {}
71 };
72 
73 /************************************************************************/
74 /*                             OGRWFSLayer                              */
75 /************************************************************************/
76 
77 class OGRWFSDataSource;
78 
79 class OGRWFSLayer final: public OGRLayer
80 {
81     OGRWFSDataSource*   poDS;
82 
83     OGRFeatureDefn*     poFeatureDefn;
84     bool                bGotApproximateLayerDefn;
85     GMLFeatureClass*    poGMLFeatureClass;
86 
87     int                 bAxisOrderAlreadyInverted;
88     OGRSpatialReference *poSRS;
89 
90     char*               pszBaseURL;
91     char*               pszName;
92     char*               pszNS;
93     char*               pszNSVal;
94 
95     bool                bStreamingDS;
96     GDALDataset        *poBaseDS;
97     OGRLayer           *poBaseLayer;
98     bool                bHasFetched;
99     bool                bReloadNeeded;
100 
101     CPLString           osGeometryColumnName;
102     OGRwkbGeometryType  eGeomType;
103     GIntBig             nFeatures;
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     double              dfMinX;
115     double              dfMinY;
116     double              dfMaxX;
117     double              dfMaxY;
118     bool                bHasExtents;
119 
120     OGRGeometry        *poFetchedFilterGeom;
121 
122     CPLString           osSQLWhere;
123     CPLString           osWFSWhere;
124 
125     CPLString           osTargetNamespace;
126     CPLString           GetDescribeFeatureTypeURL(int bWithNS);
127 
128     int                 nExpectedInserts;
129     CPLString           osGlobalInsert;
130     std::vector<CPLString> aosFIDList;
131 
132     bool                bInTransaction;
133 
134     CPLString           GetPostHeader();
135 
136     bool                bUseFeatureIdAtLayerLevel;
137 
138     bool                bPagingActive;
139     int                 nPagingStartIndex;
140     int                 nFeatureRead;
141     int                 nFeatureCountRequested;
142 
143     OGRFeatureDefn*     BuildLayerDefnFromFeatureClass(GMLFeatureClass* poClass);
144 
145     char                *pszRequiredOutputFormat;
146 
147     std::vector<OGRWFSSortDesc> aoSortColumns;
148 
149   public:
150                         OGRWFSLayer(OGRWFSDataSource* poDS,
151                                     OGRSpatialReference* poSRS,
152                                     int bAxisOrderAlreadyInverted,
153                                     const char* pszBaseURL,
154                                     const char* pszName,
155                                     const char* pszNS,
156                                     const char* pszNSVal);
157 
158                         virtual ~OGRWFSLayer();
159 
160     OGRWFSLayer*                Clone();
161 
GetName()162     const char                 *GetName() override { return pszName; }
163 
164     virtual void                ResetReading() override;
165     virtual OGRFeature*         GetNextFeature() override;
166     virtual OGRFeature*         GetFeature(GIntBig nFID) override;
167 
168     virtual OGRFeatureDefn *    GetLayerDefn() override;
169 
170     virtual int                 TestCapability( const char * ) override;
171 
172     virtual void        SetSpatialFilter( OGRGeometry * ) override;
SetSpatialFilter(int iGeomField,OGRGeometry * poGeom)173     virtual void        SetSpatialFilter( int iGeomField, OGRGeometry *poGeom ) override
174                 { OGRLayer::SetSpatialFilter(iGeomField, poGeom); }
175 
176     virtual OGRErr      SetAttributeFilter( const char * ) override;
177 
178     virtual GIntBig     GetFeatureCount( int bForce = TRUE ) override;
179 
180     void                SetExtents(double dfMinX, double dfMinY, double dfMaxX, double dfMaxY);
181     virtual OGRErr      GetExtent(OGREnvelope *psExtent, int bForce = TRUE) override;
GetExtent(int iGeomField,OGREnvelope * psExtent,int bForce)182     virtual OGRErr      GetExtent(int iGeomField, OGREnvelope *psExtent, int bForce) override
183                 { return OGRLayer::GetExtent(iGeomField, psExtent, bForce); }
184 
185     virtual OGRErr      ICreateFeature( OGRFeature *poFeature ) override;
186     virtual OGRErr      ISetFeature( OGRFeature *poFeature ) override;
187     virtual OGRErr      DeleteFeature( GIntBig nFID ) override;
188 
189     virtual OGRErr      StartTransaction() override;
190     virtual OGRErr      CommitTransaction() override;
191     virtual OGRErr      RollbackTransaction() override;
192 
193     virtual OGRErr      SetIgnoredFields( const char **papszFields ) override;
194 
HasLayerDefn()195     int                 HasLayerDefn() { return poFeatureDefn != nullptr; }
196 
197     OGRFeatureDefn*     ParseSchema(CPLXMLNode* psSchema);
198     OGRFeatureDefn*     BuildLayerDefn(OGRFeatureDefn* poSrcFDefn = nullptr);
199 
200     OGRErr              DeleteFromFilter( CPLString osOGCFilter );
201 
GetLastInsertedFIDList()202     const std::vector<CPLString>& GetLastInsertedFIDList() { return aosFIDList; }
203 
204     const char         *GetShortName();
205 
206     void                SetRequiredOutputFormat(const char* pszRequiredOutputFormatIn);
207 
GetRequiredOutputFormat()208     const char         *GetRequiredOutputFormat() { return pszRequiredOutputFormat; }
209 
210     void                SetOrderBy(const std::vector<OGRWFSSortDesc>& aoSortColumnsIn);
HasGotApproximateLayerDefn()211     bool                HasGotApproximateLayerDefn() { GetLayerDefn(); return bGotApproximateLayerDefn; }
212 
GetNamespacePrefix()213     const char*         GetNamespacePrefix() { return pszNS; }
GetNamespaceName()214     const char*         GetNamespaceName() { return pszNSVal; }
215 };
216 
217 /************************************************************************/
218 /*                          OGRWFSJoinLayer                             */
219 /************************************************************************/
220 
221 class OGRWFSJoinLayer final: public OGRLayer
222 {
223     OGRWFSDataSource   *poDS;
224     OGRFeatureDefn     *poFeatureDefn;
225 
226     CPLString           osGlobalFilter;
227     CPLString           osSortBy;
228     int                 bDistinct;
229     std::set<CPLString> aoSetMD5;
230 
231     std::vector<OGRWFSLayer*> apoLayers;
232 
233     GDALDataset        *poBaseDS;
234     OGRLayer           *poBaseLayer;
235     bool                bReloadNeeded;
236     bool                bHasFetched;
237 
238     bool                bPagingActive;
239     int                 nPagingStartIndex;
240     int                 nFeatureRead;
241     int                 nFeatureCountRequested;
242 
243     std::vector<CPLString> aoSrcFieldNames;
244     std::vector<CPLString> aoSrcGeomFieldNames;
245 
246     CPLString           osFeatureTypes;
247 
248                         OGRWFSJoinLayer(OGRWFSDataSource* poDS,
249                                         const swq_select* psSelectInfo,
250                                         const CPLString& osGlobalFilter);
251     CPLString           MakeGetFeatureURL(int bRequestHits = FALSE);
252     GDALDataset*        FetchGetFeature();
253     GIntBig             ExecuteGetFeatureResultTypeHits();
254 
255     public:
256 
257     static OGRWFSJoinLayer* Build(OGRWFSDataSource* poDS,
258                                   const swq_select* psSelectInfo);
259                        virtual ~OGRWFSJoinLayer();
260 
261     virtual void                ResetReading() override;
262     virtual OGRFeature*         GetNextFeature() override;
263 
264     virtual OGRFeatureDefn *    GetLayerDefn() override;
265 
266     virtual int                 TestCapability( const char * ) override;
267 
268     virtual GIntBig             GetFeatureCount( int bForce = TRUE ) override;
269 
270     virtual void        SetSpatialFilter( OGRGeometry * ) override;
SetSpatialFilter(int iGeomField,OGRGeometry * poGeom)271     virtual void        SetSpatialFilter( int iGeomField, OGRGeometry *poGeom ) override
272                 { OGRLayer::SetSpatialFilter(iGeomField, poGeom); }
273 
274     virtual OGRErr      SetAttributeFilter( const char * ) override;
275 };
276 
277 /************************************************************************/
278 /*                           OGRWFSDataSource                           */
279 /************************************************************************/
280 
281 class OGRWFSDataSource final: public OGRDataSource
282 {
283     char*               pszName;
284     bool                bRewriteFile;
285     CPLXMLNode*         psFileXML;
286 
287     OGRWFSLayer**       papoLayers;
288     int                 nLayers;
289     std::map<OGRLayer*, OGRLayer*> oMap;
290 
291     bool                bUpdate;
292 
293     bool                bGetFeatureSupportHits;
294     CPLString           osVersion;
295     bool                bNeedNAMESPACE;
296     bool                bHasMinOperators;
297     bool                bHasNullCheck;
298     bool                bPropertyIsNotEqualToSupported;
299     bool                bUseFeatureId;
300     bool                bGmlObjectIdNeedsGMLPrefix;
301     bool                bRequiresEnvelopeSpatialFilter;
302     static bool                DetectRequiresEnvelopeSpatialFilter( CPLXMLNode* psRoot );
303 
304     bool                bTransactionSupport;
305     char**              papszIdGenMethods;
306     bool                DetectTransactionSupport( CPLXMLNode* psRoot );
307 
308     CPLString           osBaseURL;
309     CPLString           osPostTransactionURL;
310 
311     CPLXMLNode*         LoadFromFile( const char * pszFilename );
312 
313     bool                bUseHttp10;
314 
315     char**              papszHttpOptions;
316 
317     bool                bPagingAllowed;
318     int                 nPageSize;
319     int                 nBaseStartIndex;
320     bool                DetectSupportPagingWFS2(CPLXMLNode* psRoot);
321 
322     bool                bStandardJoinsWFS2;
323     bool                DetectSupportStandardJoinsWFS2( CPLXMLNode* psRoot );
324 
325     bool                bLoadMultipleLayerDefn;
326     std::set<CPLString> aoSetAlreadyTriedLayers;
327 
328     CPLString           osLayerMetadataCSV;
329     CPLString           osLayerMetadataTmpFileName;
330     OGRDataSource      *poLayerMetadataDS;
331     OGRLayer           *poLayerMetadataLayer;
332 
333     CPLString           osGetCapabilities;
334     const char         *apszGetCapabilities[2];
335     GDALDataset        *poLayerGetCapabilitiesDS;
336     OGRLayer           *poLayerGetCapabilitiesLayer;
337 
338     bool                bKeepLayerNamePrefix;
339 
340     bool                bEmptyAsNull;
341 
342     bool                bInvertAxisOrderIfLatLong;
343     CPLString           osConsiderEPSGAsURN;
344     bool                bExposeGMLId;
345 
346     CPLHTTPResult*      SendGetCapabilities(const char* pszBaseURL,
347                                             CPLString& osTypeName);
348 
349     int                 GetLayerIndex(const char* pszName);
350 
351   public:
352                         OGRWFSDataSource();
353                         virtual ~OGRWFSDataSource();
354 
355     int                 Open( const char * pszFilename,
356                               int bUpdate,
357                               char** papszOpenOptions );
358 
GetName()359     virtual const char*         GetName() override { return pszName; }
360 
GetLayerCount()361     virtual int                 GetLayerCount() override { return nLayers; }
362     virtual OGRLayer*           GetLayer( int ) override;
363     virtual OGRLayer*           GetLayerByName(const char* pszLayerName) override;
364 
365     virtual int                 TestCapability( const char * ) override;
366 
367     virtual OGRLayer *          ExecuteSQL( const char *pszSQLCommand,
368                                         OGRGeometry *poSpatialFilter,
369                                         const char *pszDialect ) override;
370     virtual void                ReleaseResultSet( OGRLayer * poResultsSet ) override;
371 
UpdateMode()372     bool                        UpdateMode() const { return bUpdate; }
SupportTransactions()373     bool                        SupportTransactions() const
374         { return bTransactionSupport; }
DisableSupportHits()375     void                        DisableSupportHits() { bGetFeatureSupportHits = false; }
GetFeatureSupportHits()376     bool                        GetFeatureSupportHits() const
377         { return bGetFeatureSupportHits; }
GetVersion()378     const char                 *GetVersion() { return osVersion.c_str(); }
379 
380     bool                        IsOldDeegree( const char* pszErrorString );
GetNeedNAMESPACE()381     bool                        GetNeedNAMESPACE() const { return bNeedNAMESPACE; }
HasMinOperators()382     bool                        HasMinOperators() const { return bHasMinOperators; }
HasNullCheck()383     bool                        HasNullCheck() const { return bHasNullCheck; }
UseFeatureId()384     bool                        UseFeatureId() const { return bUseFeatureId; }
RequiresEnvelopeSpatialFilter()385     bool                        RequiresEnvelopeSpatialFilter() const
386         { return bRequiresEnvelopeSpatialFilter; }
SetGmlObjectIdNeedsGMLPrefix()387     void                        SetGmlObjectIdNeedsGMLPrefix() { bGmlObjectIdNeedsGMLPrefix = true; }
DoesGmlObjectIdNeedGMLPrefix()388     int                         DoesGmlObjectIdNeedGMLPrefix() const
389         { return bGmlObjectIdNeedsGMLPrefix; }
390 
SetPropertyIsNotEqualToUnSupported()391     void                        SetPropertyIsNotEqualToUnSupported() { bPropertyIsNotEqualToSupported = false; }
PropertyIsNotEqualToSupported()392     bool                        PropertyIsNotEqualToSupported() const
393         { return bPropertyIsNotEqualToSupported; }
394 
395     CPLString                   GetPostTransactionURL();
396 
397     void                        SaveLayerSchema(const char* pszLayerName, CPLXMLNode* psSchema);
398 
399     CPLHTTPResult*              HTTPFetch( const char* pszURL, char** papszOptions );
400 
IsPagingAllowed()401     bool                        IsPagingAllowed() const { return bPagingAllowed; }
GetPageSize()402     int                         GetPageSize() const { return nPageSize; }
GetBaseStartIndex()403     int                         GetBaseStartIndex() const { return nBaseStartIndex; }
404 
405     void                        LoadMultipleLayerDefn(const char* pszLayerName,
406                                                       char* pszNS, char* pszNSVal);
407 
GetKeepLayerNamePrefix()408     bool                        GetKeepLayerNamePrefix() const
409         { return bKeepLayerNamePrefix; }
GetBaseURL()410     const CPLString&            GetBaseURL() { return osBaseURL; }
411 
IsEmptyAsNull()412     bool                        IsEmptyAsNull() const
413         { return bEmptyAsNull; }
InvertAxisOrderIfLatLong()414     bool                        InvertAxisOrderIfLatLong() const
415         { return bInvertAxisOrderIfLatLong; }
GetConsiderEPSGAsURN()416     const CPLString&            GetConsiderEPSGAsURN() const { return osConsiderEPSGAsURN; }
417 
ExposeGMLId()418     bool                        ExposeGMLId() const { return bExposeGMLId; }
419 
420     virtual char**              GetMetadataDomainList() override;
421     virtual char**              GetMetadata( const char * pszDomain = "" ) override;
422 };
423 
424 #endif /* ndef OGR_WFS_H_INCLUDED */
425