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