/src/gdal/ogr/ogrsf_frmts/jsonfg/ogrjsonfgstreamedlayer.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 | | /* OGRJSONFGStreamedLayer::OGRJSONFGStreamedLayer() */ |
17 | | /************************************************************************/ |
18 | | |
19 | | OGRJSONFGStreamedLayer::OGRJSONFGStreamedLayer(GDALDataset *poDS, |
20 | | const char *pszName, |
21 | | OGRSpatialReference *poSRS, |
22 | | OGRwkbGeometryType eGType) |
23 | 15 | : m_poDS(poDS), poFeatureDefn_(new OGRFeatureDefn(pszName)) |
24 | 15 | { |
25 | | |
26 | 15 | poFeatureDefn_->Reference(); |
27 | | |
28 | 15 | SetDescription(poFeatureDefn_->GetName()); |
29 | 15 | poFeatureDefn_->SetGeomType(eGType); |
30 | | |
31 | 15 | if (eGType != wkbNone && poSRS != nullptr) |
32 | 13 | { |
33 | 13 | OGRSpatialReference *poSRSClone = poSRS->Clone(); |
34 | 13 | poFeatureDefn_->GetGeomFieldDefn(0)->SetSpatialRef(poSRSClone); |
35 | 13 | poSRSClone->Release(); |
36 | 13 | } |
37 | | |
38 | 15 | poFeatureDefn_->Seal(/* bSealFields = */ true); |
39 | 15 | } |
40 | | |
41 | | /************************************************************************/ |
42 | | /* OGRJSONFGStreamedLayer::~OGRJSONFGStreamedLayer() */ |
43 | | /************************************************************************/ |
44 | | |
45 | | OGRJSONFGStreamedLayer::~OGRJSONFGStreamedLayer() |
46 | 15 | { |
47 | 15 | poFeatureDefn_->Release(); |
48 | 15 | } |
49 | | |
50 | | /************************************************************************/ |
51 | | /* SetFile() */ |
52 | | /************************************************************************/ |
53 | | |
54 | | void OGRJSONFGStreamedLayer::SetFile(VSIVirtualHandleUniquePtr &&poFile) |
55 | 15 | { |
56 | 15 | poFile_ = std::move(poFile); |
57 | 15 | poFile_->Seek(0, SEEK_SET); |
58 | 15 | } |
59 | | |
60 | | /************************************************************************/ |
61 | | /* SetStreamingParser() */ |
62 | | /************************************************************************/ |
63 | | |
64 | | void OGRJSONFGStreamedLayer::SetStreamingParser( |
65 | | std::unique_ptr<OGRJSONFGStreamingParser> &&poStreamingParser) |
66 | 15 | { |
67 | 15 | poStreamingParser_ = std::move(poStreamingParser); |
68 | 15 | poStreamingParser_->SetRequestedLayer(GetName()); |
69 | 15 | } |
70 | | |
71 | | /************************************************************************/ |
72 | | /* ResetReading() */ |
73 | | /************************************************************************/ |
74 | | |
75 | | void OGRJSONFGStreamedLayer::ResetReading() |
76 | 0 | { |
77 | 0 | CPLAssert(poFile_); |
78 | 0 | CPLAssert(poStreamingParser_); |
79 | 0 | poStreamingParser_ = poStreamingParser_->Clone(); |
80 | 0 | poFile_->Seek(0, SEEK_SET); |
81 | 0 | oSetUsedFIDs_.clear(); |
82 | 0 | } |
83 | | |
84 | | /************************************************************************/ |
85 | | /* EnsureUniqueFID() */ |
86 | | /************************************************************************/ |
87 | | |
88 | | OGRFeature *OGRJSONFGStreamedLayer::EnsureUniqueFID(OGRFeature *poFeat) |
89 | 28 | { |
90 | 28 | GIntBig nFID = poFeat->GetFID(); |
91 | 28 | if (nFID == OGRNullFID) |
92 | 7 | { |
93 | 7 | nFID = static_cast<GIntBig>(oSetUsedFIDs_.size()); |
94 | 7 | while (oSetUsedFIDs_.find(nFID) != oSetUsedFIDs_.end()) |
95 | 0 | { |
96 | 0 | ++nFID; |
97 | 0 | } |
98 | 7 | } |
99 | 21 | else if (oSetUsedFIDs_.find(nFID) != oSetUsedFIDs_.end()) |
100 | 4 | { |
101 | 4 | if (!bOriginalIdModified_) |
102 | 4 | { |
103 | 4 | CPLError(CE_Warning, CPLE_AppDefined, |
104 | 4 | "Several features with id = " CPL_FRMT_GIB " have " |
105 | 4 | "been found. Altering it to be unique. " |
106 | 4 | "This warning will not be emitted anymore for " |
107 | 4 | "this layer", |
108 | 4 | nFID); |
109 | 4 | bOriginalIdModified_ = true; |
110 | 4 | } |
111 | 4 | nFID = static_cast<GIntBig>(oSetUsedFIDs_.size()); |
112 | 7 | while (oSetUsedFIDs_.find(nFID) != oSetUsedFIDs_.end()) |
113 | 3 | { |
114 | 3 | ++nFID; |
115 | 3 | } |
116 | 4 | } |
117 | 28 | oSetUsedFIDs_.insert(nFID); |
118 | 28 | poFeat->SetFID(nFID); |
119 | 28 | return poFeat; |
120 | 28 | } |
121 | | |
122 | | /************************************************************************/ |
123 | | /* GetNextRawFeature() */ |
124 | | /************************************************************************/ |
125 | | |
126 | | OGRFeature *OGRJSONFGStreamedLayer::GetNextRawFeature() |
127 | 43 | { |
128 | 43 | CPLAssert(poFile_); |
129 | 43 | CPLAssert(poStreamingParser_); |
130 | | |
131 | 43 | auto poFeatAndLayer = poStreamingParser_->GetNextFeature(); |
132 | 43 | if (poFeatAndLayer.first) |
133 | 13 | { |
134 | 13 | return EnsureUniqueFID(poFeatAndLayer.first.release()); |
135 | 13 | } |
136 | | |
137 | 30 | std::vector<GByte> abyBuffer; |
138 | 30 | abyBuffer.resize(4096 * 10); |
139 | 30 | while (true) |
140 | 30 | { |
141 | 30 | size_t nRead = poFile_->Read(abyBuffer.data(), 1, abyBuffer.size()); |
142 | 30 | const bool bFinished = nRead < abyBuffer.size(); |
143 | 30 | if (!poStreamingParser_->Parse( |
144 | 30 | std::string_view( |
145 | 30 | reinterpret_cast<const char *>(abyBuffer.data()), nRead), |
146 | 30 | bFinished) || |
147 | 30 | poStreamingParser_->ExceptionOccurred()) |
148 | 0 | { |
149 | 0 | break; |
150 | 0 | } |
151 | | |
152 | 30 | poFeatAndLayer = poStreamingParser_->GetNextFeature(); |
153 | 30 | if (poFeatAndLayer.first) |
154 | 15 | { |
155 | 15 | return EnsureUniqueFID(poFeatAndLayer.first.release()); |
156 | 15 | } |
157 | 15 | if (bFinished) |
158 | 15 | break; |
159 | 15 | } |
160 | | |
161 | 15 | return nullptr; |
162 | 30 | } |
163 | | |
164 | | /************************************************************************/ |
165 | | /* TestCapability() */ |
166 | | /************************************************************************/ |
167 | | |
168 | | int OGRJSONFGStreamedLayer::TestCapability(const char *pszCap) const |
169 | | |
170 | 0 | { |
171 | 0 | if (EQUAL(pszCap, OLCFastFeatureCount)) |
172 | 0 | return !m_poFilterGeom && !m_poAttrQuery && nFeatureCount_ >= 0; |
173 | | |
174 | 0 | else if (EQUAL(pszCap, OLCStringsAsUTF8)) |
175 | 0 | return TRUE; |
176 | | |
177 | 0 | else if (EQUAL(pszCap, OLCZGeometries) || |
178 | 0 | EQUAL(pszCap, OLCMeasuredGeometries) || |
179 | 0 | EQUAL(pszCap, OLCCurveGeometries)) |
180 | 0 | { |
181 | 0 | return TRUE; |
182 | 0 | } |
183 | | |
184 | 0 | return FALSE; |
185 | 0 | } |
186 | | |
187 | | /************************************************************************/ |
188 | | /* GetFeatureCount() */ |
189 | | /************************************************************************/ |
190 | | |
191 | | GIntBig OGRJSONFGStreamedLayer::GetFeatureCount(int bForce) |
192 | 0 | { |
193 | 0 | if (!m_poFilterGeom && !m_poAttrQuery && nFeatureCount_ >= 0) |
194 | 0 | return nFeatureCount_; |
195 | 0 | return OGRLayer::GetFeatureCount(bForce); |
196 | 0 | } |