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