Line data Source code
1 : /******************************************************************************
2 : * $Id$
3 : *
4 : * Project: GeoPackage Translator
5 : * Purpose: Definition of classes for OGR GeoPackage driver.
6 : * Author: Paul Ramsey, pramsey@boundlessgeo.com
7 : *
8 : ******************************************************************************
9 : * Copyright (c) 2013, Paul Ramsey <pramsey@boundlessgeo.com>
10 : *
11 : * SPDX-License-Identifier: MIT
12 : ****************************************************************************/
13 :
14 : #ifndef OGR_GEOPACKAGE_H_INCLUDED
15 : #define OGR_GEOPACKAGE_H_INCLUDED
16 :
17 : #include "ogrsf_frmts.h"
18 : #include "ogrsqlitebase.h"
19 : #include "gpkgmbtilescommon.h"
20 : #include "ogrsqliteutility.h"
21 : #include "cpl_threadsafe_queue.hpp"
22 : #include "ograrrowarrayhelper.h"
23 : #include "ogr_p.h"
24 : #include "ogr_wkb.h"
25 :
26 : #include <condition_variable>
27 : #include <limits>
28 : #include <mutex>
29 : #include <queue>
30 : #include <vector>
31 : #include <set>
32 : #include <thread>
33 : #include <cctype>
34 :
35 : #define UNKNOWN_SRID -2
36 : #define DEFAULT_SRID 0
37 :
38 : #define ENABLE_GPKG_OGR_CONTENTS
39 :
40 : #if defined(DEBUG) || defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) || \
41 : defined(ALLOW_FORMAT_DUMPS)
42 : // Enable accepting a SQL dump (starting with a "-- SQL GPKG" line) as a valid
43 : // file. This makes fuzzer life easier
44 : #define ENABLE_SQL_GPKG_FORMAT
45 : #endif
46 :
47 : typedef enum
48 : {
49 : GPKG_ATTRIBUTES,
50 : NOT_REGISTERED,
51 : } GPKGASpatialVariant;
52 :
53 : // Requirement 2
54 : static const GUInt32 GP10_APPLICATION_ID = 0x47503130U;
55 : static const GUInt32 GP11_APPLICATION_ID = 0x47503131U;
56 : static const GUInt32 GPKG_APPLICATION_ID = 0x47504B47U;
57 : static const GUInt32 GPKG_1_2_VERSION = 10200U;
58 : static const GUInt32 GPKG_1_3_VERSION = 10300U;
59 : static const GUInt32 GPKG_1_4_VERSION = 10400U;
60 :
61 : static const size_t knApplicationIdPos = 68;
62 : static const size_t knUserVersionPos = 60;
63 :
64 : struct GPKGExtensionDesc
65 : {
66 : CPLString osExtensionName{};
67 : CPLString osDefinition{};
68 : CPLString osScope{};
69 : };
70 :
71 : struct GPKGContentsDesc
72 : {
73 : CPLString osDataType{};
74 : CPLString osIdentifier{};
75 : CPLString osDescription{};
76 : CPLString osMinX{};
77 : CPLString osMinY{};
78 : CPLString osMaxX{};
79 : CPLString osMaxY{};
80 : };
81 :
82 : class OGRGeoPackageLayer;
83 :
84 : struct OGRGPKGTableLayerFillArrowArray
85 : {
86 : std::unique_ptr<OGRArrowArrayHelper> psHelper{};
87 : int nCountRows = 0;
88 : bool bErrorOccurred = false;
89 : bool bMemoryLimitReached = false;
90 : std::string osErrorMsg{};
91 : OGRFeatureDefn *poFeatureDefn = nullptr;
92 : OGRGeoPackageLayer *poLayer = nullptr;
93 :
94 : struct tm brokenDown
95 : {
96 : };
97 :
98 : sqlite3 *hDB = nullptr;
99 : int nMaxBatchSize = 0;
100 : bool bAsynchronousMode = false;
101 : std::mutex oMutex{};
102 : std::condition_variable oCV{};
103 : bool bIsFinished = false;
104 : GIntBig nCurFID = 0;
105 : uint32_t nMemLimit = 0;
106 : // For spatial filtering
107 : const OGRLayer *poLayerForFilterGeom = nullptr;
108 : };
109 :
110 : void OGR_GPKG_Intersects_Spatial_Filter(sqlite3_context *pContext, int argc,
111 : sqlite3_value **argv);
112 :
113 : /************************************************************************/
114 : /* GDALGeoPackageDataset */
115 : /************************************************************************/
116 :
117 : class OGRGeoPackageTableLayer;
118 :
119 : class GDALGeoPackageDataset final : public OGRSQLiteBaseDataSource,
120 : public GDALGPKGMBTilesLikePseudoDataset
121 : {
122 : friend class GDALGeoPackageRasterBand;
123 : friend class OGRGeoPackageLayer;
124 : friend class OGRGeoPackageTableLayer;
125 : friend void OGRGeoPackageTransform(sqlite3_context *pContext, int argc,
126 : sqlite3_value **argv);
127 :
128 : std::string m_osFilenameInZip{};
129 : void *m_pSQLFunctionData = nullptr;
130 : GUInt32 m_nApplicationId = GPKG_APPLICATION_ID;
131 : GUInt32 m_nUserVersion = GPKG_1_2_VERSION;
132 : OGRGeoPackageTableLayer **m_papoLayers = nullptr;
133 : int m_nLayers = 0;
134 : void CheckUnknownExtensions(bool bCheckRasterTable = false);
135 : #ifdef ENABLE_GPKG_OGR_CONTENTS
136 : bool m_bHasGPKGOGRContents = false;
137 : #endif
138 : bool m_bHasGPKGGeometryColumns = false;
139 : bool m_bHasDefinition12_063 = false;
140 : bool m_bHasEpochColumn =
141 : false; // whether gpkg_spatial_ref_sys has a epoch column
142 : bool m_bNonSpatialTablesNonRegisteredInGpkgContentsFound = false;
143 : mutable int m_nHasMetadataTables = -1; // -1 = unknown, 0 = false, 1 = true
144 : int m_nCreateMetadataTables = -1; // -1 = on demand, 0 = false, 1 = true
145 :
146 : // Set by CreateTileGriddedTable() and used by FinalizeRasterRegistration()
147 : std::string m_osSQLInsertIntoGpkg2dGriddedCoverageAncillary{};
148 :
149 : CPLString m_osIdentifier{};
150 : bool m_bIdentifierAsCO = false;
151 : CPLString m_osDescription{};
152 : bool m_bDescriptionAsCO = false;
153 : bool m_bGridCellEncodingAsCO = false;
154 : bool m_bHasReadMetadataFromStorage = false;
155 : bool m_bMetadataDirty = false;
156 : CPLStringList m_aosSubDatasets{};
157 : OGRSpatialReference m_oSRS{};
158 : bool m_bRecordInsertedInGPKGContent = false;
159 : bool m_bGeoTransformValid = false;
160 : double m_adfGeoTransform[6];
161 : int m_nSRID = -1; // Unknown Cartesain
162 : double m_dfTMSMinX = 0.0;
163 : double m_dfTMSMaxY = 0.0;
164 : int m_nBandCountFromMetadata = 0;
165 : std::unique_ptr<GDALColorTable> m_poCTFromMetadata{};
166 : std::string m_osTFFromMetadata{};
167 : std::string m_osNodataValueFromMetadata{};
168 :
169 : // Used by OGRGeoPackageTransform
170 : int m_nLastCachedCTSrcSRId = -1;
171 : int m_nLastCachedCTDstSRId = -1;
172 : std::unique_ptr<OGRCoordinateTransformation> m_poLastCachedCT{};
173 : OGRWKBTransformCache m_oWKBTransformCache{};
174 : std::vector<GByte> m_abyWKBTransformCache{};
175 :
176 : int m_nOverviewCount = 0;
177 : GDALGeoPackageDataset **m_papoOverviewDS = nullptr;
178 : bool m_bZoomOther = false;
179 :
180 : bool m_bInFlushCache = false;
181 :
182 : bool m_bDateTimeWithTZ = true;
183 :
184 : bool m_bRemoveOGREmptyTable = false;
185 :
186 : CPLString m_osTilingScheme = "CUSTOM";
187 :
188 : // To optimize reading table constraints
189 : int m_nReadTableDefCount = 0;
190 : std::vector<SQLSqliteMasterContent> m_aoSqliteMasterContent{};
191 :
192 728 : void IncrementReadTableDefCounter()
193 : {
194 728 : m_nReadTableDefCount++;
195 728 : }
196 :
197 720 : int GetReadTableDefCounter() const
198 : {
199 720 : return m_nReadTableDefCount;
200 : }
201 :
202 : const std::vector<SQLSqliteMasterContent> &GetSqliteMasterContent();
203 :
204 : bool ComputeTileAndPixelShifts();
205 : bool AllocCachedTiles();
206 : bool InitRaster(GDALGeoPackageDataset *poParentDS, const char *pszTableName,
207 : double dfMinX, double dfMinY, double dfMaxX, double dfMaxY,
208 : const char *pszContentsMinX, const char *pszContentsMinY,
209 : const char *pszContentsMaxX, const char *pszContentsMaxY,
210 : char **papszOpenOptions, const SQLResult &oResult,
211 : int nIdxInResult);
212 : bool InitRaster(GDALGeoPackageDataset *poParentDS, const char *pszTableName,
213 : int nZoomLevel, int nBandCount, double dfTMSMinX,
214 : double dfTMSMaxY, double dfPixelXSize, double dfPixelYSize,
215 : int nTileWidth, int nTileHeight, int nTileMatrixWidth,
216 : int nTileMatrixHeight, double dfGDALMinX, double dfGDALMinY,
217 : double dfGDALMaxX, double dfGDALMaxY);
218 :
219 : bool OpenRaster(const char *pszTableName, const char *pszIdentifier,
220 : const char *pszDescription, int nSRSId, double dfMinX,
221 : double dfMinY, double dfMaxX, double dfMaxY,
222 : const char *pszContentsMinX, const char *pszContentsMinY,
223 : const char *pszContentsMaxX, const char *pszContentsMaxY,
224 : bool bIsTiles, char **papszOptions);
225 : CPLErr FinalizeRasterRegistration();
226 :
227 : bool RegisterWebPExtension();
228 : bool RegisterZoomOtherExtension();
229 : void ParseCompressionOptions(char **papszOptions);
230 :
231 : bool HasMetadataTables() const;
232 : bool CreateMetadataTables();
233 : const char *CheckMetadataDomain(const char *pszDomain);
234 : void
235 : WriteMetadata(CPLXMLNode *psXMLNode, /* will be destroyed by the method */
236 : const char *pszTableName);
237 : void FlushMetadata();
238 :
239 : int FindLayerIndex(const char *pszLayerName);
240 :
241 : bool HasGriddedCoverageAncillaryTable();
242 : bool CreateTileGriddedTable(char **papszOptions);
243 :
244 : void RemoveOGREmptyTable();
245 :
246 : std::map<CPLString, CPLString> m_oMapNameToType{};
247 : const std::map<CPLString, CPLString> &GetNameTypeMapFromSQliteMaster();
248 : void RemoveTableFromSQLiteMasterCache(const char *pszTableName);
249 :
250 : bool m_bMapTableToExtensionsBuilt = false;
251 : std::map<CPLString, std::vector<GPKGExtensionDesc>>
252 : m_oMapTableToExtensions{};
253 : const std::map<CPLString, std::vector<GPKGExtensionDesc>> &
254 : GetUnknownExtensionsTableSpecific();
255 :
256 : bool m_bMapTableToContentsBuilt = false;
257 : std::map<CPLString, GPKGContentsDesc> m_oMapTableToContents{};
258 : const std::map<CPLString, GPKGContentsDesc> &GetContents();
259 :
260 : std::map<int, OGRSpatialReference *> m_oMapSrsIdToSrs{};
261 :
262 : OGRErr DeleteLayerCommon(const char *pszLayerName);
263 : OGRErr DeleteRasterLayer(const char *pszLayerName);
264 : bool DeleteVectorOrRasterLayer(const char *pszLayerName);
265 : bool RenameVectorOrRasterLayer(const char *pszLayerName,
266 : const char *pszNewName);
267 : bool RenameRasterLayer(const char *pszLayerName,
268 : const char *pszNewLayerName);
269 :
270 : bool ConvertGpkgSpatialRefSysToExtensionWkt2(bool bForceEpoch);
271 : void DetectSpatialRefSysColumns();
272 :
273 : std::map<int, bool> m_oSetGPKGLayerWarnings{};
274 :
275 : void FixupWrongRTreeTrigger();
276 : void FixupWrongMedataReferenceColumnNameUpdate();
277 : void ClearCachedRelationships();
278 : void LoadRelationships() const override;
279 : void LoadRelationshipsUsingRelatedTablesExtension() const;
280 : static std::string
281 : GenerateNameForRelationship(const char *pszBaseTableName,
282 : const char *pszRelatedTableName,
283 : const char *pszType);
284 : bool ValidateRelationship(const GDALRelationship *poRelationship,
285 : std::string &failureReason);
286 :
287 : // Used by GDALGeoPackageDataset::GetRasterLayerDataset()
288 : std::map<std::string, std::unique_ptr<GDALDataset>> m_oCachedRasterDS{};
289 :
290 : bool CloseDB();
291 : CPLErr Close() override;
292 :
293 : CPL_DISALLOW_COPY_ASSIGN(GDALGeoPackageDataset)
294 :
295 : public:
296 : GDALGeoPackageDataset();
297 : virtual ~GDALGeoPackageDataset();
298 :
299 : char **GetFileList(void) override;
300 :
301 : virtual char **GetMetadata(const char *pszDomain = "") override;
302 : virtual const char *GetMetadataItem(const char *pszName,
303 : const char *pszDomain = "") override;
304 : virtual char **GetMetadataDomainList() override;
305 : virtual CPLErr SetMetadata(char **papszMetadata,
306 : const char *pszDomain = "") override;
307 : virtual CPLErr SetMetadataItem(const char *pszName, const char *pszValue,
308 : const char *pszDomain = "") override;
309 :
310 : const OGRSpatialReference *GetSpatialRef() const override;
311 : CPLErr SetSpatialRef(const OGRSpatialReference *poSRS) override;
312 :
313 : virtual CPLErr GetGeoTransform(double *padfGeoTransform) override;
314 : virtual CPLErr SetGeoTransform(double *padfGeoTransform) override;
315 :
316 : virtual CPLErr FlushCache(bool bAtClosing) override;
317 : virtual CPLErr IBuildOverviews(const char *, int, const int *, int,
318 : const int *, GDALProgressFunc, void *,
319 : CSLConstList papszOptions) override;
320 :
321 19061 : virtual int GetLayerCount() override
322 : {
323 19061 : return m_nLayers;
324 : }
325 :
326 : int Open(GDALOpenInfo *poOpenInfo, const std::string &osFilenameInZip);
327 : int Create(const char *pszFilename, int nXSize, int nYSize, int nBands,
328 : GDALDataType eDT, char **papszOptions);
329 : OGRLayer *GetLayer(int iLayer) override;
330 : OGRErr DeleteLayer(int iLayer) override;
331 : OGRLayer *ICreateLayer(const char *pszName,
332 : const OGRGeomFieldDefn *poGeomFieldDefn,
333 : CSLConstList papszOptions) override;
334 : int TestCapability(const char *) override;
335 :
336 : std::vector<std::string>
337 : GetFieldDomainNames(CSLConstList papszOptions = nullptr) const override;
338 : const OGRFieldDomain *
339 : GetFieldDomain(const std::string &name) const override;
340 : bool AddFieldDomain(std::unique_ptr<OGRFieldDomain> &&domain,
341 : std::string &failureReason) override;
342 :
343 : bool AddRelationship(std::unique_ptr<GDALRelationship> &&relationship,
344 : std::string &failureReason) override;
345 :
346 : bool DeleteRelationship(const std::string &name,
347 : std::string &failureReason) override;
348 :
349 : bool UpdateRelationship(std::unique_ptr<GDALRelationship> &&relationship,
350 : std::string &failureReason) override;
351 :
352 : virtual std::pair<OGRLayer *, IOGRSQLiteGetSpatialWhere *>
353 : GetLayerWithGetSpatialWhereByName(const char *pszName) override;
354 :
355 : virtual OGRLayer *ExecuteSQL(const char *pszSQLCommand,
356 : OGRGeometry *poSpatialFilter,
357 : const char *pszDialect) override;
358 : virtual void ReleaseResultSet(OGRLayer *poLayer) override;
359 :
360 : virtual OGRErr CommitTransaction() override;
361 : virtual OGRErr RollbackTransaction() override;
362 :
363 1011 : inline bool IsInTransaction() const
364 : {
365 1011 : return nSoftTransactionLevel > 0;
366 : }
367 :
368 : static std::string LaunderName(const std::string &osStr);
369 :
370 : // At least 100000 to avoid conflicting with EPSG codes
371 : static constexpr int FIRST_CUSTOM_SRSID = 100000;
372 :
373 : int GetSrsId(const OGRSpatialReference *poSRS);
374 : const char *GetSrsName(const OGRSpatialReference &oSRS);
375 : std::unique_ptr<OGRSpatialReference, OGRSpatialReferenceReleaser>
376 : GetSpatialRef(int iSrsId, bool bFallbackToEPSG = false,
377 : bool bEmitErrorIfNotFound = true);
378 : OGRErr CreateExtensionsTableIfNecessary();
379 : bool HasExtensionsTable();
380 :
381 369 : void SetMetadataDirty()
382 : {
383 369 : m_bMetadataDirty = true;
384 369 : }
385 :
386 : bool HasDataColumnsTable() const;
387 : bool HasDataColumnConstraintsTable() const;
388 : bool HasDataColumnConstraintsTableGPKG_1_0() const;
389 : bool CreateColumnsTableAndColumnConstraintsTablesIfNecessary();
390 : bool HasGpkgextRelationsTable() const;
391 : bool CreateRelationsTableIfNecessary();
392 : bool HasQGISLayerStyles() const;
393 :
394 46 : bool HasNonSpatialTablesNonRegisteredInGpkgContents() const
395 : {
396 46 : return m_bNonSpatialTablesNonRegisteredInGpkgContentsFound;
397 : }
398 :
399 : const char *GetGeometryTypeString(OGRwkbGeometryType eType);
400 :
401 : void ResetReadingAllLayers();
402 : OGRErr UpdateGpkgContentsLastChange(const char *pszTableName);
403 :
404 : static GDALDataset *CreateCopy(const char *pszFilename,
405 : GDALDataset *poSrcDS, int bStrict,
406 : char **papszOptions,
407 : GDALProgressFunc pfnProgress,
408 : void *pProgressData);
409 :
410 : static std::string GetCurrentDateEscapedSQL();
411 :
412 : GDALDataset *GetRasterLayerDataset(const char *pszLayerName);
413 :
414 : protected:
415 : virtual CPLErr IRasterIO(GDALRWFlag, int, int, int, int, void *, int, int,
416 : GDALDataType, int, BANDMAP_TYPE, GSpacing,
417 : GSpacing, GSpacing,
418 : GDALRasterIOExtraArg *psExtraArg) override;
419 :
420 : // Coming from GDALGPKGMBTilesLikePseudoDataset
421 :
422 : virtual CPLErr IFlushCacheWithErrCode(bool bAtClosing) override;
423 :
424 26010 : virtual int IGetRasterCount() override
425 : {
426 26010 : return nBands;
427 : }
428 :
429 54019 : virtual GDALRasterBand *IGetRasterBand(int nBand) override
430 : {
431 54019 : return GetRasterBand(nBand);
432 : }
433 :
434 9962 : virtual sqlite3 *IGetDB() override
435 : {
436 9962 : return GetDB();
437 : }
438 :
439 14952 : virtual bool IGetUpdate() override
440 : {
441 14952 : return GetUpdate();
442 : }
443 :
444 : virtual bool ICanIWriteBlock() override;
445 :
446 152 : virtual OGRErr IStartTransaction() override
447 : {
448 152 : return SoftStartTransaction();
449 : }
450 :
451 152 : virtual OGRErr ICommitTransaction() override
452 : {
453 152 : return SoftCommitTransaction();
454 : }
455 :
456 26 : virtual const char *IGetFilename() override
457 : {
458 26 : return m_pszFilename;
459 : }
460 :
461 9758 : virtual int GetRowFromIntoTopConvention(int nRow) override
462 : {
463 9758 : return nRow;
464 : }
465 :
466 : private:
467 : OGRErr SetApplicationAndUserVersionId();
468 : bool ReOpenDB();
469 : bool OpenOrCreateDB(int flags);
470 : void InstallSQLFunctions();
471 : bool HasGDALAspatialExtension();
472 : std::string CreateRasterTriggersSQL(const std::string &osTableName);
473 : };
474 :
475 : /************************************************************************/
476 : /* GPKGTemporaryForeignKeyCheckDisabler */
477 : /************************************************************************/
478 :
479 : //! Instance of that class temporarily disable foreign key checks
480 : class GPKGTemporaryForeignKeyCheckDisabler
481 : {
482 : public:
483 96 : explicit GPKGTemporaryForeignKeyCheckDisabler(GDALGeoPackageDataset *poDS)
484 96 : : m_poDS(poDS), m_nPragmaForeignKeysOldValue(SQLGetInteger(
485 96 : m_poDS->GetDB(), "PRAGMA foreign_keys", nullptr))
486 : {
487 96 : if (m_nPragmaForeignKeysOldValue)
488 : {
489 0 : CPL_IGNORE_RET_VAL(
490 0 : SQLCommand(m_poDS->GetDB(), "PRAGMA foreign_keys = 0"));
491 : }
492 96 : }
493 :
494 96 : ~GPKGTemporaryForeignKeyCheckDisabler()
495 96 : {
496 96 : if (m_nPragmaForeignKeysOldValue)
497 : {
498 0 : CPL_IGNORE_RET_VAL(
499 0 : SQLCommand(m_poDS->GetDB(), "PRAGMA foreign_keys = 1"));
500 : }
501 96 : }
502 :
503 : private:
504 : CPL_DISALLOW_COPY_ASSIGN(GPKGTemporaryForeignKeyCheckDisabler)
505 :
506 : GDALGeoPackageDataset *m_poDS = nullptr;
507 : int m_nPragmaForeignKeysOldValue = 0;
508 : };
509 :
510 : /************************************************************************/
511 : /* GDALGeoPackageRasterBand */
512 : /************************************************************************/
513 :
514 : class GDALGeoPackageRasterBand final : public GDALGPKGMBTilesLikeRasterBand
515 : {
516 : // Whether STATISTICS_MINIMUM and/or STATISTICS_MAXIMUM have been computed
517 : // from the min, max columns of the gpkg_2d_gridded_tile_ancillary table
518 : // (only for non-Byte data)
519 : bool m_bMinMaxComputedFromTileAncillary = false;
520 : double m_dfStatsMinFromTileAncillary =
521 : std::numeric_limits<double>::quiet_NaN();
522 : double m_dfStatsMaxFromTileAncillary =
523 : std::numeric_limits<double>::quiet_NaN();
524 : CPLStringList m_aosMD{};
525 :
526 : // Whether gpkg_metadata has been read to set initial metadata
527 : bool m_bHasReadMetadataFromStorage = false;
528 :
529 : // Whether STATISTICS_* have been set in this "session"
530 : bool m_bStatsMetadataSetInThisSession = false;
531 :
532 : bool m_bAddImplicitStatistics = true;
533 :
534 : void LoadBandMetadata();
535 :
536 : public:
537 : GDALGeoPackageRasterBand(GDALGeoPackageDataset *poDS, int nTileWidth,
538 : int nTileHeight);
539 :
540 : virtual int GetOverviewCount() override;
541 : virtual GDALRasterBand *GetOverview(int nIdx) override;
542 :
543 : virtual CPLErr SetNoDataValue(double dfNoDataValue) override;
544 :
545 : virtual char **GetMetadata(const char *pszDomain = "") override;
546 : virtual const char *GetMetadataItem(const char *pszName,
547 : const char *pszDomain = "") override;
548 : virtual CPLErr SetMetadata(char **papszMetadata,
549 : const char *pszDomain = "") override;
550 : virtual CPLErr SetMetadataItem(const char *pszName, const char *pszValue,
551 : const char *pszDomain = "") override;
552 :
553 458 : void AddImplicitStatistics(bool b)
554 : {
555 458 : m_bAddImplicitStatistics = b;
556 458 : }
557 :
558 334 : inline bool HaveStatsMetadataBeenSetInThisSession() const
559 : {
560 334 : return m_bStatsMetadataSetInThisSession;
561 : }
562 :
563 : void InvalidateStatistics();
564 : };
565 :
566 : /************************************************************************/
567 : /* OGRGeoPackageLayer */
568 : /************************************************************************/
569 :
570 : class OGRGeoPackageLayer CPL_NON_FINAL : public OGRLayer,
571 : public IOGRSQLiteGetSpatialWhere
572 : {
573 : protected:
574 : friend void OGR_GPKG_FillArrowArray_Step(sqlite3_context *pContext,
575 : int /*argc*/,
576 : sqlite3_value **argv);
577 :
578 : GDALGeoPackageDataset *m_poDS = nullptr;
579 :
580 : OGRFeatureDefn *m_poFeatureDefn = nullptr;
581 : GIntBig m_iNextShapeId = 0;
582 :
583 : sqlite3_stmt *m_poQueryStatement = nullptr;
584 : bool m_bDoStep = true;
585 : bool m_bEOF = false;
586 :
587 : char *m_pszFidColumn = nullptr;
588 :
589 : int m_iFIDCol = -1;
590 : int m_iGeomCol = -1;
591 : std::vector<int> m_anFieldOrdinals{};
592 :
593 : //! Whether to call OGRGeometry::SetPrecision() when reading back geometries from the database
594 : bool m_bUndoDiscardCoordLSBOnReading = false;
595 :
596 : void ClearStatement();
597 : virtual OGRErr ResetStatement() = 0;
598 :
599 : void BuildFeatureDefn(const char *pszLayerName, sqlite3_stmt *hStmt);
600 :
601 : OGRFeature *TranslateFeature(sqlite3_stmt *hStmt);
602 : bool ParseDateField(const char *pszTxt, OGRField *psField,
603 : const OGRFieldDefn *poFieldDefn, GIntBig nFID);
604 : bool ParseDateField(sqlite3_stmt *hStmt, int iRawField, int nSqlite3ColType,
605 : OGRField *psField, const OGRFieldDefn *poFieldDefn,
606 : GIntBig nFID);
607 : bool ParseDateTimeField(const char *pszTxt, OGRField *psField,
608 : const OGRFieldDefn *poFieldDefn, GIntBig nFID);
609 : bool ParseDateTimeField(sqlite3_stmt *hStmt, int iRawField,
610 : int nSqlite3ColType, OGRField *psField,
611 : const OGRFieldDefn *poFieldDefn, GIntBig nFID);
612 :
613 100 : GDALDataset *GetDataset() override
614 : {
615 100 : return m_poDS;
616 : }
617 :
618 : virtual bool GetArrowStream(struct ArrowArrayStream *out_stream,
619 : CSLConstList papszOptions = nullptr) override;
620 : virtual int GetNextArrowArray(struct ArrowArrayStream *,
621 : struct ArrowArray *out_array) override;
622 :
623 : CPL_DISALLOW_COPY_ASSIGN(OGRGeoPackageLayer)
624 :
625 : public:
626 : explicit OGRGeoPackageLayer(GDALGeoPackageDataset *poDS);
627 : virtual ~OGRGeoPackageLayer();
628 : /************************************************************************/
629 : /* OGR API methods */
630 :
631 : OGRFeature *GetNextFeature() override;
632 : const char *GetFIDColumn() override;
633 : void ResetReading() override;
634 : int TestCapability(const char *) override;
635 :
636 522 : OGRFeatureDefn *GetLayerDefn() override
637 : {
638 522 : return m_poFeatureDefn;
639 : }
640 :
641 : OGRErr SetIgnoredFields(CSLConstList papszFields) override;
642 :
643 0 : virtual bool HasFastSpatialFilter(int /*iGeomCol*/) override
644 : {
645 0 : return false;
646 : }
647 :
648 0 : virtual CPLString GetSpatialWhere(int /*iGeomCol*/,
649 : OGRGeometry * /*poFilterGeom*/) override
650 : {
651 0 : return "";
652 : }
653 : };
654 :
655 : /************************************************************************/
656 : /* OGRGeoPackageTableLayer */
657 : /************************************************************************/
658 :
659 : struct OGRGPKGTableLayerFillArrowArray;
660 : struct sqlite_rtree_bl;
661 :
662 : class OGRGeoPackageTableLayer final : public OGRGeoPackageLayer
663 : {
664 : char *m_pszTableName = nullptr;
665 : bool m_bIsTable = true; // sensible init for creation mode
666 : bool m_bIsSpatial = false;
667 : bool m_bIsInGpkgContents = false;
668 : bool m_bFeatureDefnCompleted = false;
669 : int m_iSrs = 0;
670 : int m_nZFlag = 0;
671 : int m_nMFlag = 0;
672 : OGRGeomCoordinateBinaryPrecision m_sBinaryPrecision{};
673 : OGREnvelope *m_poExtent = nullptr;
674 : #ifdef ENABLE_GPKG_OGR_CONTENTS
675 : GIntBig m_nTotalFeatureCount = -1;
676 : bool m_bOGRFeatureCountTriggersEnabled = false;
677 : bool m_bAddOGRFeatureCountTriggers = false;
678 : bool m_bFeatureCountTriggersDeletedInTransaction = false;
679 : #endif
680 : CPLString m_soColumns{};
681 : std::vector<bool> m_abGeneratedColumns{}; // .size() ==
682 : // m_poFeatureDefn->GetFieldDefnCount()
683 : CPLString m_soFilter{};
684 : CPLString osQuery{};
685 : CPLString m_osRTreeName{};
686 : CPLString m_osFIDForRTree{};
687 : bool m_bExtentChanged = false;
688 : bool m_bContentChanged = false;
689 : sqlite3_stmt *m_poUpdateStatement = nullptr;
690 : std::string m_osUpdateStatementSQL{};
691 : bool m_bInsertStatementWithFID = false;
692 : bool m_bInsertStatementWithUpsert = false;
693 : std::string m_osInsertStatementUpsertUniqueColumnName{};
694 : sqlite3_stmt *m_poInsertStatement = nullptr;
695 : sqlite3_stmt *m_poGetFeatureStatement = nullptr;
696 : bool m_bDeferredSpatialIndexCreation = false;
697 : // m_bHasSpatialIndex cannot be bool. -1 is unset.
698 : int m_bHasSpatialIndex = -1;
699 : bool m_bDropRTreeTable = false;
700 : bool m_abHasGeometryExtension[wkbTriangle + 1];
701 : bool m_bPreservePrecision = true;
702 : bool m_bTruncateFields = false;
703 : bool m_bDeferredCreation = false;
704 : bool m_bTableCreatedInTransaction = false;
705 : bool m_bLaunder = false;
706 : int m_iFIDAsRegularColumnIndex = -1;
707 : std::string m_osInsertionBuffer{}; // used by FeatureBindParameters to
708 : // store datetime values
709 :
710 : CPLString m_osIdentifierLCO{};
711 : CPLString m_osDescriptionLCO{};
712 : bool m_bHasReadMetadataFromStorage = false;
713 : bool m_bHasTriedDetectingFID64 = false;
714 : GPKGASpatialVariant m_eASpatialVariant = GPKG_ATTRIBUTES;
715 : std::set<OGRwkbGeometryType> m_eSetBadGeomTypeWarned{};
716 :
717 : int m_nIsCompatOfOptimizedGetNextArrowArray = -1;
718 : bool m_bGetNextArrowArrayCalledSinceResetReading = false;
719 :
720 : int m_nCountInsertInTransactionThreshold = -1;
721 : GIntBig m_nCountInsertInTransaction = 0;
722 : std::vector<CPLString> m_aoRTreeTriggersSQL{};
723 : bool m_bUpdate1TriggerDisabled = false;
724 : bool m_bHasUpdate6And7Triggers = false;
725 : std::string m_osUpdate1Trigger{};
726 :
727 : typedef struct
728 : {
729 : GIntBig nId;
730 : float fMinX;
731 : float fMinY;
732 : float fMaxX;
733 : float fMaxY;
734 : } GPKGRTreeEntry;
735 :
736 : std::vector<GPKGRTreeEntry> m_aoRTreeEntries{};
737 :
738 : // Variables used for background RTree building
739 : std::string m_osAsyncDBName{};
740 : std::string m_osAsyncDBAttachName{};
741 : sqlite3 *m_hAsyncDBHandle = nullptr;
742 : sqlite_rtree_bl *m_hRTree = nullptr;
743 : cpl::ThreadSafeQueue<std::vector<GPKGRTreeEntry>> m_oQueueRTreeEntries{};
744 : bool m_bAllowedRTreeThread = false;
745 : bool m_bThreadRTreeStarted = false;
746 : bool m_bErrorDuringRTreeThread = false;
747 : size_t m_nRTreeBatchSize =
748 : 10 * 1000; // maximum size of a std::vector<GPKGRTreeEntry> item in
749 : // m_oQueueRTreeEntries
750 : size_t m_nRTreeBatchesBeforeStart =
751 : 10; // number of items in m_oQueueRTreeEntries before starting the
752 : // thread
753 : std::thread m_oThreadRTree{};
754 :
755 : OGRISO8601Format m_sDateTimeFormat = {OGRISO8601Precision::AUTO};
756 :
757 : void StartAsyncRTree();
758 : void CancelAsyncRTree();
759 : void RemoveAsyncRTreeTempDB();
760 : void AsyncRTreeThreadFunction();
761 :
762 : OGRErr ResetStatementInternal(GIntBig nStartIndex);
763 : virtual OGRErr ResetStatement() override;
764 :
765 : void BuildWhere();
766 : OGRErr RegisterGeometryColumn();
767 :
768 : CPLString
769 : GetColumnsOfCreateTable(const std::vector<OGRFieldDefn *> &apoFields);
770 : CPLString
771 : BuildSelectFieldList(const std::vector<OGRFieldDefn *> &apoFields);
772 : OGRErr RecreateTable(const CPLString &osColumnsForCreate,
773 : const CPLString &osFieldListForSelect);
774 : #ifdef ENABLE_GPKG_OGR_CONTENTS
775 : void CreateFeatureCountTriggers(const char *pszTableName = nullptr);
776 : void DisableFeatureCountTriggers(bool bNullifyFeatureCount = true);
777 : #endif
778 :
779 : void CheckGeometryType(const OGRFeature *poFeature);
780 :
781 : OGRErr ReadTableDefinition();
782 : void InitView();
783 :
784 : bool DoSpecialProcessingForColumnCreation(const OGRFieldDefn *poField);
785 :
786 : bool StartDeferredSpatialIndexUpdate();
787 : bool FlushPendingSpatialIndexUpdate();
788 : void WorkaroundUpdate1TriggerIssue();
789 : void RevertWorkaroundUpdate1TriggerIssue();
790 :
791 : OGRErr RenameFieldInAuxiliaryTables(const char *pszOldName,
792 : const char *pszNewName);
793 :
794 : OGRErr CreateOrUpsertFeature(OGRFeature *poFeature, bool bUpsert);
795 :
796 : GIntBig GetTotalFeatureCount();
797 :
798 : CPL_DISALLOW_COPY_ASSIGN(OGRGeoPackageTableLayer)
799 :
800 : // Used when m_nIsCompatOfOptimizedGetNextArrowArray == TRUE
801 : struct ArrowArrayPrefetchTask
802 : {
803 : std::thread m_oThread{};
804 : std::condition_variable m_oCV{};
805 : std::mutex m_oMutex{};
806 : bool m_bArrayReady = false;
807 : bool m_bFetchRows = false;
808 : bool m_bStop = false;
809 : bool m_bMemoryLimitReached = false;
810 : std::string m_osErrorMsg{};
811 : std::unique_ptr<GDALGeoPackageDataset> m_poDS{};
812 : OGRGeoPackageTableLayer *m_poLayer{};
813 : GIntBig m_iStartShapeId = 0;
814 : std::unique_ptr<struct ArrowArray> m_psArrowArray = nullptr;
815 : };
816 :
817 : std::queue<std::unique_ptr<ArrowArrayPrefetchTask>>
818 : m_oQueueArrowArrayPrefetchTasks{};
819 :
820 : // Used when m_nIsCompatOfOptimizedGetNextArrowArray == FALSE
821 : std::thread m_oThreadNextArrowArray{};
822 : std::unique_ptr<OGRGPKGTableLayerFillArrowArray> m_poFillArrowArray{};
823 : std::unique_ptr<GDALGeoPackageDataset> m_poOtherDS{};
824 :
825 : virtual int GetNextArrowArray(struct ArrowArrayStream *,
826 : struct ArrowArray *out_array) override;
827 : int GetNextArrowArrayInternal(struct ArrowArray *out_array,
828 : std::string &osErrorMsg,
829 : bool &bMemoryLimitReached);
830 : int GetNextArrowArrayAsynchronous(struct ArrowArrayStream *stream,
831 : struct ArrowArray *out_array);
832 : void GetNextArrowArrayAsynchronousWorker();
833 : void CancelAsyncNextArrowArray();
834 :
835 : protected:
836 : friend void OGR_GPKG_Intersects_Spatial_Filter(sqlite3_context *pContext,
837 : int /*argc*/,
838 : sqlite3_value **argv);
839 :
840 : public:
841 : OGRGeoPackageTableLayer(GDALGeoPackageDataset *poDS,
842 : const char *pszTableName);
843 : virtual ~OGRGeoPackageTableLayer();
844 :
845 : /************************************************************************/
846 : /* OGR API methods */
847 :
848 10964 : const char *GetName() override
849 : {
850 10964 : return GetDescription();
851 : }
852 :
853 : const char *GetFIDColumn() override;
854 : OGRwkbGeometryType GetGeomType() override;
855 : const char *GetGeometryColumn() override;
856 : OGRFeatureDefn *GetLayerDefn() override;
857 : int TestCapability(const char *) override;
858 : OGRErr CreateField(const OGRFieldDefn *poField,
859 : int bApproxOK = TRUE) override;
860 : OGRErr CreateGeomField(const OGRGeomFieldDefn *poGeomFieldIn,
861 : int bApproxOK = TRUE) override;
862 : virtual OGRErr DeleteField(int iFieldToDelete) override;
863 : virtual OGRErr AlterFieldDefn(int iFieldToAlter,
864 : OGRFieldDefn *poNewFieldDefn,
865 : int nFlagsIn) override;
866 : virtual OGRErr
867 : AlterGeomFieldDefn(int iGeomFieldToAlter,
868 : const OGRGeomFieldDefn *poNewGeomFieldDefn,
869 : int nFlagsIn) override;
870 : virtual OGRErr ReorderFields(int *panMap) override;
871 : void ResetReading() override;
872 : OGRErr SetNextByIndex(GIntBig nIndex) override;
873 : OGRErr ICreateFeature(OGRFeature *poFeature) override;
874 : OGRErr ISetFeature(OGRFeature *poFeature) override;
875 : OGRErr IUpsertFeature(OGRFeature *poFeature) override;
876 : OGRErr IUpdateFeature(OGRFeature *poFeature, int nUpdatedFieldsCount,
877 : const int *panUpdatedFieldsIdx,
878 : int nUpdatedGeomFieldsCount,
879 : const int *panUpdatedGeomFieldsIdx,
880 : bool bUpdateStyleString) override;
881 : OGRErr DeleteFeature(GIntBig nFID) override;
882 : virtual void SetSpatialFilter(OGRGeometry *) override;
883 :
884 21 : virtual void SetSpatialFilter(int iGeomField, OGRGeometry *poGeom) override
885 : {
886 21 : OGRGeoPackageLayer::SetSpatialFilter(iGeomField, poGeom);
887 21 : }
888 :
889 : OGRErr SetAttributeFilter(const char *pszQuery) override;
890 : OGRErr SyncToDisk() override;
891 : OGRFeature *GetNextFeature() override;
892 : OGRFeature *GetFeature(GIntBig nFID) override;
893 : OGRErr StartTransaction() override;
894 : OGRErr CommitTransaction() override;
895 : OGRErr RollbackTransaction() override;
896 : GIntBig GetFeatureCount(int) override;
897 : OGRErr GetExtent(OGREnvelope *psExtent, int bForce = TRUE) override;
898 :
899 73 : virtual OGRErr GetExtent(int iGeomField, OGREnvelope *psExtent,
900 : int bForce) override
901 : {
902 73 : return OGRGeoPackageLayer::GetExtent(iGeomField, psExtent, bForce);
903 : }
904 :
905 : virtual OGRErr GetExtent3D(int iGeomField, OGREnvelope3D *psExtent3D,
906 : int bForce) override;
907 : OGRGeometryTypeCounter *GetGeometryTypes(int iGeomField, int nFlagsGGT,
908 : int &nEntryCountOut,
909 : GDALProgressFunc pfnProgress,
910 : void *pProgressData) override;
911 :
912 : void RecomputeExtent();
913 :
914 : void SetOpeningParameters(const char *pszTableName,
915 : const char *pszObjectType, bool bIsInGpkgContents,
916 : bool bIsSpatial, const char *pszGeomColName,
917 : const char *pszGeomType, bool bHasZ, bool bHasM);
918 : void SetCreationParameters(
919 : OGRwkbGeometryType eGType, const char *pszGeomColumnName,
920 : int bGeomNullable, const OGRSpatialReference *poSRS,
921 : const char *pszSRID, const OGRGeomCoordinatePrecision &oCoordPrec,
922 : bool bDiscardCoordLSB, bool bUndoDiscardCoordLSBOnReading,
923 : const char *pszFIDColumnName, const char *pszIdentifier,
924 : const char *pszDescription);
925 : void SetDeferredSpatialIndexCreation(bool bFlag);
926 :
927 46 : void SetASpatialVariant(GPKGASpatialVariant eASpatialVariant)
928 : {
929 46 : m_eASpatialVariant = eASpatialVariant;
930 46 : if (eASpatialVariant == GPKG_ATTRIBUTES)
931 34 : m_bIsInGpkgContents = true;
932 46 : }
933 :
934 634 : void SetDateTimePrecision(OGRISO8601Precision ePrecision)
935 : {
936 634 : m_sDateTimeFormat.ePrecision = ePrecision;
937 634 : }
938 :
939 : void CreateSpatialIndexIfNecessary();
940 : void FinishOrDisableThreadedRTree();
941 : bool FlushInMemoryRTree(sqlite3 *hRTreeDB, const char *pszRTreeName);
942 : bool CreateSpatialIndex(const char *pszTableName = nullptr);
943 : bool DropSpatialIndex(bool bCalledFromSQLFunction = false);
944 : CPLString ReturnSQLCreateSpatialIndexTriggers(const char *pszTableName,
945 : const char *pszGeomColName);
946 : CPLString ReturnSQLDropSpatialIndexTriggers();
947 :
948 : virtual char **GetMetadata(const char *pszDomain = "") override;
949 : virtual const char *GetMetadataItem(const char *pszName,
950 : const char *pszDomain = "") override;
951 : virtual char **GetMetadataDomainList() override;
952 :
953 : virtual CPLErr SetMetadata(char **papszMetadata,
954 : const char *pszDomain = "") override;
955 : virtual CPLErr SetMetadataItem(const char *pszName, const char *pszValue,
956 : const char *pszDomain = "") override;
957 :
958 : virtual OGRErr Rename(const char *pszDstTableName) override;
959 :
960 : virtual bool HasFastSpatialFilter(int iGeomCol) override;
961 : virtual CPLString GetSpatialWhere(int iGeomCol,
962 : OGRGeometry *poFilterGeom) override;
963 :
964 : OGRErr Truncate();
965 :
966 : bool HasSpatialIndex();
967 :
968 646 : void SetPrecisionFlag(int bFlag)
969 : {
970 646 : m_bPreservePrecision = CPL_TO_BOOL(bFlag);
971 646 : }
972 :
973 646 : void SetTruncateFieldsFlag(int bFlag)
974 : {
975 646 : m_bTruncateFields = CPL_TO_BOOL(bFlag);
976 646 : }
977 :
978 646 : void SetLaunder(bool bFlag)
979 : {
980 646 : m_bLaunder = bFlag;
981 646 : }
982 :
983 : OGRErr RunDeferredCreationIfNecessary();
984 : bool RunDeferredDropRTreeTableIfNecessary();
985 : bool DoJobAtTransactionCommit();
986 : bool DoJobAtTransactionRollback();
987 : bool RunDeferredSpatialIndexUpdate();
988 :
989 : #ifdef ENABLE_GPKG_OGR_CONTENTS
990 30 : bool GetAddOGRFeatureCountTriggers() const
991 : {
992 30 : return m_bAddOGRFeatureCountTriggers;
993 : }
994 :
995 53 : void SetAddOGRFeatureCountTriggers(bool b)
996 : {
997 53 : m_bAddOGRFeatureCountTriggers = b;
998 53 : }
999 :
1000 30 : bool GetOGRFeatureCountTriggersDeletedInTransaction() const
1001 : {
1002 30 : return m_bFeatureCountTriggersDeletedInTransaction;
1003 : }
1004 :
1005 7 : void SetOGRFeatureCountTriggersEnabled(bool b)
1006 : {
1007 7 : m_bOGRFeatureCountTriggersEnabled = b;
1008 7 : }
1009 :
1010 : void DisableFeatureCount();
1011 : #endif
1012 :
1013 : bool CreateGeometryExtensionIfNecessary(OGRwkbGeometryType eGType);
1014 :
1015 : /************************************************************************/
1016 : /* GPKG methods */
1017 :
1018 : private:
1019 : bool CheckUpdatableTable(const char *pszOperation);
1020 : OGRErr UpdateExtent(const OGREnvelope *poExtent);
1021 : OGRErr SaveExtent();
1022 : OGRErr SaveTimestamp();
1023 : OGRErr BuildColumns();
1024 : bool IsGeomFieldSet(OGRFeature *poFeature);
1025 : std::string FeatureGenerateUpdateSQL(const OGRFeature *poFeature) const;
1026 : std::string FeatureGenerateUpdateSQL(
1027 : const OGRFeature *poFeature, int nUpdatedFieldsCount,
1028 : const int *panUpdatedFieldsIdx, int nUpdatedGeomFieldsCount,
1029 : const int *panUpdatedGeomFieldsIdx) const;
1030 : CPLString
1031 : FeatureGenerateInsertSQL(OGRFeature *poFeature, bool bAddFID,
1032 : bool bBindUnsetFields, bool bUpsert,
1033 : const std::string &osUpsertUniqueColumnName);
1034 : OGRErr FeatureBindUpdateParameters(OGRFeature *poFeature,
1035 : sqlite3_stmt *poStmt);
1036 : OGRErr FeatureBindInsertParameters(OGRFeature *poFeature,
1037 : sqlite3_stmt *poStmt, bool bAddFID,
1038 : bool bBindUnsetFields);
1039 : OGRErr FeatureBindParameters(OGRFeature *poFeature, sqlite3_stmt *poStmt,
1040 : int *pnColCount, bool bAddFID,
1041 : bool bBindUnsetFields, int nUpdatedFieldsCount,
1042 : const int *panUpdatedFieldsIdx,
1043 : int nUpdatedGeomFieldsCount,
1044 : const int *panUpdatedGeomFieldsIdx);
1045 :
1046 : void UpdateContentsToNullExtent();
1047 :
1048 : void CheckUnknownExtensions();
1049 : bool CreateGeometryExtensionIfNecessary(const OGRGeometry *poGeom);
1050 : };
1051 :
1052 : /************************************************************************/
1053 : /* OGRGeoPackageSelectLayer */
1054 : /************************************************************************/
1055 :
1056 : class OGRGeoPackageSelectLayer final : public OGRGeoPackageLayer,
1057 : public IOGRSQLiteSelectLayer
1058 : {
1059 : CPL_DISALLOW_COPY_ASSIGN(OGRGeoPackageSelectLayer)
1060 :
1061 : OGRSQLiteSelectLayerCommonBehaviour *poBehavior = nullptr;
1062 :
1063 : virtual OGRErr ResetStatement() override;
1064 :
1065 : public:
1066 : OGRGeoPackageSelectLayer(GDALGeoPackageDataset *, const CPLString &osSQL,
1067 : sqlite3_stmt *,
1068 : bool bUseStatementForGetNextFeature,
1069 : bool bEmptyLayer);
1070 : virtual ~OGRGeoPackageSelectLayer();
1071 :
1072 : virtual void ResetReading() override;
1073 :
1074 : virtual OGRFeature *GetNextFeature() override;
1075 : virtual GIntBig GetFeatureCount(int) override;
1076 :
1077 22 : virtual void SetSpatialFilter(OGRGeometry *poGeom) override
1078 : {
1079 22 : SetSpatialFilter(0, poGeom);
1080 22 : }
1081 :
1082 : virtual void SetSpatialFilter(int iGeomField, OGRGeometry *) override;
1083 : virtual OGRErr SetAttributeFilter(const char *) override;
1084 :
1085 : virtual int TestCapability(const char *) override;
1086 :
1087 1 : virtual OGRErr GetExtent(OGREnvelope *psExtent, int bForce = TRUE) override
1088 : {
1089 1 : return GetExtent(0, psExtent, bForce);
1090 : }
1091 :
1092 : virtual OGRErr GetExtent(int iGeomField, OGREnvelope *psExtent,
1093 : int bForce = TRUE) override;
1094 :
1095 522 : virtual OGRFeatureDefn *GetLayerDefn() override
1096 : {
1097 522 : return OGRGeoPackageLayer::GetLayerDefn();
1098 : }
1099 :
1100 95 : virtual char *&GetAttrQueryString() override
1101 : {
1102 95 : return m_pszAttrQueryString;
1103 : }
1104 :
1105 375 : virtual OGRFeatureQuery *&GetFeatureQuery() override
1106 : {
1107 375 : return m_poAttrQuery;
1108 : }
1109 :
1110 250 : virtual OGRGeometry *&GetFilterGeom() override
1111 : {
1112 250 : return m_poFilterGeom;
1113 : }
1114 :
1115 65 : virtual int &GetIGeomFieldFilter() override
1116 : {
1117 65 : return m_iGeomFieldFilter;
1118 : }
1119 :
1120 112 : virtual OGRSpatialReference *GetSpatialRef() override
1121 : {
1122 112 : return OGRGeoPackageLayer::GetSpatialRef();
1123 : }
1124 :
1125 45 : virtual int InstallFilter(OGRGeometry *poGeomIn) override
1126 : {
1127 45 : return OGRGeoPackageLayer::InstallFilter(poGeomIn);
1128 : }
1129 :
1130 176 : virtual int HasReadFeature() override
1131 : {
1132 176 : return m_iNextShapeId > 0;
1133 : }
1134 :
1135 87 : virtual void BaseResetReading() override
1136 : {
1137 87 : OGRGeoPackageLayer::ResetReading();
1138 87 : }
1139 :
1140 1946 : virtual OGRFeature *BaseGetNextFeature() override
1141 : {
1142 1946 : return OGRGeoPackageLayer::GetNextFeature();
1143 : }
1144 :
1145 0 : virtual OGRErr BaseSetAttributeFilter(const char *pszQuery) override
1146 : {
1147 0 : return OGRGeoPackageLayer::SetAttributeFilter(pszQuery);
1148 : }
1149 :
1150 1 : virtual GIntBig BaseGetFeatureCount(int bForce) override
1151 : {
1152 1 : return OGRGeoPackageLayer::GetFeatureCount(bForce);
1153 : }
1154 :
1155 24 : virtual int BaseTestCapability(const char *pszCap) override
1156 : {
1157 24 : return OGRGeoPackageLayer::TestCapability(pszCap);
1158 : }
1159 :
1160 2 : virtual OGRErr BaseGetExtent(OGREnvelope *psExtent, int bForce) override
1161 : {
1162 2 : return OGRGeoPackageLayer::GetExtent(psExtent, bForce);
1163 : }
1164 :
1165 0 : virtual OGRErr BaseGetExtent(int iGeomField, OGREnvelope *psExtent,
1166 : int bForce) override
1167 : {
1168 0 : return OGRGeoPackageLayer::GetExtent(iGeomField, psExtent, bForce);
1169 : }
1170 :
1171 : bool
1172 47 : ValidateGeometryFieldIndexForSetSpatialFilter(int iGeomField,
1173 : const OGRGeometry *poGeomIn,
1174 : bool bIsSelectLayer) override
1175 : {
1176 : return OGRGeoPackageLayer::
1177 47 : ValidateGeometryFieldIndexForSetSpatialFilter(iGeomField, poGeomIn,
1178 47 : bIsSelectLayer);
1179 : }
1180 : };
1181 :
1182 : #endif /* OGR_GEOPACKAGE_H_INCLUDED */
|