1 /******************************************************************************* 2 * Project: NextGIS Web Driver 3 * Purpose: Implements NextGIS Web Driver 4 * Author: Dmitry Baryshnikov, dmitry.baryshnikov@nextgis.com 5 * Language: C++ 6 ******************************************************************************* 7 * The MIT License (MIT) 8 * 9 * Copyright (c) 2018-2020, NextGIS 10 * 11 * Permission is hereby granted, free of charge, to any person obtaining a copy 12 * of this software and associated documentation files (the "Software"), to deal 13 * in the Software without restriction, including without limitation the rights 14 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 15 * copies of the Software, and to permit persons to whom the Software is 16 * furnished to do so, subject to the following conditions: 17 * 18 * The above copyright notice and this permission notice shall be included in all 19 * copies or substantial portions of the Software. 20 * 21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 26 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 27 * SOFTWARE. 28 *******************************************************************************/ 29 #ifndef OGR_NGW_H_INCLUDED 30 #define OGR_NGW_H_INCLUDED 31 32 // gdal headers 33 #include "ogrsf_frmts.h" 34 #include "ogr_swq.h" 35 36 #include <map> 37 #include <set> 38 39 namespace NGWAPI { 40 std::string GetPermissions(const std::string &osUrl, const std::string &osResourceId); 41 std::string GetResource(const std::string &osUrl, const std::string &osResourceId); 42 std::string GetChildren(const std::string &osUrl, const std::string &osResourceId); 43 std::string GetFeature(const std::string &osUrl, const std::string &osResourceId); 44 std::string GetTMS(const std::string &osUrl, const std::string &osResourceId); 45 std::string GetFeaturePage(const std::string &osUrl, const std::string &osResourceId, 46 GIntBig nStart, int nCount = 0, const std::string &osFields = "", 47 const std::string &osWhere = "", const std::string &osSpatialWhere = "", 48 const std::string &osExtensions = "", bool IsGeometryIgnored = false); 49 std::string GetRoute(const std::string &osUrl); 50 std::string GetUpload(const std::string &osUrl); 51 std::string GetVersion(const std::string &osUrl); 52 bool CheckVersion(const std::string &osVersion, int nMajor, int nMinor = 0, 53 int nPatch = 0); 54 55 struct Uri { 56 std::string osPrefix; 57 std::string osAddress; 58 std::string osResourceId; 59 std::string osNewResourceName; 60 }; 61 62 // C++11 allow defaults 63 struct Permissions { 64 bool bResourceCanRead = false; 65 bool bResourceCanCreate = false; 66 bool bResourceCanUpdate = false; 67 bool bResourceCanDelete = false; 68 bool bDatastructCanRead = false; 69 bool bDatastructCanWrite = false; 70 bool bDataCanRead = false; 71 bool bDataCanWrite = false; 72 bool bMetadataCanRead = false; 73 bool bMetadataCanWrite = false; 74 }; 75 76 Uri ParseUri(const std::string &osUrl); 77 Permissions CheckPermissions(const std::string &osUrl, 78 const std::string &osResourceId, char **papszHTTPOptions, bool bReadWrite); 79 bool DeleteResource(const std::string &osUrl, const std::string &osResourceId, 80 char **papszHTTPOptions); 81 bool RenameResource(const std::string &osUrl, const std::string &osResourceId, 82 const std::string &osNewName, char **papszHTTPOptions); 83 OGRwkbGeometryType NGWGeomTypeToOGRGeomType(const std::string &osGeomType); 84 std::string OGRGeomTypeToNGWGeomType(OGRwkbGeometryType eType); 85 OGRFieldType NGWFieldTypeToOGRFieldType(const std::string &osFieldType); 86 std::string OGRFieldTypeToNGWFieldType(OGRFieldType eType); 87 std::string GetFeatureCount(const std::string &osUrl, 88 const std::string &osResourceId); 89 std::string GetLayerExtent(const std::string &osUrl, 90 const std::string &osResourceId); 91 bool FlushMetadata(const std::string &osUrl, const std::string &osResourceId, 92 char **papszMetadata, char **papszHTTPOptions ); 93 std::string CreateResource(const std::string &osUrl, const std::string &osPayload, 94 char **papszHTTPOptions); 95 bool UpdateResource(const std::string &osUrl, const std::string &osResourceId, 96 const std::string &osPayload, char **papszHTTPOptions); 97 void FillResmeta(CPLJSONObject &oRoot, char **papszMetadata); 98 std::string GetResmetaSuffix(CPLJSONObject::Type eType); 99 bool DeleteFeature(const std::string &osUrl, const std::string &osResourceId, 100 const std::string &osFeatureId, char **papszHTTPOptions); 101 GIntBig CreateFeature(const std::string &osUrl, const std::string &osResourceId, 102 const std::string &osFeatureJson, char **papszHTTPOptions); 103 bool UpdateFeature(const std::string &osUrl, const std::string &osResourceId, 104 const std::string &osFeatureId, const std::string &osFeatureJson, 105 char **papszHTTPOptions); 106 std::vector<GIntBig> PatchFeatures(const std::string &osUrl, const std::string &osResourceId, 107 const std::string &osFeaturesJson, char **papszHTTPOptions); 108 bool GetExtent(const std::string &osUrl, const std::string &osResourceId, 109 char **papszHTTPOptions, int nEPSG, OGREnvelope &stExtent); 110 CPLJSONObject UploadFile(const std::string &osUrl, const std::string &osFilePath, 111 char **papszHTTPOptions, GDALProgressFunc pfnProgress, void *pProgressData); 112 } // namespace NGWAPI 113 114 class OGRNGWDataset; 115 116 class OGRNGWLayer final: public OGRLayer 117 { 118 std::string osResourceId; 119 OGRNGWDataset *poDS; 120 NGWAPI::Permissions stPermissions; 121 bool bFetchedPermissions; 122 OGRFeatureDefn *poFeatureDefn; 123 GIntBig nFeatureCount; 124 OGREnvelope stExtent; 125 std::map<GIntBig, OGRFeature*> moFeatures; 126 std::map<GIntBig, OGRFeature*>::const_iterator oNextPos; 127 GIntBig nPageStart; 128 bool bNeedSyncData, bNeedSyncStructure; 129 std::set<GIntBig> soChangedIds; 130 std::string osFields; 131 std::string osWhere; 132 std::string osSpatialFilter; 133 bool bClientSideAttributeFilter; 134 135 explicit OGRNGWLayer( const std::string &osResourceIdIn, OGRNGWDataset *poDSIn, 136 const NGWAPI::Permissions &stPermissionsIn, OGRFeatureDefn *poFeatureDefnIn, 137 GIntBig nFeatureCountIn, const OGREnvelope &stExtentIn ); 138 139 public: 140 explicit OGRNGWLayer( OGRNGWDataset *poDSIn, const CPLJSONObject &oResourceJsonObject ); 141 explicit OGRNGWLayer( OGRNGWDataset *poDSIn, const std::string &osNameIn, 142 OGRSpatialReference *poSpatialRef, OGRwkbGeometryType eGType, 143 const std::string &osKeyIn, const std::string &osDescIn ); 144 virtual ~OGRNGWLayer(); 145 146 bool Delete(); 147 bool Rename( const std::string &osNewName ); 148 std::string GetResourceId() const; 149 150 /* OGRLayer */ 151 virtual void ResetReading() override; 152 virtual OGRFeature *GetNextFeature() override; 153 virtual OGRErr SetNextByIndex( GIntBig nIndex ) override; 154 virtual OGRFeature *GetFeature( GIntBig nFID ) override; 155 virtual GIntBig GetFeatureCount( int bForce = TRUE ) override; 156 virtual OGRErr GetExtent(OGREnvelope *psExtent, int bForce = TRUE) override; 157 virtual OGRErr GetExtent(int iGeomField, OGREnvelope *psExtent, 158 int bForce = TRUE) override; 159 virtual OGRFeatureDefn *GetLayerDefn() override; 160 virtual int TestCapability( const char * ) override; 161 162 virtual OGRErr CreateField( OGRFieldDefn *poField, 163 int bApproxOK = TRUE ) override; 164 virtual OGRErr DeleteField( int iField ) override; 165 virtual OGRErr ReorderFields( int *panMap ) override; 166 virtual OGRErr AlterFieldDefn( int iField, OGRFieldDefn *poNewFieldDefn, 167 int nFlagsIn ) override; 168 169 virtual OGRErr SyncToDisk() override; 170 171 virtual OGRErr DeleteFeature(GIntBig nFID) override; 172 bool DeleteAllFeatures(); 173 174 virtual CPLErr SetMetadata( char **papszMetadata, 175 const char *pszDomain = "" ) override; 176 virtual CPLErr SetMetadataItem( const char *pszName, const char *pszValue, 177 const char *pszDomain = "" ) override; 178 179 virtual OGRErr SetIgnoredFields( const char **papszFields ) override; 180 virtual OGRErr SetAttributeFilter( const char *pszQuery ) override; 181 virtual void SetSpatialFilter( OGRGeometry *poGeom ) override; 182 virtual void SetSpatialFilter( int iGeomField, OGRGeometry *poGeom ) override; 183 184 OGRErr SetSelectedFields(const std::set<std::string> &aosFields); 185 OGRNGWLayer *Clone() const; 186 187 public: 188 static std::string TranslateSQLToFilter( swq_expr_node *poNode ); 189 190 protected: 191 virtual OGRErr ISetFeature(OGRFeature *poFeature) override; 192 virtual OGRErr ICreateFeature(OGRFeature *poFeature) override; 193 194 private: 195 void FillMetadata( const CPLJSONObject &oRootObject ); 196 void FillFields( const CPLJSONArray &oFields ); 197 void FetchPermissions(); 198 void FreeFeaturesCache( bool bForce = false ); 199 std::string CreateNGWResourceJson(); 200 OGRErr SyncFeatures(); 201 GIntBig GetMaxFeatureCount( bool bForce ); 202 bool FillFeatures(const std::string &osUrl); 203 GIntBig GetNewFeaturesCount() const; 204 }; 205 206 class OGRNGWDataset final : public GDALDataset 207 { 208 friend class OGRNGWLayer; 209 int nBatchSize; 210 int nPageSize; 211 NGWAPI::Permissions stPermissions; 212 bool bFetchedPermissions; 213 bool bHasFeaturePaging; 214 std::string osUserPwd; 215 std::string osUrl; 216 std::string osResourceId; 217 std::string osName; 218 bool bExtInNativeData; 219 bool bMetadataDerty; 220 221 // vector 222 OGRNGWLayer **papoLayers; 223 int nLayers; 224 225 // raster 226 GDALDataset *poRasterDS; 227 OGREnvelope stPixelExtent; 228 int nRasters; 229 int nCacheExpires, nCacheMaxSize; 230 231 // json 232 std::string osJsonDepth; 233 std::string osExtensions; 234 235 public: 236 OGRNGWDataset(); 237 virtual ~OGRNGWDataset(); 238 239 bool Open( const char *pszFilename, char **papszOpenOptionsIn, 240 bool bUpdateIn, int nOpenFlagsIn ); 241 bool Open( const std::string &osUrlIn, const std::string &osResourceIdIn, 242 char **papszOpenOptionsIn, bool bUpdateIn, int nOpenFlagsIn ); 243 std::string Extensions() const; 244 245 /* GDALDataset */ GetLayerCount()246 virtual int GetLayerCount() override { return nLayers; } 247 virtual OGRLayer *GetLayer( int ) override; 248 virtual int TestCapability( const char * ) override; 249 virtual OGRLayer *ICreateLayer( const char *pszName, 250 OGRSpatialReference *poSpatialRef = nullptr, 251 OGRwkbGeometryType eGType = wkbUnknown, 252 char **papszOptions = nullptr ) override; 253 virtual OGRErr DeleteLayer( int ) override; 254 virtual CPLErr SetMetadata( char **papszMetadata, 255 const char *pszDomain = "" ) override; 256 virtual CPLErr SetMetadataItem( const char *pszName, const char *pszValue, 257 const char *pszDomain = "" ) override; 258 virtual void FlushCache() override; 259 virtual OGRLayer *ExecuteSQL( const char *pszStatement, 260 OGRGeometry *poSpatialFilter, const char *pszDialect ) override; 261 262 virtual const OGRSpatialReference *GetSpatialRef() const override; 263 virtual CPLErr GetGeoTransform( double *padfTransform ) override; 264 virtual CPLErr IRasterIO( GDALRWFlag eRWFlag, int nXOff, int nYOff, 265 int nXSize, int nYSize, void *pData, int nBufXSize, int nBufYSize, 266 GDALDataType eBufType, int nBandCount, int *panBandMap, 267 GSpacing nPixelSpace, GSpacing nLineSpace, GSpacing nBandSpace, 268 GDALRasterIOExtraArg* psExtraArg ) override; 269 270 private: 271 char **GetHeaders() const; GetUrl()272 std::string GetUrl() const { return osUrl; } GetResourceId()273 std::string GetResourceId() const { return osResourceId; } 274 void FillMetadata( const CPLJSONObject &oRootObject ); 275 bool FillResources( char **papszOptions, int nOpenFlagsIn ); 276 void AddLayer( const CPLJSONObject &oResourceJsonObject, char **papszOptions, 277 int nOpenFlagsIn ); 278 void AddRaster( const CPLJSONObject &oResourceJsonObject, char **papszOptions ); 279 bool Init(int nOpenFlagsIn); 280 bool FlushMetadata( char **papszMetadata ); IsUpdateMode()281 inline bool IsUpdateMode() const { return eAccess == GA_Update; } IsBatchMode()282 bool IsBatchMode() const { return nBatchSize >= 0; } HasFeaturePaging()283 bool HasFeaturePaging() const { return bHasFeaturePaging; } GetPageSize()284 int GetPageSize() const { return bHasFeaturePaging ? nPageSize : -1; } GetBatchSize()285 int GetBatchSize() const { return nBatchSize; } IsExtInNativeData()286 bool IsExtInNativeData() const { return bExtInNativeData; } 287 void FetchPermissions(); 288 void FillCapabilities( char **papszOptions ); 289 private: 290 CPL_DISALLOW_COPY_ASSIGN(OGRNGWDataset) 291 }; 292 293 #endif // OGR_NGW_H_INCLUDED 294