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 : * SPDX-License-Identifier: MIT
11 : ****************************************************************************/
12 :
13 : #ifndef OGR_FLATGEOBUF_H_INCLUDED
14 : #define OGR_FLATGEOBUF_H_INCLUDED
15 :
16 : #include "ogrsf_frmts.h"
17 : #include "ogr_p.h"
18 : #include "ogreditablelayer.h"
19 :
20 : #if defined(__clang__)
21 : #pragma clang diagnostic push
22 : #pragma clang diagnostic ignored "-Wweak-vtables"
23 : #endif
24 :
25 : #include "header_generated.h"
26 : #include "feature_generated.h"
27 : #include "packedrtree.h"
28 :
29 : #if defined(__clang__)
30 : #pragma clang diagnostic pop
31 : #endif
32 :
33 : #include <deque>
34 : #include <limits>
35 :
36 : class OGRFlatGeobufDataset;
37 :
38 : static constexpr uint8_t magicbytes[8] = {0x66, 0x67, 0x62, 0x03,
39 : 0x66, 0x67, 0x62, 0x01};
40 :
41 : static constexpr uint32_t header_max_buffer_size = 1048576 * 10;
42 :
43 : // Cannot be larger than that, due to a x2 logic done in ensureFeatureBuf()
44 : static constexpr uint32_t feature_max_buffer_size =
45 : static_cast<uint32_t>(std::numeric_limits<int32_t>::max());
46 :
47 : // holds feature meta needed to build spatial index
48 : struct FeatureItem : FlatGeobuf::Item
49 : {
50 : uint32_t size;
51 : uint64_t offset;
52 : };
53 :
54 322 : class OGRFlatGeobufBaseLayerInterface CPL_NON_FINAL
55 : {
56 : public:
57 : virtual ~OGRFlatGeobufBaseLayerInterface();
58 :
59 : virtual const std::string &GetFilename() const = 0;
60 : virtual OGRLayer *GetLayer() = 0;
61 : virtual CPLErr Close() = 0;
62 : };
63 :
64 : class OGRFlatGeobufLayer final : public OGRLayer,
65 : public OGRFlatGeobufBaseLayerInterface
66 : {
67 : private:
68 : std::string m_osFilename;
69 : std::string m_osLayerName;
70 :
71 : VSILFILE *m_poFp = nullptr;
72 : vsi_l_offset m_nFileSize = 0;
73 :
74 : const FlatGeobuf::Header *m_poHeader = nullptr;
75 : GByte *m_headerBuf = nullptr;
76 : OGRwkbGeometryType m_eGType;
77 : FlatGeobuf::GeometryType m_geometryType;
78 : bool m_hasM = false;
79 : bool m_hasZ = false;
80 : bool m_hasT = false;
81 : bool m_hasTM = false;
82 : uint64_t m_featuresCount = 0;
83 : OGREnvelope m_sExtent;
84 : OGRFeatureDefn *m_poFeatureDefn = nullptr;
85 : OGRSpatialReference *m_poSRS = nullptr;
86 :
87 : // iteration
88 : bool m_bEOF = false;
89 : size_t m_featuresPos = 0; // current iteration position
90 : uint64_t m_offset = 0; // current read offset
91 : uint64_t m_offsetFeatures = 0; // offset of feature data
92 : std::vector<FlatGeobuf::SearchResultItem>
93 : m_foundItems; // found node items in spatial index search
94 : bool m_queriedSpatialIndex = false;
95 : bool m_ignoreSpatialFilter = false;
96 : bool m_ignoreAttributeFilter = false;
97 :
98 : // creation
99 : GDALDataset *m_poDS = nullptr; // parent dataset to get metadata from it
100 : bool m_create = false;
101 : std::deque<FeatureItem> m_featureItems; // feature item description used to
102 : // create spatial index
103 : bool m_bCreateSpatialIndexAtClose = true;
104 : bool m_bVerifyBuffers = true;
105 : VSILFILE *m_poFpWrite = nullptr;
106 : CPLStringList m_aosCreationOption{}; // layer creation options
107 : uint64_t m_writeOffset = 0; // current write offset
108 : uint64_t m_offsetAfterHeader =
109 : 0; // offset after dummy header writing (when creating a file without
110 : // spatial index)
111 : uint16_t m_indexNodeSize = 0;
112 : std::string
113 : m_osTempFile; // holds generated temp file name for two pass writing
114 : uint32_t m_maxFeatureSize = 0;
115 : std::vector<uint8_t> m_writeProperties{};
116 :
117 : // shared
118 : GByte *m_featureBuf = nullptr; // reusable/resizable feature data buffer
119 : uint32_t m_featureBufSize = 0; // current feature buffer size
120 :
121 : // deserialize
122 : void ensurePadfBuffers(size_t count);
123 : OGRErr ensureFeatureBuf(uint32_t featureSize);
124 : OGRErr parseFeature(OGRFeature *poFeature);
125 : const std::vector<flatbuffers::Offset<FlatGeobuf::Column>>
126 : writeColumns(flatbuffers::FlatBufferBuilder &fbb);
127 : void readColumns();
128 : OGRErr readIndex();
129 : OGRErr readFeatureOffset(uint64_t index, uint64_t &featureOffset);
130 :
131 : // serialize
132 : bool CreateFinalFile();
133 : void writeHeader(VSILFILE *poFp, uint64_t featuresCount,
134 : std::vector<double> *extentVector);
135 :
136 : // construction
137 : OGRFlatGeobufLayer(const FlatGeobuf::Header *, GByte *headerBuf,
138 : const char *pszFilename, VSILFILE *poFp,
139 : uint64_t offset);
140 : OGRFlatGeobufLayer(GDALDataset *poDS, const char *pszLayerName,
141 : const char *pszFilename,
142 : const OGRSpatialReference *poSpatialRef,
143 : OGRwkbGeometryType eGType,
144 : bool bCreateSpatialIndexAtClose, VSILFILE *poFpWrite,
145 : std::string &osTempFile, CSLConstList papszOptions);
146 :
147 : protected:
148 : virtual int GetNextArrowArray(struct ArrowArrayStream *,
149 : struct ArrowArray *out_array) override;
150 :
151 : CPLErr Close() override;
152 :
153 : public:
154 : virtual ~OGRFlatGeobufLayer();
155 :
156 : static OGRFlatGeobufLayer *Open(const FlatGeobuf::Header *,
157 : GByte *headerBuf, const char *pszFilename,
158 : VSILFILE *poFp, uint64_t offset);
159 : static OGRFlatGeobufLayer *Open(const char *pszFilename, VSILFILE *fp,
160 : bool bVerifyBuffers);
161 : static OGRFlatGeobufLayer *
162 : Create(GDALDataset *poDS, const char *pszLayerName, const char *pszFilename,
163 : const OGRSpatialReference *poSpatialRef, OGRwkbGeometryType eGType,
164 : bool bCreateSpatialIndexAtClose, CSLConstList papszOptions);
165 :
166 : virtual OGRFeature *GetFeature(GIntBig nFeatureId) override;
167 : virtual OGRFeature *GetNextFeature() override;
168 : virtual OGRErr CreateField(const OGRFieldDefn *poField,
169 : int bApproxOK = true) override;
170 : virtual OGRErr ICreateFeature(OGRFeature *poFeature) override;
171 : virtual int TestCapability(const char *) override;
172 :
173 : virtual void ResetReading() override;
174 :
175 1513 : virtual OGRFeatureDefn *GetLayerDefn() override
176 : {
177 1513 : return m_poFeatureDefn;
178 : }
179 :
180 : virtual GIntBig GetFeatureCount(int bForce) override;
181 : virtual OGRErr IGetExtent(int iGeomField, OGREnvelope *psExtent,
182 : bool bForce) override;
183 :
184 150 : void VerifyBuffers(int bFlag)
185 : {
186 150 : m_bVerifyBuffers = CPL_TO_BOOL(bFlag);
187 150 : }
188 :
189 39 : GDALDataset *GetDataset() override
190 : {
191 39 : return m_poDS;
192 : }
193 :
194 4 : const std::string &GetFilename() const override
195 : {
196 4 : return m_osFilename;
197 : }
198 :
199 740 : OGRLayer *GetLayer() override
200 : {
201 740 : return this;
202 : }
203 :
204 : static std::string GetTempFilePath(const CPLString &fileName,
205 : CSLConstList papszOptions);
206 : static VSILFILE *CreateOutputFile(const CPLString &pszFilename,
207 : CSLConstList papszOptions, bool isTemp);
208 :
209 1 : uint16_t GetIndexNodeSize() const
210 : {
211 1 : return m_indexNodeSize;
212 : }
213 :
214 : OGRwkbGeometryType getOGRwkbGeometryType();
215 : };
216 :
217 : class OGRFlatGeobufEditableLayer final : public OGREditableLayer,
218 : public OGRFlatGeobufBaseLayerInterface
219 : {
220 : public:
221 : OGRFlatGeobufEditableLayer(OGRFlatGeobufLayer *poFlatGeobufLayer,
222 : char **papszOpenOptions);
223 :
224 : virtual GIntBig GetFeatureCount(int bForce = TRUE) override;
225 :
226 0 : const std::string &GetFilename() const override
227 : {
228 0 : return static_cast<OGRFlatGeobufLayer *>(m_poDecoratedLayer)
229 0 : ->GetFilename();
230 : }
231 :
232 2 : OGRLayer *GetLayer() override
233 : {
234 2 : return this;
235 : }
236 :
237 : int TestCapability(const char *pszCap) override;
238 :
239 1 : CPLErr Close() override
240 : {
241 1 : return CE_None;
242 : }
243 : };
244 :
245 : class OGRFlatGeobufDataset final : public GDALDataset
246 : {
247 : private:
248 : std::vector<std::unique_ptr<OGRFlatGeobufBaseLayerInterface>> m_apoLayers;
249 : bool m_bCreate = false;
250 : bool m_bUpdate = false;
251 : bool m_bIsDir = false;
252 :
253 : bool OpenFile(const char *pszFilename, VSILFILE *fp, bool bVerifyBuffers);
254 :
255 : CPLErr Close() override;
256 :
257 : public:
258 : OGRFlatGeobufDataset(const char *pszName, bool bIsDir, bool bCreate,
259 : bool bUpdate);
260 : ~OGRFlatGeobufDataset();
261 :
262 : static GDALDataset *Open(GDALOpenInfo *);
263 : static GDALDataset *Create(const char *pszName, CPL_UNUSED int nBands,
264 : CPL_UNUSED int nXSize, CPL_UNUSED int nYSize,
265 : CPL_UNUSED GDALDataType eDT,
266 : char **papszOptions);
267 : virtual OGRLayer *GetLayer(int) override;
268 : int TestCapability(const char *pszCap) override;
269 :
270 : OGRLayer *ICreateLayer(const char *pszName,
271 : const OGRGeomFieldDefn *poGeomFieldDefn,
272 : CSLConstList papszOptions) override;
273 :
274 1844 : virtual int GetLayerCount() override
275 : {
276 1844 : return static_cast<int>(m_apoLayers.size());
277 : }
278 :
279 : char **GetFileList() override;
280 : };
281 :
282 : #endif /* ndef OGR_FLATGEOBUF_H_INCLUDED */
|