Line data Source code
1 : /******************************************************************************
2 : * $Id$
3 : *
4 : * Project: OpenGIS Simple Features Reference Implementation
5 : * Purpose: Defines GeoJSON reader within OGR OGRGeoJSON Driver.
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 : * Permission is hereby granted, free of charge, to any person obtaining a
13 : * copy of this software and associated documentation files (the "Software"),
14 : * to deal in the Software without restriction, including without limitation
15 : * the rights to use, copy, modify, merge, publish, distribute, sublicense,
16 : * and/or sell copies of the Software, and to permit persons to whom the
17 : * Software is furnished to do so, subject to the following conditions:
18 : *
19 : * The above copyright notice and this permission notice shall be included
20 : * in all copies or substantial portions of the Software.
21 : *
22 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
23 : * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
25 : * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26 : * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
27 : * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
28 : * DEALINGS IN THE SOFTWARE.
29 : ****************************************************************************/
30 : #ifndef OGR_GEOJSONREADER_H_INCLUDED
31 : #define OGR_GEOJSONREADER_H_INCLUDED
32 :
33 : #include "cpl_json_header.h"
34 : #include "cpl_string.h"
35 : #include "ogr_core.h"
36 : #include "ogrsf_frmts.h"
37 :
38 : #include "ogrgeojsonutils.h"
39 : #include "directedacyclicgraph.hpp"
40 :
41 : #include <utility>
42 : #include <map>
43 : #include <set>
44 : #include <vector>
45 :
46 : /************************************************************************/
47 : /* FORWARD DECLARATIONS */
48 : /************************************************************************/
49 :
50 : class OGRGeometry;
51 : class OGRRawPoint;
52 : class OGRPoint;
53 : class OGRMultiPoint;
54 : class OGRLineString;
55 : class OGRMultiLineString;
56 : class OGRLinearRing;
57 : class OGRPolygon;
58 : class OGRMultiPolygon;
59 : class OGRGeometryCollection;
60 : class OGRFeature;
61 : class OGRGeoJSONLayer;
62 : class OGRSpatialReference;
63 :
64 : /************************************************************************/
65 : /* GeoJSONObject */
66 : /************************************************************************/
67 :
68 : struct GeoJSONObject
69 : {
70 : enum Type
71 : {
72 : eUnknown = wkbUnknown, // non-GeoJSON properties
73 : ePoint = wkbPoint,
74 : eLineString = wkbLineString,
75 : ePolygon = wkbPolygon,
76 : eMultiPoint = wkbMultiPoint,
77 : eMultiLineString = wkbMultiLineString,
78 : eMultiPolygon = wkbMultiPolygon,
79 : eGeometryCollection = wkbGeometryCollection,
80 : eFeature,
81 : eFeatureCollection
82 : };
83 :
84 : enum CoordinateDimension
85 : {
86 : eMinCoordinateDimension = 2,
87 : eMaxCoordinateDimension = 3
88 : };
89 : };
90 :
91 : /************************************************************************/
92 : /* OGRGeoJSONBaseReader */
93 : /************************************************************************/
94 :
95 530 : class OGRGeoJSONBaseReader
96 : {
97 : public:
98 : OGRGeoJSONBaseReader();
99 :
100 : void SetPreserveGeometryType(bool bPreserve);
101 : void SetSkipAttributes(bool bSkip);
102 : void SetFlattenNestedAttributes(bool bFlatten, char chSeparator);
103 : void SetStoreNativeData(bool bStoreNativeData);
104 : void SetArrayAsString(bool bArrayAsString);
105 : void SetDateAsString(bool bDateAsString);
106 :
107 : bool GenerateFeatureDefn(
108 : std::map<std::string, int> &oMapFieldNameToIdx,
109 : std::vector<std::unique_ptr<OGRFieldDefn>> &apoFieldDefn,
110 : gdal::DirectedAcyclicGraph<int, std::string> &dag, OGRLayer *poLayer,
111 : json_object *poObj);
112 : void FinalizeLayerDefn(OGRLayer *poLayer, CPLString &osFIDColumn);
113 :
114 : OGRGeometry *ReadGeometry(json_object *poObj,
115 : OGRSpatialReference *poLayerSRS);
116 : OGRFeature *ReadFeature(OGRLayer *poLayer, json_object *poObj,
117 : const char *pszSerializedObj);
118 :
119 : bool ExtentRead() const;
120 :
121 : OGREnvelope3D GetExtent3D() const;
122 :
123 : protected:
124 : bool bGeometryPreserve_ = true;
125 : bool bAttributesSkip_ = false;
126 : bool bFlattenNestedAttributes_ = false;
127 : char chNestedAttributeSeparator_ = 0;
128 : bool bStoreNativeData_ = false;
129 : bool bArrayAsString_ = false;
130 : bool bDateAsString_ = false;
131 :
132 : private:
133 : std::set<int> aoSetUndeterminedTypeFields_;
134 :
135 : // bFlatten... is a tri-state boolean with -1 being unset.
136 : int bFlattenGeocouchSpatiallistFormat = -1;
137 :
138 : bool bFoundGeocouchId = false;
139 : bool bFoundRev = false;
140 : bool bFoundTypeFeature = false;
141 : bool bIsGeocouchSpatiallistFormat = false;
142 : bool bFeatureLevelIdAsAttribute_ = false;
143 : bool bFeatureLevelIdAsFID_ = false;
144 : bool m_bNeedFID64 = false;
145 :
146 : bool m_bFirstGeometry = true;
147 : OGREnvelope3D m_oEnvelope3D;
148 : // Becomes true when extent has been read from data
149 : bool m_bExtentRead = false;
150 : OGRwkbGeometryType m_eLayerGeomType = wkbUnknown;
151 :
152 : CPL_DISALLOW_COPY_ASSIGN(OGRGeoJSONBaseReader)
153 : };
154 :
155 : /************************************************************************/
156 : /* OGRGeoJSONReader */
157 : /************************************************************************/
158 :
159 : class OGRGeoJSONDataSource;
160 : class OGRGeoJSONReaderStreamingParser;
161 :
162 : class OGRGeoJSONReader : public OGRGeoJSONBaseReader
163 : {
164 : public:
165 : OGRGeoJSONReader();
166 : ~OGRGeoJSONReader();
167 :
168 : OGRErr Parse(const char *pszText);
169 : void ReadLayers(OGRGeoJSONDataSource *poDS);
170 : void ReadLayer(OGRGeoJSONDataSource *poDS, const char *pszName,
171 : json_object *poObj);
172 : bool FirstPassReadLayer(OGRGeoJSONDataSource *poDS, VSILFILE *fp,
173 : bool &bTryStandardReading);
174 :
175 404 : json_object *GetJSonObject()
176 : {
177 404 : return poGJObject_;
178 : }
179 :
180 : void ResetReading();
181 : OGRFeature *GetNextFeature(OGRGeoJSONLayer *poLayer);
182 : OGRFeature *GetFeature(OGRGeoJSONLayer *poLayer, GIntBig nFID);
183 : bool IngestAll(OGRGeoJSONLayer *poLayer);
184 :
185 294 : VSILFILE *GetFP()
186 : {
187 294 : return fp_;
188 : }
189 :
190 290 : bool CanEasilyAppend() const
191 : {
192 290 : return bCanEasilyAppend_;
193 : }
194 :
195 289 : bool FCHasBBOX() const
196 : {
197 289 : return bFCHasBBOX_;
198 : }
199 :
200 : private:
201 : friend class OGRGeoJSONReaderStreamingParser;
202 :
203 : json_object *poGJObject_;
204 : OGRGeoJSONReaderStreamingParser *poStreamingParser_;
205 : bool bFirstSeg_;
206 : bool bJSonPLikeWrapper_;
207 : VSILFILE *fp_;
208 : bool bCanEasilyAppend_;
209 : bool bFCHasBBOX_;
210 : bool bOriginalIdModifiedEmitted_ = false;
211 :
212 : size_t nBufferSize_;
213 : GByte *pabyBuffer_;
214 :
215 : GIntBig nTotalFeatureCount_;
216 : GUIntBig nTotalOGRFeatureMemEstimate_;
217 :
218 : std::map<GIntBig, std::pair<vsi_l_offset, vsi_l_offset>>
219 : oMapFIDToOffsetSize_;
220 : //
221 : // Copy operations not supported.
222 : //
223 : CPL_DISALLOW_COPY_ASSIGN(OGRGeoJSONReader)
224 :
225 : //
226 : // Translation utilities.
227 : //
228 : bool GenerateLayerDefn(OGRGeoJSONLayer *poLayer, json_object *poGJObject);
229 :
230 : static bool AddFeature(OGRGeoJSONLayer *poLayer, OGRGeometry *poGeometry);
231 : static bool AddFeature(OGRGeoJSONLayer *poLayer, OGRFeature *poFeature);
232 :
233 : void ReadFeatureCollection(OGRGeoJSONLayer *poLayer, json_object *poObj);
234 : size_t SkipPrologEpilogAndUpdateJSonPLikeWrapper(size_t nRead);
235 : };
236 :
237 : void OGRGeoJSONGenerateFeatureDefnDealWithID(
238 : json_object *poObj, json_object *poObjProps, int &nPrevFieldIdx,
239 : std::map<std::string, int> &oMapFieldNameToIdx,
240 : std::vector<std::unique_ptr<OGRFieldDefn>> &apoFieldDefn,
241 : gdal::DirectedAcyclicGraph<int, std::string> &dag,
242 : bool &bFeatureLevelIdAsFID, bool &bFeatureLevelIdAsAttribute,
243 : bool &bNeedFID64);
244 :
245 : void OGRGeoJSONReaderSetField(OGRLayer *poLayer, OGRFeature *poFeature,
246 : int nField, const char *pszAttrPrefix,
247 : json_object *poVal, bool bFlattenNestedAttributes,
248 : char chNestedAttributeSeparator);
249 : void OGRGeoJSONReaderAddOrUpdateField(
250 : std::vector<int> &retIndices,
251 : std::map<std::string, int> &oMapFieldNameToIdx,
252 : std::vector<std::unique_ptr<OGRFieldDefn>> &apoFieldDefn,
253 : const char *pszKey, json_object *poVal, bool bFlattenNestedAttributes,
254 : char chNestedAttributeSeparator, bool bArrayAsString, bool bDateAsString,
255 : std::set<int> &aoSetUndeterminedTypeFields);
256 :
257 : /************************************************************************/
258 : /* GeoJSON Parsing Utilities */
259 : /************************************************************************/
260 :
261 : lh_entry *OGRGeoJSONFindMemberEntryByName(json_object *poObj,
262 : const char *pszName);
263 : json_object *OGRGeoJSONFindMemberByName(json_object *poObj,
264 : const char *pszName);
265 : GeoJSONObject::Type OGRGeoJSONGetType(json_object *poObj);
266 :
267 : json_object CPL_DLL *json_ex_get_object_by_path(json_object *poObj,
268 : const char *pszPath);
269 :
270 : json_object CPL_DLL *CPL_json_object_object_get(struct json_object *obj,
271 : const char *key);
272 :
273 : bool CPL_DLL OGRJSonParse(const char *pszText, json_object **ppoObj,
274 : bool bVerboseError = true);
275 :
276 : bool OGRGeoJSONUpdateLayerGeomType(bool &bFirstGeom,
277 : OGRwkbGeometryType eGeomType,
278 : OGRwkbGeometryType &eLayerGeomType);
279 :
280 : // Get the 3D extent from the geometry coordinates of a feature
281 : bool OGRGeoJSONGetExtent3D(json_object *poObj, OGREnvelope3D *poEnvelope);
282 :
283 : /************************************************************************/
284 : /* GeoJSON Geometry Translators */
285 : /************************************************************************/
286 :
287 : OGRwkbGeometryType OGRGeoJSONGetOGRGeometryType(json_object *poObj);
288 :
289 : bool OGRGeoJSONReadRawPoint(json_object *poObj, OGRPoint &point);
290 : OGRGeometry CPL_DLL *
291 : OGRGeoJSONReadGeometry(json_object *poObj,
292 : OGRSpatialReference *poParentSRS = nullptr);
293 : OGRPoint *OGRGeoJSONReadPoint(json_object *poObj);
294 : OGRMultiPoint *OGRGeoJSONReadMultiPoint(json_object *poObj);
295 : OGRLineString *OGRGeoJSONReadLineString(json_object *poObj, bool bRaw = false);
296 : OGRMultiLineString *OGRGeoJSONReadMultiLineString(json_object *poObj);
297 : OGRLinearRing *OGRGeoJSONReadLinearRing(json_object *poObj);
298 : OGRPolygon *OGRGeoJSONReadPolygon(json_object *poObj, bool bRaw = false);
299 : OGRMultiPolygon *OGRGeoJSONReadMultiPolygon(json_object *poObj);
300 : OGRGeometryCollection *
301 : OGRGeoJSONReadGeometryCollection(json_object *poObj,
302 : OGRSpatialReference *poSRS = nullptr);
303 : OGRSpatialReference *OGRGeoJSONReadSpatialReference(json_object *poObj);
304 :
305 : /************************************************************************/
306 : /* OGRESRIJSONReader */
307 : /************************************************************************/
308 :
309 : class OGRESRIJSONReader
310 : {
311 : public:
312 : OGRESRIJSONReader();
313 : ~OGRESRIJSONReader();
314 :
315 : OGRErr Parse(const char *pszText);
316 : void ReadLayers(OGRGeoJSONDataSource *poDS, GeoJSONSourceType eSourceType);
317 :
318 19 : json_object *GetJSonObject()
319 : {
320 19 : return poGJObject_;
321 : }
322 :
323 : private:
324 : json_object *poGJObject_;
325 : OGRGeoJSONLayer *poLayer_;
326 :
327 : //
328 : // Copy operations not supported.
329 : //
330 : OGRESRIJSONReader(OGRESRIJSONReader const &);
331 : OGRESRIJSONReader &operator=(OGRESRIJSONReader const &);
332 :
333 : //
334 : // Translation utilities.
335 : //
336 : bool GenerateLayerDefn();
337 : bool ParseField(json_object *poObj);
338 : bool AddFeature(OGRFeature *poFeature);
339 :
340 : OGRFeature *ReadFeature(json_object *poObj);
341 : OGRGeoJSONLayer *ReadFeatureCollection(json_object *poObj);
342 : };
343 :
344 : OGRGeometry *OGRESRIJSONReadGeometry(json_object *poObj);
345 : OGRSpatialReference *OGRESRIJSONReadSpatialReference(json_object *poObj);
346 : OGRwkbGeometryType OGRESRIJSONGetGeometryType(json_object *poObj);
347 : OGRPoint *OGRESRIJSONReadPoint(json_object *poObj);
348 : OGRGeometry *OGRESRIJSONReadLineString(json_object *poObj);
349 : OGRGeometry *OGRESRIJSONReadPolygon(json_object *poObj);
350 : OGRMultiPoint *OGRESRIJSONReadMultiPoint(json_object *poObj);
351 :
352 : /************************************************************************/
353 : /* OGRTopoJSONReader */
354 : /************************************************************************/
355 :
356 : class OGRTopoJSONReader
357 : {
358 : public:
359 : OGRTopoJSONReader();
360 : ~OGRTopoJSONReader();
361 :
362 : OGRErr Parse(const char *pszText, bool bLooseIdentification);
363 : void ReadLayers(OGRGeoJSONDataSource *poDS);
364 :
365 : private:
366 : json_object *poGJObject_;
367 :
368 : //
369 : // Copy operations not supported.
370 : //
371 : OGRTopoJSONReader(OGRTopoJSONReader const &);
372 : OGRTopoJSONReader &operator=(OGRTopoJSONReader const &);
373 : };
374 :
375 : #endif /* OGR_GEOJSONUTILS_H_INCLUDED */
|