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 458 : static const char *GetValidLayerName(const char *pszName)
52 : {
53 458 : if (pszName == nullptr || pszName[0] == 0)
54 : {
55 : // Can happen for example if reading from /vsistdin/
56 132 : pszName = OGRGeoJSONLayer::DefaultName;
57 : }
58 458 : 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 : virtual OGRErr GetExtent(OGREnvelope *psExtent, int bForce = TRUE) override;
96 : virtual OGRErr GetExtent(int iGeomField, OGREnvelope *psExtent,
97 : int bForce = TRUE) override;
98 : virtual OGRErr GetExtent3D(int iGeomField, OGREnvelope3D *psExtent3D,
99 : int 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 4425 : void IncFeatureCount()
111 : {
112 4425 : nTotalFeatureCount_++;
113 4425 : }
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 374 : void SetWriteOptions(const OGRGeoJSONWriteOptions &options)
126 : {
127 374 : oWriteOptions_ = options;
128 374 : }
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 1926 : OGRFeatureDefn *GetLayerDefn() override
166 : {
167 1926 : 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 : OGRErr GetExtent(OGREnvelope *psExtent, int bForce) override;
188 :
189 3 : OGRErr GetExtent(int iGeomField, OGREnvelope *psExtent, int bForce) override
190 : {
191 : return iGeomField == 0
192 3 : ? OGRGeoJSONWriteLayer::GetExtent(psExtent, bForce)
193 3 : : OGRERR_FAILURE;
194 : }
195 :
196 : OGRErr SyncToDisk() override;
197 :
198 : GDALDataset *GetDataset() override;
199 :
200 : private:
201 : OGRGeoJSONDataSource *poDS_;
202 : OGRFeatureDefn *poFeatureDefn_;
203 : int nOutCounter_;
204 : /** Offset at which the '] }' terminating sequence has already been
205 : * written by SyncToDisk(). 0 if it has not been written.
206 : */
207 : vsi_l_offset m_nPositionBeforeFCClosed = 0;
208 :
209 : bool bWriteBBOX;
210 : bool bBBOX3D;
211 : bool bWriteFC_BBOX;
212 : OGREnvelope3D sEnvelopeLayer;
213 :
214 : int nSignificantFigures_;
215 :
216 : bool bRFC7946_;
217 : bool bWrapDateLine_ = false;
218 : std::string osForeignMembers_{};
219 : OGRCoordinateTransformation *poCT_;
220 : OGRGeometryFactory::TransformWithOptionsCache oTransformCache_;
221 : OGRGeoJSONWriteOptions oWriteOptions_;
222 :
223 : CPL_DISALLOW_COPY_ASSIGN(OGRGeoJSONWriteLayer)
224 :
225 : void FinishWriting();
226 : };
227 :
228 : /************************************************************************/
229 : /* OGRGeoJSONDataSource */
230 : /************************************************************************/
231 :
232 : class OGRGeoJSONDataSource final : public GDALDataset
233 : {
234 : public:
235 : OGRGeoJSONDataSource();
236 : virtual ~OGRGeoJSONDataSource();
237 :
238 : int Open(GDALOpenInfo *poOpenInfo, GeoJSONSourceType nSrcType,
239 : const char *pszJSonFlavor);
240 : int GetLayerCount() override;
241 : OGRLayer *GetLayer(int nLayer) override;
242 : OGRLayer *ICreateLayer(const char *pszName,
243 : const OGRGeomFieldDefn *poGeomFieldDefn,
244 : CSLConstList papszOptions) override;
245 : int TestCapability(const char *pszCap) override;
246 :
247 : void AddLayer(OGRGeoJSONLayer *poLayer);
248 :
249 : //
250 : // OGRGeoJSONDataSource Interface
251 : //
252 : int Create(const char *pszName, char **papszOptions);
253 :
254 1240 : VSILFILE *GetOutputFile() const
255 : {
256 1240 : return fpOut_;
257 : }
258 :
259 : enum GeometryTranslation
260 : {
261 : eGeometryPreserve,
262 : eGeometryAsCollection,
263 : };
264 :
265 : void SetGeometryTranslation(GeometryTranslation type);
266 :
267 : enum AttributesTranslation
268 : {
269 : eAttributesPreserve,
270 : eAttributesSkip
271 : };
272 :
273 : void SetAttributesTranslation(AttributesTranslation type);
274 :
275 187 : int GetFpOutputIsSeekable() const
276 : {
277 187 : return bFpOutputIsSeekable_;
278 : }
279 :
280 23 : int GetBBOXInsertLocation() const
281 : {
282 23 : return nBBOXInsertLocation_;
283 : }
284 :
285 477 : int HasOtherPages() const
286 : {
287 477 : return bOtherPages_;
288 : }
289 :
290 487 : bool IsUpdatable() const
291 : {
292 487 : return bUpdatable_;
293 : }
294 :
295 22 : const CPLString &GetJSonFlavor() const
296 : {
297 22 : return osJSonFlavor_;
298 : }
299 :
300 : virtual CPLErr FlushCache(bool bAtClosing) override;
301 :
302 : CPLErr Close() override;
303 :
304 : // Analyze the OGR_SCHEMA open options and apply changes to the feature definition, return false in case of a critical error
305 : bool DealWithOgrSchemaOpenOption(const GDALOpenInfo *poOpenInfo);
306 :
307 : static const size_t SPACE_FOR_BBOX = 130;
308 :
309 : private:
310 : //
311 : // Private data members
312 : //
313 : char *pszName_;
314 : char *pszGeoData_;
315 : vsi_l_offset nGeoDataLen_;
316 : OGRGeoJSONLayer **papoLayers_;
317 : OGRGeoJSONWriteLayer **papoLayersWriter_;
318 : int nLayers_;
319 : VSILFILE *fpOut_;
320 :
321 : //
322 : // Translation/Creation control flags
323 : //
324 : GeometryTranslation flTransGeom_;
325 : AttributesTranslation flTransAttrs_;
326 : bool bOtherPages_; // ESRI Feature Service specific.
327 :
328 : bool bFpOutputIsSeekable_;
329 : int nBBOXInsertLocation_;
330 :
331 : bool bUpdatable_;
332 :
333 : CPLString osJSonFlavor_;
334 :
335 : //
336 : // Private utility functions
337 : //
338 : bool Clear();
339 : int ReadFromFile(GDALOpenInfo *poOpenInfo, const char *pszUnprefixed);
340 : int ReadFromService(GDALOpenInfo *poOpenInfo, const char *pszSource);
341 : void LoadLayers(GDALOpenInfo *poOpenInfo, GeoJSONSourceType nSrcType,
342 : const char *pszUnprefixed, const char *pszJSonFlavor);
343 : void SetOptionsOnReader(GDALOpenInfo *poOpenInfo,
344 : OGRGeoJSONReader *poReader);
345 : void CheckExceededTransferLimit(json_object *poObj);
346 : void RemoveJSonPStuff();
347 :
348 : CPL_DISALLOW_COPY_ASSIGN(OGRGeoJSONDataSource)
349 : };
350 :
351 : #endif // OGR_GEOJSON_H_INCLUDED
|