/src/gdal/ogr/ogrsf_frmts/jsonfg/ogrjsonfgstreamingparser.cpp
Line | Count | Source |
1 | | /****************************************************************************** |
2 | | * |
3 | | * Project: OpenGIS Simple Features Reference Implementation |
4 | | * Purpose: Implementation of OGC Features and Geometries JSON (JSON-FG) |
5 | | * Author: Even Rouault <even.rouault at spatialys.com> |
6 | | * |
7 | | ****************************************************************************** |
8 | | * Copyright (c) 2023, Even Rouault <even.rouault at spatialys.com> |
9 | | * |
10 | | * SPDX-License-Identifier: MIT |
11 | | ****************************************************************************/ |
12 | | |
13 | | #include "ogr_jsonfg.h" |
14 | | |
15 | | /************************************************************************/ |
16 | | /* OGRJSONFGStreamingParserGetMaxObjectSize() */ |
17 | | /************************************************************************/ |
18 | | |
19 | | static size_t OGRJSONFGStreamingParserGetMaxObjectSize() |
20 | 251 | { |
21 | 251 | const double dfTmp = |
22 | 251 | CPLAtof(CPLGetConfigOption("OGR_JSONFG_MAX_OBJ_SIZE", "200")); |
23 | 251 | return dfTmp > 0 ? static_cast<size_t>(dfTmp * 1024 * 1024) : 0; |
24 | 251 | } |
25 | | |
26 | | /************************************************************************/ |
27 | | /* OGRJSONFGStreamingParser() */ |
28 | | /************************************************************************/ |
29 | | |
30 | | OGRJSONFGStreamingParser::OGRJSONFGStreamingParser(OGRJSONFGReader &oReader, |
31 | | bool bFirstPass, |
32 | | bool bHasTopLevelMeasures) |
33 | 251 | : OGRJSONCollectionStreamingParser( |
34 | 251 | bFirstPass, /*bStoreNativeData=*/false, |
35 | 251 | OGRJSONFGStreamingParserGetMaxObjectSize()), |
36 | 251 | m_oReader(oReader) |
37 | 251 | { |
38 | 251 | m_bHasTopLevelMeasures = bHasTopLevelMeasures; |
39 | 251 | } |
40 | | |
41 | | /************************************************************************/ |
42 | | /* ~OGRJSONFGStreamingParser() */ |
43 | | /************************************************************************/ |
44 | | |
45 | 251 | OGRJSONFGStreamingParser::~OGRJSONFGStreamingParser() = default; |
46 | | |
47 | | /************************************************************************/ |
48 | | /* OGRJSONFGStreamingParser::Clone() */ |
49 | | /************************************************************************/ |
50 | | |
51 | | std::unique_ptr<OGRJSONFGStreamingParser> OGRJSONFGStreamingParser::Clone() |
52 | 0 | { |
53 | 0 | auto poRet = std::make_unique<OGRJSONFGStreamingParser>( |
54 | 0 | m_oReader, IsFirstPass(), m_bHasTopLevelMeasures); |
55 | 0 | poRet->m_osRequestedLayer = m_osRequestedLayer; |
56 | 0 | return poRet; |
57 | 0 | } |
58 | | |
59 | | /************************************************************************/ |
60 | | /* GetNextFeature() */ |
61 | | /************************************************************************/ |
62 | | |
63 | | std::pair<std::unique_ptr<OGRFeature>, OGRLayer *> |
64 | | OGRJSONFGStreamingParser::GetNextFeature() |
65 | 91 | { |
66 | 91 | if (m_nCurFeatureIdx < m_apoFeatures.size()) |
67 | 37 | { |
68 | 37 | auto poRet = std::move(m_apoFeatures[m_nCurFeatureIdx]); |
69 | 37 | m_apoFeatures[m_nCurFeatureIdx].first = nullptr; |
70 | 37 | m_apoFeatures[m_nCurFeatureIdx].second = nullptr; |
71 | 37 | m_nCurFeatureIdx++; |
72 | 37 | return poRet; |
73 | 37 | } |
74 | 54 | m_nCurFeatureIdx = 0; |
75 | 54 | m_apoFeatures.clear(); |
76 | 54 | return std::pair(nullptr, nullptr); |
77 | 91 | } |
78 | | |
79 | | /************************************************************************/ |
80 | | /* AnalyzeFeature() */ |
81 | | /************************************************************************/ |
82 | | |
83 | | void OGRJSONFGStreamingParser::GotFeature(json_object *poObj, bool bFirstPass, |
84 | | const std::string & /*osJson*/) |
85 | 339 | { |
86 | 339 | if (bFirstPass) |
87 | 302 | { |
88 | 302 | m_oReader.GenerateLayerDefnFromFeature(poObj); |
89 | 302 | } |
90 | 37 | else |
91 | 37 | { |
92 | 37 | OGRJSONFGStreamedLayer *poStreamedLayer = nullptr; |
93 | 37 | auto poFeat = m_oReader.ReadFeature(poObj, m_osRequestedLayer.c_str(), |
94 | 37 | m_bHasTopLevelMeasures, nullptr, |
95 | 37 | &poStreamedLayer); |
96 | 37 | if (poFeat) |
97 | 37 | { |
98 | 37 | CPLAssert(poStreamedLayer); |
99 | 37 | m_apoFeatures.emplace_back( |
100 | 37 | std::pair(std::move(poFeat), poStreamedLayer)); |
101 | 37 | } |
102 | 37 | } |
103 | 339 | } |
104 | | |
105 | | /************************************************************************/ |
106 | | /* TooComplex() */ |
107 | | /************************************************************************/ |
108 | | |
109 | | void OGRJSONFGStreamingParser::TooComplex() |
110 | 0 | { |
111 | 0 | if (!ExceptionOccurred()) |
112 | 0 | EmitException("JSON object too complex/large. You may define the " |
113 | 0 | "OGR_JSONFG_MAX_OBJ_SIZE configuration option to " |
114 | 0 | "a value in megabytes to allow " |
115 | 0 | "for larger features, or 0 to remove any size limit."); |
116 | 0 | } |