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 511 : static const char *GetValidLayerName(const char *pszName)
52 : {
53 511 : if (pszName == nullptr || pszName[0] == 0)
54 : {
55 : // Can happen for example if reading from /vsistdin/
56 168 : pszName = OGRGeoJSONLayer::DefaultName;
57 : }
58 511 : return pszName;
59 : }
60 :
61 : OGRGeoJSONLayer(const char *pszName, OGRSpatialReference *poSRS,
62 : OGRwkbGeometryType eGType, OGRGeoJSONDataSource *poDS,
63 : OGRGeoJSONReader *poReader);
64 : ~OGRGeoJSONLayer() override;
65 :
66 : //
67 : // OGRLayer Interface
68 : //
69 : const char *GetFIDColumn() const override;
70 : int TestCapability(const char *pszCap) const override;
71 :
72 : OGRErr SyncToDisk() override;
73 :
74 : void ResetReading() override;
75 : OGRFeature *GetNextFeature() override;
76 : OGRFeature *GetFeature(GIntBig nFID) override;
77 : 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 : OGRErr DeleteFeature(GIntBig nFID) override;
87 : virtual OGRErr CreateField(const OGRFieldDefn *poField,
88 : int bApproxOK = TRUE) override;
89 : OGRErr DeleteField(int iField) override;
90 : 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 : OGRErr IGetExtent(int iGeomField, OGREnvelope *psExtent,
97 : bool bForce = true) override;
98 : 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 384 : void SetWriteOptions(const OGRGeoJSONWriteOptions &options)
126 : {
127 384 : oWriteOptions_ = options;
128 384 : }
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() override;
173 :
174 : //
175 : // OGRLayer Interface
176 : //
177 : using OGRLayer::GetLayerDefn;
178 :
179 1951 : const OGRFeatureDefn *GetLayerDefn() const override
180 : {
181 1951 : return poFeatureDefn_;
182 : }
183 :
184 4 : const OGRSpatialReference *GetSpatialRef() const override
185 : {
186 4 : return nullptr;
187 : }
188 :
189 16 : void ResetReading() override
190 : {
191 16 : }
192 :
193 16 : OGRFeature *GetNextFeature() override
194 : {
195 16 : return nullptr;
196 : }
197 :
198 : OGRErr ICreateFeature(OGRFeature *poFeature) override;
199 : OGRErr CreateField(const OGRFieldDefn *poField, int bApproxOK) override;
200 : int TestCapability(const char *pszCap) const override;
201 :
202 : OGRErr IGetExtent(int iGeomField, OGREnvelope *psExtent,
203 : bool bForce) override;
204 :
205 : OGRErr SyncToDisk() override;
206 :
207 : GDALDataset *GetDataset() override;
208 :
209 : private:
210 : OGRGeoJSONDataSource *poDS_;
211 : OGRFeatureDefn *poFeatureDefn_;
212 : int nOutCounter_;
213 : /** Offset at which the '] }' terminating sequence has already been
214 : * written by SyncToDisk(). 0 if it has not been written.
215 : */
216 : vsi_l_offset m_nPositionBeforeFCClosed = 0;
217 :
218 : bool bWriteBBOX;
219 : bool bBBOX3D;
220 : bool bWriteFC_BBOX;
221 : OGREnvelope3D sEnvelopeLayer;
222 :
223 : int nSignificantFigures_;
224 :
225 : bool bRFC7946_;
226 : bool bWrapDateLine_ = false;
227 : std::string osForeignMembers_{};
228 : OGRCoordinateTransformation *poCT_;
229 : OGRGeometryFactory::TransformWithOptionsCache oTransformCache_;
230 : OGRGeoJSONWriteOptions oWriteOptions_;
231 :
232 : CPL_DISALLOW_COPY_ASSIGN(OGRGeoJSONWriteLayer)
233 :
234 : void FinishWriting();
235 : };
236 :
237 : /************************************************************************/
238 : /* OGRGeoJSONDataSource */
239 : /************************************************************************/
240 :
241 : class OGRGeoJSONDataSource final : public GDALDataset
242 : {
243 : public:
244 : OGRGeoJSONDataSource();
245 : ~OGRGeoJSONDataSource() override;
246 :
247 : int Open(GDALOpenInfo *poOpenInfo, GeoJSONSourceType nSrcType,
248 : const char *pszJSonFlavor);
249 : int GetLayerCount() const override;
250 :
251 : using GDALDataset::GetLayer;
252 : const OGRLayer *GetLayer(int nLayer) const override;
253 : OGRLayer *ICreateLayer(const char *pszName,
254 : const OGRGeomFieldDefn *poGeomFieldDefn,
255 : CSLConstList papszOptions) override;
256 : int TestCapability(const char *pszCap) const override;
257 :
258 : void AddLayer(OGRGeoJSONLayer *poLayer);
259 :
260 : //
261 : // OGRGeoJSONDataSource Interface
262 : //
263 : int Create(const char *pszName, char **papszOptions);
264 :
265 1251 : VSILFILE *GetOutputFile() const
266 : {
267 1251 : return fpOut_;
268 : }
269 :
270 : enum GeometryTranslation
271 : {
272 : eGeometryPreserve,
273 : eGeometryAsCollection,
274 : };
275 :
276 : void SetGeometryTranslation(GeometryTranslation type);
277 :
278 : enum AttributesTranslation
279 : {
280 : eAttributesPreserve,
281 : eAttributesSkip
282 : };
283 :
284 : void SetAttributesTranslation(AttributesTranslation type);
285 :
286 190 : int GetFpOutputIsSeekable() const
287 : {
288 190 : return bFpOutputIsSeekable_;
289 : }
290 :
291 23 : int GetBBOXInsertLocation() const
292 : {
293 23 : return nBBOXInsertLocation_;
294 : }
295 :
296 502 : int HasOtherPages() const
297 : {
298 502 : return bOtherPages_;
299 : }
300 :
301 542 : bool IsUpdatable() const
302 : {
303 542 : return bUpdatable_;
304 : }
305 :
306 22 : const CPLString &GetJSonFlavor() const
307 : {
308 22 : return osJSonFlavor_;
309 : }
310 :
311 21 : void SetSupportsMGeometries(bool bSupportsMGeometries)
312 : {
313 21 : m_bSupportsMGeometries = bSupportsMGeometries;
314 21 : }
315 :
316 5 : void SetSupportsZGeometries(bool bSupportsZGeometries)
317 : {
318 5 : m_bSupportsZGeometries = bSupportsZGeometries;
319 5 : }
320 :
321 : CPLErr FlushCache(bool bAtClosing) override;
322 :
323 : CPLErr Close() override;
324 :
325 : // Analyze the OGR_SCHEMA open options and apply changes to the feature definition, return false in case of a critical error
326 : bool DealWithOgrSchemaOpenOption(const GDALOpenInfo *poOpenInfo);
327 :
328 : static const size_t SPACE_FOR_BBOX = 130;
329 :
330 : private:
331 : //
332 : // Private data members
333 : //
334 : char *pszName_;
335 : char *pszGeoData_;
336 : vsi_l_offset nGeoDataLen_;
337 : OGRGeoJSONLayer **papoLayers_;
338 : OGRGeoJSONWriteLayer **papoLayersWriter_;
339 : int nLayers_;
340 : VSILFILE *fpOut_;
341 :
342 : //
343 : // Translation/Creation control flags
344 : //
345 : GeometryTranslation flTransGeom_;
346 : AttributesTranslation flTransAttrs_;
347 : bool bOtherPages_; // ESRI Feature Service specific.
348 :
349 : bool bFpOutputIsSeekable_;
350 : int nBBOXInsertLocation_;
351 :
352 : bool bUpdatable_;
353 :
354 : CPLString osJSonFlavor_;
355 :
356 : bool m_bSupportsMGeometries = false;
357 : bool m_bSupportsZGeometries = true;
358 :
359 : //
360 : // Private utility functions
361 : //
362 : bool Clear();
363 : int ReadFromFile(GDALOpenInfo *poOpenInfo, const char *pszUnprefixed);
364 : int ReadFromService(GDALOpenInfo *poOpenInfo, const char *pszSource);
365 : void LoadLayers(GDALOpenInfo *poOpenInfo, GeoJSONSourceType nSrcType,
366 : const char *pszUnprefixed, const char *pszJSonFlavor);
367 : void SetOptionsOnReader(GDALOpenInfo *poOpenInfo,
368 : OGRGeoJSONReader *poReader);
369 : void CheckExceededTransferLimit(json_object *poObj);
370 : void RemoveJSonPStuff();
371 :
372 : CPL_DISALLOW_COPY_ASSIGN(OGRGeoJSONDataSource)
373 : };
374 :
375 : #endif // OGR_GEOJSON_H_INCLUDED
|