Line data Source code
1 : /******************************************************************************
2 : *
3 : * Project: FlatGeobuf driver
4 : * Purpose: Declaration of classes for OGR FlatGeobuf driver.
5 : * Author: Björn Harrtell <bjorn at wololo dot org>
6 : *
7 : ******************************************************************************
8 : * Copyright (c) 2018-2020, Björn Harrtell <bjorn at wololo dot org>
9 : *
10 : * Permission is hereby granted, free of charge, to any person obtaining a
11 : * copy of this software and associated documentation files (the "Software"),
12 : * to deal in the Software without restriction, including without limitation
13 : * the rights to use, copy, modify, merge, publish, distribute, sublicense,
14 : * and/or sell copies of the Software, and to permit persons to whom the
15 : * Software is furnished to do so, subject to the following conditions:
16 : *
17 : * The above copyright notice and this permission notice shall be included
18 : * in all copies or substantial portions of the Software.
19 : *
20 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21 : * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23 : * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 : * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
25 : * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26 : * DEALINGS IN THE SOFTWARE.
27 : ****************************************************************************/
28 :
29 : #ifndef OGR_FLATGEOBUF_H_INCLUDED
30 : #define OGR_FLATGEOBUF_H_INCLUDED
31 :
32 : #include "ogrsf_frmts.h"
33 : #include "ogr_p.h"
34 : #include "ogreditablelayer.h"
35 :
36 : #include "header_generated.h"
37 : #include "feature_generated.h"
38 : #include "packedrtree.h"
39 :
40 : #include <deque>
41 : #include <limits>
42 :
43 : class OGRFlatGeobufDataset;
44 :
45 : static constexpr uint8_t magicbytes[8] = {0x66, 0x67, 0x62, 0x03,
46 : 0x66, 0x67, 0x62, 0x01};
47 :
48 : static constexpr uint32_t header_max_buffer_size = 1048576 * 10;
49 :
50 : // Cannot be larger than that, due to a x2 logic done in ensureFeatureBuf()
51 : static constexpr uint32_t feature_max_buffer_size =
52 : static_cast<uint32_t>(std::numeric_limits<int32_t>::max());
53 :
54 : // holds feature meta needed to build spatial index
55 : struct FeatureItem : FlatGeobuf::Item
56 : {
57 : uint32_t size;
58 : uint64_t offset;
59 : };
60 :
61 313 : class OGRFlatGeobufBaseLayerInterface CPL_NON_FINAL
62 : {
63 : public:
64 : virtual ~OGRFlatGeobufBaseLayerInterface();
65 :
66 : virtual const std::string &GetFilename() const = 0;
67 : virtual OGRLayer *GetLayer() = 0;
68 : virtual CPLErr Close() = 0;
69 : };
70 :
71 : class OGRFlatGeobufLayer final : public OGRLayer,
72 : public OGRFlatGeobufBaseLayerInterface
73 : {
74 : private:
75 : std::string m_osFilename;
76 : std::string m_osLayerName;
77 :
78 : VSILFILE *m_poFp = nullptr;
79 : vsi_l_offset m_nFileSize = 0;
80 :
81 : const FlatGeobuf::Header *m_poHeader = nullptr;
82 : GByte *m_headerBuf = nullptr;
83 : OGRwkbGeometryType m_eGType;
84 : FlatGeobuf::GeometryType m_geometryType;
85 : bool m_hasM = false;
86 : bool m_hasZ = false;
87 : bool m_hasT = false;
88 : bool m_hasTM = false;
89 : uint64_t m_featuresCount = 0;
90 : OGREnvelope m_sExtent;
91 : OGRFeatureDefn *m_poFeatureDefn = nullptr;
92 : OGRSpatialReference *m_poSRS = nullptr;
93 :
94 : // iteration
95 : bool m_bEOF = false;
96 : size_t m_featuresPos = 0; // current iteration position
97 : uint64_t m_offset = 0; // current read offset
98 : uint64_t m_offsetFeatures = 0; // offset of feature data
99 : std::vector<FlatGeobuf::SearchResultItem>
100 : m_foundItems; // found node items in spatial index search
101 : bool m_queriedSpatialIndex = false;
102 : bool m_ignoreSpatialFilter = false;
103 : bool m_ignoreAttributeFilter = false;
104 :
105 : // creation
106 : GDALDataset *m_poDS = nullptr; // parent dataset to get metadata from it
107 : bool m_create = false;
108 : std::deque<FeatureItem> m_featureItems; // feature item description used to
109 : // create spatial index
110 : bool m_bCreateSpatialIndexAtClose = true;
111 : bool m_bVerifyBuffers = true;
112 : VSILFILE *m_poFpWrite = nullptr;
113 : CPLStringList m_aosCreationOption{}; // layer creation options
114 : uint64_t m_writeOffset = 0; // current write offset
115 : uint64_t m_offsetAfterHeader =
116 : 0; // offset after dummy header writing (when creating a file without
117 : // spatial index)
118 : uint16_t m_indexNodeSize = 0;
119 : std::string
120 : m_osTempFile; // holds generated temp file name for two pass writing
121 : uint32_t m_maxFeatureSize = 0;
122 : std::vector<uint8_t> m_writeProperties{};
123 :
124 : // shared
125 : GByte *m_featureBuf = nullptr; // reusable/resizable feature data buffer
126 : uint32_t m_featureBufSize = 0; // current feature buffer size
127 :
128 : // deserialize
129 : void ensurePadfBuffers(size_t count);
130 : OGRErr ensureFeatureBuf(uint32_t featureSize);
131 : OGRErr parseFeature(OGRFeature *poFeature);
132 : const std::vector<flatbuffers::Offset<FlatGeobuf::Column>>
133 : writeColumns(flatbuffers::FlatBufferBuilder &fbb);
134 : void readColumns();
135 : OGRErr readIndex();
136 : OGRErr readFeatureOffset(uint64_t index, uint64_t &featureOffset);
137 :
138 : // serialize
139 : bool CreateFinalFile();
140 : void writeHeader(VSILFILE *poFp, uint64_t featuresCount,
141 : std::vector<double> *extentVector);
142 :
143 : // construction
144 : OGRFlatGeobufLayer(const FlatGeobuf::Header *, GByte *headerBuf,
145 : const char *pszFilename, VSILFILE *poFp,
146 : uint64_t offset);
147 : OGRFlatGeobufLayer(GDALDataset *poDS, const char *pszLayerName,
148 : const char *pszFilename,
149 : const OGRSpatialReference *poSpatialRef,
150 : OGRwkbGeometryType eGType,
151 : bool bCreateSpatialIndexAtClose, VSILFILE *poFpWrite,
152 : std::string &osTempFile, CSLConstList papszOptions);
153 :
154 : protected:
155 : virtual int GetNextArrowArray(struct ArrowArrayStream *,
156 : struct ArrowArray *out_array) override;
157 :
158 : CPLErr Close() override;
159 :
160 : public:
161 : virtual ~OGRFlatGeobufLayer();
162 :
163 : static OGRFlatGeobufLayer *Open(const FlatGeobuf::Header *,
164 : GByte *headerBuf, const char *pszFilename,
165 : VSILFILE *poFp, uint64_t offset);
166 : static OGRFlatGeobufLayer *Open(const char *pszFilename, VSILFILE *fp,
167 : bool bVerifyBuffers);
168 : static OGRFlatGeobufLayer *
169 : Create(GDALDataset *poDS, const char *pszLayerName, const char *pszFilename,
170 : const OGRSpatialReference *poSpatialRef, OGRwkbGeometryType eGType,
171 : bool bCreateSpatialIndexAtClose, CSLConstList papszOptions);
172 :
173 : virtual OGRFeature *GetFeature(GIntBig nFeatureId) override;
174 : virtual OGRFeature *GetNextFeature() override;
175 : virtual OGRErr CreateField(const OGRFieldDefn *poField,
176 : int bApproxOK = true) override;
177 : virtual OGRErr ICreateFeature(OGRFeature *poFeature) override;
178 : virtual int TestCapability(const char *) override;
179 :
180 : virtual void ResetReading() override;
181 :
182 968 : virtual OGRFeatureDefn *GetLayerDefn() override
183 : {
184 968 : return m_poFeatureDefn;
185 : }
186 :
187 : virtual GIntBig GetFeatureCount(int bForce) override;
188 : virtual OGRErr GetExtent(OGREnvelope *psExtent, int bForce) override;
189 :
190 7 : virtual OGRErr GetExtent(int iGeomField, OGREnvelope *psExtent,
191 : int bForce) override
192 : {
193 7 : return OGRLayer::GetExtent(iGeomField, psExtent, bForce);
194 : }
195 :
196 145 : void VerifyBuffers(int bFlag)
197 : {
198 145 : m_bVerifyBuffers = CPL_TO_BOOL(bFlag);
199 145 : }
200 :
201 38 : GDALDataset *GetDataset() override
202 : {
203 38 : return m_poDS;
204 : }
205 :
206 4 : const std::string &GetFilename() const override
207 : {
208 4 : return m_osFilename;
209 : }
210 :
211 647 : OGRLayer *GetLayer() override
212 : {
213 647 : return this;
214 : }
215 :
216 : static std::string GetTempFilePath(const CPLString &fileName,
217 : CSLConstList papszOptions);
218 : static VSILFILE *CreateOutputFile(const CPLString &pszFilename,
219 : CSLConstList papszOptions, bool isTemp);
220 :
221 1 : uint16_t GetIndexNodeSize() const
222 : {
223 1 : return m_indexNodeSize;
224 : }
225 :
226 : OGRwkbGeometryType getOGRwkbGeometryType();
227 : };
228 :
229 : class OGRFlatGeobufEditableLayer final : public OGREditableLayer,
230 : public OGRFlatGeobufBaseLayerInterface
231 : {
232 : public:
233 : OGRFlatGeobufEditableLayer(OGRFlatGeobufLayer *poFlatGeobufLayer,
234 : char **papszOpenOptions);
235 :
236 : virtual GIntBig GetFeatureCount(int bForce = TRUE) override;
237 :
238 0 : const std::string &GetFilename() const override
239 : {
240 0 : return static_cast<OGRFlatGeobufLayer *>(m_poDecoratedLayer)
241 0 : ->GetFilename();
242 : }
243 :
244 2 : OGRLayer *GetLayer() override
245 : {
246 2 : return this;
247 : }
248 :
249 : int TestCapability(const char *pszCap) override;
250 :
251 1 : CPLErr Close() override
252 : {
253 1 : return CE_None;
254 : }
255 : };
256 :
257 : class OGRFlatGeobufDataset final : public GDALDataset
258 : {
259 : private:
260 : std::vector<std::unique_ptr<OGRFlatGeobufBaseLayerInterface>> m_apoLayers;
261 : bool m_bCreate = false;
262 : bool m_bUpdate = false;
263 : bool m_bIsDir = false;
264 :
265 : bool OpenFile(const char *pszFilename, VSILFILE *fp, bool bVerifyBuffers);
266 :
267 : CPLErr Close() override;
268 :
269 : public:
270 : OGRFlatGeobufDataset(const char *pszName, bool bIsDir, bool bCreate,
271 : bool bUpdate);
272 : ~OGRFlatGeobufDataset();
273 :
274 : static GDALDataset *Open(GDALOpenInfo *);
275 : static GDALDataset *Create(const char *pszName, CPL_UNUSED int nBands,
276 : CPL_UNUSED int nXSize, CPL_UNUSED int nYSize,
277 : CPL_UNUSED GDALDataType eDT,
278 : char **papszOptions);
279 : virtual OGRLayer *GetLayer(int) override;
280 : int TestCapability(const char *pszCap) override;
281 :
282 : OGRLayer *ICreateLayer(const char *pszName,
283 : const OGRGeomFieldDefn *poGeomFieldDefn,
284 : CSLConstList papszOptions) override;
285 :
286 1560 : virtual int GetLayerCount() override
287 : {
288 1560 : return static_cast<int>(m_apoLayers.size());
289 : }
290 :
291 : char **GetFileList() override;
292 : };
293 :
294 : #endif /* ndef OGR_FLATGEOBUF_H_INCLUDED */
|