LCOV - code coverage report
Current view: directory - frmts/rasterlite - rasterliteoverviews.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 287 226 78.7 %
Date: 2011-12-18 Functions: 5 5 100.0 %

       1                 : /******************************************************************************
       2                 :  * $Id: rasterliteoverviews.cpp 20090 2010-07-17 22:18:37Z 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 "cpl_string.h"
      31                 : #include "ogr_api.h"
      32                 : #include "ogr_srs_api.h"
      33                 : 
      34                 : #include "rasterlitedataset.h"
      35                 : 
      36                 : CPL_CVSID("$Id: rasterliteoverviews.cpp 20090 2010-07-17 22:18:37Z rouault $");
      37                 : 
      38                 : /************************************************************************/
      39                 : /*                         ReloadOverviews()                            */
      40                 : /************************************************************************/
      41                 : 
      42               2 : CPLErr RasterliteDataset::ReloadOverviews()
      43                 : {
      44               2 :     if (nLevel != 0)
      45               0 :         return CE_Failure;
      46                 :         
      47                 : /* -------------------------------------------------------------------- */
      48                 : /*      Fetch resolutions                                               */
      49                 : /* -------------------------------------------------------------------- */
      50                 : 
      51               2 :     CPLString osSQL;
      52               2 :     OGRLayerH hRasterPyramidsLyr = OGR_DS_GetLayerByName(hDS, "raster_pyramids");
      53               2 :     if (hRasterPyramidsLyr)
      54                 :     {
      55                 :         osSQL.Printf("SELECT pixel_x_size, pixel_y_size "
      56                 :                      "FROM raster_pyramids WHERE table_prefix = '%s' "
      57                 :                      "ORDER BY pixel_x_size ASC",
      58               2 :                      osTableName.c_str());
      59                 :      }
      60                 :      else
      61                 :      {
      62                 :         osSQL.Printf("SELECT DISTINCT(pixel_x_size), pixel_y_size "
      63                 :                      "FROM \"%s_metadata\" WHERE pixel_x_size != 0  "
      64                 :                      "ORDER BY pixel_x_size ASC",
      65               0 :                      osTableName.c_str());
      66                 :      }
      67                 : 
      68               2 :     OGRLayerH hSQLLyr = OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);
      69               2 :     if (hSQLLyr == NULL)
      70                 :     {
      71               0 :         if (hRasterPyramidsLyr == NULL)
      72               0 :             return CE_Failure;
      73                 :             
      74                 :         osSQL.Printf("SELECT DISTINCT(pixel_x_size), pixel_y_size "
      75                 :                      "FROM \"%s_metadata\" WHERE pixel_x_size != 0  "
      76                 :                      "ORDER BY pixel_x_size ASC",
      77               0 :                      osTableName.c_str());
      78                 :                      
      79               0 :         hSQLLyr = OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);
      80               0 :         if (hSQLLyr == NULL)
      81               0 :             return CE_Failure;
      82                 :     }
      83                 : 
      84                 : /* -------------------------------------------------------------------- */
      85                 : /*      Cleanup                                                         */
      86                 : /* -------------------------------------------------------------------- */
      87                 : 
      88                 :     int i;
      89               3 :     for(i=1;i<nResolutions;i++)
      90               1 :         delete papoOverviews[i-1];
      91               2 :     CPLFree(papoOverviews);
      92               2 :     papoOverviews = NULL;
      93               2 :     CPLFree(padfXResolutions);
      94               2 :     padfXResolutions = NULL;
      95               2 :     CPLFree(padfYResolutions);
      96               2 :     padfYResolutions = NULL;
      97                 :     
      98                 : /* -------------------------------------------------------------------- */
      99                 : /*      Rebuild arrays                                                  */
     100                 : /* -------------------------------------------------------------------- */
     101                 : 
     102               2 :     nResolutions = OGR_L_GetFeatureCount(hSQLLyr, TRUE);
     103                 :     
     104                 :     padfXResolutions =
     105               2 :         (double*)CPLMalloc(sizeof(double) * nResolutions);
     106                 :     padfYResolutions =
     107               2 :         (double*)CPLMalloc(sizeof(double) * nResolutions);
     108                 : 
     109               2 :     i = 0;
     110                 :     OGRFeatureH hFeat;
     111               9 :     while((hFeat = OGR_L_GetNextFeature(hSQLLyr)) != NULL)
     112                 :     {
     113               5 :         padfXResolutions[i] = OGR_F_GetFieldAsDouble(hFeat, 0);
     114               5 :         padfYResolutions[i] = OGR_F_GetFieldAsDouble(hFeat, 1);
     115                 : 
     116               5 :         OGR_F_Destroy(hFeat);
     117                 : 
     118               5 :         i ++;
     119                 :     }
     120                 : 
     121               2 :     OGR_DS_ReleaseResultSet(hDS, hSQLLyr);
     122               2 :     hSQLLyr = NULL;
     123                 : 
     124                 : /* -------------------------------------------------------------------- */
     125                 : /*      Add overview levels as internal datasets                        */
     126                 : /* -------------------------------------------------------------------- */
     127               2 :     if (nResolutions > 1)
     128                 :     {
     129               2 :         CPLString osRasterTableName = osTableName;
     130               2 :         osRasterTableName += "_rasters";
     131                 :         
     132               2 :         OGRLayerH hRasterLyr = OGR_DS_GetLayerByName(hDS, osRasterTableName.c_str());
     133                 :         
     134                 :         papoOverviews = (RasterliteDataset**)
     135               2 :             CPLCalloc(nResolutions - 1, sizeof(RasterliteDataset*));
     136                 :         int nLev;
     137               5 :         for(nLev=1;nLev<nResolutions;nLev++)
     138                 :         {
     139                 :             int nOvrBands;
     140                 :             GDALDataType eOvrDataType;
     141                 :             int nBlockXSize, nBlockYSize;
     142               3 :             if (GetBlockParams(hRasterLyr, nLev, &nOvrBands, &eOvrDataType,
     143                 :                                &nBlockXSize, &nBlockYSize))
     144                 :             {
     145               3 :                 if (eOvrDataType == GDT_Byte && nOvrBands == 1 && nBands == 3)
     146               0 :                     nOvrBands = 3;
     147                 : 
     148               3 :                 papoOverviews[nLev-1] = new RasterliteDataset(this, nLev);
     149                 :                   
     150                 :                 int iBand;
     151               6 :                 for(iBand=0;iBand<nBands;iBand++)
     152                 :                 {
     153               3 :                     papoOverviews[nLev-1]->SetBand(iBand+1,
     154                 :                         new RasterliteBand(papoOverviews[nLev-1], iBand+1, eOvrDataType,
     155               6 :                                            nBlockXSize, nBlockYSize));
     156                 :                 }
     157                 :             }
     158                 :             else
     159                 :             {
     160                 :                 CPLError(CE_Failure, CPLE_AppDefined,
     161               0 :                          "Cannot find block characteristics for overview %d", nLev);
     162               0 :                 papoOverviews[nLev-1] = NULL;
     163                 :             }
     164               2 :         }
     165                 :     }
     166                 :     
     167               2 :     return CE_None;
     168                 : }
     169                 : 
     170                 : /************************************************************************/
     171                 : /*                          CleanOverviews()                            */
     172                 : /************************************************************************/
     173                 : 
     174               1 : CPLErr RasterliteDataset::CleanOverviews()
     175                 : {
     176               1 :     CPLString osSQL;
     177                 :     
     178               1 :     if (nLevel != 0)
     179               0 :         return CE_Failure;
     180                 :         
     181               1 :     osSQL.Printf("BEGIN");
     182               1 :     OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);
     183                 :     
     184               1 :     CPLString osResolutionCond;
     185                 :     osResolutionCond.Printf(
     186                 :                  "(pixel_x_size < %.15f OR pixel_x_size > %.15f) AND "
     187                 :                  "(pixel_y_size < %.15f OR pixel_y_size > %.15f)",
     188               2 :                  padfXResolutions[0] - 1e-15, padfXResolutions[0] + 1e-15,
     189               3 :                  padfYResolutions[0] - 1e-15, padfYResolutions[0] + 1e-15);
     190                 :     
     191                 :     osSQL.Printf("DELETE FROM \"%s_rasters\" WHERE id "
     192                 :                  "IN(SELECT id FROM \"%s_metadata\" WHERE %s)",
     193                 :                   osTableName.c_str(), osTableName.c_str(),
     194               1 :                   osResolutionCond.c_str());
     195               1 :     OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);
     196                 : 
     197                 :     osSQL.Printf("DELETE FROM \"%s_metadata\" WHERE %s",
     198               1 :                   osTableName.c_str(), osResolutionCond.c_str());
     199               1 :     OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);
     200                 :     
     201               1 :     OGRLayerH hRasterPyramidsLyr = OGR_DS_GetLayerByName(hDS, "raster_pyramids");
     202               1 :     if (hRasterPyramidsLyr)
     203                 :     {
     204                 :         osSQL.Printf("DELETE FROM raster_pyramids WHERE table_prefix = '%s' AND %s",
     205               1 :                       osTableName.c_str(), osResolutionCond.c_str());
     206               1 :         OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);
     207                 :     }
     208                 :     
     209               1 :     osSQL.Printf("COMMIT");
     210               1 :     OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);
     211                 :     
     212                 :     int i;
     213               3 :     for(i=1;i<nResolutions;i++)
     214               2 :         delete papoOverviews[i-1];
     215               1 :     CPLFree(papoOverviews);
     216               1 :     papoOverviews = NULL;
     217               1 :     nResolutions = 1;
     218                 :     
     219               1 :     return CE_None;
     220                 : }
     221                 : 
     222                 : /************************************************************************/
     223                 : /*                       CleanOverviewLevel()                           */
     224                 : /************************************************************************/
     225                 : 
     226               2 : CPLErr RasterliteDataset::CleanOverviewLevel(int nOvrFactor)
     227                 : {
     228               2 :     CPLString osSQL;
     229                 :     
     230               2 :     if (nLevel != 0)
     231               0 :         return CE_Failure;
     232                 :     
     233                 : /* -------------------------------------------------------------------- */
     234                 : /*      Find the index of the overview matching the overview factor     */
     235                 : /* -------------------------------------------------------------------- */
     236                 :     int iLev;
     237               3 :     for(iLev=1;iLev<nResolutions;iLev++)
     238                 :     {
     239               1 :         if (fabs(padfXResolutions[0] * nOvrFactor - padfXResolutions[iLev]) < 1e-15 &&
     240               0 :             fabs(padfYResolutions[0] * nOvrFactor - padfYResolutions[iLev]) < 1e-15)
     241               0 :             break;
     242                 :     }
     243                 :     
     244               2 :     if (iLev == nResolutions)
     245               2 :         return CE_None;
     246                 :         
     247                 : /* -------------------------------------------------------------------- */
     248                 : /*      Now clean existing overviews at that resolution                 */
     249                 : /* -------------------------------------------------------------------- */
     250                 : 
     251               0 :     osSQL.Printf("BEGIN");
     252               0 :     OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);
     253                 :     
     254               0 :     CPLString osResolutionCond;
     255                 :     osResolutionCond.Printf(
     256                 :                  "pixel_x_size >= %.15f AND pixel_x_size <= %.15f AND "
     257                 :                  "pixel_y_size >= %.15f AND pixel_y_size <= %.15f",
     258               0 :                  padfXResolutions[iLev] - 1e-15, padfXResolutions[iLev] + 1e-15,
     259               0 :                  padfYResolutions[iLev] - 1e-15, padfYResolutions[iLev] + 1e-15);
     260                 :     
     261                 :     osSQL.Printf("DELETE FROM \"%s_rasters\" WHERE id "
     262                 :                  "IN(SELECT id FROM \"%s_metadata\" WHERE %s)",
     263                 :                   osTableName.c_str(), osTableName.c_str(),
     264               0 :                   osResolutionCond.c_str());
     265               0 :     OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);
     266                 : 
     267                 :     osSQL.Printf("DELETE FROM \"%s_metadata\" WHERE %s",
     268               0 :                   osTableName.c_str(), osResolutionCond.c_str());
     269               0 :     OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);
     270                 :     
     271               0 :     OGRLayerH hRasterPyramidsLyr = OGR_DS_GetLayerByName(hDS, "raster_pyramids");
     272               0 :     if (hRasterPyramidsLyr)
     273                 :     {
     274                 :         osSQL.Printf("DELETE FROM raster_pyramids WHERE table_prefix = '%s' AND %s",
     275               0 :                       osTableName.c_str(), osResolutionCond.c_str());
     276               0 :         OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);
     277                 :     }
     278                 :     
     279               0 :     osSQL.Printf("COMMIT");
     280               0 :     OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);
     281                 :     
     282               0 :     return CE_None;
     283                 : }
     284                 : 
     285                 : /************************************************************************/
     286                 : /*                       CleanOverviewLevel()                           */
     287                 : /************************************************************************/
     288                 : 
     289               2 : CPLErr RasterliteDataset::CreateOverviewLevel(int nOvrFactor,
     290                 :                                               GDALProgressFunc pfnProgress,
     291                 :                                               void * pProgressData)
     292                 : {
     293                 : 
     294               2 :     double dfXResolution = padfXResolutions[0] * nOvrFactor;
     295               2 :     double dfYResolution = padfXResolutions[0] * nOvrFactor;
     296                 :     
     297               2 :     CPLString osSQL;
     298                 : 
     299               2 :     int nBlockXSize = 256;
     300               2 :     int nBlockYSize = 256;
     301               2 :     int nOvrXSize = nRasterXSize / nOvrFactor;
     302               2 :     int nOvrYSize = nRasterYSize / nOvrFactor;
     303                 :     
     304               2 :     if (nOvrXSize == 0 || nOvrYSize == 0)
     305               0 :         return CE_Failure;
     306                 :     
     307               2 :     int nXBlocks = (nOvrXSize + nBlockXSize - 1) / nBlockXSize;
     308               2 :     int nYBlocks = (nOvrYSize + nBlockYSize - 1) / nBlockYSize;
     309                 :     
     310               2 :     const char* pszDriverName = "GTiff";
     311               2 :     GDALDriverH hTileDriver = GDALGetDriverByName(pszDriverName);
     312               2 :     if (hTileDriver == NULL)
     313                 :     {
     314               0 :         CPLError(CE_Failure, CPLE_AppDefined, "Cannot load GDAL %s driver", pszDriverName);
     315               0 :         return CE_Failure;
     316                 :     }
     317                 :     
     318               2 :     GDALDriverH hMemDriver = GDALGetDriverByName("MEM");
     319               2 :     if (hMemDriver == NULL)
     320                 :     {
     321               0 :         CPLError(CE_Failure, CPLE_AppDefined, "Cannot load GDAL MEM driver");
     322               0 :         return CE_Failure;
     323                 :     }   
     324                 : 
     325               2 :     GDALDataType eDataType = GetRasterBand(1)->GetRasterDataType();
     326               2 :     int nDataTypeSize = GDALGetDataTypeSize(eDataType) / 8;
     327                 :     GByte* pabyMEMDSBuffer =
     328               2 :         (GByte*)VSIMalloc3(nBlockXSize, nBlockYSize, nBands * nDataTypeSize);
     329               2 :     if (pabyMEMDSBuffer == NULL)
     330                 :     {
     331               0 :         return CE_Failure;
     332                 :     }
     333                 :     
     334               2 :     char** papszTileDriverOptions = NULL;
     335                 :     
     336               2 :     CPLString osTempFileName;
     337               2 :     osTempFileName.Printf("/vsimem/%p", hDS);
     338                 :     
     339               2 :     int nTileId = 0;
     340               2 :     int nBlocks = 0;
     341               2 :     int nTotalBlocks = nXBlocks * nYBlocks;
     342                 :     
     343               2 :     CPLString osRasterLayer;
     344               2 :     osRasterLayer.Printf("%s_rasters", osTableName.c_str());
     345                 :     
     346               2 :     CPLString osMetatadataLayer;
     347               2 :     osMetatadataLayer.Printf("%s_metadata", osTableName.c_str());
     348                 :     
     349               2 :     OGRLayerH hRasterLayer = OGR_DS_GetLayerByName(hDS, osRasterLayer.c_str());
     350               2 :     OGRLayerH hMetadataLayer = OGR_DS_GetLayerByName(hDS, osMetatadataLayer.c_str());
     351                 :     
     352               2 :     CPLString osSourceName = "unknown";
     353                 :     
     354                 :     osSQL.Printf("SELECT source_name FROM \"%s\" WHERE "
     355                 :                  "pixel_x_size >= %.15f AND pixel_x_size <= %.15f AND "
     356                 :                  "pixel_y_size >= %.15f AND pixel_y_size <= %.15f LIMIT 1",
     357                 :                  osMetatadataLayer.c_str(),
     358               4 :                  padfXResolutions[0] - 1e-15, padfXResolutions[0] + 1e-15,
     359               6 :                  padfYResolutions[0] - 1e-15, padfYResolutions[0] + 1e-15);
     360               2 :     OGRLayerH hSQLLyr = OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);
     361               2 :     if (hSQLLyr)
     362                 :     {
     363               2 :         OGRFeatureH hFeat = OGR_L_GetNextFeature(hSQLLyr);
     364               2 :         if (hFeat)
     365                 :         {
     366               2 :             const char* pszVal = OGR_F_GetFieldAsString(hFeat, 0);
     367               2 :             if (pszVal)
     368               2 :                 osSourceName = pszVal;
     369               2 :             OGR_F_Destroy(hFeat);
     370                 :         }
     371               2 :         OGR_DS_ReleaseResultSet(hDS, hSQLLyr);
     372                 :     }
     373                 :     
     374                 : /* -------------------------------------------------------------------- */
     375                 : /*      Compute up to which existing overview level we can use for      */
     376                 : /*      computing the requested overview                                */
     377                 : /* -------------------------------------------------------------------- */
     378                 :     int iLev;
     379               2 :     nLimitOvrCount = 0;
     380               3 :     for(iLev=1;iLev<nResolutions;iLev++)
     381                 :     {
     382               2 :         if (!(padfXResolutions[iLev] < dfXResolution - 1e-10 &&
     383               1 :               padfYResolutions[iLev] < dfYResolution - 1e-10))
     384                 :         {
     385               0 :             break;
     386                 :         }
     387               1 :         nLimitOvrCount++;
     388                 :     }
     389                 :     
     390                 : /* -------------------------------------------------------------------- */
     391                 : /*      Iterate over blocks to add data into raster and metadata tables */
     392                 : /* -------------------------------------------------------------------- */
     393                 : 
     394               2 :     OGR_DS_ExecuteSQL(hDS, "BEGIN", NULL, NULL);
     395                 :     
     396               2 :     CPLErr eErr = CE_None;
     397                 :     int nBlockXOff, nBlockYOff;
     398               4 :     for(nBlockYOff=0;eErr == CE_None && nBlockYOff<nYBlocks;nBlockYOff++)
     399                 :     {
     400               4 :         for(nBlockXOff=0;eErr == CE_None && nBlockXOff<nXBlocks;nBlockXOff++)
     401                 :         {
     402                 : /* -------------------------------------------------------------------- */
     403                 : /*      Create in-memory tile                                           */
     404                 : /* -------------------------------------------------------------------- */
     405               2 :             int nReqXSize = nBlockXSize, nReqYSize = nBlockYSize;
     406               2 :             if ((nBlockXOff+1) * nBlockXSize > nOvrXSize)
     407               2 :                 nReqXSize = nOvrXSize - nBlockXOff * nBlockXSize;
     408               2 :             if ((nBlockYOff+1) * nBlockYSize > nOvrYSize)
     409               2 :                 nReqYSize = nOvrYSize - nBlockYOff * nBlockYSize;
     410                 :             
     411                 :             eErr = RasterIO(GF_Read,
     412                 :                             nBlockXOff * nBlockXSize * nOvrFactor,
     413                 :                             nBlockYOff * nBlockYSize * nOvrFactor,
     414                 :                             nReqXSize * nOvrFactor, nReqYSize * nOvrFactor,
     415                 :                             pabyMEMDSBuffer, nReqXSize, nReqYSize,
     416                 :                             eDataType, nBands, NULL,
     417               2 :                             0, 0, 0);
     418               2 :             if (eErr != CE_None)
     419                 :             {
     420               0 :                 break;
     421                 :             }
     422                 :             
     423                 :             GDALDatasetH hMemDS = GDALCreate(hMemDriver, "MEM:::",
     424                 :                                               nReqXSize, nReqYSize, 0, 
     425               2 :                                               eDataType, NULL);
     426               2 :             if (hMemDS == NULL)
     427                 :             {
     428               0 :                 eErr = CE_Failure;
     429               0 :                 break;
     430                 :             }
     431                 :             
     432                 :             int iBand;
     433               4 :             for(iBand = 0; iBand < nBands; iBand ++)
     434                 :             {
     435               2 :                 char** papszOptions = NULL;
     436                 :                 char szTmp[64];
     437               2 :                 memset(szTmp, 0, sizeof(szTmp));
     438                 :                 CPLPrintPointer(szTmp,
     439                 :                                 pabyMEMDSBuffer + iBand * nDataTypeSize *
     440               2 :                                 nReqXSize * nReqYSize, sizeof(szTmp));
     441               2 :                 papszOptions = CSLSetNameValue(papszOptions, "DATAPOINTER", szTmp);
     442               2 :                 GDALAddBand(hMemDS, eDataType, papszOptions);
     443               2 :                 CSLDestroy(papszOptions);
     444                 :             }
     445                 :             
     446                 :             GDALDatasetH hOutDS = GDALCreateCopy(hTileDriver,
     447                 :                                         osTempFileName.c_str(), hMemDS, FALSE,
     448               2 :                                         papszTileDriverOptions, NULL, NULL);
     449                 : 
     450               2 :             GDALClose(hMemDS);
     451               2 :             if (hOutDS)
     452               2 :                 GDALClose(hOutDS);
     453                 :             else
     454                 :             {
     455               0 :                 eErr = CE_Failure;
     456               0 :                 break;
     457                 :             }
     458                 : 
     459                 : /* -------------------------------------------------------------------- */
     460                 : /*      Insert new entry into raster table                              */
     461                 : /* -------------------------------------------------------------------- */
     462                 : 
     463                 :             vsi_l_offset nDataLength;
     464                 :             GByte *pabyData = VSIGetMemFileBuffer( osTempFileName.c_str(),
     465               4 :                                                    &nDataLength, FALSE);
     466                 : 
     467               2 :             OGRFeatureH hFeat = OGR_F_Create( OGR_L_GetLayerDefn(hRasterLayer) );
     468               2 :             OGR_F_SetFieldBinary(hFeat, 0, (int)nDataLength, pabyData);
     469                 :             
     470               2 :             OGR_L_CreateFeature(hRasterLayer, hFeat);
     471                 :             /* Query raster ID to set it as the ID of the associated metadata */
     472               2 :             int nRasterID = (int)OGR_F_GetFID(hFeat);
     473                 :             
     474               2 :             OGR_F_Destroy(hFeat);
     475                 :             
     476               2 :             VSIUnlink(osTempFileName.c_str());
     477                 :             
     478                 : /* -------------------------------------------------------------------- */
     479                 : /*      Insert new entry into metadata table                            */
     480                 : /* -------------------------------------------------------------------- */
     481                 :             
     482               2 :             hFeat = OGR_F_Create( OGR_L_GetLayerDefn(hMetadataLayer) );
     483               2 :             OGR_F_SetFID(hFeat, nRasterID);
     484               2 :             OGR_F_SetFieldString(hFeat, 0, osSourceName);
     485               2 :             OGR_F_SetFieldInteger(hFeat, 1, nTileId ++);
     486               2 :             OGR_F_SetFieldInteger(hFeat, 2, nReqXSize);
     487               2 :             OGR_F_SetFieldInteger(hFeat, 3, nReqYSize);
     488               2 :             OGR_F_SetFieldDouble(hFeat, 4, dfXResolution);
     489               2 :             OGR_F_SetFieldDouble(hFeat, 5, dfYResolution);
     490                 :             
     491                 :             double minx, maxx, maxy, miny;
     492               2 :             minx = adfGeoTransform[0] +
     493               2 :                 (nBlockXSize * nBlockXOff) * dfXResolution;
     494               2 :             maxx = adfGeoTransform[0] +
     495               2 :                 (nBlockXSize * nBlockXOff + nReqXSize) * dfXResolution;
     496               2 :             maxy = adfGeoTransform[3] +
     497               2 :                 (nBlockYSize * nBlockYOff) * (-dfYResolution);
     498               2 :             miny = adfGeoTransform[3] +
     499               2 :                 (nBlockYSize * nBlockYOff + nReqYSize) * (-dfYResolution);
     500                 :             
     501               2 :             OGRGeometryH hRectangle = OGR_G_CreateGeometry(wkbPolygon);
     502               2 :             OGRGeometryH hLinearRing = OGR_G_CreateGeometry(wkbLinearRing);
     503               2 :             OGR_G_AddPoint_2D(hLinearRing, minx, miny);
     504               2 :             OGR_G_AddPoint_2D(hLinearRing, minx, maxy);
     505               2 :             OGR_G_AddPoint_2D(hLinearRing, maxx, maxy);
     506               2 :             OGR_G_AddPoint_2D(hLinearRing, maxx, miny);
     507               2 :             OGR_G_AddPoint_2D(hLinearRing, minx, miny);
     508               2 :             OGR_G_AddGeometryDirectly(hRectangle, hLinearRing);
     509                 :             
     510               2 :             OGR_F_SetGeometryDirectly(hFeat, hRectangle);
     511                 :             
     512               2 :             OGR_L_CreateFeature(hMetadataLayer, hFeat);
     513               2 :             OGR_F_Destroy(hFeat);
     514                 :             
     515               2 :             nBlocks++;
     516               2 :             if (pfnProgress && !pfnProgress(1.0 * nBlocks / nTotalBlocks,
     517                 :                                             NULL, pProgressData))
     518               0 :                 eErr = CE_Failure;
     519                 :         }
     520                 :     }
     521                 :     
     522               2 :     nLimitOvrCount = -1;
     523                 :     
     524               2 :     if (eErr == CE_None)
     525               2 :         OGR_DS_ExecuteSQL(hDS, "COMMIT", NULL, NULL);
     526                 :     else
     527               0 :         OGR_DS_ExecuteSQL(hDS, "ROLLBACK", NULL, NULL);
     528                 :     
     529               2 :     VSIFree(pabyMEMDSBuffer);
     530                 :     
     531                 : /* -------------------------------------------------------------------- */
     532                 : /*      Update raster_pyramids table                                    */
     533                 : /* -------------------------------------------------------------------- */
     534               2 :     if (eErr == CE_None)
     535                 :     {
     536               2 :         OGRLayerH hRasterPyramidsLyr = OGR_DS_GetLayerByName(hDS, "raster_pyramids");
     537               2 :         if (hRasterPyramidsLyr == NULL)
     538                 :         {
     539                 :             osSQL.Printf   ("CREATE TABLE raster_pyramids ("
     540                 :                             "table_prefix TEXT NOT NULL,"
     541                 :                             "pixel_x_size DOUBLE NOT NULL,"
     542                 :                             "pixel_y_size DOUBLE NOT NULL,"
     543               1 :                             "tile_count INTEGER NOT NULL)");
     544               1 :             OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);
     545                 :             
     546                 :             /* Re-open the DB to take into account the new tables*/
     547               1 :             OGRReleaseDataSource(hDS);
     548                 :             
     549               1 :             CPLString osOldVal = CPLGetConfigOption("SQLITE_LIST_ALL_TABLES", "FALSE");
     550               1 :             CPLSetThreadLocalConfigOption("SQLITE_LIST_ALL_TABLES", "TRUE");
     551               1 :             hDS = OGROpen(osFileName.c_str(), TRUE, NULL);
     552               1 :             CPLSetThreadLocalConfigOption("SQLITE_LIST_ALL_TABLES", osOldVal.c_str());
     553                 :             
     554                 :             osSQL.Printf("SELECT COUNT(*) FROM \"%s\" WHERE "
     555                 :                           "pixel_x_size >= %.15f AND pixel_x_size <= %.15f AND "
     556                 :                           "pixel_y_size >= %.15f AND pixel_y_size <= %.15f",
     557                 :                           osMetatadataLayer.c_str(),
     558               2 :                           padfXResolutions[0] - 1e-15, padfXResolutions[0] + 1e-15,
     559               3 :                           padfYResolutions[0] - 1e-15, padfYResolutions[0] + 1e-15);
     560                 :                           
     561               1 :             int nBlocksMainRes = 0;
     562                 :             
     563               1 :             hSQLLyr = OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);
     564               1 :             if (hSQLLyr)
     565                 :             {
     566               1 :                 OGRFeatureH hFeat = OGR_L_GetNextFeature(hSQLLyr);
     567               1 :                 if (hFeat)
     568                 :                 {
     569               1 :                     nBlocksMainRes = OGR_F_GetFieldAsInteger(hFeat, 0);
     570               1 :                     OGR_F_Destroy(hFeat);
     571                 :                 }
     572               1 :                 OGR_DS_ReleaseResultSet(hDS, hSQLLyr);
     573                 :             }
     574                 :             
     575                 :             osSQL.Printf("INSERT INTO raster_pyramids "
     576                 :                          "( table_prefix, pixel_x_size, pixel_y_size, tile_count ) "
     577                 :                          "VALUES ( '%s', %.18f, %.18f, %d )",
     578                 :                          osTableName.c_str(), padfXResolutions[0], padfYResolutions[0],
     579               1 :                          nBlocksMainRes);
     580               1 :             OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);
     581                 :         }
     582                 :         
     583                 :         osSQL.Printf("INSERT INTO raster_pyramids "
     584                 :                      "( table_prefix, pixel_x_size, pixel_y_size, tile_count ) "
     585                 :                      "VALUES ( '%s', %.18f, %.18f, %d )",
     586                 :                      osTableName.c_str(), dfXResolution, dfYResolution,
     587               2 :                      nTotalBlocks);
     588               2 :         OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);
     589                 :     }
     590                 : 
     591               2 :     return eErr;
     592                 : }
     593                 : 
     594                 : /************************************************************************/
     595                 : /*                          IBuildOverviews()                           */
     596                 : /************************************************************************/
     597                 : 
     598               2 : CPLErr RasterliteDataset::IBuildOverviews( const char * pszResampling, 
     599                 :                                            int nOverviews, int * panOverviewList,
     600                 :                                            int nBands, int * panBandList,
     601                 :                                            GDALProgressFunc pfnProgress,
     602                 :                                            void * pProgressData )
     603                 : {
     604               2 :     CPLErr eErr = CE_None;
     605                 :     
     606               2 :     if (nLevel != 0)
     607                 :     {
     608                 :         CPLError(CE_Failure, CPLE_AppDefined,
     609               0 :                  "Overviews can only be computed on the base dataset");
     610               0 :         return CE_Failure;
     611                 :     }
     612                 :         
     613               2 :     if (osTableName.size() == 0)
     614               0 :         return CE_Failure;
     615                 :     
     616                 : /* -------------------------------------------------------------------- */
     617                 : /*      If we don't have read access, then create the overviews         */
     618                 : /*      externally.                                                     */
     619                 : /* -------------------------------------------------------------------- */
     620               2 :     if( GetAccess() != GA_Update )
     621                 :     {
     622                 :         CPLDebug( "Rasterlite",
     623                 :                   "File open for read-only accessing, "
     624               0 :                   "creating overviews externally." );
     625                 :                   
     626               0 :         if (nResolutions != 1)
     627                 :         {
     628                 :             CPLError(CE_Failure, CPLE_NotSupported,
     629                 :                      "Cannot add external overviews to a "
     630               0 :                      "dataset with internal overviews");
     631               0 :             return CE_Failure;
     632                 :         }
     633                 : 
     634               0 :         bCheckForExistingOverview = FALSE;
     635                 :         eErr = GDALDataset::IBuildOverviews( 
     636                 :                             pszResampling, nOverviews, panOverviewList, 
     637               0 :                             nBands, panBandList, pfnProgress, pProgressData );
     638               0 :         bCheckForExistingOverview = TRUE;
     639               0 :         return eErr;
     640                 :     }
     641                 :     
     642                 : /* -------------------------------------------------------------------- */
     643                 : /*      If zero overviews were requested, we need to clear all          */
     644                 : /*      existing overviews.                                             */
     645                 : /* -------------------------------------------------------------------- */
     646               2 :     if (nOverviews == 0)
     647                 :     {
     648               1 :         return CleanOverviews();
     649                 :     }
     650                 :     
     651               1 :     if( nBands != GetRasterCount() )
     652                 :     {
     653                 :         CPLError( CE_Failure, CPLE_NotSupported,
     654                 :                   "Generation of overviews in RASTERLITE only"
     655                 :                   " supported when operating on all bands.\n" 
     656               0 :                   "Operation failed.\n" );
     657               0 :         return CE_Failure;
     658                 :     }
     659                 :     
     660               1 :     if( !EQUALN(pszResampling, "NEAR", 4))
     661                 :     {
     662                 :         CPLError( CE_Failure, CPLE_NotSupported,
     663                 :                   "Only NEAREST resampling is allowed for now "
     664               0 :                   "for RASTERLITE overviews");
     665               0 :         return CE_Failure;
     666                 :     }
     667                 :     
     668                 :     int i;
     669               3 :     for(i=0;i<nOverviews && eErr == CE_None;i++)
     670                 :     {
     671               2 :         if (panOverviewList[i] <= 1)
     672               0 :             continue;
     673                 : 
     674               2 :         eErr = CleanOverviewLevel(panOverviewList[i]);
     675               2 :         if (eErr == CE_None)
     676               2 :             eErr = CreateOverviewLevel(panOverviewList[i], pfnProgress, pProgressData);
     677                 :     
     678               2 :         ReloadOverviews();
     679                 :     }
     680                 :     
     681               1 :     return eErr;
     682                 : }

Generated by: LCOV version 1.7