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 "../mem/ogr_mem.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 459 : static const char *GetValidLayerName(const char *pszName)
52 : {
53 459 : if (pszName == nullptr || pszName[0] == 0)
54 : {
55 : // Can happen for example if reading from /vsistdin/
56 132 : pszName = OGRGeoJSONLayer::DefaultName;
57 : }
58 459 : 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 4426 : void IncFeatureCount()
111 : {
112 4426 : nTotalFeatureCount_++;
113 4426 : }
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 375 : void SetWriteOptions(const OGRGeoJSONWriteOptions &options)
126 : {
127 375 : oWriteOptions_ = options;
128 375 : }
129 :
130 : private:
131 : OGRGeoJSONDataSource *poDS_;
132 : OGRGeoJSONReader *poReader_;
133 : bool bHasAppendedFeatures_;
134 : CPLString sFIDColumn_;
135 : bool bOriginalIdModified_;
136 : GIntBig nTotalFeatureCount_;
137 : GIntBig nFeatureReadSinceReset_ = 0;
138 :
139 : //! Write options used by ICreateFeature() in append scenarios
140 : OGRGeoJSONWriteOptions oWriteOptions_;
141 :
142 : bool IngestAll();
143 : void TerminateAppendSession();
144 : bool SetOrUpdateFeaturePreparation();
145 :
146 : CPL_DISALLOW_COPY_ASSIGN(OGRGeoJSONLayer)
147 : };
148 :
149 : /************************************************************************/
150 : /* OGRGeoJSONWriteLayer */
151 : /************************************************************************/
152 :
153 : class OGRGeoJSONWriteLayer final : public OGRLayer
154 : {
155 : public:
156 : OGRGeoJSONWriteLayer(const char *pszName, OGRwkbGeometryType eGType,
157 : CSLConstList papszOptions, bool bWriteFC_BBOXIn,
158 : OGRCoordinateTransformation *poCT,
159 : OGRGeoJSONDataSource *poDS);
160 : ~OGRGeoJSONWriteLayer();
161 :
162 : //
163 : // OGRLayer Interface
164 : //
165 1931 : OGRFeatureDefn *GetLayerDefn() override
166 : {
167 1931 : return poFeatureDefn_;
168 : }
169 :
170 4 : OGRSpatialReference *GetSpatialRef() override
171 : {
172 4 : return nullptr;
173 : }
174 :
175 16 : void ResetReading() override
176 : {
177 16 : }
178 :
179 16 : OGRFeature *GetNextFeature() override
180 : {
181 16 : return nullptr;
182 : }
183 :
184 : OGRErr ICreateFeature(OGRFeature *poFeature) override;
185 : OGRErr CreateField(const OGRFieldDefn *poField, int bApproxOK) override;
186 : int TestCapability(const char *pszCap) override;
187 :
188 : OGRErr IGetExtent(int iGeomField, OGREnvelope *psExtent,
189 : bool bForce) override;
190 :
191 : OGRErr SyncToDisk() override;
192 :
193 : GDALDataset *GetDataset() override;
194 :
195 : private:
196 : OGRGeoJSONDataSource *poDS_;
197 : OGRFeatureDefn *poFeatureDefn_;
198 : int nOutCounter_;
199 : /** Offset at which the '] }' terminating sequence has already been
200 : * written by SyncToDisk(). 0 if it has not been written.
201 : */
202 : vsi_l_offset m_nPositionBeforeFCClosed = 0;
203 :
204 : bool bWriteBBOX;
205 : bool bBBOX3D;
206 : bool bWriteFC_BBOX;
207 : OGREnvelope3D sEnvelopeLayer;
208 :
209 : int nSignificantFigures_;
210 :
211 : bool bRFC7946_;
212 : bool bWrapDateLine_ = false;
213 : std::string osForeignMembers_{};
214 : OGRCoordinateTransformation *poCT_;
215 : OGRGeometryFactory::TransformWithOptionsCache oTransformCache_;
216 : OGRGeoJSONWriteOptions oWriteOptions_;
217 :
218 : CPL_DISALLOW_COPY_ASSIGN(OGRGeoJSONWriteLayer)
219 :
220 : void FinishWriting();
221 : };
222 :
223 : /************************************************************************/
224 : /* OGRGeoJSONDataSource */
225 : /************************************************************************/
226 :
227 : class OGRGeoJSONDataSource final : public GDALDataset
228 : {
229 : public:
230 : OGRGeoJSONDataSource();
231 : virtual ~OGRGeoJSONDataSource();
232 :
233 : int Open(GDALOpenInfo *poOpenInfo, GeoJSONSourceType nSrcType,
234 : const char *pszJSonFlavor);
235 : int GetLayerCount() override;
236 : OGRLayer *GetLayer(int nLayer) override;
237 : OGRLayer *ICreateLayer(const char *pszName,
238 : const OGRGeomFieldDefn *poGeomFieldDefn,
239 : CSLConstList papszOptions) override;
240 : int TestCapability(const char *pszCap) override;
241 :
242 : void AddLayer(OGRGeoJSONLayer *poLayer);
243 :
244 : //
245 : // OGRGeoJSONDataSource Interface
246 : //
247 : int Create(const char *pszName, char **papszOptions);
248 :
249 1240 : VSILFILE *GetOutputFile() const
250 : {
251 1240 : return fpOut_;
252 : }
253 :
254 : enum GeometryTranslation
255 : {
256 : eGeometryPreserve,
257 : eGeometryAsCollection,
258 : };
259 :
260 : void SetGeometryTranslation(GeometryTranslation type);
261 :
262 : enum AttributesTranslation
263 : {
264 : eAttributesPreserve,
265 : eAttributesSkip
266 : };
267 :
268 : void SetAttributesTranslation(AttributesTranslation type);
269 :
270 187 : int GetFpOutputIsSeekable() const
271 : {
272 187 : return bFpOutputIsSeekable_;
273 : }
274 :
275 23 : int GetBBOXInsertLocation() const
276 : {
277 23 : return nBBOXInsertLocation_;
278 : }
279 :
280 478 : int HasOtherPages() const
281 : {
282 478 : return bOtherPages_;
283 : }
284 :
285 488 : bool IsUpdatable() const
286 : {
287 488 : return bUpdatable_;
288 : }
289 :
290 22 : const CPLString &GetJSonFlavor() const
291 : {
292 22 : return osJSonFlavor_;
293 : }
294 :
295 : virtual CPLErr FlushCache(bool bAtClosing) override;
296 :
297 : CPLErr Close() override;
298 :
299 : // Analyze the OGR_SCHEMA open options and apply changes to the feature definition, return false in case of a critical error
300 : bool DealWithOgrSchemaOpenOption(const GDALOpenInfo *poOpenInfo);
301 :
302 : static const size_t SPACE_FOR_BBOX = 130;
303 :
304 : private:
305 : //
306 : // Private data members
307 : //
308 : char *pszName_;
309 : char *pszGeoData_;
310 : vsi_l_offset nGeoDataLen_;
311 : OGRGeoJSONLayer **papoLayers_;
312 : OGRGeoJSONWriteLayer **papoLayersWriter_;
313 : int nLayers_;
314 : VSILFILE *fpOut_;
315 :
316 : //
317 : // Translation/Creation control flags
318 : //
319 : GeometryTranslation flTransGeom_;
320 : AttributesTranslation flTransAttrs_;
321 : bool bOtherPages_; // ESRI Feature Service specific.
322 :
323 : bool bFpOutputIsSeekable_;
324 : int nBBOXInsertLocation_;
325 :
326 : bool bUpdatable_;
327 :
328 : CPLString osJSonFlavor_;
329 :
330 : //
331 : // Private utility functions
332 : //
333 : bool Clear();
334 : int ReadFromFile(GDALOpenInfo *poOpenInfo, const char *pszUnprefixed);
335 : int ReadFromService(GDALOpenInfo *poOpenInfo, const char *pszSource);
336 : void LoadLayers(GDALOpenInfo *poOpenInfo, GeoJSONSourceType nSrcType,
337 : const char *pszUnprefixed, const char *pszJSonFlavor);
338 : void SetOptionsOnReader(GDALOpenInfo *poOpenInfo,
339 : OGRGeoJSONReader *poReader);
340 : void CheckExceededTransferLimit(json_object *poObj);
341 : void RemoveJSonPStuff();
342 :
343 : CPL_DISALLOW_COPY_ASSIGN(OGRGeoJSONDataSource)
344 : };
345 :
346 : #endif // OGR_GEOJSON_H_INCLUDED
|