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