Line data Source code
1 : /******************************************************************************
2 : *
3 : * Project: OpenGIS Simple Features Reference Implementation
4 : * Purpose: Definitions of OGR OGRGeoJSON driver types.
5 : * Author: Mateusz Loskot, mateusz@loskot.net
6 : *
7 : ******************************************************************************
8 : * Copyright (c) 2007, Mateusz Loskot
9 : * Copyright (c) 2010-2013, Even Rouault <even dot rouault at spatialys.com>
10 : *
11 : * SPDX-License-Identifier: MIT
12 : ****************************************************************************/
13 :
14 : #ifndef OGR_GEOJSON_H_INCLUDED
15 : #define OGR_GEOJSON_H_INCLUDED
16 :
17 : #include "cpl_port.h"
18 : #include "ogrsf_frmts.h"
19 : #include "memdataset.h"
20 :
21 : #include <cstdio>
22 : #include <vector> // Used by OGRGeoJSONLayer.
23 : #include "ogrgeojsonutils.h"
24 : #include "ogrgeojsonwriter.h"
25 :
26 : constexpr const char *INVALID_CONTENT_FOR_JSON_LIKE =
27 : "__INVALID_CONTENT_FOR_JSON_LIKE__";
28 :
29 : class OGRGeoJSONDataSource;
30 :
31 : GDALDataset *OGRGeoJSONDriverOpenInternal(GDALOpenInfo *poOpenInfo,
32 : GeoJSONSourceType nSrcType,
33 : const char *pszJSonFlavor);
34 : void OGRGeoJSONDriverStoreContent(const char *pszSource, char *pszText);
35 : char *OGRGeoJSONDriverStealStoredContent(const char *pszSource);
36 :
37 : /************************************************************************/
38 : /* OGRGeoJSONLayer */
39 : /************************************************************************/
40 :
41 : class OGRGeoJSONReader;
42 :
43 : class OGRGeoJSONLayer final : public OGRMemLayer
44 : {
45 : friend class OGRGeoJSONDataSource;
46 :
47 : public:
48 : static const char *const DefaultName;
49 : static const OGRwkbGeometryType DefaultGeometryType;
50 :
51 510 : static const char *GetValidLayerName(const char *pszName)
52 : {
53 510 : if (pszName == nullptr || pszName[0] == 0)
54 : {
55 : // Can happen for example if reading from /vsistdin/
56 168 : pszName = OGRGeoJSONLayer::DefaultName;
57 : }
58 510 : return pszName;
59 : }
60 :
61 : OGRGeoJSONLayer(const char *pszName, OGRSpatialReference *poSRS,
62 : OGRwkbGeometryType eGType, OGRGeoJSONDataSource *poDS,
63 : OGRGeoJSONReader *poReader);
64 : virtual ~OGRGeoJSONLayer();
65 :
66 : //
67 : // OGRLayer Interface
68 : //
69 : virtual const char *GetFIDColumn() override;
70 : virtual int TestCapability(const char *pszCap) override;
71 :
72 : virtual OGRErr SyncToDisk() override;
73 :
74 : virtual void ResetReading() override;
75 : virtual OGRFeature *GetNextFeature() override;
76 : virtual OGRFeature *GetFeature(GIntBig nFID) override;
77 : virtual GIntBig GetFeatureCount(int bForce) override;
78 :
79 : OGRErr ISetFeature(OGRFeature *poFeature) override;
80 : OGRErr ICreateFeature(OGRFeature *poFeature) override;
81 : OGRErr IUpdateFeature(OGRFeature *poFeature, int nUpdatedFieldsCount,
82 : const int *panUpdatedFieldsIdx,
83 : int nUpdatedGeomFieldsCount,
84 : const int *panUpdatedGeomFieldsIdx,
85 : bool bUpdateStyleString) override;
86 : virtual OGRErr DeleteFeature(GIntBig nFID) override;
87 : virtual OGRErr CreateField(const OGRFieldDefn *poField,
88 : int bApproxOK = TRUE) override;
89 : virtual OGRErr DeleteField(int iField) override;
90 : virtual OGRErr ReorderFields(int *panMap) override;
91 : virtual OGRErr AlterFieldDefn(int iField, OGRFieldDefn *poNewFieldDefn,
92 : int nFlags) override;
93 : virtual OGRErr CreateGeomField(const OGRGeomFieldDefn *poGeomField,
94 : int bApproxOK = TRUE) override;
95 :
96 : virtual OGRErr IGetExtent(int iGeomField, OGREnvelope *psExtent,
97 : bool bForce = true) override;
98 : virtual OGRErr IGetExtent3D(int iGeomField, OGREnvelope3D *psExtent3D,
99 : bool bForce = true) override;
100 :
101 : GDALDataset *GetDataset() override;
102 :
103 : //
104 : // OGRGeoJSONLayer Interface
105 : //
106 : void SetFIDColumn(const char *pszFIDColumn);
107 : void AddFeature(OGRFeature *poFeature);
108 : void DetectGeometryType();
109 :
110 4436 : void IncFeatureCount()
111 : {
112 4436 : nTotalFeatureCount_++;
113 4436 : }
114 :
115 3 : void UnsetReader()
116 : {
117 3 : poReader_ = nullptr;
118 3 : }
119 :
120 0 : void InvalidateFeatureCount()
121 : {
122 0 : nTotalFeatureCount_ = -1;
123 0 : }
124 :
125 383 : void SetWriteOptions(const OGRGeoJSONWriteOptions &options)
126 : {
127 383 : oWriteOptions_ = options;
128 383 : }
129 :
130 21 : void SetSupportsMGeometries(bool bSupportsMGeometries)
131 : {
132 21 : m_bSupportsMGeometries = bSupportsMGeometries;
133 21 : }
134 :
135 10 : void SetSupportsZGeometries(bool bSupportsZGeometries)
136 : {
137 10 : m_bSupportsZGeometries = bSupportsZGeometries;
138 10 : }
139 :
140 : private:
141 : OGRGeoJSONDataSource *poDS_;
142 : OGRGeoJSONReader *poReader_;
143 : bool bHasAppendedFeatures_;
144 : CPLString sFIDColumn_;
145 : bool bOriginalIdModified_;
146 : GIntBig nTotalFeatureCount_;
147 : GIntBig nFeatureReadSinceReset_ = 0;
148 : bool m_bSupportsMGeometries = false;
149 : bool m_bSupportsZGeometries = true;
150 :
151 : //! Write options used by ICreateFeature() in append scenarios
152 : OGRGeoJSONWriteOptions oWriteOptions_;
153 :
154 : bool IngestAll();
155 : void TerminateAppendSession();
156 : bool SetOrUpdateFeaturePreparation();
157 :
158 : CPL_DISALLOW_COPY_ASSIGN(OGRGeoJSONLayer)
159 : };
160 :
161 : /************************************************************************/
162 : /* OGRGeoJSONWriteLayer */
163 : /************************************************************************/
164 :
165 : class OGRGeoJSONWriteLayer final : public OGRLayer
166 : {
167 : public:
168 : OGRGeoJSONWriteLayer(const char *pszName, OGRwkbGeometryType eGType,
169 : CSLConstList papszOptions, bool bWriteFC_BBOXIn,
170 : OGRCoordinateTransformation *poCT,
171 : OGRGeoJSONDataSource *poDS);
172 : ~OGRGeoJSONWriteLayer();
173 :
174 : //
175 : // OGRLayer Interface
176 : //
177 1944 : OGRFeatureDefn *GetLayerDefn() override
178 : {
179 1944 : return poFeatureDefn_;
180 : }
181 :
182 4 : OGRSpatialReference *GetSpatialRef() override
183 : {
184 4 : return nullptr;
185 : }
186 :
187 16 : void ResetReading() override
188 : {
189 16 : }
190 :
191 16 : OGRFeature *GetNextFeature() override
192 : {
193 16 : return nullptr;
194 : }
195 :
196 : OGRErr ICreateFeature(OGRFeature *poFeature) override;
197 : OGRErr CreateField(const OGRFieldDefn *poField, int bApproxOK) override;
198 : int TestCapability(const char *pszCap) override;
199 :
200 : OGRErr IGetExtent(int iGeomField, OGREnvelope *psExtent,
201 : bool bForce) override;
202 :
203 : OGRErr SyncToDisk() override;
204 :
205 : GDALDataset *GetDataset() override;
206 :
207 : private:
208 : OGRGeoJSONDataSource *poDS_;
209 : OGRFeatureDefn *poFeatureDefn_;
210 : int nOutCounter_;
211 : /** Offset at which the '] }' terminating sequence has already been
212 : * written by SyncToDisk(). 0 if it has not been written.
213 : */
214 : vsi_l_offset m_nPositionBeforeFCClosed = 0;
215 :
216 : bool bWriteBBOX;
217 : bool bBBOX3D;
218 : bool bWriteFC_BBOX;
219 : OGREnvelope3D sEnvelopeLayer;
220 :
221 : int nSignificantFigures_;
222 :
223 : bool bRFC7946_;
224 : bool bWrapDateLine_ = false;
225 : std::string osForeignMembers_{};
226 : OGRCoordinateTransformation *poCT_;
227 : OGRGeometryFactory::TransformWithOptionsCache oTransformCache_;
228 : OGRGeoJSONWriteOptions oWriteOptions_;
229 :
230 : CPL_DISALLOW_COPY_ASSIGN(OGRGeoJSONWriteLayer)
231 :
232 : void FinishWriting();
233 : };
234 :
235 : /************************************************************************/
236 : /* OGRGeoJSONDataSource */
237 : /************************************************************************/
238 :
239 : class OGRGeoJSONDataSource final : public GDALDataset
240 : {
241 : public:
242 : OGRGeoJSONDataSource();
243 : virtual ~OGRGeoJSONDataSource();
244 :
245 : int Open(GDALOpenInfo *poOpenInfo, GeoJSONSourceType nSrcType,
246 : const char *pszJSonFlavor);
247 : int GetLayerCount() override;
248 : OGRLayer *GetLayer(int nLayer) override;
249 : OGRLayer *ICreateLayer(const char *pszName,
250 : const OGRGeomFieldDefn *poGeomFieldDefn,
251 : CSLConstList papszOptions) override;
252 : int TestCapability(const char *pszCap) override;
253 :
254 : void AddLayer(OGRGeoJSONLayer *poLayer);
255 :
256 : //
257 : // OGRGeoJSONDataSource Interface
258 : //
259 : int Create(const char *pszName, char **papszOptions);
260 :
261 1249 : VSILFILE *GetOutputFile() const
262 : {
263 1249 : return fpOut_;
264 : }
265 :
266 : enum GeometryTranslation
267 : {
268 : eGeometryPreserve,
269 : eGeometryAsCollection,
270 : };
271 :
272 : void SetGeometryTranslation(GeometryTranslation type);
273 :
274 : enum AttributesTranslation
275 : {
276 : eAttributesPreserve,
277 : eAttributesSkip
278 : };
279 :
280 : void SetAttributesTranslation(AttributesTranslation type);
281 :
282 188 : int GetFpOutputIsSeekable() const
283 : {
284 188 : return bFpOutputIsSeekable_;
285 : }
286 :
287 23 : int GetBBOXInsertLocation() const
288 : {
289 23 : return nBBOXInsertLocation_;
290 : }
291 :
292 501 : int HasOtherPages() const
293 : {
294 501 : return bOtherPages_;
295 : }
296 :
297 541 : bool IsUpdatable() const
298 : {
299 541 : return bUpdatable_;
300 : }
301 :
302 22 : const CPLString &GetJSonFlavor() const
303 : {
304 22 : return osJSonFlavor_;
305 : }
306 :
307 21 : void SetSupportsMGeometries(bool bSupportsMGeometries)
308 : {
309 21 : m_bSupportsMGeometries = bSupportsMGeometries;
310 21 : }
311 :
312 5 : void SetSupportsZGeometries(bool bSupportsZGeometries)
313 : {
314 5 : m_bSupportsZGeometries = bSupportsZGeometries;
315 5 : }
316 :
317 : virtual CPLErr FlushCache(bool bAtClosing) override;
318 :
319 : CPLErr Close() override;
320 :
321 : // Analyze the OGR_SCHEMA open options and apply changes to the feature definition, return false in case of a critical error
322 : bool DealWithOgrSchemaOpenOption(const GDALOpenInfo *poOpenInfo);
323 :
324 : static const size_t SPACE_FOR_BBOX = 130;
325 :
326 : private:
327 : //
328 : // Private data members
329 : //
330 : char *pszName_;
331 : char *pszGeoData_;
332 : vsi_l_offset nGeoDataLen_;
333 : OGRGeoJSONLayer **papoLayers_;
334 : OGRGeoJSONWriteLayer **papoLayersWriter_;
335 : int nLayers_;
336 : VSILFILE *fpOut_;
337 :
338 : //
339 : // Translation/Creation control flags
340 : //
341 : GeometryTranslation flTransGeom_;
342 : AttributesTranslation flTransAttrs_;
343 : bool bOtherPages_; // ESRI Feature Service specific.
344 :
345 : bool bFpOutputIsSeekable_;
346 : int nBBOXInsertLocation_;
347 :
348 : bool bUpdatable_;
349 :
350 : CPLString osJSonFlavor_;
351 :
352 : bool m_bSupportsMGeometries = false;
353 : bool m_bSupportsZGeometries = true;
354 :
355 : //
356 : // Private utility functions
357 : //
358 : bool Clear();
359 : int ReadFromFile(GDALOpenInfo *poOpenInfo, const char *pszUnprefixed);
360 : int ReadFromService(GDALOpenInfo *poOpenInfo, const char *pszSource);
361 : void LoadLayers(GDALOpenInfo *poOpenInfo, GeoJSONSourceType nSrcType,
362 : const char *pszUnprefixed, const char *pszJSonFlavor);
363 : void SetOptionsOnReader(GDALOpenInfo *poOpenInfo,
364 : OGRGeoJSONReader *poReader);
365 : void CheckExceededTransferLimit(json_object *poObj);
366 : void RemoveJSonPStuff();
367 :
368 : CPL_DISALLOW_COPY_ASSIGN(OGRGeoJSONDataSource)
369 : };
370 :
371 : #endif // OGR_GEOJSON_H_INCLUDED
|