LTP GCOV extension - code coverage report
Current view: directory - frmts/rasterlite - rasterliteoverviews.cpp
Test: gdal_filtered.info
Date: 2010-07-12 Instrumented lines: 276
Code covered: 78.6 % Executed lines: 217

       1                 : /******************************************************************************
       2                 :  * $Id: rasterliteoverviews.cpp 19563 2010-04-28 21:02:05Z 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 19563 2010-04-28 21:02:05Z 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                 :                     papoOverviews[nLev-1]->SetBand(iBand+1,
     154                 :                         new RasterliteBand(papoOverviews[nLev-1], iBand+1, eOvrDataType,
     155               3 :                                            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                 :                  padfXResolutions[0] - 1e-15, padfXResolutions[0] + 1e-15,
     189               1 :                  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                 :             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                 :                  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                 : CPLErr RasterliteDataset::CreateOverviewLevel(int nOvrFactor,
     290                 :                                               GDALProgressFunc pfnProgress,
     291               2 :                                               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                 :                  padfXResolutions[0] - 1e-15, padfXResolutions[0] + 1e-15,
     359               2 :                  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               1 :         if (!(padfXResolutions[iLev] < dfXResolution - 1e-10 &&

     383                 :               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                 :             minx = adfGeoTransform[0] +
     493               2 :                 (nBlockXSize * nBlockXOff) * dfXResolution;

     494                 :             maxx = adfGeoTransform[0] +
     495               2 :                 (nBlockXSize * nBlockXOff + nReqXSize) * dfXResolution;

     496                 :             maxy = adfGeoTransform[3] +
     497               2 :                 (nBlockYSize * nBlockYOff) * (-dfYResolution);

     498                 :             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 :             CPLSetConfigOption("SQLITE_LIST_ALL_TABLES", "TRUE");

     551               1 :             hDS = OGROpen(osFileName.c_str(), TRUE, NULL);

     552               1 :             CPLSetConfigOption("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                 :                           padfXResolutions[0] - 1e-15, padfXResolutions[0] + 1e-15,
     559               1 :                           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                 : CPLErr RasterliteDataset::IBuildOverviews( const char * pszResampling, 
     599                 :                                            int nOverviews, int * panOverviewList,
     600                 :                                            int nBands, int * panBandList,
     601                 :                                            GDALProgressFunc pfnProgress,
     602               2 :                                            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: LTP GCOV extension version 1.5