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