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