LCOV - code coverage report
Current view: directory - frmts/rasterlite - rasterlitedataset.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 576 461 80.0 %
Date: 2011-12-18 Functions: 25 18 72.0 %

       1                 : /******************************************************************************
       2                 :  * $Id: rasterlitedataset.cpp 23344 2011-11-06 15:05:13Z rouault $
       3                 :  *
       4                 :  * Project:  GDAL Rasterlite driver
       5                 :  * Purpose:  Implement GDAL Rasterlite support using OGR SQLite driver
       6                 :  * Author:   Even Rouault, <even dot rouault at mines dash paris dot org>
       7                 :  *
       8                 :  **********************************************************************
       9                 :  * Copyright (c) 2009, Even Rouault, <even dot rouault at mines dash paris dot org>
      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                 : #include "gdal_frmts.h"
      31                 : #include "cpl_string.h"
      32                 : #include "ogr_api.h"
      33                 : #include "ogr_srs_api.h"
      34                 : 
      35                 : #include "rasterlitedataset.h"
      36                 : 
      37                 : CPL_CVSID("$Id: rasterlitedataset.cpp 23344 2011-11-06 15:05:13Z rouault $");
      38                 : 
      39                 : /************************************************************************/
      40                 : /*                            RasterliteBand()                          */
      41                 : /************************************************************************/
      42                 : 
      43              53 : RasterliteBand::RasterliteBand(RasterliteDataset* poDS, int nBand,
      44                 :                                 GDALDataType eDataType,
      45              53 :                                 int nBlockXSize, int nBlockYSize)
      46                 : {
      47              53 :     this->poDS = poDS;
      48              53 :     this->nBand = nBand;
      49              53 :     this->eDataType = eDataType;
      50              53 :     this->nBlockXSize = nBlockXSize;
      51              53 :     this->nBlockYSize = nBlockYSize;
      52              53 : }
      53                 : 
      54                 : /************************************************************************/
      55                 : /*                            IReadBlock()                              */
      56                 : /************************************************************************/
      57                 : 
      58                 : //#define RASTERLITE_DEBUG
      59                 : 
      60              14 : CPLErr RasterliteBand::IReadBlock( int nBlockXOff, int nBlockYOff, void * pImage)
      61                 : {
      62              14 :     RasterliteDataset* poGDS = (RasterliteDataset*) poDS;
      63                 :     
      64              14 :     double minx = poGDS->adfGeoTransform[0] +
      65              14 :                   nBlockXOff * nBlockXSize * poGDS->adfGeoTransform[1];
      66              14 :     double maxx = poGDS->adfGeoTransform[0] +
      67              14 :                   (nBlockXOff + 1) * nBlockXSize * poGDS->adfGeoTransform[1];
      68              14 :     double maxy = poGDS->adfGeoTransform[3] +
      69              14 :                   nBlockYOff * nBlockYSize * poGDS->adfGeoTransform[5];
      70              14 :     double miny = poGDS->adfGeoTransform[3] +
      71              14 :                   (nBlockYOff + 1) * nBlockYSize * poGDS->adfGeoTransform[5];
      72              14 :     int nDataTypeSize = GDALGetDataTypeSize(eDataType) / 8;
      73                 : 
      74                 : #ifdef RASTERLITE_DEBUG
      75                 :     if (nBand == 1)
      76                 :     {
      77                 :         printf("nBlockXOff = %d, nBlockYOff = %d, nBlockXSize = %d, nBlockYSize = %d\n"
      78                 :                "minx=%.15f miny=%.15f maxx=%.15f maxy=%.15f\n",
      79                 :                 nBlockXOff, nBlockYOff, nBlockXSize, nBlockYSize, minx, miny, maxx, maxy);
      80                 :     }
      81                 : #endif
      82                 :     
      83              14 :     CPLString osSQL;
      84                 :     osSQL.Printf("SELECT m.geometry, r.raster, m.id, m.width, m.height FROM \"%s_metadata\" AS m, "
      85                 :                  "\"%s_rasters\" AS r WHERE m.rowid IN "
      86                 :                  "(SELECT pkid FROM \"idx_%s_metadata_geometry\" "
      87                 :                   "WHERE xmin < %.15f AND xmax > %.15f "
      88                 :                   "AND ymin < %.15f  AND ymax > %.15f) "
      89                 :                  "AND m.pixel_x_size >= %.15f AND m.pixel_x_size <= %.15f AND "
      90                 :                  "m.pixel_y_size >= %.15f AND m.pixel_y_size <= %.15f AND r.id = m.id",
      91                 :                   poGDS->osTableName.c_str(),
      92                 :                   poGDS->osTableName.c_str(),
      93                 :                   poGDS->osTableName.c_str(),
      94                 :                   maxx, minx, maxy, miny,
      95              28 :                   poGDS->adfGeoTransform[1] - 1e-15, poGDS->adfGeoTransform[1] + 1e-15,
      96              42 :                   - poGDS->adfGeoTransform[5] - 1e-15, - poGDS->adfGeoTransform[5] + 1e-15);
      97                 :     
      98              14 :     OGRLayerH hSQLLyr = OGR_DS_ExecuteSQL(poGDS->hDS, osSQL.c_str(), NULL, NULL);
      99              14 :     if (hSQLLyr == NULL)
     100                 :     {
     101               2 :         memset(pImage, 0, nBlockXSize * nBlockYSize * nDataTypeSize);
     102               2 :         return CE_None;
     103                 :     }
     104                 : 
     105              12 :     CPLString osMemFileName;
     106              12 :     osMemFileName.Printf("/vsimem/%p", this);
     107                 :     
     108              12 :     int bHasFoundTile = FALSE;
     109              12 :     int bHasMemsetTile = FALSE;
     110                 : 
     111                 : #ifdef RASTERLITE_DEBUG
     112                 :     if (nBand == 1)
     113                 :     {
     114                 :         printf("nTiles = %d\n", OGR_L_GetFeatureCount(hSQLLyr, TRUE));
     115                 :     }
     116                 : #endif
     117                 : 
     118                 :     OGRFeatureH hFeat;
     119              36 :     while( (hFeat = OGR_L_GetNextFeature(hSQLLyr)) != NULL )
     120                 :     {
     121              12 :         OGRGeometryH hGeom = OGR_F_GetGeometryRef(hFeat);
     122              12 :         if (hGeom == NULL)
     123                 :         {
     124               0 :             CPLError(CE_Failure, CPLE_AppDefined, "null geometry found");
     125               0 :             OGR_F_Destroy(hFeat);
     126               0 :             OGR_DS_ReleaseResultSet(poGDS->hDS, hSQLLyr);
     127               0 :             return CE_Failure;
     128                 :         }
     129                 :         
     130              12 :         OGREnvelope oEnvelope;
     131              12 :         OGR_G_GetEnvelope(hGeom, &oEnvelope);
     132                 : 
     133              12 :         int nTileId = OGR_F_GetFieldAsInteger(hFeat, 1);
     134              12 :         int nTileXSize = OGR_F_GetFieldAsInteger(hFeat, 2);
     135              12 :         int nTileYSize = OGR_F_GetFieldAsInteger(hFeat, 3);
     136                 :         
     137                 :         int nDstXOff =
     138              12 :             (int)((oEnvelope.MinX - minx) / poGDS->adfGeoTransform[1] + 0.5);
     139                 :         int nDstYOff =
     140              12 :             (int)((maxy - oEnvelope.MaxY) / (-poGDS->adfGeoTransform[5]) + 0.5);
     141                 :         
     142              12 :         int nReqXSize = nTileXSize;
     143              12 :         int nReqYSize = nTileYSize;
     144                 :         
     145                 :         int nSrcXOff, nSrcYOff;
     146                 : 
     147              12 :         if (nDstXOff >= 0)
     148                 :         {
     149              11 :             nSrcXOff = 0;
     150                 :         }
     151                 :         else
     152                 :         {
     153               1 :             nSrcXOff = -nDstXOff;
     154               1 :             nReqXSize += nDstXOff;
     155               1 :             nDstXOff = 0;
     156                 :         }
     157                 :         
     158                 :         
     159              12 :         if (nDstYOff >= 0)
     160                 :         {
     161              11 :             nSrcYOff = 0;
     162                 :         }
     163                 :         else
     164                 :         {
     165               1 :             nSrcYOff = -nDstYOff;
     166               1 :             nReqYSize += nDstYOff;
     167               1 :             nDstYOff = 0;
     168                 :         }
     169                 :         
     170              12 :         if (nDstXOff + nReqXSize > nBlockXSize)
     171               0 :             nReqXSize = nBlockXSize - nDstXOff;
     172                 :             
     173              12 :         if (nDstYOff + nReqYSize > nBlockYSize)
     174               0 :             nReqYSize = nBlockYSize - nDstYOff;
     175                 : 
     176                 : #ifdef RASTERLITE_DEBUG
     177                 :         if (nBand == 1)
     178                 :         {
     179                 :             printf("id = %d, minx=%.15f miny=%.15f maxx=%.15f maxy=%.15f\n"
     180                 :                    "nDstXOff = %d, nDstYOff = %d, nSrcXOff = %d, nSrcYOff = %d, "
     181                 :                    "nReqXSize=%d, nReqYSize=%d\n",
     182                 :                    nTileId,
     183                 :                    oEnvelope.MinX, oEnvelope.MinY, oEnvelope.MaxX, oEnvelope.MaxY,
     184                 :                    nDstXOff, nDstYOff,
     185                 :                    nSrcXOff, nSrcYOff, nReqXSize, nReqYSize);
     186                 :         }
     187                 : #endif
     188                 : 
     189              12 :         if (nReqXSize > 0 && nReqYSize > 0 &&
     190                 :             nSrcXOff < nTileXSize && nSrcYOff < nTileYSize)
     191                 :         {
     192                 :                 
     193                 : #ifdef RASTERLITE_DEBUG
     194                 :             if (nBand == 1)
     195                 :             {
     196                 :                 printf("id = %d, selected !\n",  nTileId);
     197                 :             }
     198                 : #endif
     199              12 :             int nDataSize = 0;
     200              12 :             GByte* pabyData = OGR_F_GetFieldAsBinary(hFeat, 0, &nDataSize);
     201                 : 
     202                 :             VSILFILE * fp = VSIFileFromMemBuffer( osMemFileName.c_str(), pabyData,
     203              12 :                                               nDataSize, FALSE);
     204              12 :             VSIFCloseL(fp);
     205                 :             
     206              12 :             GDALDatasetH hDSTile = GDALOpen(osMemFileName.c_str(), GA_ReadOnly);
     207              12 :             int nTileBands = 0;
     208              12 :             if (hDSTile && (nTileBands = GDALGetRasterCount(hDSTile)) == 0)
     209                 :             {
     210               0 :                 GDALClose(hDSTile);
     211               0 :                 hDSTile = NULL;
     212                 :             }
     213              12 :             if (hDSTile == NULL)
     214                 :             {
     215                 :                 CPLError(CE_Failure, CPLE_AppDefined, "Can't open tile %d", 
     216               0 :                          nTileId);
     217                 :             }
     218                 :             
     219              12 :             int nReqBand = 1;
     220              12 :             if (nTileBands == poGDS->nBands)
     221              11 :                 nReqBand = nBand;
     222               2 :             else if (eDataType == GDT_Byte && nTileBands == 1 && poGDS->nBands == 3)
     223               1 :                 nReqBand = 1;
     224                 :             else
     225                 :             {
     226               0 :                 GDALClose(hDSTile);
     227               0 :                 hDSTile = NULL;
     228                 :             }
     229                 :                 
     230              12 :             if (hDSTile)
     231                 :             {
     232              12 :                 CPLAssert(GDALGetRasterXSize(hDSTile) == nTileXSize);
     233              12 :                 CPLAssert(GDALGetRasterYSize(hDSTile) == nTileYSize);
     234                 : 
     235              12 :                 bHasFoundTile = TRUE;
     236                 :                 
     237              12 :                 int bHasJustMemsetTileBand1 = FALSE;
     238                 :                 
     239                 :                 /* If the source tile doesn't fit the entire block size, then */
     240                 :                 /* we memset 0 before */
     241              12 :                 if (!(nDstXOff == 0 && nDstYOff == 0 &&
     242                 :                       nReqXSize == nBlockXSize && nReqYSize == nBlockYSize) &&
     243                 :                     !bHasMemsetTile)
     244                 :                 {
     245               5 :                     memset(pImage, 0, nBlockXSize * nBlockYSize * nDataTypeSize);
     246               5 :                     bHasMemsetTile = TRUE;
     247               5 :                     bHasJustMemsetTileBand1 = TRUE;
     248                 :                 }
     249                 :                 
     250                 :                 GDALColorTable* poTileCT =
     251              12 :                     (GDALColorTable* )GDALGetRasterColorTable(GDALGetRasterBand(hDSTile, 1));
     252              12 :                 unsigned char* pabyTranslationTable = NULL;
     253              12 :                 if (poGDS->nBands == 1 && poGDS->poCT != NULL && poTileCT != NULL)
     254                 :                 {
     255                 :                     pabyTranslationTable =
     256                 :                         ((GDALRasterBand*)GDALGetRasterBand(hDSTile, 1))->
     257               1 :                                 GetIndexColorTranslationTo(this, NULL, NULL);
     258                 :                 }
     259                 :                     
     260                 : /* -------------------------------------------------------------------- */
     261                 : /*      Read tile data                                                  */
     262                 : /* -------------------------------------------------------------------- */
     263                 :                 GDALRasterIO(GDALGetRasterBand(hDSTile, nReqBand), GF_Read,
     264                 :                              nSrcXOff, nSrcYOff, nReqXSize, nReqYSize,
     265                 :                              ((char*) pImage) + (nDstXOff + nDstYOff * nBlockXSize) * nDataTypeSize,
     266                 :                              nReqXSize, nReqYSize,
     267              12 :                              eDataType, nDataTypeSize, nBlockXSize * nDataTypeSize);
     268                 : 
     269              12 :                 if (eDataType == GDT_Byte && pabyTranslationTable)
     270                 :                 {
     271                 : /* -------------------------------------------------------------------- */
     272                 : /*      Convert from tile CT to band CT                                 */
     273                 : /* -------------------------------------------------------------------- */
     274                 :                     int i, j;
     275               0 :                     for(j=nDstYOff;j<nDstYOff + nReqYSize;j++)
     276                 :                     {
     277               0 :                         for(i=nDstXOff;i<nDstXOff + nReqXSize;i++)
     278                 :                         {
     279               0 :                             GByte* pPixel = ((GByte*) pImage) + i + j * nBlockXSize;
     280               0 :                             *pPixel = pabyTranslationTable[*pPixel];
     281                 :                         }
     282                 :                     }
     283               0 :                     CPLFree(pabyTranslationTable);
     284               0 :                     pabyTranslationTable = NULL;
     285                 :                 }
     286              12 :                 else if (eDataType == GDT_Byte && nTileBands == 1 &&
     287                 :                          poGDS->nBands == 3 && poTileCT != NULL)
     288                 :                 {
     289                 : /* -------------------------------------------------------------------- */
     290                 : /*      Expand from PCT to RGB                                          */
     291                 : /* -------------------------------------------------------------------- */
     292                 :                     int i, j;
     293                 :                     GByte abyCT[256];
     294               1 :                     int nEntries = MIN(256, poTileCT->GetColorEntryCount());
     295             257 :                     for(i=0;i<nEntries;i++)
     296                 :                     {
     297             256 :                         const GDALColorEntry* psEntry = poTileCT->GetColorEntry(i);
     298             256 :                         if (nBand == 1)
     299             256 :                             abyCT[i] = (GByte)psEntry->c1;
     300               0 :                         else if (nBand == 2)
     301               0 :                             abyCT[i] = (GByte)psEntry->c2;
     302                 :                         else
     303               0 :                             abyCT[i] = (GByte)psEntry->c3;
     304                 :                     }
     305               1 :                     for(;i<256;i++)
     306               0 :                         abyCT[i] = 0;
     307                 :                     
     308             170 :                     for(j=nDstYOff;j<nDstYOff + nReqYSize;j++)
     309                 :                     {
     310           57291 :                         for(i=nDstXOff;i<nDstXOff + nReqXSize;i++)
     311                 :                         {
     312           57122 :                             GByte* pPixel = ((GByte*) pImage) + i + j * nBlockXSize;
     313           57122 :                             *pPixel = abyCT[*pPixel];
     314                 :                         }
     315                 :                     }
     316                 :                 }
     317                 :                 
     318                 : /* -------------------------------------------------------------------- */
     319                 : /*      Put in the block cache the data for this block into other bands */
     320                 : /*      while the underlying dataset is opened                          */
     321                 : /* -------------------------------------------------------------------- */
     322              12 :                 if (nBand == 1 && poGDS->nBands > 1)
     323                 :                 {
     324                 :                     int iOtherBand;
     325              12 :                     for(iOtherBand=2;iOtherBand<=poGDS->nBands;iOtherBand++)
     326                 :                     {
     327                 :                         GDALRasterBlock *poBlock;
     328                 : 
     329                 :                         poBlock = poGDS->GetRasterBand(iOtherBand)->
     330               8 :                             GetLockedBlockRef(nBlockXOff,nBlockYOff, TRUE);
     331               8 :                         if (poBlock == NULL)
     332               0 :                             break;
     333                 :                             
     334               8 :                         GByte* pabySrcBlock = (GByte *) poBlock->GetDataRef();
     335               8 :                         if( pabySrcBlock == NULL )
     336                 :                         {
     337               0 :                             poBlock->DropLock();
     338               0 :                             break;
     339                 :                         }
     340                 :             
     341               8 :                         if (nTileBands == 1)
     342               2 :                             nReqBand = 1;
     343                 :                         else
     344               6 :                             nReqBand = iOtherBand;
     345                 : 
     346               8 :                         if (bHasJustMemsetTileBand1)
     347                 :                             memset(pabySrcBlock, 0,
     348               2 :                                    nBlockXSize * nBlockYSize * nDataTypeSize);
     349                 :             
     350                 : /* -------------------------------------------------------------------- */
     351                 : /*      Read tile data                                                  */
     352                 : /* -------------------------------------------------------------------- */
     353                 :                         GDALRasterIO(GDALGetRasterBand(hDSTile, nReqBand), GF_Read,
     354                 :                                      nSrcXOff, nSrcYOff, nReqXSize, nReqYSize,
     355                 :                                      ((char*) pabySrcBlock) +
     356                 :                                      (nDstXOff + nDstYOff * nBlockXSize) * nDataTypeSize,
     357                 :                                      nReqXSize, nReqYSize,
     358               8 :                                      eDataType, nDataTypeSize, nBlockXSize * nDataTypeSize);
     359                 :                         
     360               8 :                         if (eDataType == GDT_Byte && nTileBands == 1 &&
     361                 :                             poGDS->nBands == 3 && poTileCT != NULL)
     362                 :                         {
     363                 : /* -------------------------------------------------------------------- */
     364                 : /*      Expand from PCT to RGB                                          */
     365                 : /* -------------------------------------------------------------------- */
     366                 : 
     367                 :                             int i, j;
     368                 :                             GByte abyCT[256];
     369               2 :                             int nEntries = MIN(256, poTileCT->GetColorEntryCount());
     370             514 :                             for(i=0;i<nEntries;i++)
     371                 :                             {
     372             512 :                                 const GDALColorEntry* psEntry = poTileCT->GetColorEntry(i);
     373             512 :                                 if (iOtherBand == 1)
     374               0 :                                     abyCT[i] = (GByte)psEntry->c1;
     375             512 :                                 else if (iOtherBand == 2)
     376             256 :                                     abyCT[i] = (GByte)psEntry->c2;
     377                 :                                 else
     378             256 :                                     abyCT[i] = (GByte)psEntry->c3;
     379                 :                             }
     380               2 :                             for(;i<256;i++)
     381               0 :                                 abyCT[i] = 0;
     382                 :                             
     383             340 :                             for(j=nDstYOff;j<nDstYOff + nReqYSize;j++)
     384                 :                             {
     385          114582 :                                 for(i=nDstXOff;i<nDstXOff + nReqXSize;i++)
     386                 :                                 {
     387          114244 :                                     GByte* pPixel = ((GByte*) pabySrcBlock) + i + j * nBlockXSize;
     388          114244 :                                     *pPixel = abyCT[*pPixel];
     389                 :                                 }
     390                 :                             }
     391                 :                         }
     392                 :                         
     393               8 :                         poBlock->DropLock();
     394                 :                     }
     395                 :                   
     396                 :                 }
     397              12 :                 GDALClose(hDSTile);
     398                 :             }
     399                 :             
     400              12 :             VSIUnlink(osMemFileName.c_str());
     401                 :         }
     402                 :         else
     403                 :         {
     404                 : #ifdef RASTERLITE_DEBUG
     405                 :             if (nBand == 1)
     406                 :             {
     407                 :                 printf("id = %d, NOT selected !\n",  nTileId);
     408                 :             }
     409                 : #endif
     410                 :         }
     411                 :         
     412              12 :         OGR_F_Destroy(hFeat);
     413                 :     }
     414                 :     
     415              12 :     if (!bHasFoundTile)
     416                 :     {
     417               0 :         memset(pImage, 0, nBlockXSize * nBlockYSize * nDataTypeSize);
     418                 :     }
     419                 :             
     420              12 :     OGR_DS_ReleaseResultSet(poGDS->hDS, hSQLLyr);
     421                 :     
     422                 : #ifdef RASTERLITE_DEBUG
     423                 :     if (nBand == 1)
     424                 :         printf("\n");
     425                 : #endif
     426                 : 
     427              12 :     return CE_None;
     428                 : }
     429                 : 
     430                 : /************************************************************************/
     431                 : /*                         GetOverviewCount()                           */
     432                 : /************************************************************************/
     433                 : 
     434               7 : int RasterliteBand::GetOverviewCount()
     435                 : {
     436               7 :     RasterliteDataset* poGDS = (RasterliteDataset*) poDS;
     437                 :     
     438               7 :     if (poGDS->nLimitOvrCount >= 0)
     439               3 :         return poGDS->nLimitOvrCount;
     440               4 :     else if (poGDS->nResolutions > 1)
     441               1 :         return poGDS->nResolutions - 1;
     442                 :     else
     443               3 :         return GDALPamRasterBand::GetOverviewCount();
     444                 : }
     445                 : 
     446                 : /************************************************************************/
     447                 : /*                              GetOverview()                           */
     448                 : /************************************************************************/
     449                 : 
     450               9 : GDALRasterBand* RasterliteBand::GetOverview(int nLevel)
     451                 : {
     452               9 :     RasterliteDataset* poGDS = (RasterliteDataset*) poDS;
     453                 :     
     454               9 :     if (poGDS->nLimitOvrCount >= 0)
     455                 :     {
     456               2 :         if (nLevel < 0 || nLevel >= poGDS->nLimitOvrCount)
     457               0 :             return NULL;
     458                 :     }
     459                 :     
     460               9 :     if (poGDS->nResolutions == 1)
     461               0 :         return GDALPamRasterBand::GetOverview(nLevel);
     462                 :     
     463               9 :     if (nLevel < 0 || nLevel >= poGDS->nResolutions - 1)
     464               0 :         return NULL;
     465                 :         
     466               9 :     GDALDataset* poOvrDS = poGDS->papoOverviews[nLevel];
     467               9 :     if (poOvrDS)
     468               9 :         return poOvrDS->GetRasterBand(nBand);
     469                 :     else
     470               0 :         return NULL;
     471                 : }
     472                 : 
     473                 : /************************************************************************/
     474                 : /*                   GetColorInterpretation()                           */
     475                 : /************************************************************************/
     476                 : 
     477               1 : GDALColorInterp RasterliteBand::GetColorInterpretation()
     478                 : {
     479               1 :     RasterliteDataset* poGDS = (RasterliteDataset*) poDS;
     480               1 :     if (poGDS->nBands == 1)
     481                 :     {
     482               1 :         if (poGDS->poCT != NULL)
     483               1 :             return GCI_PaletteIndex;
     484                 :         else
     485               0 :             return GCI_GrayIndex;
     486                 :     }
     487               0 :     else if (poGDS->nBands == 3)
     488                 :     {
     489               0 :         if (nBand == 1)
     490               0 :             return GCI_RedBand;
     491               0 :         else if (nBand == 2)
     492               0 :             return GCI_GreenBand;
     493               0 :         else if (nBand == 3)
     494               0 :             return GCI_BlueBand;
     495                 :     }
     496                 :     
     497               0 :     return GCI_Undefined;
     498                 : }
     499                 : 
     500                 : /************************************************************************/
     501                 : /*                        GetColorTable()                               */
     502                 : /************************************************************************/
     503                 : 
     504               3 : GDALColorTable* RasterliteBand::GetColorTable()
     505                 : {
     506               3 :     RasterliteDataset* poGDS = (RasterliteDataset*) poDS;
     507               3 :     if (poGDS->nBands == 1)
     508               2 :         return poGDS->poCT;
     509                 :     else
     510               1 :         return NULL;
     511                 : }
     512                 : 
     513                 : /************************************************************************/
     514                 : /*                         RasterliteDataset()                          */
     515                 : /************************************************************************/
     516                 : 
     517              48 : RasterliteDataset::RasterliteDataset()
     518                 : {
     519              48 :     nLimitOvrCount = -1;
     520              48 :     bValidGeoTransform = FALSE;
     521              48 :     bMustFree = FALSE;
     522              48 :     nLevel = 0;
     523              48 :     poMainDS = NULL;
     524              48 :     nResolutions = 0;
     525              48 :     padfXResolutions = NULL;
     526              48 :     padfYResolutions = NULL;
     527              48 :     pszSRS = NULL;
     528              48 :     hDS = NULL;
     529              48 :     papoOverviews = NULL;
     530              48 :     papszMetadata = NULL;
     531              48 :     papszSubDatasets = NULL;
     532                 :     papszImageStructure =
     533              48 :         CSLAddString(NULL, "INTERLEAVE=PIXEL");
     534              48 :     poCT = NULL;
     535              48 :     bCheckForExistingOverview = TRUE;
     536              48 : }
     537                 : 
     538                 : /************************************************************************/
     539                 : /*                         RasterliteDataset()                          */
     540                 : /************************************************************************/
     541                 : 
     542               8 : RasterliteDataset::RasterliteDataset(RasterliteDataset* poMainDS, int nLevel)
     543                 : {
     544               8 :     nLimitOvrCount = -1;
     545               8 :     bMustFree = FALSE;
     546               8 :     this->nLevel = nLevel;
     547               8 :     this->poMainDS = poMainDS;
     548               8 :     nResolutions = poMainDS->nResolutions - nLevel;
     549               8 :     padfXResolutions = poMainDS->padfXResolutions + nLevel;
     550               8 :     padfYResolutions = poMainDS->padfYResolutions + nLevel;
     551               8 :     pszSRS = poMainDS->pszSRS;
     552               8 :     hDS = poMainDS->hDS;
     553               8 :     papoOverviews = poMainDS->papoOverviews + nLevel;
     554               8 :     papszMetadata = poMainDS->papszMetadata;
     555               8 :     papszSubDatasets = poMainDS->papszSubDatasets;
     556               8 :     papszImageStructure =  poMainDS->papszImageStructure;
     557               8 :     poCT =  poMainDS->poCT;
     558               8 :     bCheckForExistingOverview = TRUE;
     559                 : 
     560               8 :     osTableName = poMainDS->osTableName;
     561               8 :     osFileName = poMainDS->osFileName;
     562                 :     
     563                 :     nRasterXSize = (int)(poMainDS->nRasterXSize *
     564               8 :         (poMainDS->padfXResolutions[0] / padfXResolutions[0]) + 0.5);
     565                 :     nRasterYSize = (int)(poMainDS->nRasterYSize *
     566               8 :         (poMainDS->padfYResolutions[0] / padfYResolutions[0]) + 0.5);
     567                 : 
     568               8 :     bValidGeoTransform = TRUE;
     569               8 :     memcpy(adfGeoTransform, poMainDS->adfGeoTransform, 6 * sizeof(double));
     570               8 :     adfGeoTransform[1] = padfXResolutions[0];
     571               8 :     adfGeoTransform[5] = - padfYResolutions[0];
     572               8 : }
     573                 : 
     574                 : /************************************************************************/
     575                 : /*                        ~RasterliteDataset()                          */
     576                 : /************************************************************************/
     577                 : 
     578              56 : RasterliteDataset::~RasterliteDataset()
     579                 : {
     580              56 :     CloseDependentDatasets();
     581              56 : }
     582                 : 
     583                 : /************************************************************************/
     584                 : /*                      CloseDependentDatasets()                        */
     585                 : /************************************************************************/
     586                 : 
     587              56 : int RasterliteDataset::CloseDependentDatasets()
     588                 : {
     589              56 :     int bRet = GDALPamDataset::CloseDependentDatasets();
     590                 : 
     591             104 :     if (poMainDS == NULL && !bMustFree)
     592                 :     {
     593              48 :         CSLDestroy(papszMetadata);
     594              48 :         papszMetadata = NULL;
     595              48 :         CSLDestroy(papszSubDatasets);
     596              48 :         papszSubDatasets = NULL;
     597              48 :         CSLDestroy(papszImageStructure);
     598              48 :         papszImageStructure = NULL;
     599              48 :         CPLFree(pszSRS);
     600              48 :         pszSRS = NULL;
     601                 : 
     602              48 :         if (papoOverviews)
     603                 :         {
     604                 :             int i;
     605               8 :             for(i=1;i<nResolutions;i++)
     606                 :             {
     607              10 :                 if (papoOverviews[i-1] != NULL &&
     608               5 :                     papoOverviews[i-1]->bMustFree)
     609                 :                 {
     610               0 :                     papoOverviews[i-1]->poMainDS = NULL;
     611                 :                 }
     612               5 :                 delete papoOverviews[i-1];
     613                 :             }
     614               3 :             CPLFree(papoOverviews);
     615               3 :             papoOverviews = NULL;
     616               3 :             nResolutions = 0;
     617               3 :             bRet = TRUE;
     618                 :         }
     619                 : 
     620              48 :         if (hDS != NULL)
     621              25 :             OGRReleaseDataSource(hDS);
     622              48 :         hDS = NULL;
     623                 : 
     624              48 :         CPLFree(padfXResolutions);
     625              48 :         CPLFree(padfYResolutions);
     626              48 :         padfXResolutions = padfYResolutions = NULL;
     627                 : 
     628              48 :         delete poCT;
     629              48 :         poCT = NULL;
     630                 :     }
     631               8 :     else if (poMainDS != NULL && bMustFree)
     632                 :     {
     633               0 :         poMainDS->papoOverviews[nLevel-1] = NULL;
     634               0 :         delete poMainDS;
     635               0 :         poMainDS = NULL;
     636               0 :         bRet = TRUE;
     637                 :     }
     638                 : 
     639              56 :     return bRet;
     640                 : }
     641                 : 
     642                 : /************************************************************************/
     643                 : /*                           AddSubDataset()                            */
     644                 : /************************************************************************/
     645                 : 
     646              23 : void RasterliteDataset::AddSubDataset( const char* pszDSName)
     647                 : {
     648                 :     char  szName[80];
     649              23 :     int   nCount = CSLCount(papszSubDatasets ) / 2;
     650                 : 
     651              23 :     sprintf( szName, "SUBDATASET_%d_NAME", nCount+1 );
     652                 :     papszSubDatasets = 
     653              23 :         CSLSetNameValue( papszSubDatasets, szName, pszDSName);
     654                 : 
     655              23 :     sprintf( szName, "SUBDATASET_%d_DESC", nCount+1 );
     656                 :     papszSubDatasets = 
     657              23 :         CSLSetNameValue( papszSubDatasets, szName, pszDSName);
     658              23 : }
     659                 : 
     660                 : /************************************************************************/
     661                 : /*                            GetMetadata()                             */
     662                 : /************************************************************************/
     663                 : 
     664               0 : char **RasterliteDataset::GetMetadata( const char *pszDomain )
     665                 : 
     666                 : {
     667               0 :     if( pszDomain != NULL && EQUAL(pszDomain,"SUBDATASETS") )
     668               0 :         return papszSubDatasets;
     669                 :         
     670               0 :     if( CSLCount(papszSubDatasets) < 2 &&
     671                 :         pszDomain != NULL && EQUAL(pszDomain,"IMAGE_STRUCTURE") )
     672               0 :         return papszImageStructure;
     673                 :         
     674               0 :     if ( pszDomain == NULL || EQUAL(pszDomain, "") )
     675               0 :         return papszMetadata;
     676                 :         
     677               0 :     return GDALPamDataset::GetMetadata( pszDomain );
     678                 : }
     679                 : 
     680                 : /************************************************************************/
     681                 : /*                          GetMetadataItem()                           */
     682                 : /************************************************************************/
     683                 : 
     684               2 : const char *RasterliteDataset::GetMetadataItem( const char *pszName, 
     685                 :                                                 const char *pszDomain )
     686                 : {
     687               2 :     if (pszDomain != NULL &&EQUAL(pszDomain,"OVERVIEWS") )
     688                 :     {
     689               2 :         if (nResolutions > 1 || CSLCount(papszSubDatasets) > 2)
     690               0 :             return NULL;
     691                 :         else
     692                 :         {
     693               2 :             osOvrFileName.Printf("%s_%s", osFileName.c_str(), osTableName.c_str());
     694               2 :             if (bCheckForExistingOverview == FALSE ||
     695                 :                 CPLCheckForFile((char*) osOvrFileName.c_str(), NULL))
     696               0 :                 return osOvrFileName.c_str();
     697                 :             else
     698               2 :                 return NULL;
     699                 :         }
     700                 :     }
     701               0 :     return GDALPamDataset::GetMetadataItem(pszName, pszDomain);
     702                 : }
     703                 : 
     704                 : /************************************************************************/
     705                 : /*                          GetGeoTransform()                           */
     706                 : /************************************************************************/
     707                 : 
     708               2 : CPLErr RasterliteDataset::GetGeoTransform( double* padfGeoTransform )
     709                 : {
     710               2 :     if (bValidGeoTransform)
     711                 :     {
     712               2 :         memcpy(padfGeoTransform, adfGeoTransform, 6 * sizeof(double));
     713               2 :         return CE_None;
     714                 :     }
     715                 :     else
     716               0 :         return CE_Failure;
     717                 : }
     718                 : 
     719                 : /************************************************************************/
     720                 : /*                         GetProjectionRef()                           */
     721                 : /************************************************************************/
     722                 : 
     723               2 : const char* RasterliteDataset::GetProjectionRef()
     724                 : {
     725               2 :     if (pszSRS)
     726               2 :         return pszSRS;
     727                 :     else
     728               0 :         return "";
     729                 : }
     730                 : 
     731                 : /************************************************************************/
     732                 : /*                           GetFileList()                              */
     733                 : /************************************************************************/
     734                 : 
     735               0 : char** RasterliteDataset::GetFileList()
     736                 : {
     737               0 :     char** papszFileList = NULL;
     738               0 :     papszFileList = CSLAddString(papszFileList, osFileName);
     739               0 :     return papszFileList;
     740                 : }
     741                 : 
     742                 : /************************************************************************/
     743                 : /*                         GetBlockParams()                             */
     744                 : /************************************************************************/
     745                 : 
     746              33 : int RasterliteDataset::GetBlockParams(OGRLayerH hRasterLyr, int nLevel,
     747                 :                                       int* pnBands, GDALDataType* peDataType,
     748                 :                                       int* pnBlockXSize, int* pnBlockYSize)
     749                 : {
     750              33 :     CPLString osSQL;
     751                 :     
     752                 :     osSQL.Printf("SELECT m.geometry, r.raster, m.id "
     753                 :                  "FROM \"%s_metadata\" AS m, \"%s_rasters\" AS r "
     754                 :                  "WHERE m.pixel_x_size >= %.15f AND m.pixel_x_size <= %.15f AND "
     755                 :                  "m.pixel_y_size >= %.15f AND m.pixel_y_size <= %.15f AND r.id = m.id",
     756                 :                  osTableName.c_str(), osTableName.c_str(),
     757              66 :                  padfXResolutions[nLevel] - 1e-15, padfXResolutions[nLevel] + 1e-15,
     758              99 :                  padfYResolutions[nLevel] - 1e-15, padfYResolutions[nLevel] + 1e-15);
     759                 :     
     760              33 :     OGRLayerH hSQLLyr = OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);
     761              33 :     if (hSQLLyr == NULL)
     762                 :     {
     763               0 :         return FALSE;
     764                 :     }
     765                 :     
     766              33 :     OGRFeatureH hFeat = OGR_L_GetNextFeature(hRasterLyr);
     767              33 :     if (hFeat == NULL)
     768                 :     {
     769               0 :         OGR_DS_ReleaseResultSet(hDS, hSQLLyr);
     770               0 :         return FALSE;
     771                 :     }
     772                 :     
     773                 :     int nDataSize;
     774              33 :     GByte* pabyData = OGR_F_GetFieldAsBinary(hFeat, 0, &nDataSize);
     775                 :     
     776              33 :     if (nDataSize > 32 &&
     777                 :         EQUALN((const char*)pabyData, "StartWaveletsImage$$", strlen("StartWaveletsImage$$")))
     778                 :     {
     779               2 :         if (GDALGetDriverByName("EPSILON") == NULL)
     780                 :         {
     781                 :             CPLError(CE_Failure, CPLE_NotSupported,
     782               0 :                      "Rasterlite driver doesn't support WAVELET compressed images if EPSILON driver is not compiled");
     783               0 :             OGR_F_Destroy(hFeat);
     784               0 :             OGR_DS_ReleaseResultSet(hDS, hSQLLyr);
     785               0 :             return FALSE;
     786                 :         }
     787                 :     }
     788                 :     
     789              33 :     CPLString osMemFileName;
     790              33 :     osMemFileName.Printf("/vsimem/%p", this);
     791                 :     VSILFILE * fp = VSIFileFromMemBuffer( osMemFileName.c_str(), pabyData,
     792              33 :                                       nDataSize, FALSE);
     793              33 :     VSIFCloseL(fp);
     794                 :     
     795              33 :     GDALDatasetH hDSTile = GDALOpen(osMemFileName.c_str(), GA_ReadOnly);
     796              33 :     if (hDSTile)
     797                 :     {
     798              33 :         *pnBands = GDALGetRasterCount(hDSTile);
     799              33 :         if (*pnBands == 0)
     800                 :         {
     801               0 :             GDALClose(hDSTile);
     802               0 :             hDSTile = NULL;
     803                 :         }
     804                 :     }
     805                 :     else
     806                 :     {
     807                 :         CPLError(CE_Failure, CPLE_AppDefined, "Can't open tile %d", 
     808               0 :                  OGR_F_GetFieldAsInteger(hFeat, 1));
     809                 :     }
     810                 :     
     811              33 :     if (hDSTile)
     812                 :     {
     813                 :         int iBand;
     814              33 :         *peDataType = GDALGetRasterDataType(GDALGetRasterBand(hDSTile, 1));
     815                 :         
     816              51 :         for(iBand=2;iBand<=*pnBands;iBand++)
     817                 :         {
     818              18 :             if (*peDataType != GDALGetRasterDataType(GDALGetRasterBand(hDSTile, 1)))
     819                 :             {
     820               0 :                 CPLError(CE_Failure, CPLE_NotSupported, "Band types must be identical");
     821               0 :                 GDALClose(hDSTile);
     822               0 :                 hDSTile = NULL;
     823               0 :                 goto end;
     824                 :             }
     825                 :         }
     826                 :         
     827              33 :         *pnBlockXSize = GDALGetRasterXSize(hDSTile);
     828              33 :         *pnBlockYSize = GDALGetRasterYSize(hDSTile);
     829              33 :         if (CSLFindName(papszImageStructure, "COMPRESSION") == -1)
     830                 :         {
     831                 :             const char* pszCompression =
     832              32 :                 GDALGetMetadataItem(hDSTile, "COMPRESSION", "IMAGE_STRUCTURE");
     833              32 :             if (pszCompression != NULL && EQUAL(pszCompression, "JPEG"))
     834                 :                 papszImageStructure =
     835               2 :                     CSLAddString(papszImageStructure, "COMPRESSION=JPEG");
     836                 :         }
     837                 :         
     838              33 :         if (CSLFindName(papszMetadata, "TILE_FORMAT") == -1)
     839                 :         {
     840                 :             papszMetadata =
     841                 :                 CSLSetNameValue(papszMetadata, "TILE_FORMAT",
     842              25 :                            GDALGetDriverShortName(GDALGetDatasetDriver(hDSTile)));
     843                 :         }
     844                 :         
     845                 :         
     846              33 :         if (*pnBands == 1 && this->poCT == NULL)
     847                 :         {
     848                 :             GDALColorTable* poCT =
     849              25 :                 (GDALColorTable*)GDALGetRasterColorTable(GDALGetRasterBand(hDSTile, 1));
     850              25 :             if (poCT)
     851               2 :                 this->poCT = poCT->Clone();
     852                 :         }
     853                 : 
     854              33 :         GDALClose(hDSTile);
     855                 :     }
     856                 : end:    
     857              33 :     VSIUnlink(osMemFileName.c_str());
     858                 :     
     859              33 :     OGR_F_Destroy(hFeat);
     860                 :     
     861              33 :     OGR_DS_ReleaseResultSet(hDS, hSQLLyr);
     862                 :     
     863              33 :     return hDSTile != NULL;
     864                 : }
     865                 : 
     866                 : /************************************************************************/
     867                 : /*                             Identify()                               */
     868                 : /************************************************************************/
     869                 : 
     870            9245 : int RasterliteDataset::Identify(GDALOpenInfo* poOpenInfo)
     871                 : {
     872            9245 :     if (poOpenInfo->nHeaderBytes >= 1024 &&
     873                 :         EQUALN((const char*)poOpenInfo->pabyHeader, "SQLite Format 3", 15))
     874                 :     {
     875               0 :         return TRUE;
     876                 :     }
     877            9245 :     else if (EQUALN(poOpenInfo->pszFilename, "RASTERLITE:", 11))
     878                 :     {
     879               1 :         return TRUE;
     880                 :     }
     881                 :     
     882            9244 :     return FALSE;
     883                 : }
     884                 : 
     885                 : /************************************************************************/
     886                 : /*                                Open()                                */
     887                 : /************************************************************************/
     888                 : 
     889            1433 : GDALDataset* RasterliteDataset::Open(GDALOpenInfo* poOpenInfo)
     890                 : {
     891            1433 :     CPLString osFileName;
     892            1433 :     CPLString osTableName;
     893            1433 :     char **papszTokens = NULL;
     894            1433 :     int nLevel = 0;
     895            1433 :     double minx = 0, miny = 0, maxx = 0, maxy = 0;
     896            1433 :     int bMinXSet = FALSE, bMinYSet = FALSE, bMaxXSet = FALSE, bMaxYSet = FALSE;
     897            1433 :     int nReqBands = 0;
     898                 :     
     899                 : /* -------------------------------------------------------------------- */
     900                 : /*      Parse "file name"                                               */
     901                 : /* -------------------------------------------------------------------- */
     902            1454 :     if (poOpenInfo->nHeaderBytes >= 1024 &&
     903                 :         EQUALN((const char*)poOpenInfo->pabyHeader, "SQLite Format 3", 15))
     904                 :     {
     905              21 :         osFileName = poOpenInfo->pszFilename;
     906                 :     }
     907            1412 :     else if (!EQUALN(poOpenInfo->pszFilename, "RASTERLITE:", 11))
     908                 :     {
     909            1408 :         return NULL;
     910                 :     }
     911                 :     else
     912                 :     {
     913                 :         papszTokens = CSLTokenizeStringComplex( 
     914               4 :                 poOpenInfo->pszFilename + 11, ", ", FALSE, FALSE );
     915               4 :         int nTokens = CSLCount(papszTokens);
     916               4 :         if (nTokens == 0)
     917                 :         {
     918               0 :             CSLDestroy(papszTokens);
     919               0 :             return NULL;
     920                 :         }
     921                 :                 
     922               4 :         osFileName = papszTokens[0];
     923                 :         
     924                 :         int i;
     925              11 :         for(i=1;i<nTokens;i++)
     926                 :         {
     927               7 :             if (EQUALN(papszTokens[i], "table=", 6))
     928               2 :                 osTableName = papszTokens[i] + 6;
     929               5 :             else if (EQUALN(papszTokens[i], "level=", 6))
     930               0 :                 nLevel = atoi(papszTokens[i] + 6);
     931               5 :             else if (EQUALN(papszTokens[i], "minx=", 5))
     932                 :             {
     933               1 :                 bMinXSet = TRUE;
     934               1 :                 minx = atof(papszTokens[i] + 5);
     935                 :             }
     936               4 :             else if (EQUALN(papszTokens[i], "miny=", 5))
     937                 :             {
     938               1 :                 bMinYSet = TRUE;
     939               1 :                 miny = atof(papszTokens[i] + 5);
     940                 :             }
     941               3 :             else if (EQUALN(papszTokens[i], "maxx=", 5))
     942                 :             {
     943               1 :                 bMaxXSet = TRUE;
     944               1 :                 maxx = atof(papszTokens[i] + 5);
     945                 :             }
     946               2 :             else if (EQUALN(papszTokens[i], "maxy=", 5))
     947                 :             {
     948               1 :                 bMaxYSet = TRUE;
     949               1 :                 maxy = atof(papszTokens[i] + 5);
     950                 :             }
     951               1 :             else if (EQUALN(papszTokens[i], "bands=", 6))
     952                 :             {
     953               1 :                 nReqBands = atoi(papszTokens[i] + 6);
     954                 :             }
     955                 :             else
     956                 :             {
     957                 :                 CPLError(CE_Warning, CPLE_AppDefined,
     958               0 :                          "Invalid option : %s", papszTokens[i]);
     959                 :             }
     960                 :         }
     961                 :     }
     962                 :     
     963              25 :     if (OGRGetDriverCount() == 0)
     964               0 :         OGRRegisterAll();
     965                 :     
     966                 : /* -------------------------------------------------------------------- */
     967                 : /*      Open underlying OGR DB                                          */
     968                 : /* -------------------------------------------------------------------- */
     969                 : 
     970                 :     /* Set SQLITE_LIST_ALL_TABLES option as we wan't to be able to */
     971                 :     /* fetch non spatial tables */
     972              25 :     CPLString osOldVal = CPLGetConfigOption("SQLITE_LIST_ALL_TABLES", "FALSE");
     973              25 :     CPLSetThreadLocalConfigOption("SQLITE_LIST_ALL_TABLES", "TRUE");
     974              25 :     OGRDataSourceH hDS = OGROpen(osFileName.c_str(), (poOpenInfo->eAccess == GA_Update) ? TRUE : FALSE, NULL);
     975              25 :     CPLSetThreadLocalConfigOption("SQLITE_LIST_ALL_TABLES", osOldVal.c_str());
     976              25 :     CPLDebug("RASTERLITE", "SQLite DB Open");
     977                 :     
     978              25 :     RasterliteDataset* poDS = NULL;
     979                 : 
     980              25 :     if (hDS == NULL)
     981               0 :         goto end;
     982                 :     
     983              25 :     if (strlen(osTableName) == 0)
     984                 :     {
     985              23 :         int nCountSubdataset = 0;
     986              23 :         int nLayers = OGR_DS_GetLayerCount(hDS);
     987                 :         int i;
     988                 : /* -------------------------------------------------------------------- */
     989                 : /*      Add raster layers as subdatasets                                */
     990                 : /* -------------------------------------------------------------------- */
     991             355 :         for(i=0;i<nLayers;i++)
     992                 :         {   
     993             332 :             OGRLayerH hLyr = OGR_DS_GetLayer(hDS, i);
     994             332 :             const char* pszLayerName = OGR_FD_GetName(OGR_L_GetLayerDefn(hLyr));
     995             332 :             if (strstr(pszLayerName, "_rasters"))
     996                 :             {
     997              23 :                 char* pszShortName = CPLStrdup(pszLayerName);
     998              23 :                 *strstr(pszShortName, "_rasters") = '\0';
     999                 :                 
    1000              23 :                 CPLString osMetadataTableName = pszShortName;
    1001              23 :                 osMetadataTableName += "_metadata";
    1002                 :                 
    1003              23 :                 if (OGR_DS_GetLayerByName(hDS, osMetadataTableName.c_str()) != NULL)
    1004                 :                 {
    1005              23 :                     if (poDS == NULL)
    1006                 :                     {
    1007              23 :                         poDS = new RasterliteDataset();
    1008              46 :                         osTableName = pszShortName;
    1009                 :                     }
    1010                 :                         
    1011              23 :                     CPLString osSubdatasetName;
    1012              23 :                     if (!EQUALN(poOpenInfo->pszFilename, "RASTERLITE:", 11))
    1013              21 :                         osSubdatasetName += "RASTERLITE:";
    1014              23 :                     osSubdatasetName += poOpenInfo->pszFilename;
    1015              23 :                     osSubdatasetName += ",table=";
    1016              23 :                     osSubdatasetName += pszShortName;
    1017              23 :                     poDS->AddSubDataset(osSubdatasetName.c_str());
    1018                 :                     
    1019              23 :                     nCountSubdataset++;
    1020                 :                 }
    1021                 :                 
    1022              23 :                 CPLFree(pszShortName);
    1023                 :             }
    1024                 :         }
    1025                 :         
    1026              23 :         if (nCountSubdataset == 0)
    1027                 :         {
    1028               0 :             goto end;
    1029                 :         }
    1030              23 :         else if (nCountSubdataset != 1)
    1031                 :         {
    1032               0 :             poDS->SetDescription( poOpenInfo->pszFilename );
    1033               0 :             goto end;
    1034                 :         }
    1035                 :         
    1036                 : /* -------------------------------------------------------------------- */
    1037                 : /*      If just one subdataset, then open it                            */
    1038                 : /* -------------------------------------------------------------------- */
    1039              23 :         delete poDS;
    1040              23 :         poDS = NULL;
    1041                 :     }
    1042                 :     
    1043                 : /* -------------------------------------------------------------------- */
    1044                 : /*      Build dataset                                                   */
    1045                 : /* -------------------------------------------------------------------- */
    1046                 :     {
    1047              25 :         CPLString osMetadataTableName, osRasterTableName;
    1048              25 :         CPLString osSQL;
    1049                 :         OGRLayerH hMetadataLyr, hRasterLyr, hRasterPyramidsLyr;
    1050                 :         OGRLayerH hSQLLyr;
    1051                 :         OGRFeatureH hFeat;
    1052                 :         int i, nResolutions;
    1053                 :         int iBand, nBands, nBlockXSize, nBlockYSize;
    1054                 :         GDALDataType eDataType;
    1055                 : 
    1056              25 :         osMetadataTableName = osTableName;
    1057              25 :         osMetadataTableName += "_metadata";
    1058                 :         
    1059              25 :         hMetadataLyr = OGR_DS_GetLayerByName(hDS, osMetadataTableName.c_str());
    1060              25 :         if (hMetadataLyr == NULL)
    1061                 :             goto end;
    1062                 :             
    1063              25 :         osRasterTableName = osTableName;
    1064              25 :         osRasterTableName += "_rasters";
    1065                 :         
    1066              25 :         hRasterLyr = OGR_DS_GetLayerByName(hDS, osRasterTableName.c_str());
    1067              25 :         if (hRasterLyr == NULL)
    1068                 :             goto end;
    1069                 :         
    1070                 : /* -------------------------------------------------------------------- */
    1071                 : /*      Fetch resolutions                                               */
    1072                 : /* -------------------------------------------------------------------- */
    1073                 : 
    1074              25 :         hRasterPyramidsLyr = OGR_DS_GetLayerByName(hDS, "raster_pyramids");
    1075              25 :         if (hRasterPyramidsLyr)
    1076                 :         {
    1077                 :             osSQL.Printf("SELECT pixel_x_size, pixel_y_size "
    1078                 :                          "FROM raster_pyramids WHERE table_prefix = '%s' "
    1079                 :                          "ORDER BY pixel_x_size ASC",
    1080               3 :                          osTableName.c_str());
    1081                 :          }
    1082                 :          else
    1083                 :          {
    1084                 :             osSQL.Printf("SELECT DISTINCT(pixel_x_size), pixel_y_size "
    1085                 :                          "FROM \"%s_metadata\" WHERE pixel_x_size != 0  "
    1086                 :                          "ORDER BY pixel_x_size ASC",
    1087              22 :                          osTableName.c_str());
    1088                 :          }
    1089                 : 
    1090              25 :         hSQLLyr = OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);
    1091              25 :         if (hSQLLyr == NULL)
    1092                 :         {
    1093               0 :             if (hRasterPyramidsLyr == NULL)
    1094                 :                 goto end;
    1095                 :                 
    1096                 :             osSQL.Printf("SELECT DISTINCT(pixel_x_size), pixel_y_size "
    1097                 :                          "FROM \"%s_metadata\" WHERE pixel_x_size != 0  "
    1098                 :                          "ORDER BY pixel_x_size ASC",
    1099               0 :                          osTableName.c_str());
    1100                 :                          
    1101               0 :             hSQLLyr = OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);
    1102               0 :             if (hSQLLyr == NULL)
    1103                 :                 goto end;
    1104                 :         }
    1105                 :             
    1106              25 :         nResolutions = OGR_L_GetFeatureCount(hSQLLyr, TRUE);
    1107                 :                      
    1108              25 :         if (nResolutions == 0)
    1109                 :         {
    1110               0 :             OGR_DS_ReleaseResultSet(hDS, hSQLLyr);
    1111                 :             goto end;
    1112                 :         }
    1113                 :             
    1114                 : /* -------------------------------------------------------------------- */
    1115                 : /*      Set dataset attributes                                          */
    1116                 : /* -------------------------------------------------------------------- */
    1117                 : 
    1118              25 :         poDS = new RasterliteDataset();
    1119              25 :         poDS->SetDescription( poOpenInfo->pszFilename );
    1120              25 :         poDS->eAccess = poOpenInfo->eAccess;
    1121              25 :         poDS->osTableName = osTableName;
    1122              25 :         poDS->osFileName = osFileName;
    1123              25 :         poDS->hDS = hDS;
    1124                 :         
    1125                 :         /* poDS will release it from now */
    1126              25 :         hDS = NULL;
    1127                 :         
    1128                 : /* -------------------------------------------------------------------- */
    1129                 : /*      Fetch spatial extent or use the one provided by the user        */
    1130                 : /* -------------------------------------------------------------------- */
    1131              25 :         OGREnvelope oEnvelope;
    1132              26 :         if (bMinXSet && bMinYSet && bMaxXSet && bMaxYSet)
    1133                 :         {
    1134               1 :             oEnvelope.MinX = minx;
    1135               1 :             oEnvelope.MinY = miny;
    1136               1 :             oEnvelope.MaxX = maxx;
    1137               1 :             oEnvelope.MaxY = maxy;
    1138                 :         }
    1139                 :         else
    1140                 :         {
    1141              24 :             OGR_L_GetExtent(hMetadataLyr, &oEnvelope, TRUE);
    1142                 :             //printf("minx=%.15f miny=%.15f maxx=%.15f maxy=%.15f\n",
    1143                 :             //       oEnvelope.MinX, oEnvelope.MinY, oEnvelope.MaxX, oEnvelope.MaxY);
    1144                 :         }
    1145                 :         
    1146                 : /* -------------------------------------------------------------------- */
    1147                 : /*      Store resolutions                                               */
    1148                 : /* -------------------------------------------------------------------- */
    1149              25 :         poDS->nResolutions = nResolutions;
    1150                 :         poDS->padfXResolutions =
    1151              25 :             (double*)CPLMalloc(sizeof(double) * poDS->nResolutions);
    1152                 :         poDS->padfYResolutions =
    1153              25 :             (double*)CPLMalloc(sizeof(double) * poDS->nResolutions);
    1154                 : 
    1155              25 :         i = 0;
    1156              80 :         while((hFeat = OGR_L_GetNextFeature(hSQLLyr)) != NULL)
    1157                 :         {
    1158              30 :             poDS->padfXResolutions[i] = OGR_F_GetFieldAsDouble(hFeat, 0);
    1159              30 :             poDS->padfYResolutions[i] = OGR_F_GetFieldAsDouble(hFeat, 1);
    1160                 : 
    1161              30 :             OGR_F_Destroy(hFeat);
    1162                 :             
    1163                 :             //printf("[%d] xres=%.15f yres=%.15f\n", i,
    1164                 :             //       poDS->padfXResolutions[i], poDS->padfYResolutions[i]);
    1165                 :             
    1166              30 :             if (poDS->padfXResolutions[i] <= 0 || poDS->padfXResolutions[i] <= 0)
    1167                 :             {
    1168                 :                 CPLError(CE_Failure, CPLE_NotSupported,
    1169                 :                          "res=%d, xres=%.15f, yres=%.15f",
    1170               0 :                          i, poDS->padfXResolutions[i], poDS->padfYResolutions[i]);
    1171               0 :                 OGR_DS_ReleaseResultSet(hDS, hSQLLyr);
    1172               0 :                 delete poDS;
    1173               0 :                 poDS = NULL;
    1174                 :                 goto end;
    1175                 :             }
    1176              30 :             i ++;
    1177                 :         }
    1178                 : 
    1179              25 :         OGR_DS_ReleaseResultSet(poDS->hDS, hSQLLyr);
    1180              25 :         hSQLLyr = NULL;
    1181                 : 
    1182                 : /* -------------------------------------------------------------------- */
    1183                 : /*      Compute raster size, geotransform and projection                */
    1184                 : /* -------------------------------------------------------------------- */
    1185                 :         poDS->nRasterXSize =
    1186              25 :             (int)((oEnvelope.MaxX - oEnvelope.MinX) / poDS->padfXResolutions[0] + 0.5);
    1187                 :         poDS->nRasterYSize =
    1188              25 :             (int)((oEnvelope.MaxY - oEnvelope.MinY) / poDS->padfYResolutions[0] + 0.5);
    1189                 : 
    1190              25 :         poDS->bValidGeoTransform = TRUE;
    1191              25 :         poDS->adfGeoTransform[0] = oEnvelope.MinX;
    1192              25 :         poDS->adfGeoTransform[1] = poDS->padfXResolutions[0];
    1193              25 :         poDS->adfGeoTransform[2] = 0;
    1194              25 :         poDS->adfGeoTransform[3] = oEnvelope.MaxY;
    1195              25 :         poDS->adfGeoTransform[4] = 0;
    1196              25 :         poDS->adfGeoTransform[5] = - poDS->padfYResolutions[0];
    1197                 :         
    1198              25 :         OGRSpatialReferenceH hSRS = OGR_L_GetSpatialRef(hMetadataLyr);
    1199              25 :         if (hSRS)
    1200                 :         {
    1201              25 :             OSRExportToWkt(hSRS, &poDS->pszSRS);
    1202                 :         }
    1203                 :         
    1204                 : /* -------------------------------------------------------------------- */
    1205                 : /*      Get number of bands and block size                              */
    1206                 : /* -------------------------------------------------------------------- */
    1207                 : 
    1208              25 :         if (poDS->GetBlockParams(hRasterLyr, 0, &nBands, &eDataType,
    1209                 :                                  &nBlockXSize, &nBlockYSize) == FALSE)
    1210                 :         {
    1211               0 :             CPLError(CE_Failure, CPLE_AppDefined, "Cannot find block characteristics");
    1212               0 :             delete poDS;
    1213               0 :             poDS = NULL;
    1214                 :             goto end;
    1215                 :         }
    1216                 :         
    1217              26 :         if (eDataType == GDT_Byte && nBands == 1 && nReqBands == 3)
    1218               1 :             nBands = 3;
    1219              24 :         else if (nReqBands != 0)
    1220                 :         {
    1221                 :             CPLError(CE_Warning, CPLE_NotSupported,
    1222               0 :                      "Parameters bands=%d ignored", nReqBands);
    1223                 :         }
    1224                 :         
    1225                 : /* -------------------------------------------------------------------- */
    1226                 : /*      Add bands                                                       */
    1227                 : /* -------------------------------------------------------------------- */
    1228                 :         
    1229              68 :         for(iBand=0;iBand<nBands;iBand++)
    1230                 :             poDS->SetBand(iBand+1, new RasterliteBand(poDS, iBand+1, eDataType, 
    1231              43 :                                                   nBlockXSize, nBlockYSize));
    1232                 :         
    1233                 : /* -------------------------------------------------------------------- */
    1234                 : /*      Add overview levels as internal datasets                        */
    1235                 : /* -------------------------------------------------------------------- */
    1236              25 :         if (nResolutions > 1)
    1237                 :         {
    1238                 :             poDS->papoOverviews = (RasterliteDataset**)
    1239               3 :                 CPLCalloc(nResolutions - 1, sizeof(RasterliteDataset*));
    1240                 :             int nLev;
    1241               8 :             for(nLev=1;nLev<nResolutions;nLev++)
    1242                 :             {
    1243                 :                 int nOvrBands;
    1244                 :                 GDALDataType eOvrDataType;
    1245               5 :                 if (poDS->GetBlockParams(hRasterLyr, nLev, &nOvrBands, &eOvrDataType,
    1246                 :                                          &nBlockXSize, &nBlockYSize) == FALSE)
    1247                 :                 {
    1248                 :                     CPLError(CE_Failure, CPLE_AppDefined,
    1249               0 :                              "Cannot find block characteristics for overview %d", nLev);
    1250               0 :                     delete poDS;
    1251               0 :                     poDS = NULL;
    1252                 :                     goto end;
    1253                 :                 }
    1254                 :                 
    1255               5 :                 if (eDataType == GDT_Byte && nOvrBands == 1 && nReqBands == 3)
    1256               0 :                     nOvrBands = 3;
    1257                 :                     
    1258               5 :                 if (nBands != nOvrBands || eDataType != eOvrDataType)
    1259                 :                 {
    1260                 :                     CPLError(CE_Failure, CPLE_AppDefined,
    1261               0 :                              "Overview %d has not the same number characteristics as main band", nLev);
    1262               0 :                     delete poDS;
    1263               0 :                     poDS = NULL;
    1264                 :                     goto end;
    1265                 :                 }
    1266                 :                 
    1267               5 :                 poDS->papoOverviews[nLev-1] = new RasterliteDataset(poDS, nLev);
    1268                 :                     
    1269              12 :                 for(iBand=0;iBand<nBands;iBand++)
    1270                 :                 {
    1271               7 :                     poDS->papoOverviews[nLev-1]->SetBand(iBand+1,
    1272                 :                         new RasterliteBand(poDS->papoOverviews[nLev-1], iBand+1, eDataType,
    1273              14 :                                            nBlockXSize, nBlockYSize));
    1274                 :                 }
    1275                 :             }
    1276                 :         }
    1277                 :         
    1278                 : /* -------------------------------------------------------------------- */
    1279                 : /*      Select an overview if the user has requested so                 */
    1280                 : /* -------------------------------------------------------------------- */
    1281              25 :         if (nLevel == 0)
    1282                 :         {
    1283                 :         }
    1284               0 :         else if (nLevel >= 1 && nLevel <= nResolutions - 1)
    1285                 :         {
    1286               0 :             poDS->papoOverviews[nLevel-1]->bMustFree = TRUE;
    1287               0 :             poDS = poDS->papoOverviews[nLevel-1];
    1288                 :         }
    1289                 :         else
    1290                 :         {
    1291                 :             CPLError(CE_Failure, CPLE_AppDefined,
    1292                 :                       "Invalid requested level : %d. Must be >= 0 and <= %d",
    1293               0 :                       nLevel, nResolutions - 1);
    1294               0 :             delete poDS;
    1295               0 :             poDS = NULL;
    1296               0 :         }
    1297                 : 
    1298                 :     }
    1299                 : 
    1300              25 :     if (poDS)
    1301                 :     {
    1302                 : /* -------------------------------------------------------------------- */
    1303                 : /*      Setup PAM info for this subdatasets                             */
    1304                 : /* -------------------------------------------------------------------- */
    1305              25 :         poDS->SetPhysicalFilename( osFileName.c_str() );
    1306                 :         
    1307              25 :         CPLString osSubdatasetName;
    1308                 :         osSubdatasetName.Printf("RASTERLITE:%s:table=%s",
    1309              25 :                                 osFileName.c_str(), osTableName.c_str());
    1310              25 :         poDS->SetSubdatasetName( osSubdatasetName.c_str() );
    1311              25 :         poDS->TryLoadXML();
    1312              25 :         poDS->oOvManager.Initialize( poDS, ":::VIRTUAL:::" );
    1313                 :     }
    1314                 : 
    1315                 :     
    1316                 : end:
    1317              25 :     if (hDS)
    1318               0 :         OGRReleaseDataSource(hDS);
    1319              25 :     CSLDestroy(papszTokens);
    1320                 :     
    1321              25 :     return poDS;
    1322                 : }
    1323                 : 
    1324                 : /************************************************************************/
    1325                 : /*                     GDALRegister_Rasterlite()                        */
    1326                 : /************************************************************************/
    1327                 : 
    1328             558 : void GDALRegister_Rasterlite()
    1329                 : 
    1330                 : {
    1331                 :     GDALDriver  *poDriver;
    1332                 :     
    1333             558 :     if (! GDAL_CHECK_VERSION("Rasterlite driver"))
    1334               0 :         return;
    1335                 : 
    1336             558 :     if( GDALGetDriverByName( "Rasterlite" ) == NULL )
    1337                 :     {
    1338             537 :         poDriver = new GDALDriver();
    1339                 :         
    1340             537 :         poDriver->SetDescription( "Rasterlite" );
    1341                 :         poDriver->SetMetadataItem( GDAL_DMD_LONGNAME, 
    1342             537 :                                    "Rasterlite" );
    1343                 :         poDriver->SetMetadataItem( GDAL_DMD_HELPTOPIC, 
    1344             537 :                                    "frmt_rasterlite.html" );
    1345             537 :         poDriver->SetMetadataItem( GDAL_DMD_EXTENSION, "sqlite" );
    1346                 :         poDriver->SetMetadataItem( GDAL_DMD_CREATIONDATATYPES, 
    1347                 :                                    "Byte UInt16 Int16 UInt32 Int32 Float32 "
    1348             537 :                                    "Float64 CInt16 CInt32 CFloat32 CFloat64" );
    1349                 :         poDriver->SetMetadataItem( GDAL_DMD_CREATIONOPTIONLIST, 
    1350                 : "<CreationOptionList>"
    1351                 : "   <Option name='WIPE' type='boolean' default='NO' description='Erase all prexisting data in the specified table'/>"
    1352                 : "   <Option name='TILED' type='boolean' default='YES' description='Use tiling'/>"
    1353                 : "   <Option name='BLOCKXSIZE' type='int' default='256' description='Tile Width'/>"
    1354                 : "   <Option name='BLOCKYSIZE' type='int' default='256' description='Tile Height'/>"
    1355                 : "   <Option name='DRIVER' type='string' default='GTiff' description='GDAL driver to use for storing tiles' default='GTiff'/>"
    1356                 : "   <Option name='COMPRESS' type='string' default='(GTiff driver) Compression method' default='NONE'/>"
    1357                 : "   <Option name='QUALITY' type='int' description='(JPEG-compressed GTiff, JPEG and WEBP drivers) JPEG/WEBP Quality 1-100' default='75'/>"
    1358                 : "   <Option name='PHOTOMETRIC' type='string-select' description='(GTiff driver) Photometric interpretation'>"
    1359                 : "       <Value>MINISBLACK</Value>"
    1360                 : "       <Value>MINISWHITE</Value>"
    1361                 : "       <Value>PALETTE</Value>"
    1362                 : "       <Value>RGB</Value>"
    1363                 : "       <Value>CMYK</Value>"
    1364                 : "       <Value>YCBCR</Value>"
    1365                 : "       <Value>CIELAB</Value>"
    1366                 : "       <Value>ICCLAB</Value>"
    1367                 : "       <Value>ITULAB</Value>"
    1368                 : "   </Option>"
    1369                 : "   <Option name='TARGET' type='int' description='(EPSILON driver) target size reduction as a percentage of the original (0-100)' default='96'/>"
    1370                 : "   <Option name='FILTER' type='string' description='(EPSILON driver) Filter ID' default='daub97lift'/>"
    1371             537 : "</CreationOptionList>" );
    1372                 : 
    1373             537 :         poDriver->pfnOpen = RasterliteDataset::Open;
    1374             537 :         poDriver->pfnIdentify = RasterliteDataset::Identify;
    1375             537 :         poDriver->pfnCreateCopy = RasterliteCreateCopy;
    1376             537 :         poDriver->pfnDelete = RasterliteDelete;
    1377                 : 
    1378             537 :         GetGDALDriverManager()->RegisterDriver( poDriver );
    1379                 :     }
    1380                 : }

Generated by: LCOV version 1.7