Line data Source code
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 : * SPDX-License-Identifier: MIT
12 : *******************************************************************************/
13 : #ifndef OGR_NGW_H_INCLUDED
14 : #define OGR_NGW_H_INCLUDED
15 :
16 : // gdal headers
17 : #include "ogrsf_frmts.h"
18 : #include "ogr_swq.h"
19 :
20 : #include <map>
21 : #include <set>
22 :
23 : namespace NGWAPI
24 : {
25 : std::string GetPermissions(const std::string &osUrl,
26 : const std::string &osResourceId);
27 : std::string GetResource(const std::string &osUrl,
28 : const std::string &osResourceId);
29 : std::string GetChildren(const std::string &osUrl,
30 : const std::string &osResourceId);
31 : std::string GetFeature(const std::string &osUrl,
32 : const std::string &osResourceId);
33 : std::string GetTMS(const std::string &osUrl, const std::string &osResourceId);
34 : std::string GetFeaturePage(const std::string &osUrl,
35 : const std::string &osResourceId, GIntBig nStart,
36 : int nCount = 0, const std::string &osFields = "",
37 : const std::string &osWhere = "",
38 : const std::string &osSpatialWhere = "",
39 : const std::string &osExtensions = "",
40 : bool IsGeometryIgnored = false);
41 : std::string GetRoute(const std::string &osUrl);
42 : std::string GetUpload(const std::string &osUrl);
43 : std::string GetVersion(const std::string &osUrl);
44 : bool CheckVersion(const std::string &osVersion, int nMajor, int nMinor = 0,
45 : int nPatch = 0);
46 :
47 : struct Uri
48 : {
49 : std::string osPrefix;
50 : std::string osAddress;
51 : std::string osResourceId;
52 : std::string osNewResourceName;
53 : };
54 :
55 : // C++11 allow defaults
56 : struct Permissions
57 : {
58 : bool bResourceCanRead = false;
59 : bool bResourceCanCreate = false;
60 : bool bResourceCanUpdate = false;
61 : bool bResourceCanDelete = false;
62 : bool bDatastructCanRead = false;
63 : bool bDatastructCanWrite = false;
64 : bool bDataCanRead = false;
65 : bool bDataCanWrite = false;
66 : bool bMetadataCanRead = false;
67 : bool bMetadataCanWrite = false;
68 : };
69 :
70 : Uri ParseUri(const std::string &osUrl);
71 : Permissions CheckPermissions(const std::string &osUrl,
72 : const std::string &osResourceId,
73 : char **papszHTTPOptions, bool bReadWrite);
74 : bool DeleteResource(const std::string &osUrl, const std::string &osResourceId,
75 : char **papszHTTPOptions);
76 : bool RenameResource(const std::string &osUrl, const std::string &osResourceId,
77 : const std::string &osNewName, char **papszHTTPOptions);
78 : OGRwkbGeometryType NGWGeomTypeToOGRGeomType(const std::string &osGeomType);
79 : std::string OGRGeomTypeToNGWGeomType(OGRwkbGeometryType eType);
80 : OGRFieldType NGWFieldTypeToOGRFieldType(const std::string &osFieldType);
81 : std::string OGRFieldTypeToNGWFieldType(OGRFieldType eType);
82 : std::string GetFeatureCount(const std::string &osUrl,
83 : const std::string &osResourceId);
84 : std::string GetLayerExtent(const std::string &osUrl,
85 : const std::string &osResourceId);
86 : bool FlushMetadata(const std::string &osUrl, const std::string &osResourceId,
87 : char **papszMetadata, char **papszHTTPOptions);
88 : std::string CreateResource(const std::string &osUrl,
89 : const std::string &osPayload,
90 : char **papszHTTPOptions);
91 : bool UpdateResource(const std::string &osUrl, const std::string &osResourceId,
92 : const std::string &osPayload, char **papszHTTPOptions);
93 : void FillResmeta(const CPLJSONObject &oRoot, char **papszMetadata);
94 : std::string GetResmetaSuffix(CPLJSONObject::Type eType);
95 : bool DeleteFeature(const std::string &osUrl, const std::string &osResourceId,
96 : const std::string &osFeatureId, char **papszHTTPOptions);
97 : GIntBig CreateFeature(const std::string &osUrl, const std::string &osResourceId,
98 : const std::string &osFeatureJson,
99 : char **papszHTTPOptions);
100 : bool UpdateFeature(const std::string &osUrl, const std::string &osResourceId,
101 : const std::string &osFeatureId,
102 : const std::string &osFeatureJson, char **papszHTTPOptions);
103 : std::vector<GIntBig> PatchFeatures(const std::string &osUrl,
104 : const std::string &osResourceId,
105 : const std::string &osFeaturesJson,
106 : char **papszHTTPOptions);
107 : bool GetExtent(const std::string &osUrl, const std::string &osResourceId,
108 : char **papszHTTPOptions, int nEPSG, OGREnvelope &stExtent);
109 : CPLJSONObject UploadFile(const std::string &osUrl,
110 : const std::string &osFilePath, char **papszHTTPOptions,
111 : 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,
136 : OGRNGWDataset *poDSIn,
137 : const NGWAPI::Permissions &stPermissionsIn,
138 : OGRFeatureDefn *poFeatureDefnIn,
139 : GIntBig nFeatureCountIn,
140 : const OGREnvelope &stExtentIn);
141 :
142 : public:
143 : explicit OGRNGWLayer(OGRNGWDataset *poDSIn,
144 : const CPLJSONObject &oResourceJsonObject);
145 : explicit OGRNGWLayer(OGRNGWDataset *poDSIn, const std::string &osNameIn,
146 : OGRSpatialReference *poSpatialRef,
147 : OGRwkbGeometryType eGType, const std::string &osKeyIn,
148 : const std::string &osDescIn);
149 : virtual ~OGRNGWLayer();
150 :
151 : bool Delete();
152 : virtual OGRErr Rename(const char *pszNewName) override;
153 : std::string GetResourceId() const;
154 :
155 : /* OGRLayer */
156 : virtual void ResetReading() override;
157 : virtual OGRFeature *GetNextFeature() override;
158 : virtual OGRErr SetNextByIndex(GIntBig nIndex) override;
159 : virtual OGRFeature *GetFeature(GIntBig nFID) override;
160 : virtual GIntBig GetFeatureCount(int bForce = TRUE) override;
161 : virtual OGRErr GetExtent(OGREnvelope *psExtent, int bForce = TRUE) override;
162 : virtual OGRErr GetExtent(int iGeomField, OGREnvelope *psExtent,
163 : int bForce = TRUE) override;
164 : virtual OGRFeatureDefn *GetLayerDefn() override;
165 : virtual int TestCapability(const char *) override;
166 :
167 : virtual OGRErr CreateField(const OGRFieldDefn *poField,
168 : int bApproxOK = TRUE) override;
169 : virtual OGRErr DeleteField(int iField) override;
170 : virtual OGRErr ReorderFields(int *panMap) override;
171 : virtual OGRErr AlterFieldDefn(int iField, OGRFieldDefn *poNewFieldDefn,
172 : int nFlagsIn) override;
173 :
174 : virtual OGRErr SyncToDisk() override;
175 :
176 : virtual OGRErr DeleteFeature(GIntBig nFID) override;
177 : bool DeleteAllFeatures();
178 :
179 : virtual CPLErr SetMetadata(char **papszMetadata,
180 : const char *pszDomain = "") override;
181 : virtual CPLErr SetMetadataItem(const char *pszName, const char *pszValue,
182 : const char *pszDomain = "") override;
183 :
184 : virtual OGRErr SetIgnoredFields(CSLConstList papszFields) override;
185 : virtual OGRErr SetAttributeFilter(const char *pszQuery) override;
186 : virtual void SetSpatialFilter(OGRGeometry *poGeom) override;
187 : virtual void SetSpatialFilter(int iGeomField, OGRGeometry *poGeom) override;
188 :
189 : OGRErr SetSelectedFields(const std::set<std::string> &aosFields);
190 : OGRNGWLayer *Clone() const;
191 :
192 : public:
193 : static std::string TranslateSQLToFilter(swq_expr_node *poNode);
194 :
195 : protected:
196 : virtual OGRErr ISetFeature(OGRFeature *poFeature) override;
197 : virtual OGRErr ICreateFeature(OGRFeature *poFeature) override;
198 :
199 : private:
200 : void FillMetadata(const CPLJSONObject &oRootObject);
201 : void FillFields(const CPLJSONArray &oFields);
202 : void FetchPermissions();
203 : void FreeFeaturesCache(bool bForce = false);
204 : std::string CreateNGWResourceJson();
205 : OGRErr SyncFeatures();
206 : GIntBig GetMaxFeatureCount(bool bForce);
207 : bool FillFeatures(const std::string &osUrl);
208 : GIntBig GetNewFeaturesCount() const;
209 : };
210 :
211 : class OGRNGWDataset final : public GDALDataset
212 : {
213 : friend class OGRNGWLayer;
214 : int nBatchSize;
215 : int nPageSize;
216 : NGWAPI::Permissions stPermissions;
217 : bool bFetchedPermissions;
218 : bool bHasFeaturePaging;
219 : std::string osUserPwd;
220 : std::string osUrl;
221 : std::string osResourceId;
222 : std::string osName;
223 : bool bExtInNativeData;
224 : bool bMetadataDerty;
225 :
226 : // vector
227 : OGRNGWLayer **papoLayers;
228 : int nLayers;
229 :
230 : // raster
231 : GDALDataset *poRasterDS;
232 : OGREnvelope stPixelExtent;
233 : int nRasters;
234 : int nCacheExpires, nCacheMaxSize;
235 :
236 : // json
237 : std::string osJsonDepth;
238 : std::string osExtensions;
239 :
240 : public:
241 : OGRNGWDataset();
242 : virtual ~OGRNGWDataset();
243 :
244 : bool Open(const char *pszFilename, char **papszOpenOptionsIn,
245 : bool bUpdateIn, int nOpenFlagsIn);
246 : bool Open(const std::string &osUrlIn, const std::string &osResourceIdIn,
247 : char **papszOpenOptionsIn, bool bUpdateIn, int nOpenFlagsIn);
248 : std::string Extensions() const;
249 :
250 : /* GDALDataset */
251 0 : virtual int GetLayerCount() override
252 : {
253 0 : return nLayers;
254 : }
255 :
256 : virtual OGRLayer *GetLayer(int) override;
257 : virtual int TestCapability(const char *) override;
258 : virtual OGRLayer *ICreateLayer(const char *pszName,
259 : const OGRGeomFieldDefn *poGeomFieldDefn,
260 : CSLConstList papszOptions) override;
261 : virtual OGRErr DeleteLayer(int) override;
262 : virtual CPLErr SetMetadata(char **papszMetadata,
263 : const char *pszDomain = "") override;
264 : virtual CPLErr SetMetadataItem(const char *pszName, const char *pszValue,
265 : const char *pszDomain = "") override;
266 : virtual CPLErr FlushCache(bool bAtClosing) override;
267 : virtual OGRLayer *ExecuteSQL(const char *pszStatement,
268 : OGRGeometry *poSpatialFilter,
269 : const char *pszDialect) override;
270 :
271 : virtual const OGRSpatialReference *GetSpatialRef() const override;
272 : virtual CPLErr GetGeoTransform(double *padfTransform) override;
273 : virtual CPLErr IRasterIO(GDALRWFlag eRWFlag, int nXOff, int nYOff,
274 : int nXSize, int nYSize, void *pData, int nBufXSize,
275 : int nBufYSize, GDALDataType eBufType,
276 : int nBandCount, BANDMAP_TYPE panBandMap,
277 : GSpacing nPixelSpace, GSpacing nLineSpace,
278 : GSpacing nBandSpace,
279 : GDALRasterIOExtraArg *psExtraArg) override;
280 :
281 : private:
282 : char **GetHeaders() const;
283 :
284 0 : std::string GetUrl() const
285 : {
286 0 : return osUrl;
287 : }
288 :
289 0 : std::string GetResourceId() const
290 : {
291 0 : return osResourceId;
292 : }
293 :
294 : void FillMetadata(const CPLJSONObject &oRootObject);
295 : bool FillResources(char **papszOptions, int nOpenFlagsIn);
296 : void AddLayer(const CPLJSONObject &oResourceJsonObject, char **papszOptions,
297 : int nOpenFlagsIn);
298 : void AddRaster(const CPLJSONObject &oResourceJsonObject,
299 : char **papszOptions);
300 : bool Init(int nOpenFlagsIn);
301 : bool FlushMetadata(char **papszMetadata);
302 :
303 0 : inline bool IsUpdateMode() const
304 : {
305 0 : return eAccess == GA_Update;
306 : }
307 :
308 0 : bool IsBatchMode() const
309 : {
310 0 : return nBatchSize >= 0;
311 : }
312 :
313 0 : bool HasFeaturePaging() const
314 : {
315 0 : return bHasFeaturePaging;
316 : }
317 :
318 0 : int GetPageSize() const
319 : {
320 0 : return bHasFeaturePaging ? nPageSize : -1;
321 : }
322 :
323 0 : int GetBatchSize() const
324 : {
325 0 : return nBatchSize;
326 : }
327 :
328 0 : bool IsExtInNativeData() const
329 : {
330 0 : return bExtInNativeData;
331 : }
332 :
333 : void FetchPermissions();
334 : void FillCapabilities(char **papszOptions);
335 :
336 : private:
337 : CPL_DISALLOW_COPY_ASSIGN(OGRNGWDataset)
338 : };
339 :
340 : #endif // OGR_NGW_H_INCLUDED
|