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