Line data Source code
1 : /******************************************************************************
2 : *
3 : * Project: VFK Reader
4 : * Purpose: Public Declarations for OGR free VFK Reader code.
5 : * Author: Martin Landa, landa.martin gmail.com
6 : *
7 : ******************************************************************************
8 : * Copyright (c) 2009-2014, Martin Landa <landa.martin gmail.com>
9 : *
10 : * SPDX-License-Identifier: MIT
11 : ****************************************************************************/
12 :
13 : #ifndef GDAL_OGR_VFK_VFKREADER_H_INCLUDED
14 : #define GDAL_OGR_VFK_VFKREADER_H_INCLUDED
15 :
16 : #include <vector>
17 : #include <string>
18 :
19 : #include "ogrsf_frmts.h"
20 :
21 : #include "cpl_port.h"
22 : #include "cpl_minixml.h"
23 : #include "cpl_string.h"
24 :
25 : #include "sqlite3.h"
26 :
27 : class IVFKReader;
28 : class IVFKDataBlock;
29 : class VFKFeature;
30 : class VFKFeatureSQLite;
31 :
32 : typedef std::vector<VFKFeature *> VFKFeatureList;
33 : typedef std::vector<VFKFeatureSQLite *> VFKFeatureSQLiteList;
34 :
35 : #define FID_COLUMN "ogr_fid"
36 : #define GEOM_COLUMN "geometry"
37 : #define FILE_COLUMN "VFK_FILENAME"
38 :
39 : #define VFK_DB_HEADER_TABLE "vfk_header"
40 : #define VFK_DB_TABLE "vfk_tables"
41 : #define VFK_DB_GEOMETRY_TABLE "geometry_columns"
42 : #define VFK_DB_SPATIAL_REF_TABLE "spatial_ref_sys"
43 :
44 : enum RecordType
45 : {
46 : RecordValid,
47 : RecordSkipped,
48 : RecordDuplicated
49 : };
50 :
51 : /************************************************************************/
52 : /* VFKProperty */
53 : /************************************************************************/
54 10920 : class VFKProperty final
55 : {
56 : private:
57 : bool m_bIsNull;
58 :
59 : GIntBig m_iValue;
60 : double m_dValue;
61 : CPLString m_strValue;
62 :
63 : public:
64 : VFKProperty();
65 : explicit VFKProperty(int);
66 : explicit VFKProperty(GIntBig);
67 : explicit VFKProperty(double);
68 : explicit VFKProperty(const char *);
69 : explicit VFKProperty(CPLString const &);
70 : ~VFKProperty();
71 :
72 10920 : VFKProperty(VFKProperty const &other) = default;
73 : VFKProperty &operator=(VFKProperty const &) = default;
74 : VFKProperty &operator=(VFKProperty &&) = default;
75 :
76 10920 : bool IsNull() const
77 : {
78 10920 : return m_bIsNull;
79 : }
80 :
81 2205 : int GetValueI() const
82 : {
83 2205 : return static_cast<int>(m_iValue);
84 : }
85 :
86 4305 : GIntBig GetValueI64() const
87 : {
88 4305 : return m_iValue;
89 : }
90 :
91 390 : double GetValueD() const
92 : {
93 390 : return m_dValue;
94 : }
95 :
96 : const char *GetValueS(bool = false) const;
97 : };
98 :
99 : /************************************************************************/
100 : /* IVFKFeature */
101 : /************************************************************************/
102 : class IVFKFeature /* non final */
103 : {
104 : private:
105 : static double GetDeterminatOfMatrixDim3(double[3], double[3], double[3]);
106 : static void GetCircleCenterFrom3Points(double[2], double[3], double[3]);
107 : static void AddCirclePointsToGeomString(OGRCircularString &, double, double,
108 : double);
109 :
110 : protected:
111 : IVFKDataBlock *m_poDataBlock;
112 : GIntBig m_nFID;
113 : OGRwkbGeometryType m_nGeometryType;
114 : bool m_bGeometry;
115 : bool m_bValid;
116 : std::unique_ptr<OGRGeometry> m_paGeom{};
117 :
118 : virtual bool LoadGeometryPoint() = 0;
119 : virtual bool LoadGeometryLineStringSBP() = 0;
120 : virtual bool LoadGeometryLineStringHP() = 0;
121 : virtual bool LoadGeometryPolygon() = 0;
122 :
123 : public:
124 : explicit IVFKFeature(IVFKDataBlock *);
125 : virtual ~IVFKFeature();
126 :
127 2162 : GIntBig GetFID() const
128 : {
129 2162 : return m_nFID;
130 : }
131 :
132 : void SetFID(GIntBig);
133 : void SetGeometryType(OGRwkbGeometryType);
134 :
135 : bool IsValid() const
136 : {
137 : return m_bValid;
138 : }
139 :
140 : IVFKDataBlock *GetDataBlock() const
141 : {
142 : return m_poDataBlock;
143 : }
144 :
145 61 : OGRwkbGeometryType GetGeometryType() const
146 : {
147 61 : return m_nGeometryType;
148 : }
149 :
150 : bool SetGeometry(const OGRGeometry *, const char * = nullptr);
151 : const OGRGeometry *GetGeometry();
152 :
153 : bool LoadGeometry();
154 : virtual OGRErr LoadProperties(OGRFeature *) = 0;
155 : };
156 :
157 : /************************************************************************/
158 : /* VFKFeature */
159 : /************************************************************************/
160 : class VFKFeature final : public IVFKFeature
161 : {
162 : private:
163 : typedef std::vector<VFKProperty> VFKPropertyList;
164 :
165 : VFKPropertyList m_propertyList;
166 :
167 : bool SetProperty(int, const char *);
168 :
169 : friend class VFKFeatureSQLite;
170 :
171 : bool LoadGeometryPoint() override;
172 : bool LoadGeometryLineStringSBP() override;
173 : bool LoadGeometryLineStringHP() override;
174 : bool LoadGeometryPolygon() override;
175 :
176 : public:
177 : VFKFeature(IVFKDataBlock *, GIntBig);
178 :
179 : bool SetProperties(const char *);
180 : const VFKProperty *GetProperty(int) const;
181 : const VFKProperty *GetProperty(const char *) const;
182 :
183 : OGRErr LoadProperties(OGRFeature *) override;
184 :
185 : bool AppendLineToRing(int, const OGRLineString *);
186 : };
187 :
188 : /************************************************************************/
189 : /* VFKFeatureSQLite */
190 : /************************************************************************/
191 : class VFKFeatureSQLite final : public IVFKFeature
192 : {
193 : private:
194 : int m_iRowId; /* rowid in DB */
195 : sqlite3_stmt *m_hStmt;
196 :
197 : bool LoadGeometryPoint() override;
198 : bool LoadGeometryLineStringSBP() override;
199 : bool LoadGeometryLineStringHP() override;
200 : bool LoadGeometryPolygon() override;
201 :
202 : OGRErr SetFIDFromDB();
203 : OGRErr ExecuteSQL(const char *);
204 : void FinalizeSQL();
205 :
206 : public:
207 : explicit VFKFeatureSQLite(IVFKDataBlock *);
208 : VFKFeatureSQLite(IVFKDataBlock *, int, GIntBig);
209 : explicit VFKFeatureSQLite(const VFKFeature *);
210 :
211 : OGRErr LoadProperties(OGRFeature *) override;
212 : void SetRowId(int);
213 : };
214 :
215 : /************************************************************************/
216 : /* VFKPropertyDefn */
217 : /************************************************************************/
218 : class VFKPropertyDefn final
219 : {
220 : private:
221 : char *m_pszName;
222 :
223 : char *m_pszType;
224 : char *m_pszEncoding;
225 : OGRFieldType m_eFType;
226 :
227 : int m_nWidth;
228 : int m_nPrecision;
229 :
230 : public:
231 : VFKPropertyDefn(const char *, const char *, const char *);
232 : ~VFKPropertyDefn();
233 :
234 21970 : const char *GetName() const
235 : {
236 21970 : return m_pszName;
237 : }
238 :
239 18464 : int GetWidth() const
240 : {
241 18464 : return m_nWidth;
242 : }
243 :
244 9712 : int GetPrecision() const
245 : {
246 9712 : return m_nPrecision;
247 : }
248 :
249 27937 : OGRFieldType GetType() const
250 : {
251 27937 : return m_eFType;
252 : }
253 :
254 : CPLString GetTypeSQL() const;
255 :
256 1320 : const char *GetEncoding() const
257 : {
258 1320 : return m_pszEncoding;
259 : }
260 : };
261 :
262 : /************************************************************************/
263 : /* IVFKDataBlock */
264 : /************************************************************************/
265 : class IVFKDataBlock /* non final */
266 : {
267 : private:
268 : IVFKFeature **m_papoFeature;
269 :
270 : int m_nPropertyCount;
271 : VFKPropertyDefn **m_papoProperty;
272 :
273 : int AddProperty(const char *, const char *);
274 :
275 : IVFKDataBlock(IVFKDataBlock &) = delete;
276 : IVFKDataBlock &operator=(const IVFKDataBlock &) = delete;
277 : IVFKDataBlock(IVFKDataBlock &&) = delete;
278 : IVFKDataBlock &operator=(IVFKDataBlock &&) = delete;
279 :
280 : protected:
281 : typedef std::vector<OGRPoint> PointList;
282 : typedef std::vector<PointList *> PointListArray;
283 :
284 : char *m_pszName;
285 : bool m_bGeometry;
286 :
287 : OGRwkbGeometryType m_nGeometryType;
288 : bool m_bGeometryPerBlock;
289 :
290 : int m_nFeatureCount;
291 : int m_iNextFeature;
292 :
293 : // TODO: Make m_poReader const.
294 : IVFKReader *m_poReader;
295 :
296 : GIntBig m_nRecordCount[3];
297 :
298 : bool AppendLineToRing(PointListArray *, const OGRLineString *, bool,
299 : bool = false);
300 : int LoadData();
301 :
302 : virtual int LoadGeometryPoint() = 0;
303 : virtual int LoadGeometryLineStringSBP() = 0;
304 : virtual int LoadGeometryLineStringHP() = 0;
305 : virtual int LoadGeometryPolygon() = 0;
306 :
307 : static void FillPointList(PointList *poList, const OGRLineString *poLine);
308 :
309 : public:
310 : IVFKDataBlock(const char *, const IVFKReader *);
311 : virtual ~IVFKDataBlock();
312 :
313 70847 : const char *GetName() const
314 : {
315 70847 : return m_pszName;
316 : }
317 :
318 56652 : int GetPropertyCount() const
319 : {
320 56652 : return m_nPropertyCount;
321 : }
322 :
323 : VFKPropertyDefn *GetProperty(int) const;
324 : void SetProperties(const char *);
325 : int GetPropertyIndex(const char *) const;
326 :
327 : GIntBig GetFeatureCount(bool = true);
328 : void SetFeatureCount(int, bool = false);
329 : IVFKFeature *GetFeatureByIndex(int) const;
330 : IVFKFeature *GetFeature(GIntBig);
331 : void AddFeature(IVFKFeature *);
332 :
333 : void ResetReading(int iIdx = -1);
334 : IVFKFeature *GetNextFeature();
335 : IVFKFeature *GetPreviousFeature();
336 : IVFKFeature *GetFirstFeature();
337 : IVFKFeature *GetLastFeature();
338 : int SetNextFeature(const IVFKFeature *);
339 :
340 : OGRwkbGeometryType SetGeometryType(bool = false);
341 : OGRwkbGeometryType GetGeometryType() const;
342 :
343 : int LoadGeometry();
344 :
345 : virtual OGRErr LoadProperties() = 0;
346 : virtual OGRErr CleanProperties() = 0;
347 :
348 1039 : IVFKReader *GetReader() const
349 : {
350 1039 : return m_poReader;
351 : }
352 :
353 : int GetRecordCount(RecordType = RecordValid) const;
354 : void SetIncRecordCount(RecordType);
355 : };
356 :
357 : /************************************************************************/
358 : /* VFKDataBlock */
359 : /************************************************************************/
360 : class VFKDataBlock final : public IVFKDataBlock
361 : {
362 : private:
363 : int LoadGeometryPoint() override;
364 : int LoadGeometryLineStringSBP() override;
365 : int LoadGeometryLineStringHP() override;
366 : int LoadGeometryPolygon() override;
367 :
368 : public:
369 0 : VFKDataBlock(const char *pszName, const IVFKReader *poReader)
370 0 : : IVFKDataBlock(pszName, poReader)
371 : {
372 0 : }
373 :
374 : VFKFeature *GetFeature(int, GUIntBig, VFKFeatureList *poList = nullptr);
375 : VFKFeatureList GetFeatures(int, GUIntBig);
376 : VFKFeatureList GetFeatures(int, int, GUIntBig);
377 :
378 : GIntBig GetFeatureCount(const char *, const char *);
379 :
380 0 : OGRErr LoadProperties() override
381 : {
382 0 : return OGRERR_UNSUPPORTED_OPERATION;
383 : }
384 :
385 0 : OGRErr CleanProperties() override
386 : {
387 0 : return OGRERR_UNSUPPORTED_OPERATION;
388 : }
389 : };
390 :
391 : /************************************************************************/
392 : /* VFKDataBlockSQLite */
393 : /************************************************************************/
394 : class VFKDataBlockSQLite final : public IVFKDataBlock
395 : {
396 : private:
397 : sqlite3_stmt *m_hStmt;
398 :
399 : bool SetGeometryLineString(VFKFeatureSQLite *, OGRLineString *, bool &,
400 : const char *, std::vector<int> &, int &);
401 :
402 : int LoadGeometryPoint() override;
403 : int LoadGeometryLineStringSBP() override;
404 : int LoadGeometryLineStringHP() override;
405 : int LoadGeometryPolygon() override;
406 :
407 : bool LoadGeometryFromDB();
408 : OGRErr SaveGeometryToDB(const OGRGeometry *, int);
409 :
410 : OGRErr LoadProperties() override;
411 : OGRErr CleanProperties() override;
412 :
413 : static bool IsRingClosed(const OGRLinearRing *);
414 : void UpdateVfkBlocks(int);
415 : void UpdateFID(GIntBig, const std::vector<int> &);
416 :
417 : friend class VFKFeatureSQLite;
418 :
419 : public:
420 : VFKDataBlockSQLite(const char *, const IVFKReader *);
421 :
422 : const char *GetKey() const;
423 : IVFKFeature *GetFeature(GIntBig);
424 : VFKFeatureSQLite *GetFeature(const char *, GUIntBig, bool = false);
425 : VFKFeatureSQLite *GetFeature(const char **, GUIntBig *, int, bool = false);
426 : VFKFeatureSQLiteList GetFeatures(const char **, GUIntBig *, int);
427 :
428 : int GetGeometrySQLType() const;
429 :
430 : OGRErr AddGeometryColumn() const;
431 : };
432 :
433 : /************************************************************************/
434 : /* IVFKReader */
435 : /************************************************************************/
436 : class IVFKReader /* non final */
437 : {
438 : private:
439 : virtual void AddInfo(const char *) = 0;
440 :
441 : protected:
442 : virtual IVFKDataBlock *CreateDataBlock(const char *) = 0;
443 : virtual void AddDataBlock(IVFKDataBlock * = nullptr,
444 : const char * = nullptr) = 0;
445 : virtual OGRErr AddFeature(IVFKDataBlock * = nullptr,
446 : VFKFeature * = nullptr) = 0;
447 :
448 : public:
449 : virtual ~IVFKReader();
450 :
451 : virtual const char *GetFilename() const = 0;
452 :
453 : virtual const char *GetEncoding() const = 0;
454 : virtual bool IsSpatial() const = 0;
455 : virtual bool IsPreProcessed() const = 0;
456 : virtual bool IsValid() const = 0;
457 : virtual bool HasFileField() const = 0;
458 : virtual int ReadDataBlocks(bool = false) = 0;
459 : virtual int64_t ReadDataRecords(IVFKDataBlock * = nullptr) = 0;
460 : virtual int LoadGeometry() = 0;
461 :
462 : virtual int GetDataBlockCount() const = 0;
463 : virtual IVFKDataBlock *GetDataBlock(int) const = 0;
464 : virtual IVFKDataBlock *GetDataBlock(const char *) const = 0;
465 :
466 : virtual const char *GetInfo(const char *) = 0;
467 : };
468 :
469 : IVFKReader *CreateVFKReader(const GDALOpenInfo *);
470 :
471 : #endif // GDAL_OGR_VFK_VFKREADER_H_INCLUDED
|