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