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 "ogr_sqlite.h" 35 #include "ogrgeopackageutility.h" 36 37 #define UNKNOWN_SRID -2 38 #define DEFAULT_SRID 0 39 40 /************************************************************************/ 41 /* GDALGeoPackageDataset */ 42 /************************************************************************/ 43 44 class OGRGeoPackageTableLayer; 45 46 typedef struct 47 { 48 int nRow; 49 int nCol; 50 int nIdxWithinTileData; 51 int abBandDirty[4]; 52 } CachedTileDesc; 53 54 typedef enum 55 { 56 GPKG_TF_PNG_JPEG, 57 GPKG_TF_PNG, 58 GPKG_TF_PNG8, 59 GPKG_TF_JPEG, 60 GPKG_TF_WEBP 61 } GPKGTileFormat; 62 63 class GDALGeoPackageDataset : public OGRSQLiteBaseDataSource 64 { 65 friend class GDALGeoPackageRasterBand; 66 friend class OGRGeoPackageTableLayer; 67 68 OGRGeoPackageTableLayer** m_papoLayers; 69 int m_nLayers; 70 int m_bUtf8; 71 void CheckUnknownExtensions(int bCheckRasterTable = FALSE); 72 73 int m_bNew; 74 75 CPLString m_osRasterTable; 76 CPLString m_osIdentifier; 77 int m_bIdentifierAsCO; 78 CPLString m_osDescription; 79 int m_bDescriptionAsCO; 80 int m_bHasReadMetadataFromStorage; 81 int m_bMetadataDirty; 82 char **m_papszSubDatasets; 83 char *m_pszProjection; 84 int m_bRecordInsertedInGPKGContent; 85 int m_bGeoTransformValid; 86 double m_adfGeoTransform[6]; 87 int m_nSRID; 88 double m_dfTMSMinX; 89 double m_dfTMSMaxY; 90 int m_nZoomLevel; 91 GByte *m_pabyCachedTiles; 92 CachedTileDesc m_asCachedTilesDesc[4]; 93 int m_nShiftXTiles; 94 int m_nShiftXPixelsMod; 95 int m_nShiftYTiles; 96 int m_nShiftYPixelsMod; 97 int m_nTileMatrixWidth; 98 int m_nTileMatrixHeight; 99 100 GPKGTileFormat m_eTF; 101 int m_nZLevel; 102 int m_nQuality; 103 int m_bDither; 104 105 GDALColorTable* m_poCT; 106 int m_bTriedEstablishingCT; 107 GByte* m_pabyHugeColorArray; 108 109 GDALGeoPackageDataset* m_poParentDS; 110 int m_nOverviewCount; 111 GDALGeoPackageDataset** m_papoOverviewDS; 112 int m_bZoomOther; 113 114 CPLString m_osWHERE; 115 116 sqlite3 *m_hTempDB; 117 CPLString m_osTempDBFilename; 118 119 int m_bInFlushCache; 120 121 int m_nTileInsertionCount; 122 123 CPLString m_osTilingScheme; 124 125 void ComputeTileAndPixelShifts(); 126 int InitRaster ( GDALGeoPackageDataset* poParentDS, 127 const char* pszTableName, 128 double dfMinX, 129 double dfMinY, 130 double dfMaxX, 131 double dfMaxY, 132 const char* pszContentsMinX, 133 const char* pszContentsMinY, 134 const char* pszContentsMaxX, 135 const char* pszContentsMaxY, 136 char** papszOpenOptions, 137 const SQLResult& oResult, 138 int nIdxInResult ); 139 int InitRaster ( GDALGeoPackageDataset* poParentDS, 140 const char* pszTableName, 141 int nZoomLevel, 142 int nBandCount, 143 double dfTMSMinX, 144 double dfTMSMaxY, 145 double dfPixelXSize, 146 double dfPixelYSize, 147 int nTileWidth, 148 int nTileHeight, 149 int nTileMatrixWidth, 150 int nTileMatrixHeight, 151 double dfGDALMinX, 152 double dfGDALMinY, 153 double dfGDALMaxX, 154 double dfGDALMaxY ); 155 156 int OpenRaster( const char* pszTableName, 157 const char* pszIdentifier, 158 const char* pszDescription, 159 int nSRSId, 160 double dfMinX, 161 double dfMinY, 162 double dfMaxX, 163 double dfMaxY, 164 const char* pszContentsMinX, 165 const char* pszContentsMinY, 166 const char* pszContentsMaxX, 167 const char* pszContentsMaxY, 168 char** papszOptions ); 169 CPLErr FinalizeRasterRegistration(); 170 171 CPLErr ReadTile(const CPLString& osMemFileName, 172 GByte* pabyTileData, 173 int* pbIsLossyFormat = NULL); 174 GByte* ReadTile(int nRow, int nCol); 175 GByte* ReadTile(int nRow, int nCol, GByte* pabyData, 176 int* pbIsLossyFormat = NULL); 177 178 int m_bInWriteTile; 179 CPLErr WriteTile(); 180 181 CPLErr WriteTileInternal(); /* should only be called by WriteTile() */ 182 CPLErr FlushRemainingShiftedTiles(); 183 CPLErr WriteShiftedTile(int nRow, int nCol, int iBand, 184 int nDstXOffset, int nDstYOffset, 185 int nDstXSize, int nDstYSize); 186 187 int RegisterWebPExtension(); 188 int RegisterZoomOtherExtension(); 189 void ParseCompressionOptions(char** papszOptions); 190 191 int HasMetadataTables(); 192 int CreateMetadataTables(); 193 const char* CheckMetadataDomain( const char* pszDomain ); 194 void WriteMetadata(CPLXMLNode* psXMLNode, /* will be destroyed by the method /*/ 195 const char* pszTableName); 196 CPLErr FlushMetadata(); 197 198 public: 199 GDALGeoPackageDataset(); 200 ~GDALGeoPackageDataset(); 201 202 virtual char ** GetMetadata( const char *pszDomain = NULL ); 203 virtual const char *GetMetadataItem( const char * pszName, 204 const char * pszDomain = "" ); 205 virtual char ** GetMetadataDomainList(); 206 virtual CPLErr SetMetadata( char ** papszMetadata, 207 const char * pszDomain = "" ); 208 virtual CPLErr SetMetadataItem( const char * pszName, 209 const char * pszValue, 210 const char * pszDomain = "" ); 211 212 virtual const char* GetProjectionRef(); 213 virtual CPLErr SetProjection( const char* pszProjection ); 214 215 virtual CPLErr GetGeoTransform( double* padfGeoTransform ); 216 virtual CPLErr SetGeoTransform( double* padfGeoTransform ); 217 218 virtual void FlushCache(); 219 CPLErr FlushCacheWithErrCode(); 220 virtual CPLErr IBuildOverviews( const char *, int, int *, 221 int, int *, GDALProgressFunc, void * ); 222 GetLayerCount()223 virtual int GetLayerCount() { return m_nLayers; } 224 int Open( GDALOpenInfo* poOpenInfo ); 225 int Create( const char * pszFilename, 226 int nXSize, 227 int nYSize, 228 int nBands, 229 GDALDataType eDT, 230 char **papszOptions ); 231 OGRLayer* GetLayer( int iLayer ); 232 int DeleteLayer( int iLayer ); 233 OGRLayer* ICreateLayer( const char * pszLayerName, 234 OGRSpatialReference * poSpatialRef, 235 OGRwkbGeometryType eGType, 236 char **papszOptions ); 237 int TestCapability( const char * ); 238 239 virtual std::pair<OGRLayer*, IOGRSQLiteGetSpatialWhere*> GetLayerWithGetSpatialWhereByName( const char* pszName ); 240 241 virtual OGRLayer * ExecuteSQL( const char *pszSQLCommand, 242 OGRGeometry *poSpatialFilter, 243 const char *pszDialect ); 244 virtual void ReleaseResultSet( OGRLayer * poLayer ); 245 246 virtual OGRErr CommitTransaction(); 247 virtual OGRErr RollbackTransaction(); 248 249 int GetSrsId( const OGRSpatialReference * poSRS ); 250 const char* GetSrsName( const OGRSpatialReference * poSRS ); 251 OGRSpatialReference* GetSpatialRef( int iSrsId ); GetUTF8()252 virtual int GetUTF8() { return m_bUtf8; } 253 OGRErr CreateExtensionsTableIfNecessary(); 254 int HasExtensionsTable(); 255 OGRErr CreateGDALAspatialExtension(); SetMetadataDirty()256 void SetMetadataDirty() { m_bMetadataDirty = TRUE; } 257 258 const char* GetGeometryTypeString(OGRwkbGeometryType eType); 259 260 static GDALDataset* CreateCopy( const char *pszFilename, 261 GDALDataset *poSrcDS, 262 int bStrict, 263 char ** papszOptions, 264 GDALProgressFunc pfnProgress, 265 void * pProgressData ); 266 private: 267 268 OGRErr PragmaCheck(const char * pszPragma, const char * pszExpected, int nRowsExpected); 269 OGRErr SetApplicationId(); 270 int OpenOrCreateDB(int flags); 271 int HasGDALAspatialExtension(); 272 }; 273 274 /************************************************************************/ 275 /* GDALGeoPackageRasterBand */ 276 /************************************************************************/ 277 278 class GDALGeoPackageRasterBand: public GDALPamRasterBand 279 { 280 public: 281 282 GDALGeoPackageRasterBand(GDALGeoPackageDataset* poDS, 283 int nBand, 284 int nTileWidth, int nTileHeight); 285 286 virtual CPLErr IReadBlock(int nBlockXOff, int nBlockYOff, 287 void* pData); 288 virtual CPLErr IWriteBlock(int nBlockXOff, int nBlockYOff, 289 void* pData); 290 virtual CPLErr FlushCache(); 291 292 virtual GDALColorTable* GetColorTable(); 293 virtual CPLErr SetColorTable(GDALColorTable* poCT); 294 295 virtual GDALColorInterp GetColorInterpretation(); 296 virtual CPLErr SetColorInterpretation( GDALColorInterp ); 297 298 virtual int GetOverviewCount(); 299 virtual GDALRasterBand* GetOverview(int nIdx); 300 }; 301 302 /************************************************************************/ 303 /* OGRGeoPackageLayer */ 304 /************************************************************************/ 305 306 class OGRGeoPackageLayer : public OGRLayer, public IOGRSQLiteGetSpatialWhere 307 { 308 protected: 309 GDALGeoPackageDataset *m_poDS; 310 311 OGRFeatureDefn* m_poFeatureDefn; 312 int iNextShapeId; 313 314 sqlite3_stmt *m_poQueryStatement; 315 int bDoStep; 316 317 char *m_pszFidColumn; 318 319 int iFIDCol; 320 int iGeomCol; 321 int *panFieldOrdinals; 322 323 void ClearStatement(); 324 virtual OGRErr ResetStatement() = 0; 325 326 void BuildFeatureDefn( const char *pszLayerName, 327 sqlite3_stmt *hStmt ); 328 329 OGRFeature* TranslateFeature(sqlite3_stmt* hStmt); 330 331 public: 332 333 OGRGeoPackageLayer(GDALGeoPackageDataset* poDS); 334 ~OGRGeoPackageLayer(); 335 /************************************************************************/ 336 /* OGR API methods */ 337 338 OGRFeature* GetNextFeature(); 339 const char* GetFIDColumn(); 340 void ResetReading(); 341 int TestCapability( const char * ); GetLayerDefn()342 OGRFeatureDefn* GetLayerDefn() { return m_poFeatureDefn; } 343 HasFastSpatialFilter(CPL_UNUSED int iGeomCol)344 virtual int HasFastSpatialFilter(CPL_UNUSED int iGeomCol) { return FALSE; } GetSpatialWhere(CPL_UNUSED int iGeomCol,CPL_UNUSED OGRGeometry * poFilterGeom)345 virtual CPLString GetSpatialWhere(CPL_UNUSED int iGeomCol, 346 CPL_UNUSED OGRGeometry* poFilterGeom) { return ""; } 347 348 }; 349 350 /************************************************************************/ 351 /* OGRGeoPackageTableLayer */ 352 /************************************************************************/ 353 354 class OGRGeoPackageTableLayer : public OGRGeoPackageLayer 355 { 356 char* m_pszTableName; 357 int m_iSrs; 358 OGREnvelope* m_poExtent; 359 CPLString m_soColumns; 360 CPLString m_soFilter; 361 CPLString osQuery; 362 OGRBoolean m_bExtentChanged; 363 sqlite3_stmt* m_poUpdateStatement; 364 int m_bInsertStatementWithFID; 365 sqlite3_stmt* m_poInsertStatement; 366 int bDeferedSpatialIndexCreation; 367 int m_bHasSpatialIndex; 368 int bDropRTreeTable; 369 int m_anHasGeometryExtension[wkbMultiSurface+1]; 370 int m_bPreservePrecision; 371 int m_bTruncateFields; 372 int m_bDeferredCreation; 373 int m_iFIDAsRegularColumnIndex; 374 375 CPLString m_osIdentifierLCO; 376 CPLString m_osDescriptionLCO; 377 int m_bHasReadMetadataFromStorage; 378 379 virtual OGRErr ResetStatement(); 380 381 void BuildWhere(void); 382 OGRErr RegisterGeometryColumn(); 383 384 public: 385 386 OGRGeoPackageTableLayer( GDALGeoPackageDataset *poDS, 387 const char * pszTableName ); 388 ~OGRGeoPackageTableLayer(); 389 390 /************************************************************************/ 391 /* OGR API methods */ 392 393 int TestCapability( const char * ); 394 OGRErr CreateField( OGRFieldDefn *poField, int bApproxOK = TRUE ); 395 OGRErr CreateGeomField( OGRGeomFieldDefn *poGeomFieldIn, 396 int bApproxOK = TRUE ); 397 void ResetReading(); 398 OGRErr ICreateFeature( OGRFeature *poFeater ); 399 OGRErr ISetFeature( OGRFeature *poFeature ); 400 OGRErr DeleteFeature(GIntBig nFID); 401 virtual void SetSpatialFilter( OGRGeometry * ); 402 OGRErr SetAttributeFilter( const char *pszQuery ); 403 OGRErr SyncToDisk(); 404 OGRFeature* GetNextFeature(); 405 OGRFeature* GetFeature(GIntBig nFID); 406 OGRErr StartTransaction(); 407 OGRErr CommitTransaction(); 408 OGRErr RollbackTransaction(); 409 GIntBig GetFeatureCount( int ); 410 OGRErr GetExtent(OGREnvelope *psExtent, int bForce = TRUE); 411 412 // void SetSpatialFilter( int iGeomField, OGRGeometry * poGeomIn ); 413 414 OGRErr ReadTableDefinition(int bIsSpatial); 415 void SetCreationParameters( OGRwkbGeometryType eGType, 416 const char* pszGeomColumnName, 417 int bGeomNullable, 418 OGRSpatialReference* poSRS, 419 const char* pszFIDColumnName, 420 const char* pszIdentifier, 421 const char* pszDescription ); SetDeferedSpatialIndexCreation(int bFlag)422 void SetDeferedSpatialIndexCreation( int bFlag ) 423 { bDeferedSpatialIndexCreation = bFlag; } 424 425 void CreateSpatialIndexIfNecessary(); 426 int CreateSpatialIndex(); 427 int DropSpatialIndex(int bCalledFromSQLFunction = FALSE); 428 429 virtual char ** GetMetadata( const char *pszDomain = NULL ); 430 virtual const char *GetMetadataItem( const char * pszName, 431 const char * pszDomain = "" ); 432 virtual char ** GetMetadataDomainList(); 433 434 virtual CPLErr SetMetadata( char ** papszMetadata, 435 const char * pszDomain = "" ); 436 virtual CPLErr SetMetadataItem( const char * pszName, 437 const char * pszValue, 438 const char * pszDomain = "" ); 439 440 void RenameTo(const char* pszDstTableName); 441 442 virtual int HasFastSpatialFilter(int iGeomCol); 443 virtual CPLString GetSpatialWhere(int iGeomCol, 444 OGRGeometry* poFilterGeom); 445 446 int HasSpatialIndex(); SetPrecisionFlag(int bFlag)447 void SetPrecisionFlag( int bFlag ) 448 { m_bPreservePrecision = bFlag; } SetTruncateFieldsFlag(int bFlag)449 void SetTruncateFieldsFlag( int bFlag ) 450 { m_bTruncateFields = bFlag; } 451 OGRErr RunDeferredCreationIfNecessary(); 452 453 /************************************************************************/ 454 /* GPKG methods */ 455 456 private: 457 458 OGRErr UpdateExtent( const OGREnvelope *poExtent ); 459 OGRErr SaveExtent(); 460 OGRErr BuildColumns(); 461 OGRBoolean IsGeomFieldSet( OGRFeature *poFeature ); 462 CPLString FeatureGenerateUpdateSQL( OGRFeature *poFeature ); 463 CPLString FeatureGenerateInsertSQL( OGRFeature *poFeature, int bAddFID, int bBindNullFields ); 464 OGRErr FeatureBindUpdateParameters( OGRFeature *poFeature, sqlite3_stmt *poStmt ); 465 OGRErr FeatureBindInsertParameters( OGRFeature *poFeature, sqlite3_stmt *poStmt, int bAddFID, int bBindNullFields ); 466 OGRErr FeatureBindParameters( OGRFeature *poFeature, sqlite3_stmt *poStmt, int *pnColCount, int bAddFID, int bBindNullFields ); 467 468 void CheckUnknownExtensions(); 469 int CreateGeometryExtensionIfNecessary(OGRwkbGeometryType eGType); 470 }; 471 472 /************************************************************************/ 473 /* OGRGeoPackageSelectLayer */ 474 /************************************************************************/ 475 476 class OGRGeoPackageSelectLayer : public OGRGeoPackageLayer, public IOGRSQLiteSelectLayer 477 { 478 OGRSQLiteSelectLayerCommonBehaviour* poBehaviour; 479 480 virtual OGRErr ResetStatement(); 481 482 public: 483 OGRGeoPackageSelectLayer( GDALGeoPackageDataset *, 484 CPLString osSQL, 485 sqlite3_stmt *, 486 int bUseStatementForGetNextFeature, 487 int bEmptyLayer ); 488 ~OGRGeoPackageSelectLayer(); 489 490 virtual void ResetReading(); 491 492 virtual OGRFeature *GetNextFeature(); 493 virtual GIntBig GetFeatureCount( int ); 494 SetSpatialFilter(OGRGeometry * poGeom)495 virtual void SetSpatialFilter( OGRGeometry * poGeom ) { SetSpatialFilter(0, poGeom); } 496 virtual void SetSpatialFilter( int iGeomField, OGRGeometry * ); 497 virtual OGRErr SetAttributeFilter( const char * ); 498 499 virtual int TestCapability( const char * ); 500 501 virtual OGRErr GetExtent(OGREnvelope *psExtent, int bForce = TRUE) { return GetExtent(0, psExtent, bForce); } 502 virtual OGRErr GetExtent(int iGeomField, OGREnvelope *psExtent, int bForce = TRUE); 503 GetLayerDefn()504 virtual OGRFeatureDefn * GetLayerDefn() { return OGRGeoPackageLayer::GetLayerDefn(); } GetAttrQueryString()505 virtual char*& GetAttrQueryString() { return m_pszAttrQueryString; } GetFeatureQuery()506 virtual OGRFeatureQuery*& GetFeatureQuery() { return m_poAttrQuery; } GetFilterGeom()507 virtual OGRGeometry*& GetFilterGeom() { return m_poFilterGeom; } GetIGeomFieldFilter()508 virtual int& GetIGeomFieldFilter() { return m_iGeomFieldFilter; } GetSpatialRef()509 virtual OGRSpatialReference* GetSpatialRef() { return OGRGeoPackageLayer::GetSpatialRef(); } InstallFilter(OGRGeometry * poGeomIn)510 virtual int InstallFilter( OGRGeometry * poGeomIn ) { return OGRGeoPackageLayer::InstallFilter(poGeomIn); } HasReadFeature()511 virtual int HasReadFeature() { return iNextShapeId > 0; } BaseResetReading()512 virtual void BaseResetReading() { OGRGeoPackageLayer::ResetReading(); } BaseGetNextFeature()513 virtual OGRFeature *BaseGetNextFeature() { return OGRGeoPackageLayer::GetNextFeature(); } BaseSetAttributeFilter(const char * pszQuery)514 virtual OGRErr BaseSetAttributeFilter(const char* pszQuery) { return OGRGeoPackageLayer::SetAttributeFilter(pszQuery); } BaseGetFeatureCount(int bForce)515 virtual GIntBig BaseGetFeatureCount(int bForce) { return OGRGeoPackageLayer::GetFeatureCount(bForce); } BaseTestCapability(const char * pszCap)516 virtual int BaseTestCapability( const char *pszCap ) { return OGRGeoPackageLayer::TestCapability(pszCap); } BaseGetExtent(OGREnvelope * psExtent,int bForce)517 virtual OGRErr BaseGetExtent(OGREnvelope *psExtent, int bForce) { return OGRGeoPackageLayer::GetExtent(psExtent, bForce); } BaseGetExtent(int iGeomField,OGREnvelope * psExtent,int bForce)518 virtual OGRErr BaseGetExtent(int iGeomField, OGREnvelope *psExtent, int bForce) { return OGRGeoPackageLayer::GetExtent(iGeomField, psExtent, bForce); } 519 }; 520 521 522 #endif /* _OGR_GEOPACKAGE_H_INCLUDED */ 523