LTP GCOV extension - code coverage report
Current view: directory - frmts/rasterlite - rasterlitedataset.cpp
Test: gdal_filtered.info
Date: 2010-07-12 Instrumented lines: 547
Code covered: 79.7 % Executed lines: 436

       1                 : /******************************************************************************
       2                 :  * $Id: rasterlitedataset.cpp 18343 2009-12-19 10:39:30Z 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 18343 2009-12-19 10:39:30Z rouault $");
      38                 : 
      39                 : /************************************************************************/
      40                 : /*                            RasterliteBand()                          */
      41                 : /************************************************************************/
      42                 : 
      43                 : RasterliteBand::RasterliteBand(RasterliteDataset* poDS, int nBand,
      44                 :                                 GDALDataType eDataType,
      45              57 :                                 int nBlockXSize, int nBlockYSize)

      46                 : {
      47              57 :     this->poDS = poDS;

      48              57 :     this->nBand = nBand;

      49              57 :     this->eDataType = eDataType;

      50              57 :     this->nBlockXSize = nBlockXSize;

      51              57 :     this->nBlockYSize = nBlockYSize;

      52              57 : }

      53                 : 
      54                 : /************************************************************************/
      55                 : /*                            IReadBlock()                              */
      56                 : /************************************************************************/
      57                 : 
      58                 : //#define RASTERLITE_DEBUG
      59                 : 
      60              16 : CPLErr RasterliteBand::IReadBlock( int nBlockXOff, int nBlockYOff, void * pImage)

      61                 : {
      62              16 :     RasterliteDataset* poGDS = (RasterliteDataset*) poDS;

      63                 :     
      64                 :     double minx = poGDS->adfGeoTransform[0] +
      65              16 :                   nBlockXOff * nBlockXSize * poGDS->adfGeoTransform[1];

      66                 :     double maxx = poGDS->adfGeoTransform[0] +
      67              16 :                   (nBlockXOff + 1) * nBlockXSize * poGDS->adfGeoTransform[1];

      68                 :     double maxy = poGDS->adfGeoTransform[3] +
      69              16 :                   nBlockYOff * nBlockYSize * poGDS->adfGeoTransform[5];

      70                 :     double miny = poGDS->adfGeoTransform[3] +
      71              16 :                   (nBlockYOff + 1) * nBlockYSize * poGDS->adfGeoTransform[5];

      72              16 :     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              16 :     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                 :                   poGDS->adfGeoTransform[1] - 1e-15, poGDS->adfGeoTransform[1] + 1e-15,
      96              16 :                   - poGDS->adfGeoTransform[5] - 1e-15, - poGDS->adfGeoTransform[5] + 1e-15);

      97                 :     
      98              16 :     OGRLayerH hSQLLyr = OGR_DS_ExecuteSQL(poGDS->hDS, osSQL.c_str(), NULL, NULL);

      99              16 :     if (hSQLLyr == NULL)

     100                 :     {
     101               0 :         memset(pImage, 0, nBlockXSize * nBlockYSize * nDataTypeSize);

     102               0 :         return CE_None;

     103                 :     }
     104                 : 
     105              16 :     CPLString osMemFileName;

     106              16 :     osMemFileName.Printf("/vsimem/%p", this);

     107                 :     
     108              16 :     int bHasFoundTile = FALSE;

     109              16 :     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              48 :     while( (hFeat = OGR_L_GetNextFeature(hSQLLyr)) != NULL )

     120                 :     {
     121              16 :         OGRGeometryH hGeom = OGR_F_GetGeometryRef(hFeat);

     122                 :         
     123              16 :         OGREnvelope oEnvelope;

     124              16 :         OGR_G_GetEnvelope(hGeom, &oEnvelope);

     125                 : 
     126              16 :         int nTileId = OGR_F_GetFieldAsInteger(hFeat, 1);

     127              16 :         int nTileXSize = OGR_F_GetFieldAsInteger(hFeat, 2);

     128              16 :         int nTileYSize = OGR_F_GetFieldAsInteger(hFeat, 3);

     129                 :         
     130                 :         int nDstXOff =
     131              16 :             (int)((oEnvelope.MinX - minx) / poGDS->adfGeoTransform[1] + 0.5);

     132                 :         int nDstYOff =
     133              16 :             (int)((maxy - oEnvelope.MaxY) / (-poGDS->adfGeoTransform[5]) + 0.5);

     134                 :         
     135              16 :         int nReqXSize = nTileXSize;

     136              16 :         int nReqYSize = nTileYSize;

     137                 :         
     138                 :         int nSrcXOff, nSrcYOff;
     139                 : 
     140              16 :         if (nDstXOff >= 0)

     141                 :         {
     142              15 :             nSrcXOff = 0;

     143                 :         }
     144                 :         else
     145                 :         {
     146               1 :             nSrcXOff = -nDstXOff;

     147               1 :             nReqXSize += nDstXOff;

     148               1 :             nDstXOff = 0;

     149                 :         }
     150                 :         
     151                 :         
     152              16 :         if (nDstYOff >= 0)

     153                 :         {
     154              15 :             nSrcYOff = 0;

     155                 :         }
     156                 :         else
     157                 :         {
     158               1 :             nSrcYOff = -nDstYOff;

     159               1 :             nReqYSize += nDstYOff;

     160               1 :             nDstYOff = 0;

     161                 :         }
     162                 :         
     163              16 :         if (nDstXOff + nReqXSize > nBlockXSize)

     164               0 :             nReqXSize = nBlockXSize - nDstXOff;

     165                 :             
     166              16 :         if (nDstYOff + nReqYSize > nBlockYSize)

     167               0 :             nReqYSize = nBlockYSize - nDstYOff;

     168                 : 
     169                 : #ifdef RASTERLITE_DEBUG
     170                 :         if (nBand == 1)
     171                 :         {
     172                 :             printf("id = %d, minx=%.15f miny=%.15f maxx=%.15f maxy=%.15f\n"
     173                 :                    "nDstXOff = %d, nDstYOff = %d, nSrcXOff = %d, nSrcYOff = %d, "
     174                 :                    "nReqXSize=%d, nReqYSize=%d\n",
     175                 :                    nTileId,
     176                 :                    oEnvelope.MinX, oEnvelope.MinY, oEnvelope.MaxX, oEnvelope.MaxY,
     177                 :                    nDstXOff, nDstYOff,
     178                 :                    nSrcXOff, nSrcYOff, nReqXSize, nReqYSize);
     179                 :         }
     180                 : #endif
     181                 : 
     182              16 :         if (nReqXSize > 0 && nReqYSize > 0 &&

     183                 :             nSrcXOff < nTileXSize && nSrcYOff < nTileYSize)
     184                 :         {
     185                 :                 
     186                 : #ifdef RASTERLITE_DEBUG
     187                 :             if (nBand == 1)
     188                 :             {
     189                 :                 printf("id = %d, selected !\n",  nTileId);
     190                 :             }
     191                 : #endif
     192              16 :             int nDataSize = 0;

     193              16 :             GByte* pabyData = OGR_F_GetFieldAsBinary(hFeat, 0, &nDataSize);

     194                 : 
     195                 :             FILE * fp = VSIFileFromMemBuffer( osMemFileName.c_str(), pabyData,
     196              16 :                                               nDataSize, FALSE);

     197              16 :             VSIFCloseL(fp);

     198                 :             
     199              16 :             GDALDatasetH hDSTile = GDALOpen(osMemFileName.c_str(), GA_ReadOnly);

     200              16 :             int nTileBands = 0;

     201              16 :             if (hDSTile && (nTileBands = GDALGetRasterCount(hDSTile)) == 0)

     202                 :             {
     203               0 :                 GDALClose(hDSTile);

     204               0 :                 hDSTile = NULL;

     205                 :             }
     206              16 :             if (hDSTile == NULL)

     207                 :             {
     208                 :                 CPLError(CE_Failure, CPLE_AppDefined, "Can't open tile %d", 
     209               0 :                          nTileId);

     210                 :             }
     211                 :             
     212              16 :             int nReqBand = 1;

     213              16 :             if (nTileBands == poGDS->nBands)

     214              15 :                 nReqBand = nBand;

     215               2 :             else if (eDataType == GDT_Byte && nTileBands == 1 && poGDS->nBands == 3)

     216               1 :                 nReqBand = 1;

     217                 :             else
     218                 :             {
     219               0 :                 GDALClose(hDSTile);

     220               0 :                 hDSTile = NULL;

     221                 :             }
     222                 :                 
     223              16 :             if (hDSTile)

     224                 :             {
     225              16 :                 CPLAssert(GDALGetRasterXSize(hDSTile) == nTileXSize);

     226              16 :                 CPLAssert(GDALGetRasterYSize(hDSTile) == nTileYSize);

     227                 : 
     228              16 :                 bHasFoundTile = TRUE;

     229                 :                 
     230              16 :                 int bHasJustMemsetTileBand1 = FALSE;

     231                 :                 
     232                 :                 /* If the source tile doesn't fit the entire block size, then */
     233                 :                 /* we memset 0 before */
     234              16 :                 if (!(nDstXOff == 0 && nDstYOff == 0 &&

     235                 :                       nReqXSize == nBlockXSize && nReqYSize == nBlockYSize) &&
     236                 :                     !bHasMemsetTile)
     237                 :                 {
     238               5 :                     memset(pImage, 0, nBlockXSize * nBlockYSize * nDataTypeSize);

     239               5 :                     bHasMemsetTile = TRUE;

     240               5 :                     bHasJustMemsetTileBand1 = TRUE;

     241                 :                 }
     242                 :                 
     243                 :                 GDALColorTable* poTileCT =
     244              16 :                     (GDALColorTable* )GDALGetRasterColorTable(GDALGetRasterBand(hDSTile, 1));

     245              16 :                 unsigned char* pabyTranslationTable = NULL;

     246              16 :                 if (poGDS->nBands == 1 && poGDS->poCT != NULL && poTileCT != NULL)

     247                 :                 {
     248                 :                     pabyTranslationTable =
     249                 :                         ((GDALRasterBand*)GDALGetRasterBand(hDSTile, 1))->
     250               1 :                                 GetIndexColorTranslationTo(this, NULL, NULL);

     251                 :                 }
     252                 :                     
     253                 : /* -------------------------------------------------------------------- */
     254                 : /*      Read tile data                                                  */
     255                 : /* -------------------------------------------------------------------- */
     256                 :                 GDALRasterIO(GDALGetRasterBand(hDSTile, nReqBand), GF_Read,
     257                 :                              nSrcXOff, nSrcYOff, nReqXSize, nReqYSize,
     258                 :                              ((char*) pImage) + (nDstXOff + nDstYOff * nBlockXSize) * nDataTypeSize,
     259                 :                              nReqXSize, nReqYSize,
     260              16 :                              eDataType, nDataTypeSize, nBlockXSize * nDataTypeSize);

     261                 : 
     262              16 :                 if (eDataType == GDT_Byte && pabyTranslationTable)

     263                 :                 {
     264                 : /* -------------------------------------------------------------------- */
     265                 : /*      Convert from tile CT to band CT                                 */
     266                 : /* -------------------------------------------------------------------- */
     267                 :                     int i, j;
     268               0 :                     for(j=nDstYOff;j<nDstYOff + nReqYSize;j++)

     269                 :                     {
     270               0 :                         for(i=nDstXOff;i<nDstXOff + nReqXSize;i++)

     271                 :                         {
     272               0 :                             GByte* pPixel = ((GByte*) pImage) + i + j * nBlockXSize;

     273               0 :                             *pPixel = pabyTranslationTable[*pPixel];

     274                 :                         }
     275                 :                     }
     276               0 :                     CPLFree(pabyTranslationTable);

     277               0 :                     pabyTranslationTable = NULL;

     278                 :                 }
     279              16 :                 else if (eDataType == GDT_Byte && nTileBands == 1 &&

     280                 :                          poGDS->nBands == 3 && poTileCT != NULL)
     281                 :                 {
     282                 : /* -------------------------------------------------------------------- */
     283                 : /*      Expand from PCT to RGB                                          */
     284                 : /* -------------------------------------------------------------------- */
     285                 :                     int i, j;
     286                 :                     GByte abyCT[256];
     287               1 :                     int nEntries = MIN(256, poTileCT->GetColorEntryCount());

     288             257 :                     for(i=0;i<nEntries;i++)

     289                 :                     {
     290             256 :                         const GDALColorEntry* psEntry = poTileCT->GetColorEntry(i);

     291             256 :                         if (nBand == 1)

     292             256 :                             abyCT[i] = (GByte)psEntry->c1;

     293               0 :                         else if (nBand == 2)

     294               0 :                             abyCT[i] = (GByte)psEntry->c2;

     295                 :                         else
     296               0 :                             abyCT[i] = (GByte)psEntry->c3;

     297                 :                     }
     298               1 :                     for(;i<256;i++)

     299               0 :                         abyCT[i] = 0;

     300                 :                     
     301             170 :                     for(j=nDstYOff;j<nDstYOff + nReqYSize;j++)

     302                 :                     {
     303           57291 :                         for(i=nDstXOff;i<nDstXOff + nReqXSize;i++)

     304                 :                         {
     305           57122 :                             GByte* pPixel = ((GByte*) pImage) + i + j * nBlockXSize;

     306           57122 :                             *pPixel = abyCT[*pPixel];

     307                 :                         }
     308                 :                     }
     309                 :                 }
     310                 :                 
     311                 : /* -------------------------------------------------------------------- */
     312                 : /*      Put in the block cache the data for this block into other bands */
     313                 : /*      while the underlying dataset is opened                          */
     314                 : /* -------------------------------------------------------------------- */
     315              16 :                 if (nBand == 1 && poGDS->nBands > 1)

     316                 :                 {
     317                 :                     int iOtherBand;
     318              18 :                     for(iOtherBand=2;iOtherBand<=poGDS->nBands;iOtherBand++)

     319                 :                     {
     320                 :                         GDALRasterBlock *poBlock;
     321                 : 
     322                 :                         poBlock = poGDS->GetRasterBand(iOtherBand)->
     323              12 :                             GetLockedBlockRef(nBlockXOff,nBlockYOff, TRUE);

     324              12 :                         if (poBlock == NULL)

     325               0 :                             break;

     326                 :                             
     327              12 :                         GByte* pabySrcBlock = (GByte *) poBlock->GetDataRef();

     328              12 :                         if( pabySrcBlock == NULL )

     329                 :                         {
     330               0 :                             poBlock->DropLock();

     331               0 :                             break;

     332                 :                         }
     333                 :             
     334              12 :                         if (nTileBands == 1)

     335               2 :                             nReqBand = 1;

     336                 :                         else
     337              10 :                             nReqBand = iOtherBand;

     338                 : 
     339              12 :                         if (bHasJustMemsetTileBand1)

     340                 :                             memset(pabySrcBlock, 0,
     341               2 :                                    nBlockXSize * nBlockYSize * nDataTypeSize);

     342                 :             
     343                 : /* -------------------------------------------------------------------- */
     344                 : /*      Read tile data                                                  */
     345                 : /* -------------------------------------------------------------------- */
     346                 :                         GDALRasterIO(GDALGetRasterBand(hDSTile, nReqBand), GF_Read,
     347                 :                                      nSrcXOff, nSrcYOff, nReqXSize, nReqYSize,
     348                 :                                      ((char*) pabySrcBlock) +
     349                 :                                      (nDstXOff + nDstYOff * nBlockXSize) * nDataTypeSize,
     350                 :                                      nReqXSize, nReqYSize,
     351              12 :                                      eDataType, nDataTypeSize, nBlockXSize * nDataTypeSize);

     352                 :                         
     353              12 :                         if (eDataType == GDT_Byte && nTileBands == 1 &&

     354                 :                             poGDS->nBands == 3 && poTileCT != NULL)
     355                 :                         {
     356                 : /* -------------------------------------------------------------------- */
     357                 : /*      Expand from PCT to RGB                                          */
     358                 : /* -------------------------------------------------------------------- */
     359                 : 
     360                 :                             int i, j;
     361                 :                             GByte abyCT[256];
     362               2 :                             int nEntries = MIN(256, poTileCT->GetColorEntryCount());

     363             514 :                             for(i=0;i<nEntries;i++)

     364                 :                             {
     365             512 :                                 const GDALColorEntry* psEntry = poTileCT->GetColorEntry(i);

     366             512 :                                 if (iOtherBand == 1)

     367               0 :                                     abyCT[i] = (GByte)psEntry->c1;

     368             512 :                                 else if (iOtherBand == 2)

     369             256 :                                     abyCT[i] = (GByte)psEntry->c2;

     370                 :                                 else
     371             256 :                                     abyCT[i] = (GByte)psEntry->c3;

     372                 :                             }
     373               2 :                             for(;i<256;i++)

     374               0 :                                 abyCT[i] = 0;

     375                 :                             
     376             340 :                             for(j=nDstYOff;j<nDstYOff + nReqYSize;j++)

     377                 :                             {
     378          114582 :                                 for(i=nDstXOff;i<nDstXOff + nReqXSize;i++)

     379                 :                                 {
     380          114244 :                                     GByte* pPixel = ((GByte*) pabySrcBlock) + i + j * nBlockXSize;

     381          114244 :                                     *pPixel = abyCT[*pPixel];

     382                 :                                 }
     383                 :                             }
     384                 :                         }
     385                 :                         
     386              12 :                         poBlock->DropLock();

     387                 :                     }
     388                 :                   
     389                 :                 }
     390              16 :                 GDALClose(hDSTile);

     391                 :             }
     392                 :             
     393              16 :             VSIUnlink(osMemFileName.c_str());

     394                 :         }
     395                 :         else
     396                 :         {
     397                 : #ifdef RASTERLITE_DEBUG
     398                 :             if (nBand == 1)
     399                 :             {
     400                 :                 printf("id = %d, NOT selected !\n",  nTileId);
     401                 :             }
     402                 : #endif
     403                 :         }
     404                 :         
     405              16 :         OGR_F_Destroy(hFeat);

     406                 :     }
     407                 :     
     408              16 :     if (!bHasFoundTile)

     409                 :     {
     410               0 :         memset(pImage, 0, nBlockXSize * nBlockYSize * nDataTypeSize);

     411                 :     }
     412                 :             
     413              16 :     OGR_DS_ReleaseResultSet(poGDS->hDS, hSQLLyr);

     414                 :     
     415                 : #ifdef RASTERLITE_DEBUG
     416                 :     if (nBand == 1)
     417                 :         printf("\n");
     418                 : #endif
     419                 : 
     420              16 :     return CE_None;

     421                 : }
     422                 : 
     423                 : /************************************************************************/
     424                 : /*                         GetOverviewCount()                           */
     425                 : /************************************************************************/
     426                 : 
     427               7 : int RasterliteBand::GetOverviewCount()

     428                 : {
     429               7 :     RasterliteDataset* poGDS = (RasterliteDataset*) poDS;

     430                 :     
     431               7 :     if (poGDS->nLimitOvrCount >= 0)

     432               3 :         return poGDS->nLimitOvrCount;

     433               4 :     else if (poGDS->nResolutions > 1)

     434               1 :         return poGDS->nResolutions - 1;

     435                 :     else
     436               3 :         return GDALPamRasterBand::GetOverviewCount();

     437                 : }
     438                 : 
     439                 : /************************************************************************/
     440                 : /*                              GetOverview()                           */
     441                 : /************************************************************************/
     442                 : 
     443               9 : GDALRasterBand* RasterliteBand::GetOverview(int nLevel)

     444                 : {
     445               9 :     RasterliteDataset* poGDS = (RasterliteDataset*) poDS;

     446                 :     
     447               9 :     if (poGDS->nLimitOvrCount >= 0)

     448                 :     {
     449               2 :         if (nLevel < 0 || nLevel >= poGDS->nLimitOvrCount)

     450               0 :             return NULL;

     451                 :     }
     452                 :     
     453               9 :     if (poGDS->nResolutions == 1)

     454               0 :         return GDALPamRasterBand::GetOverview(nLevel);

     455                 :     
     456               9 :     if (nLevel < 0 || nLevel >= poGDS->nResolutions - 1)

     457               0 :         return NULL;

     458                 :         
     459               9 :     GDALDataset* poOvrDS = poGDS->papoOverviews[nLevel];

     460               9 :     if (poOvrDS)

     461               9 :         return poOvrDS->GetRasterBand(nBand);

     462                 :     else
     463               0 :         return NULL;

     464                 : }
     465                 : 
     466                 : /************************************************************************/
     467                 : /*                   GetColorInterpretation()                           */
     468                 : /************************************************************************/
     469                 : 
     470               1 : GDALColorInterp RasterliteBand::GetColorInterpretation()

     471                 : {
     472               1 :     RasterliteDataset* poGDS = (RasterliteDataset*) poDS;

     473               1 :     if (poGDS->nBands == 1)

     474                 :     {
     475               1 :         if (poGDS->poCT != NULL)

     476               1 :             return GCI_PaletteIndex;

     477                 :         else
     478               0 :             return GCI_GrayIndex;

     479                 :     }
     480               0 :     else if (poGDS->nBands == 3)

     481                 :     {
     482               0 :         if (nBand == 1)

     483               0 :             return GCI_RedBand;

     484               0 :         else if (nBand == 2)

     485               0 :             return GCI_GreenBand;

     486               0 :         else if (nBand == 3)

     487               0 :             return GCI_BlueBand;

     488                 :     }
     489                 :     
     490               0 :     return GCI_Undefined;

     491                 : }
     492                 : 
     493                 : /************************************************************************/
     494                 : /*                        GetColorTable()                               */
     495                 : /************************************************************************/
     496                 : 
     497               3 : GDALColorTable* RasterliteBand::GetColorTable()

     498                 : {
     499               3 :     RasterliteDataset* poGDS = (RasterliteDataset*) poDS;

     500               3 :     if (poGDS->nBands == 1)

     501               2 :         return poGDS->poCT;

     502                 :     else
     503               1 :         return NULL;

     504                 : }
     505                 : 
     506                 : /************************************************************************/
     507                 : /*                         RasterliteDataset()                          */
     508                 : /************************************************************************/
     509                 : 
     510              52 : RasterliteDataset::RasterliteDataset()

     511                 : {
     512              52 :     nLimitOvrCount = -1;

     513              52 :     bValidGeoTransform = FALSE;

     514              52 :     bMustFree = FALSE;

     515              52 :     nLevel = 0;

     516              52 :     poMainDS = NULL;

     517              52 :     nResolutions = 0;

     518              52 :     padfXResolutions = NULL;

     519              52 :     padfYResolutions = NULL;

     520              52 :     pszSRS = NULL;

     521              52 :     hDS = NULL;

     522              52 :     papoOverviews = NULL;

     523              52 :     papszMetadata = NULL;

     524              52 :     papszSubDatasets = NULL;

     525                 :     papszImageStructure =
     526              52 :         CSLAddString(NULL, "INTERLEAVE=PIXEL");

     527              52 :     poCT = NULL;

     528              52 :     bCheckForExistingOverview = TRUE;

     529              52 : }

     530                 : 
     531                 : /************************************************************************/
     532                 : /*                         RasterliteDataset()                          */
     533                 : /************************************************************************/
     534                 : 
     535               8 : RasterliteDataset::RasterliteDataset(RasterliteDataset* poMainDS, int nLevel)

     536                 : {
     537               8 :     nLimitOvrCount = -1;

     538               8 :     bMustFree = FALSE;

     539               8 :     this->nLevel = nLevel;

     540               8 :     this->poMainDS = poMainDS;

     541               8 :     nResolutions = poMainDS->nResolutions - nLevel;

     542               8 :     padfXResolutions = poMainDS->padfXResolutions + nLevel;

     543               8 :     padfYResolutions = poMainDS->padfYResolutions + nLevel;

     544               8 :     pszSRS = poMainDS->pszSRS;

     545               8 :     hDS = poMainDS->hDS;

     546               8 :     papoOverviews = poMainDS->papoOverviews + nLevel;

     547               8 :     papszMetadata = poMainDS->papszMetadata;

     548               8 :     papszSubDatasets = poMainDS->papszSubDatasets;

     549               8 :     papszImageStructure =  poMainDS->papszImageStructure;

     550               8 :     poCT =  poMainDS->poCT;

     551               8 :     bCheckForExistingOverview = TRUE;

     552                 : 
     553               8 :     osTableName = poMainDS->osTableName;

     554               8 :     osFileName = poMainDS->osFileName;

     555                 :     
     556                 :     nRasterXSize = (int)(poMainDS->nRasterXSize *
     557               8 :         (poMainDS->padfXResolutions[0] / padfXResolutions[0]) + 0.5);

     558                 :     nRasterYSize = (int)(poMainDS->nRasterYSize *
     559               8 :         (poMainDS->padfYResolutions[0] / padfYResolutions[0]) + 0.5);

     560                 : 
     561               8 :     bValidGeoTransform = TRUE;

     562               8 :     memcpy(adfGeoTransform, poMainDS->adfGeoTransform, 6 * sizeof(double));

     563               8 :     adfGeoTransform[1] = padfXResolutions[0];

     564               8 :     adfGeoTransform[5] = - padfYResolutions[0];

     565               8 : }

     566                 : 
     567                 : /************************************************************************/
     568                 : /*                        ~RasterliteDataset()                          */
     569                 : /************************************************************************/
     570                 : 
     571              60 : RasterliteDataset::~RasterliteDataset()

     572                 : {
     573              60 :     if (poMainDS == NULL)

     574                 :     {
     575              52 :         CSLDestroy(papszMetadata);

     576              52 :         CSLDestroy(papszSubDatasets);

     577              52 :         CSLDestroy(papszImageStructure);

     578              52 :         CPLFree(pszSRS);

     579                 : 
     580              52 :         if (papoOverviews)

     581                 :         {
     582                 :             int i;
     583               8 :             for(i=1;i<nResolutions;i++)

     584               5 :                 delete papoOverviews[i-1];

     585               3 :             CPLFree(papoOverviews);

     586                 :         }
     587                 : 
     588              52 :         if (hDS != NULL)

     589              27 :             OGRReleaseDataSource(hDS);

     590                 :             
     591              52 :         CPLFree(padfXResolutions);

     592              52 :         CPLFree(padfYResolutions);

     593                 :         
     594              52 :         delete poCT;

     595                 :     }
     596               8 :     else if (bMustFree)

     597                 :     {
     598               0 :         poMainDS->papoOverviews[nLevel-1] = NULL;

     599               0 :         delete poMainDS;

     600                 :     }
     601              60 : }

     602                 : 
     603                 : /************************************************************************/
     604                 : /*                           AddSubDataset()                            */
     605                 : /************************************************************************/
     606                 : 
     607              25 : void RasterliteDataset::AddSubDataset( const char* pszDSName)

     608                 : {
     609                 :     char  szName[80];
     610              25 :     int   nCount = CSLCount(papszSubDatasets ) / 2;

     611                 : 
     612              25 :     sprintf( szName, "SUBDATASET_%d_NAME", nCount+1 );

     613                 :     papszSubDatasets = 
     614              25 :         CSLSetNameValue( papszSubDatasets, szName, pszDSName);

     615                 : 
     616              25 :     sprintf( szName, "SUBDATASET_%d_DESC", nCount+1 );

     617                 :     papszSubDatasets = 
     618              25 :         CSLSetNameValue( papszSubDatasets, szName, pszDSName);

     619              25 : }

     620                 : 
     621                 : /************************************************************************/
     622                 : /*                            GetMetadata()                             */
     623                 : /************************************************************************/
     624                 : 
     625               0 : char **RasterliteDataset::GetMetadata( const char *pszDomain )

     626                 : 
     627                 : {
     628               0 :     if( pszDomain != NULL && EQUAL(pszDomain,"SUBDATASETS") )

     629               0 :         return papszSubDatasets;

     630                 :         
     631               0 :     if( CSLCount(papszSubDatasets) < 2 &&

     632                 :         pszDomain != NULL && EQUAL(pszDomain,"IMAGE_STRUCTURE") )
     633               0 :         return papszImageStructure;

     634                 :         
     635               0 :     if ( pszDomain == NULL || EQUAL(pszDomain, "") )

     636               0 :         return papszMetadata;

     637                 :         
     638               0 :     return GDALPamDataset::GetMetadata( pszDomain );

     639                 : }
     640                 : 
     641                 : /************************************************************************/
     642                 : /*                          GetMetadataItem()                           */
     643                 : /************************************************************************/
     644                 : 
     645                 : const char *RasterliteDataset::GetMetadataItem( const char *pszName, 
     646               2 :                                                 const char *pszDomain )

     647                 : {
     648               2 :     if (pszDomain != NULL &&EQUAL(pszDomain,"OVERVIEWS") )

     649                 :     {
     650               2 :         if (nResolutions > 1 || CSLCount(papszSubDatasets) > 2)

     651               0 :             return NULL;

     652                 :         else
     653                 :         {
     654               2 :             osOvrFileName.Printf("%s_%s", osFileName.c_str(), osTableName.c_str());

     655               2 :             if (bCheckForExistingOverview == FALSE ||

     656                 :                 CPLCheckForFile((char*) osOvrFileName.c_str(), NULL))
     657               0 :                 return osOvrFileName.c_str();

     658                 :             else
     659               2 :                 return NULL;

     660                 :         }
     661                 :     }
     662               0 :     return GDALPamDataset::GetMetadataItem(pszName, pszDomain);

     663                 : }
     664                 : 
     665                 : /************************************************************************/
     666                 : /*                          GetGeoTransform()                           */
     667                 : /************************************************************************/
     668                 : 
     669               4 : CPLErr RasterliteDataset::GetGeoTransform( double* padfGeoTransform )

     670                 : {
     671               4 :     if (bValidGeoTransform)

     672                 :     {
     673               4 :         memcpy(padfGeoTransform, adfGeoTransform, 6 * sizeof(double));

     674               4 :         return CE_None;

     675                 :     }
     676                 :     else
     677               0 :         return CE_Failure;

     678                 : }
     679                 : 
     680                 : /************************************************************************/
     681                 : /*                         GetProjectionRef()                           */
     682                 : /************************************************************************/
     683                 : 
     684               4 : const char* RasterliteDataset::GetProjectionRef()

     685                 : {
     686               4 :     if (pszSRS)

     687               4 :         return pszSRS;

     688                 :     else
     689               0 :         return "";

     690                 : }
     691                 : 
     692                 : /************************************************************************/
     693                 : /*                           GetFileList()                              */
     694                 : /************************************************************************/
     695                 : 
     696               0 : char** RasterliteDataset::GetFileList()

     697                 : {
     698               0 :     char** papszFileList = NULL;

     699               0 :     papszFileList = CSLAddString(papszFileList, osFileName);

     700               0 :     return papszFileList;

     701                 : }
     702                 : 
     703                 : /************************************************************************/
     704                 : /*                         GetBlockParams()                             */
     705                 : /************************************************************************/
     706                 : 
     707                 : int RasterliteDataset::GetBlockParams(OGRLayerH hRasterLyr, int nLevel,
     708                 :                                       int* pnBands, GDALDataType* peDataType,
     709              35 :                                       int* pnBlockXSize, int* pnBlockYSize)

     710                 : {
     711              35 :     CPLString osSQL;

     712                 :     
     713                 :     osSQL.Printf("SELECT m.geometry, r.raster, m.id "
     714                 :                  "FROM \"%s_metadata\" AS m, \"%s_rasters\" AS r "
     715                 :                  "WHERE m.pixel_x_size >= %.15f AND m.pixel_x_size <= %.15f AND "
     716                 :                  "m.pixel_y_size >= %.15f AND m.pixel_y_size <= %.15f AND r.id = m.id",
     717                 :                  osTableName.c_str(), osTableName.c_str(),
     718                 :                  padfXResolutions[nLevel] - 1e-15, padfXResolutions[nLevel] + 1e-15,
     719              35 :                  padfYResolutions[nLevel] - 1e-15, padfYResolutions[nLevel] + 1e-15);

     720                 :     
     721              35 :     OGRLayerH hSQLLyr = OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);

     722              35 :     if (hSQLLyr == NULL)

     723                 :     {
     724               0 :         return FALSE;

     725                 :     }
     726                 :     
     727              35 :     OGRFeatureH hFeat = OGR_L_GetNextFeature(hRasterLyr);

     728              35 :     if (hFeat == NULL)

     729                 :     {
     730               0 :         OGR_DS_ReleaseResultSet(hDS, hSQLLyr);

     731               0 :         return FALSE;

     732                 :     }
     733                 :     
     734                 :     int nDataSize;
     735              35 :     GByte* pabyData = OGR_F_GetFieldAsBinary(hFeat, 0, &nDataSize);

     736                 :     
     737              35 :     if (nDataSize > 32 &&

     738                 :         EQUALN((const char*)pabyData, "StartWaveletsImage$$", strlen("StartWaveletsImage$$")))
     739                 :     {
     740               4 :         if (GDALGetDriverByName("EPSILON") == NULL)

     741                 :         {
     742                 :             CPLError(CE_Failure, CPLE_NotSupported,
     743               0 :                      "Rasterlite driver doesn't support WAVELET compressed images if EPSILON driver is not compiled");

     744               0 :             OGR_F_Destroy(hFeat);

     745               0 :             OGR_DS_ReleaseResultSet(hDS, hSQLLyr);

     746               0 :             return FALSE;

     747                 :         }
     748                 :     }
     749                 :     
     750              35 :     CPLString osMemFileName;

     751              35 :     osMemFileName.Printf("/vsimem/%p", this);

     752                 :     FILE * fp = VSIFileFromMemBuffer( osMemFileName.c_str(), pabyData,
     753              35 :                                       nDataSize, FALSE);

     754              35 :     VSIFCloseL(fp);

     755                 :     
     756              35 :     GDALDatasetH hDSTile = GDALOpen(osMemFileName.c_str(), GA_ReadOnly);

     757              35 :     if (hDSTile)

     758                 :     {
     759              35 :         *pnBands = GDALGetRasterCount(hDSTile);

     760              35 :         if (*pnBands == 0)

     761                 :         {
     762               0 :             GDALClose(hDSTile);

     763               0 :             hDSTile = NULL;

     764                 :         }
     765                 :     }
     766                 :     else
     767                 :     {
     768                 :         CPLError(CE_Failure, CPLE_AppDefined, "Can't open tile %d", 
     769               0 :                  OGR_F_GetFieldAsInteger(hFeat, 1));

     770                 :     }
     771                 :     
     772              35 :     if (hDSTile)

     773                 :     {
     774                 :         int iBand;
     775              35 :         *peDataType = GDALGetRasterDataType(GDALGetRasterBand(hDSTile, 1));

     776                 :         
     777              55 :         for(iBand=2;iBand<=*pnBands;iBand++)

     778                 :         {
     779              20 :             if (*peDataType != GDALGetRasterDataType(GDALGetRasterBand(hDSTile, 1)))

     780                 :             {
     781               0 :                 CPLError(CE_Failure, CPLE_NotSupported, "Band types must be identical");

     782               0 :                 GDALClose(hDSTile);

     783               0 :                 hDSTile = NULL;

     784               0 :                 goto end;

     785                 :             }
     786                 :         }
     787                 :         
     788              35 :         *pnBlockXSize = GDALGetRasterXSize(hDSTile);

     789              35 :         *pnBlockYSize = GDALGetRasterYSize(hDSTile);

     790              35 :         if (CSLFindName(papszImageStructure, "COMPRESSION") == -1)

     791                 :         {
     792                 :             const char* pszCompression =
     793              34 :                 GDALGetMetadataItem(hDSTile, "COMPRESSION", "IMAGE_STRUCTURE");

     794              34 :             if (pszCompression != NULL && EQUAL(pszCompression, "JPEG"))

     795                 :                 papszImageStructure =
     796               2 :                     CSLAddString(papszImageStructure, "COMPRESSION=JPEG");

     797                 :         }
     798                 :         
     799              35 :         if (CSLFindName(papszMetadata, "TILE_FORMAT") == -1)

     800                 :         {
     801                 :             papszMetadata =
     802                 :                 CSLSetNameValue(papszMetadata, "TILE_FORMAT",
     803              27 :                            GDALGetDriverShortName(GDALGetDatasetDriver(hDSTile)));

     804                 :         }
     805                 :         
     806                 :         
     807              35 :         if (*pnBands == 1 && this->poCT == NULL)

     808                 :         {
     809                 :             GDALColorTable* poCT =
     810              26 :                 (GDALColorTable*)GDALGetRasterColorTable(GDALGetRasterBand(hDSTile, 1));

     811              26 :             if (poCT)

     812               2 :                 this->poCT = poCT->Clone();

     813                 :         }
     814                 : 
     815              35 :         GDALClose(hDSTile);

     816                 :     }
     817              35 : end:    

     818              35 :     VSIUnlink(osMemFileName.c_str());

     819                 :     
     820              35 :     OGR_F_Destroy(hFeat);

     821                 :     
     822              35 :     OGR_DS_ReleaseResultSet(hDS, hSQLLyr);

     823                 :     
     824              35 :     return hDSTile != NULL;

     825                 : }
     826                 : 
     827                 : /************************************************************************/
     828                 : /*                             Identify()                               */
     829                 : /************************************************************************/
     830                 : 
     831            8245 : int RasterliteDataset::Identify(GDALOpenInfo* poOpenInfo)

     832                 : {
     833            8245 :     if (poOpenInfo->nHeaderBytes >= 1024 &&

     834                 :         EQUALN((const char*)poOpenInfo->pabyHeader, "SQLite Format 3", 15))
     835                 :     {
     836               0 :         return TRUE;

     837                 :     }
     838            8245 :     else if (EQUALN(poOpenInfo->pszFilename, "RASTERLITE:", 11))

     839                 :     {
     840               1 :         return TRUE;

     841                 :     }
     842                 :     
     843            8244 :     return FALSE;

     844                 : }
     845                 : 
     846                 : /************************************************************************/
     847                 : /*                                Open()                                */
     848                 : /************************************************************************/
     849                 : 
     850            1300 : GDALDataset* RasterliteDataset::Open(GDALOpenInfo* poOpenInfo)

     851                 : {
     852            1300 :     CPLString osFileName;

     853            1300 :     CPLString osTableName;

     854            1300 :     char **papszTokens = NULL;

     855            1300 :     int nLevel = 0;

     856            1300 :     double minx = 0, miny = 0, maxx = 0, maxy = 0;

     857            1300 :     int bMinXSet = FALSE, bMinYSet = FALSE, bMaxXSet = FALSE, bMaxYSet = FALSE;

     858            1300 :     int nReqBands = 0;

     859                 :     
     860                 : /* -------------------------------------------------------------------- */
     861                 : /*      Parse "file name"                                               */
     862                 : /* -------------------------------------------------------------------- */
     863            1323 :     if (poOpenInfo->nHeaderBytes >= 1024 &&

     864                 :         EQUALN((const char*)poOpenInfo->pabyHeader, "SQLite Format 3", 15))
     865                 :     {
     866              23 :         osFileName = poOpenInfo->pszFilename;

     867                 :     }
     868            1277 :     else if (!EQUALN(poOpenInfo->pszFilename, "RASTERLITE:", 11))

     869                 :     {
     870            1273 :         return NULL;

     871                 :     }
     872                 :     else
     873                 :     {
     874                 :         papszTokens = CSLTokenizeStringComplex( 
     875               4 :                 poOpenInfo->pszFilename + 11, ", ", FALSE, FALSE );

     876               4 :         int nTokens = CSLCount(papszTokens);

     877               4 :         if (nTokens == 0)

     878                 :         {
     879               0 :             CSLDestroy(papszTokens);

     880               0 :             return NULL;

     881                 :         }
     882                 :                 
     883               4 :         osFileName = papszTokens[0];

     884                 :         
     885                 :         int i;
     886              11 :         for(i=1;i<nTokens;i++)

     887                 :         {
     888               7 :             if (EQUALN(papszTokens[i], "table=", 6))

     889               2 :                 osTableName = papszTokens[i] + 6;

     890               5 :             else if (EQUALN(papszTokens[i], "level=", 6))

     891               0 :                 nLevel = atoi(papszTokens[i] + 6);

     892               5 :             else if (EQUALN(papszTokens[i], "minx=", 5))

     893                 :             {
     894               1 :                 bMinXSet = TRUE;

     895               1 :                 minx = atof(papszTokens[i] + 5);

     896                 :             }
     897               4 :             else if (EQUALN(papszTokens[i], "miny=", 5))

     898                 :             {
     899               1 :                 bMinYSet = TRUE;

     900               1 :                 miny = atof(papszTokens[i] + 5);

     901                 :             }
     902               3 :             else if (EQUALN(papszTokens[i], "maxx=", 5))

     903                 :             {
     904               1 :                 bMaxXSet = TRUE;

     905               1 :                 maxx = atof(papszTokens[i] + 5);

     906                 :             }
     907               2 :             else if (EQUALN(papszTokens[i], "maxy=", 5))

     908                 :             {
     909               1 :                 bMaxYSet = TRUE;

     910               1 :                 maxy = atof(papszTokens[i] + 5);

     911                 :             }
     912               1 :             else if (EQUALN(papszTokens[i], "bands=", 6))

     913                 :             {
     914               1 :                 nReqBands = atoi(papszTokens[i] + 6);

     915                 :             }
     916                 :             else
     917                 :             {
     918                 :                 CPLError(CE_Warning, CPLE_AppDefined,
     919               0 :                          "Invalid option : %s", papszTokens[i]);

     920                 :             }
     921                 :         }
     922                 :     }
     923                 :     
     924              27 :     if (OGRGetDriverCount() == 0)

     925               0 :         OGRRegisterAll();

     926                 :     
     927                 : /* -------------------------------------------------------------------- */
     928                 : /*      Open underlying OGR DB                                          */
     929                 : /* -------------------------------------------------------------------- */
     930                 : 
     931                 :     /* Set SQLITE_LIST_ALL_TABLES option as we wan't to be able to */
     932                 :     /* fetch non spatial tables */
     933              27 :     CPLString osOldVal = CPLGetConfigOption("SQLITE_LIST_ALL_TABLES", "FALSE");

     934              27 :     CPLSetConfigOption("SQLITE_LIST_ALL_TABLES", "TRUE");

     935              27 :     OGRDataSourceH hDS = OGROpen(osFileName.c_str(), TRUE, NULL);

     936              27 :     CPLSetConfigOption("SQLITE_LIST_ALL_TABLES", osOldVal.c_str());

     937              27 :     CPLDebug("RASTERLITE", "SQLite DB Open");

     938                 :     
     939              27 :     RasterliteDataset* poDS = NULL;

     940                 : 
     941              27 :     if (hDS == NULL)

     942               0 :         goto end;

     943                 :     
     944              27 :     if (strlen(osTableName) == 0)

     945                 :     {
     946              25 :         int nCountSubdataset = 0;

     947              25 :         int nLayers = OGR_DS_GetLayerCount(hDS);

     948                 :         int i;
     949                 : /* -------------------------------------------------------------------- */
     950                 : /*      Add raster layers as subdatasets                                */
     951                 : /* -------------------------------------------------------------------- */
     952             277 :         for(i=0;i<nLayers;i++)

     953                 :         {   
     954             252 :             OGRLayerH hLyr = OGR_DS_GetLayer(hDS, i);

     955             252 :             const char* pszLayerName = OGR_FD_GetName(OGR_L_GetLayerDefn(hLyr));

     956             252 :             if (strstr(pszLayerName, "_rasters"))

     957                 :             {
     958              25 :                 char* pszShortName = CPLStrdup(pszLayerName);

     959              25 :                 *strstr(pszShortName, "_rasters") = '\0';

     960                 :                 
     961              25 :                 CPLString osMetadataTableName = pszShortName;

     962              25 :                 osMetadataTableName += "_metadata";

     963                 :                 
     964              25 :                 if (OGR_DS_GetLayerByName(hDS, osMetadataTableName.c_str()) != NULL)

     965                 :                 {
     966              25 :                     if (poDS == NULL)

     967                 :                     {
     968              25 :                         poDS = new RasterliteDataset();

     969              50 :                         osTableName = pszShortName;

     970                 :                     }
     971                 :                         
     972              25 :                     CPLString osSubdatasetName;

     973              25 :                     if (!EQUALN(poOpenInfo->pszFilename, "RASTERLITE:", 11))

     974              23 :                         osSubdatasetName += "RASTERLITE:";

     975              25 :                     osSubdatasetName += poOpenInfo->pszFilename;

     976              25 :                     osSubdatasetName += ",table=";

     977              25 :                     osSubdatasetName += pszShortName;

     978              25 :                     poDS->AddSubDataset(osSubdatasetName.c_str());

     979                 :                     
     980              25 :                     nCountSubdataset++;

     981                 :                 }
     982                 :                 
     983              25 :                 CPLFree(pszShortName);

     984                 :             }
     985                 :         }
     986                 :         
     987              25 :         if (nCountSubdataset == 0)

     988                 :         {
     989               0 :             goto end;

     990                 :         }
     991              25 :         else if (nCountSubdataset != 1)

     992                 :         {
     993               0 :             poDS->SetDescription( poOpenInfo->pszFilename );

     994               0 :             goto end;

     995                 :         }
     996                 :         
     997                 : /* -------------------------------------------------------------------- */
     998                 : /*      If just one subdataset, then open it                            */
     999                 : /* -------------------------------------------------------------------- */
    1000              25 :         delete poDS;

    1001              25 :         poDS = NULL;

    1002                 :     }
    1003                 :     
    1004                 : /* -------------------------------------------------------------------- */
    1005                 : /*      Build dataset                                                   */
    1006                 : /* -------------------------------------------------------------------- */
    1007                 :     {
    1008              27 :         CPLString osMetadataTableName, osRasterTableName;

    1009              27 :         CPLString osSQL;

    1010                 :         OGRLayerH hMetadataLyr, hRasterLyr, hRasterPyramidsLyr;
    1011                 :         OGRLayerH hSQLLyr;
    1012                 :         OGRFeatureH hFeat;
    1013                 :         int i, nResolutions;
    1014                 :         int iBand, nBands, nBlockXSize, nBlockYSize;
    1015                 :         GDALDataType eDataType;
    1016                 : 
    1017              27 :         osMetadataTableName = osTableName;

    1018              27 :         osMetadataTableName += "_metadata";

    1019                 :         
    1020              27 :         hMetadataLyr = OGR_DS_GetLayerByName(hDS, osMetadataTableName.c_str());

    1021              27 :         if (hMetadataLyr == NULL)

    1022               0 :             goto end;

    1023                 :             
    1024              27 :         osRasterTableName = osTableName;

    1025              27 :         osRasterTableName += "_rasters";

    1026                 :         
    1027              27 :         hRasterLyr = OGR_DS_GetLayerByName(hDS, osRasterTableName.c_str());

    1028              27 :         if (hRasterLyr == NULL)

    1029                 :             goto end;
    1030                 :         
    1031                 : /* -------------------------------------------------------------------- */
    1032                 : /*      Fetch resolutions                                               */
    1033                 : /* -------------------------------------------------------------------- */
    1034                 : 
    1035              27 :         hRasterPyramidsLyr = OGR_DS_GetLayerByName(hDS, "raster_pyramids");

    1036              27 :         if (hRasterPyramidsLyr)

    1037                 :         {
    1038                 :             osSQL.Printf("SELECT pixel_x_size, pixel_y_size "
    1039                 :                          "FROM raster_pyramids WHERE table_prefix = '%s' "
    1040                 :                          "ORDER BY pixel_x_size ASC",
    1041               3 :                          osTableName.c_str());

    1042                 :          }
    1043                 :          else
    1044                 :          {
    1045                 :             osSQL.Printf("SELECT DISTINCT(pixel_x_size), pixel_y_size "
    1046                 :                          "FROM \"%s_metadata\" WHERE pixel_x_size != 0  "
    1047                 :                          "ORDER BY pixel_x_size ASC",
    1048              24 :                          osTableName.c_str());

    1049                 :          }
    1050                 : 
    1051              27 :         hSQLLyr = OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);

    1052              27 :         if (hSQLLyr == NULL)

    1053                 :         {
    1054               0 :             if (hRasterPyramidsLyr == NULL)

    1055                 :                 goto end;
    1056                 :                 
    1057                 :             osSQL.Printf("SELECT DISTINCT(pixel_x_size), pixel_y_size "
    1058                 :                          "FROM \"%s_metadata\" WHERE pixel_x_size != 0  "
    1059                 :                          "ORDER BY pixel_x_size ASC",
    1060               0 :                          osTableName.c_str());

    1061                 :                          
    1062               0 :             hSQLLyr = OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);

    1063               0 :             if (hSQLLyr == NULL)

    1064                 :                 goto end;
    1065                 :         }
    1066                 :             
    1067              27 :         nResolutions = OGR_L_GetFeatureCount(hSQLLyr, TRUE);

    1068                 :                      
    1069              27 :         if (nResolutions == 0)

    1070                 :         {
    1071               0 :             OGR_DS_ReleaseResultSet(hDS, hSQLLyr);

    1072                 :             goto end;
    1073                 :         }
    1074                 :             
    1075                 : /* -------------------------------------------------------------------- */
    1076                 : /*      Set dataset attributes                                          */
    1077                 : /* -------------------------------------------------------------------- */
    1078                 : 
    1079              27 :         poDS = new RasterliteDataset();

    1080              27 :         poDS->SetDescription( poOpenInfo->pszFilename );

    1081              27 :         poDS->eAccess = poOpenInfo->eAccess;

    1082              27 :         poDS->osTableName = osTableName;

    1083              27 :         poDS->osFileName = osFileName;

    1084              27 :         poDS->hDS = hDS;

    1085                 :         
    1086                 :         /* poDS will release it from now */
    1087              27 :         hDS = NULL;

    1088                 :         
    1089                 : /* -------------------------------------------------------------------- */
    1090                 : /*      Fetch spatial extent or use the one provided by the user        */
    1091                 : /* -------------------------------------------------------------------- */
    1092              27 :         OGREnvelope oEnvelope;

    1093              28 :         if (bMinXSet && bMinYSet && bMaxXSet && bMaxYSet)

    1094                 :         {
    1095               1 :             oEnvelope.MinX = minx;

    1096               1 :             oEnvelope.MinY = miny;

    1097               1 :             oEnvelope.MaxX = maxx;

    1098               1 :             oEnvelope.MaxY = maxy;

    1099                 :         }
    1100                 :         else
    1101                 :         {
    1102              26 :             OGR_L_GetExtent(hMetadataLyr, &oEnvelope, TRUE);

    1103                 :             //printf("minx=%.15f miny=%.15f maxx=%.15f maxy=%.15f\n",
    1104                 :             //       oEnvelope.MinX, oEnvelope.MinY, oEnvelope.MaxX, oEnvelope.MaxY);
    1105                 :         }
    1106                 :         
    1107                 : /* -------------------------------------------------------------------- */
    1108                 : /*      Store resolutions                                               */
    1109                 : /* -------------------------------------------------------------------- */
    1110              27 :         poDS->nResolutions = nResolutions;

    1111                 :         poDS->padfXResolutions =
    1112              27 :             (double*)CPLMalloc(sizeof(double) * poDS->nResolutions);

    1113                 :         poDS->padfYResolutions =
    1114              27 :             (double*)CPLMalloc(sizeof(double) * poDS->nResolutions);

    1115                 : 
    1116              27 :         i = 0;

    1117              86 :         while((hFeat = OGR_L_GetNextFeature(hSQLLyr)) != NULL)

    1118                 :         {
    1119              32 :             poDS->padfXResolutions[i] = OGR_F_GetFieldAsDouble(hFeat, 0);

    1120              32 :             poDS->padfYResolutions[i] = OGR_F_GetFieldAsDouble(hFeat, 1);

    1121                 : 
    1122              32 :             OGR_F_Destroy(hFeat);

    1123                 :             
    1124                 :             //printf("[%d] xres=%.15f yres=%.15f\n", i,
    1125                 :             //       poDS->padfXResolutions[i], poDS->padfYResolutions[i]);
    1126                 :             
    1127              32 :             if (poDS->padfXResolutions[i] <= 0 || poDS->padfXResolutions[i] <= 0)

    1128                 :             {
    1129                 :                 CPLError(CE_Failure, CPLE_NotSupported,
    1130                 :                          "res=%d, xres=%.15f, yres=%.15f",
    1131               0 :                          i, poDS->padfXResolutions[i], poDS->padfYResolutions[i]);

    1132               0 :                 OGR_DS_ReleaseResultSet(hDS, hSQLLyr);

    1133               0 :                 delete poDS;

    1134               0 :                 poDS = NULL;

    1135                 :                 goto end;
    1136                 :             }
    1137              32 :             i ++;

    1138                 :         }
    1139                 : 
    1140              27 :         OGR_DS_ReleaseResultSet(poDS->hDS, hSQLLyr);

    1141              27 :         hSQLLyr = NULL;

    1142                 : 
    1143                 : /* -------------------------------------------------------------------- */
    1144                 : /*      Compute raster size, geotransform and projection                */
    1145                 : /* -------------------------------------------------------------------- */
    1146                 :         poDS->nRasterXSize =
    1147              27 :             (int)((oEnvelope.MaxX - oEnvelope.MinX) / poDS->padfXResolutions[0] + 0.5);

    1148                 :         poDS->nRasterYSize =
    1149              27 :             (int)((oEnvelope.MaxY - oEnvelope.MinY) / poDS->padfYResolutions[0] + 0.5);

    1150                 : 
    1151              27 :         poDS->bValidGeoTransform = TRUE;

    1152              27 :         poDS->adfGeoTransform[0] = oEnvelope.MinX;

    1153              27 :         poDS->adfGeoTransform[1] = poDS->padfXResolutions[0];

    1154              27 :         poDS->adfGeoTransform[2] = 0;

    1155              27 :         poDS->adfGeoTransform[3] = oEnvelope.MaxY;

    1156              27 :         poDS->adfGeoTransform[4] = 0;

    1157              27 :         poDS->adfGeoTransform[5] = - poDS->padfYResolutions[0];

    1158                 :         
    1159              27 :         OGRSpatialReferenceH hSRS = OGR_L_GetSpatialRef(hMetadataLyr);

    1160              27 :         if (hSRS)

    1161                 :         {
    1162              27 :             OSRExportToWkt(hSRS, &poDS->pszSRS);

    1163                 :         }
    1164                 :         
    1165                 : /* -------------------------------------------------------------------- */
    1166                 : /*      Get number of bands and block size                              */
    1167                 : /* -------------------------------------------------------------------- */
    1168                 : 
    1169              27 :         if (poDS->GetBlockParams(hRasterLyr, 0, &nBands, &eDataType,

    1170                 :                                  &nBlockXSize, &nBlockYSize) == FALSE)
    1171                 :         {
    1172               0 :             CPLError(CE_Failure, CPLE_AppDefined, "Cannot find block characteristics");

    1173               0 :             delete poDS;

    1174               0 :             poDS = NULL;

    1175                 :             goto end;
    1176                 :         }
    1177                 :         
    1178              28 :         if (eDataType == GDT_Byte && nBands == 1 && nReqBands == 3)

    1179               1 :             nBands = 3;

    1180              26 :         else if (nReqBands != 0)

    1181                 :         {
    1182                 :             CPLError(CE_Warning, CPLE_NotSupported,
    1183               0 :                      "Parameters bands=%d ignored", nReqBands);

    1184                 :         }
    1185                 :         
    1186                 : /* -------------------------------------------------------------------- */
    1187                 : /*      Add bands                                                       */
    1188                 : /* -------------------------------------------------------------------- */
    1189                 :         
    1190              74 :         for(iBand=0;iBand<nBands;iBand++)

    1191                 :             poDS->SetBand(iBand+1, new RasterliteBand(poDS, iBand+1, eDataType, 
    1192              47 :                                                   nBlockXSize, nBlockYSize));

    1193                 :         
    1194                 : /* -------------------------------------------------------------------- */
    1195                 : /*      Add overview levels as internal datasets                        */
    1196                 : /* -------------------------------------------------------------------- */
    1197              27 :         if (nResolutions > 1)

    1198                 :         {
    1199                 :             poDS->papoOverviews = (RasterliteDataset**)
    1200               3 :                 CPLCalloc(nResolutions - 1, sizeof(RasterliteDataset*));

    1201                 :             int nLev;
    1202               8 :             for(nLev=1;nLev<nResolutions;nLev++)

    1203                 :             {
    1204                 :                 int nOvrBands;
    1205                 :                 GDALDataType eOvrDataType;
    1206               5 :                 if (poDS->GetBlockParams(hRasterLyr, nLev, &nOvrBands, &eOvrDataType,

    1207                 :                                          &nBlockXSize, &nBlockYSize) == FALSE)
    1208                 :                 {
    1209                 :                     CPLError(CE_Failure, CPLE_AppDefined,
    1210               0 :                              "Cannot find block characteristics for overview %d", nLev);

    1211               0 :                     delete poDS;

    1212               0 :                     poDS = NULL;

    1213                 :                     goto end;
    1214                 :                 }
    1215                 :                 
    1216               5 :                 if (eDataType == GDT_Byte && nOvrBands == 1 && nReqBands == 3)

    1217               0 :                     nOvrBands = 3;

    1218                 :                     
    1219               5 :                 if (nBands != nOvrBands || eDataType != eOvrDataType)

    1220                 :                 {
    1221                 :                     CPLError(CE_Failure, CPLE_AppDefined,
    1222               0 :                              "Overview %d has not the same number characteristics as main band", nLev);

    1223               0 :                     delete poDS;

    1224               0 :                     poDS = NULL;

    1225                 :                     goto end;
    1226                 :                 }
    1227                 :                 
    1228               5 :                 poDS->papoOverviews[nLev-1] = new RasterliteDataset(poDS, nLev);

    1229                 :                     
    1230              12 :                 for(iBand=0;iBand<nBands;iBand++)

    1231                 :                 {
    1232                 :                     poDS->papoOverviews[nLev-1]->SetBand(iBand+1,
    1233                 :                         new RasterliteBand(poDS->papoOverviews[nLev-1], iBand+1, eDataType,
    1234               7 :                                            nBlockXSize, nBlockYSize));

    1235                 :                 }
    1236                 :             }
    1237                 :         }
    1238                 :         
    1239                 : /* -------------------------------------------------------------------- */
    1240                 : /*      Select an overview if the user has requested so                 */
    1241                 : /* -------------------------------------------------------------------- */
    1242              27 :         if (nLevel == 0)

    1243                 :         {
    1244                 :         }
    1245               0 :         else if (nLevel >= 1 && nLevel <= nResolutions - 1)

    1246                 :         {
    1247               0 :             poDS->papoOverviews[nLevel-1]->bMustFree = TRUE;

    1248               0 :             poDS = poDS->papoOverviews[nLevel-1];

    1249                 :         }
    1250                 :         else
    1251                 :         {
    1252                 :             CPLError(CE_Failure, CPLE_AppDefined,
    1253                 :                       "Invalid requested level : %d. Must be >= 0 and <= %d",
    1254               0 :                       nLevel, nResolutions - 1);

    1255               0 :             delete poDS;

    1256               0 :             poDS = NULL;

    1257               0 :         }

    1258                 : 
    1259                 :     }
    1260                 : 
    1261              27 :     if (poDS)

    1262                 :     {
    1263                 : /* -------------------------------------------------------------------- */
    1264                 : /*      Setup PAM info for this subdatasets                             */
    1265                 : /* -------------------------------------------------------------------- */
    1266              27 :         poDS->SetPhysicalFilename( osFileName.c_str() );

    1267                 :         
    1268              27 :         CPLString osSubdatasetName;

    1269                 :         osSubdatasetName.Printf("RASTERLITE:%s:table=%s",
    1270              27 :                                 osFileName.c_str(), osTableName.c_str());

    1271              27 :         poDS->SetSubdatasetName( osSubdatasetName.c_str() );

    1272              27 :         poDS->TryLoadXML();

    1273              27 :         poDS->oOvManager.Initialize( poDS, ":::VIRTUAL:::" );

    1274                 :     }
    1275                 : 
    1276                 :     
    1277              27 : end:

    1278              27 :     if (hDS)

    1279               0 :         OGRReleaseDataSource(hDS);

    1280              27 :     CSLDestroy(papszTokens);

    1281                 :     
    1282              27 :     return poDS;

    1283                 : }
    1284                 : 
    1285                 : /************************************************************************/
    1286                 : /*                     GDALRegister_Rasterlite()                        */
    1287                 : /************************************************************************/
    1288                 : 
    1289             409 : void GDALRegister_Rasterlite()

    1290                 : 
    1291                 : {
    1292                 :     GDALDriver  *poDriver;
    1293                 :     
    1294             409 :     if (! GDAL_CHECK_VERSION("Rasterlite driver"))

    1295               0 :         return;

    1296                 : 
    1297             409 :     if( GDALGetDriverByName( "Rasterlite" ) == NULL )

    1298                 :     {
    1299             392 :         poDriver = new GDALDriver();

    1300                 :         
    1301             392 :         poDriver->SetDescription( "Rasterlite" );

    1302                 :         poDriver->SetMetadataItem( GDAL_DMD_LONGNAME, 
    1303             392 :                                    "Rasterlite" );

    1304                 :         poDriver->SetMetadataItem( GDAL_DMD_HELPTOPIC, 
    1305             392 :                                    "frmt_rasterlite.html" );

    1306             392 :         poDriver->SetMetadataItem( GDAL_DMD_EXTENSION, "sqlite" );

    1307                 :         poDriver->SetMetadataItem( GDAL_DMD_CREATIONDATATYPES, 
    1308                 :                                    "Byte UInt16 Int16 UInt32 Int32 Float32 "
    1309             392 :                                    "Float64 CInt16 CInt32 CFloat32 CFloat64" );

    1310                 :         poDriver->SetMetadataItem( GDAL_DMD_CREATIONOPTIONLIST, 
    1311                 : "<CreationOptionList>"
    1312                 : "   <Option name='WIPE' type='boolean' default='NO' description='Erase all prexisting data in the specified table'/>"
    1313                 : "   <Option name='TILED' type='boolean' default='YES' description='Use tiling'/>"
    1314                 : "   <Option name='BLOCKXSIZE' type='int' default='256' description='Tile Width'/>"
    1315                 : "   <Option name='BLOCKYSIZE' type='int' default='256' description='Tile Height'/>"
    1316                 : "   <Option name='DRIVER' type='string' default='GTiff' description='GDAL driver to use for storing tiles' default='GTiff'/>"
    1317                 : "   <Option name='COMPRESS' type='string' default='(GTiff driver) Compression method' default='NONE'/>"
    1318                 : "   <Option name='QUALITY' type='int' description='(GTiff / JPEG drivers) JPEG quality 1-100' default='75'/>"
    1319                 : "   <Option name='PHOTOMETRIC' type='string-select' description='(GTiff driver) Photometric interpretation'>"
    1320                 : "       <Value>MINISBLACK</Value>"
    1321                 : "       <Value>MINISWHITE</Value>"
    1322                 : "       <Value>PALETTE</Value>"
    1323                 : "       <Value>RGB</Value>"
    1324                 : "       <Value>CMYK</Value>"
    1325                 : "       <Value>YCBCR</Value>"
    1326                 : "       <Value>CIELAB</Value>"
    1327                 : "       <Value>ICCLAB</Value>"
    1328                 : "       <Value>ITULAB</Value>"
    1329                 : "   </Option>"
    1330                 : "   <Option name='TARGET' type='int' description='(EPSILON driver) target size reduction as a percentage of the original (0-100)' default='96'/>"
    1331                 : "   <Option name='FILTER' type='string' description='(EPSILON driver) Filter ID' default='daub97lift'/>"
    1332             392 : "</CreationOptionList>" );

    1333                 : 
    1334             392 :         poDriver->pfnOpen = RasterliteDataset::Open;

    1335             392 :         poDriver->pfnIdentify = RasterliteDataset::Identify;

    1336             392 :         poDriver->pfnCreateCopy = RasterliteCreateCopy;

    1337             392 :         poDriver->pfnDelete = RasterliteDelete;

    1338                 : 
    1339             392 :         GetGDALDriverManager()->RegisterDriver( poDriver );

    1340                 :     }
    1341                 : }

Generated by: LTP GCOV extension version 1.5