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