LCOV - code coverage report
Current view: directory - frmts/rasterlite - rasterliteoverviews.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 298 237 79.5 %
Date: 2012-04-28 Functions: 5 5 100.0 %

       1                 : /******************************************************************************
       2                 :  * $Id: rasterliteoverviews.cpp 24127 2012-03-18 15:33:15Z 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 24127 2012-03-18 15:33:15Z rouault $");
      37                 : 
      38                 : /************************************************************************/
      39                 : /*                         ReloadOverviews()                            */
      40                 : /************************************************************************/
      41                 : 
      42               4 : CPLErr RasterliteDataset::ReloadOverviews()
      43                 : {
      44               4 :     if (nLevel != 0)
      45               0 :         return CE_Failure;
      46                 :         
      47                 : /* -------------------------------------------------------------------- */
      48                 : /*      Fetch resolutions                                               */
      49                 : /* -------------------------------------------------------------------- */
      50                 : 
      51               4 :     CPLString osSQL;
      52               4 :     OGRLayerH hRasterPyramidsLyr = OGR_DS_GetLayerByName(hDS, "raster_pyramids");
      53               4 :     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               4 :                      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               4 :     OGRLayerH hSQLLyr = OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);
      69               4 :     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               6 :     for(i=1;i<nResolutions;i++)
      90               2 :         delete papoOverviews[i-1];
      91               4 :     CPLFree(papoOverviews);
      92               4 :     papoOverviews = NULL;
      93               4 :     CPLFree(padfXResolutions);
      94               4 :     padfXResolutions = NULL;
      95               4 :     CPLFree(padfYResolutions);
      96               4 :     padfYResolutions = NULL;
      97                 :     
      98                 : /* -------------------------------------------------------------------- */
      99                 : /*      Rebuild arrays                                                  */
     100                 : /* -------------------------------------------------------------------- */
     101                 : 
     102               4 :     nResolutions = OGR_L_GetFeatureCount(hSQLLyr, TRUE);
     103                 :     
     104                 :     padfXResolutions =
     105               4 :         (double*)CPLMalloc(sizeof(double) * nResolutions);
     106                 :     padfYResolutions =
     107               4 :         (double*)CPLMalloc(sizeof(double) * nResolutions);
     108                 : 
     109               4 :     i = 0;
     110                 :     OGRFeatureH hFeat;
     111              18 :     while((hFeat = OGR_L_GetNextFeature(hSQLLyr)) != NULL)
     112                 :     {
     113              10 :         padfXResolutions[i] = OGR_F_GetFieldAsDouble(hFeat, 0);
     114              10 :         padfYResolutions[i] = OGR_F_GetFieldAsDouble(hFeat, 1);
     115                 : 
     116              10 :         OGR_F_Destroy(hFeat);
     117                 : 
     118              10 :         i ++;
     119                 :     }
     120                 : 
     121               4 :     OGR_DS_ReleaseResultSet(hDS, hSQLLyr);
     122               4 :     hSQLLyr = NULL;
     123                 : 
     124                 : /* -------------------------------------------------------------------- */
     125                 : /*      Add overview levels as internal datasets                        */
     126                 : /* -------------------------------------------------------------------- */
     127               4 :     if (nResolutions > 1)
     128                 :     {
     129               4 :         CPLString osRasterTableName = osTableName;
     130               4 :         osRasterTableName += "_rasters";
     131                 :         
     132               4 :         OGRLayerH hRasterLyr = OGR_DS_GetLayerByName(hDS, osRasterTableName.c_str());
     133                 :         
     134                 :         papoOverviews = (RasterliteDataset**)
     135               4 :             CPLCalloc(nResolutions - 1, sizeof(RasterliteDataset*));
     136                 :         int nLev;
     137              10 :         for(nLev=1;nLev<nResolutions;nLev++)
     138                 :         {
     139                 :             int nOvrBands;
     140                 :             GDALDataType eOvrDataType;
     141                 :             int nBlockXSize, nBlockYSize;
     142               6 :             if (GetBlockParams(hRasterLyr, nLev, &nOvrBands, &eOvrDataType,
     143                 :                                &nBlockXSize, &nBlockYSize))
     144                 :             {
     145               6 :                 if (eOvrDataType == GDT_Byte && nOvrBands == 1 && nBands == 3)
     146               0 :                     nOvrBands = 3;
     147                 : 
     148               6 :                 papoOverviews[nLev-1] = new RasterliteDataset(this, nLev);
     149                 :                   
     150                 :                 int iBand;
     151              12 :                 for(iBand=0;iBand<nBands;iBand++)
     152                 :                 {
     153               6 :                     papoOverviews[nLev-1]->SetBand(iBand+1,
     154                 :                         new RasterliteBand(papoOverviews[nLev-1], iBand+1, eOvrDataType,
     155              12 :                                            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               4 :         }
     165                 :     }
     166                 :     
     167               4 :     return CE_None;
     168                 : }
     169                 : 
     170                 : /************************************************************************/
     171                 : /*                          CleanOverviews()                            */
     172                 : /************************************************************************/
     173                 : 
     174               2 : CPLErr RasterliteDataset::CleanOverviews()
     175                 : {
     176               2 :     CPLString osSQL;
     177                 :     
     178               2 :     if (nLevel != 0)
     179               0 :         return CE_Failure;
     180                 :         
     181               2 :     osSQL.Printf("BEGIN");
     182               2 :     OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);
     183                 :     
     184               2 :     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               4 :                  padfXResolutions[0] - 1e-15, padfXResolutions[0] + 1e-15,
     189               6 :                  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               2 :                   osResolutionCond.c_str());
     195               2 :     OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);
     196                 : 
     197                 :     osSQL.Printf("DELETE FROM \"%s_metadata\" WHERE %s",
     198               2 :                   osTableName.c_str(), osResolutionCond.c_str());
     199               2 :     OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);
     200                 :     
     201               2 :     OGRLayerH hRasterPyramidsLyr = OGR_DS_GetLayerByName(hDS, "raster_pyramids");
     202               2 :     if (hRasterPyramidsLyr)
     203                 :     {
     204                 :         osSQL.Printf("DELETE FROM raster_pyramids WHERE table_prefix = '%s' AND %s",
     205               2 :                       osTableName.c_str(), osResolutionCond.c_str());
     206               2 :         OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);
     207                 :     }
     208                 :     
     209               2 :     osSQL.Printf("COMMIT");
     210               2 :     OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);
     211                 :     
     212                 :     int i;
     213               6 :     for(i=1;i<nResolutions;i++)
     214               4 :         delete papoOverviews[i-1];
     215               2 :     CPLFree(papoOverviews);
     216               2 :     papoOverviews = NULL;
     217               2 :     nResolutions = 1;
     218                 :     
     219               2 :     return CE_None;
     220                 : }
     221                 : 
     222                 : /************************************************************************/
     223                 : /*                       CleanOverviewLevel()                           */
     224                 : /************************************************************************/
     225                 : 
     226               4 : CPLErr RasterliteDataset::CleanOverviewLevel(int nOvrFactor)
     227                 : {
     228               4 :     CPLString osSQL;
     229                 :     
     230               4 :     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               6 :     for(iLev=1;iLev<nResolutions;iLev++)
     238                 :     {
     239               2 :         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               4 :     if (iLev == nResolutions)
     245               4 :         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               4 : CPLErr RasterliteDataset::CreateOverviewLevel(int nOvrFactor,
     290                 :                                               GDALProgressFunc pfnProgress,
     291                 :                                               void * pProgressData)
     292                 : {
     293                 : 
     294               4 :     double dfXResolution = padfXResolutions[0] * nOvrFactor;
     295               4 :     double dfYResolution = padfXResolutions[0] * nOvrFactor;
     296                 :     
     297               4 :     CPLString osSQL;
     298                 : 
     299               4 :     int nBlockXSize = 256;
     300               4 :     int nBlockYSize = 256;
     301               4 :     int nOvrXSize = nRasterXSize / nOvrFactor;
     302               4 :     int nOvrYSize = nRasterYSize / nOvrFactor;
     303                 :     
     304               4 :     if (nOvrXSize == 0 || nOvrYSize == 0)
     305               0 :         return CE_Failure;
     306                 :     
     307               4 :     int nXBlocks = (nOvrXSize + nBlockXSize - 1) / nBlockXSize;
     308               4 :     int nYBlocks = (nOvrYSize + nBlockYSize - 1) / nBlockYSize;
     309                 :     
     310               4 :     const char* pszDriverName = "GTiff";
     311               4 :     GDALDriverH hTileDriver = GDALGetDriverByName(pszDriverName);
     312               4 :     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               4 :     GDALDriverH hMemDriver = GDALGetDriverByName("MEM");
     319               4 :     if (hMemDriver == NULL)
     320                 :     {
     321               0 :         CPLError(CE_Failure, CPLE_AppDefined, "Cannot load GDAL MEM driver");
     322               0 :         return CE_Failure;
     323                 :     }   
     324                 : 
     325               4 :     GDALDataType eDataType = GetRasterBand(1)->GetRasterDataType();
     326               4 :     int nDataTypeSize = GDALGetDataTypeSize(eDataType) / 8;
     327                 :     GByte* pabyMEMDSBuffer =
     328               4 :         (GByte*)VSIMalloc3(nBlockXSize, nBlockYSize, nBands * nDataTypeSize);
     329               4 :     if (pabyMEMDSBuffer == NULL)
     330                 :     {
     331               0 :         return CE_Failure;
     332                 :     }
     333                 :     
     334               4 :     char** papszTileDriverOptions = NULL;
     335                 :     
     336               4 :     CPLString osTempFileName;
     337               4 :     osTempFileName.Printf("/vsimem/%p", hDS);
     338                 :     
     339               4 :     int nTileId = 0;
     340               4 :     int nBlocks = 0;
     341               4 :     int nTotalBlocks = nXBlocks * nYBlocks;
     342                 :     
     343               4 :     CPLString osRasterLayer;
     344               4 :     osRasterLayer.Printf("%s_rasters", osTableName.c_str());
     345                 :     
     346               4 :     CPLString osMetatadataLayer;
     347               4 :     osMetatadataLayer.Printf("%s_metadata", osTableName.c_str());
     348                 :     
     349               4 :     OGRLayerH hRasterLayer = OGR_DS_GetLayerByName(hDS, osRasterLayer.c_str());
     350               4 :     OGRLayerH hMetadataLayer = OGR_DS_GetLayerByName(hDS, osMetatadataLayer.c_str());
     351                 :     
     352               4 :     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               8 :                  padfXResolutions[0] - 1e-15, padfXResolutions[0] + 1e-15,
     359              12 :                  padfYResolutions[0] - 1e-15, padfYResolutions[0] + 1e-15);
     360               4 :     OGRLayerH hSQLLyr = OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);
     361               4 :     if (hSQLLyr)
     362                 :     {
     363               4 :         OGRFeatureH hFeat = OGR_L_GetNextFeature(hSQLLyr);
     364               4 :         if (hFeat)
     365                 :         {
     366               4 :             const char* pszVal = OGR_F_GetFieldAsString(hFeat, 0);
     367               4 :             if (pszVal)
     368               4 :                 osSourceName = pszVal;
     369               4 :             OGR_F_Destroy(hFeat);
     370                 :         }
     371               4 :         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               4 :     nLimitOvrCount = 0;
     380               6 :     for(iLev=1;iLev<nResolutions;iLev++)
     381                 :     {
     382               4 :         if (!(padfXResolutions[iLev] < dfXResolution - 1e-10 &&
     383               2 :               padfYResolutions[iLev] < dfYResolution - 1e-10))
     384                 :         {
     385               0 :             break;
     386                 :         }
     387               2 :         nLimitOvrCount++;
     388                 :     }
     389                 :     
     390                 : /* -------------------------------------------------------------------- */
     391                 : /*      Iterate over blocks to add data into raster and metadata tables */
     392                 : /* -------------------------------------------------------------------- */
     393                 : 
     394               4 :     OGR_DS_ExecuteSQL(hDS, "BEGIN", NULL, NULL);
     395                 :     
     396               4 :     CPLErr eErr = CE_None;
     397                 :     int nBlockXOff, nBlockYOff;
     398               8 :     for(nBlockYOff=0;eErr == CE_None && nBlockYOff<nYBlocks;nBlockYOff++)
     399                 :     {
     400               8 :         for(nBlockXOff=0;eErr == CE_None && nBlockXOff<nXBlocks;nBlockXOff++)
     401                 :         {
     402                 : /* -------------------------------------------------------------------- */
     403                 : /*      Create in-memory tile                                           */
     404                 : /* -------------------------------------------------------------------- */
     405               4 :             int nReqXSize = nBlockXSize, nReqYSize = nBlockYSize;
     406               4 :             if ((nBlockXOff+1) * nBlockXSize > nOvrXSize)
     407               4 :                 nReqXSize = nOvrXSize - nBlockXOff * nBlockXSize;
     408               4 :             if ((nBlockYOff+1) * nBlockYSize > nOvrYSize)
     409               4 :                 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               4 :                             0, 0, 0);
     418               4 :             if (eErr != CE_None)
     419                 :             {
     420               0 :                 break;
     421                 :             }
     422                 :             
     423                 :             GDALDatasetH hMemDS = GDALCreate(hMemDriver, "MEM:::",
     424                 :                                               nReqXSize, nReqYSize, 0, 
     425               4 :                                               eDataType, NULL);
     426               4 :             if (hMemDS == NULL)
     427                 :             {
     428               0 :                 eErr = CE_Failure;
     429               0 :                 break;
     430                 :             }
     431                 :             
     432                 :             int iBand;
     433               8 :             for(iBand = 0; iBand < nBands; iBand ++)
     434                 :             {
     435               4 :                 char** papszOptions = NULL;
     436                 :                 char szTmp[64];
     437               4 :                 memset(szTmp, 0, sizeof(szTmp));
     438                 :                 CPLPrintPointer(szTmp,
     439                 :                                 pabyMEMDSBuffer + iBand * nDataTypeSize *
     440               4 :                                 nReqXSize * nReqYSize, sizeof(szTmp));
     441               4 :                 papszOptions = CSLSetNameValue(papszOptions, "DATAPOINTER", szTmp);
     442               4 :                 GDALAddBand(hMemDS, eDataType, papszOptions);
     443               4 :                 CSLDestroy(papszOptions);
     444                 :             }
     445                 :             
     446                 :             GDALDatasetH hOutDS = GDALCreateCopy(hTileDriver,
     447                 :                                         osTempFileName.c_str(), hMemDS, FALSE,
     448               4 :                                         papszTileDriverOptions, NULL, NULL);
     449                 : 
     450               4 :             GDALClose(hMemDS);
     451               4 :             if (hOutDS)
     452               4 :                 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               8 :                                                    &nDataLength, FALSE);
     466                 : 
     467               4 :             OGRFeatureH hFeat = OGR_F_Create( OGR_L_GetLayerDefn(hRasterLayer) );
     468               4 :             OGR_F_SetFieldBinary(hFeat, 0, (int)nDataLength, pabyData);
     469                 :             
     470               4 :             OGR_L_CreateFeature(hRasterLayer, hFeat);
     471                 :             /* Query raster ID to set it as the ID of the associated metadata */
     472               4 :             int nRasterID = (int)OGR_F_GetFID(hFeat);
     473                 :             
     474               4 :             OGR_F_Destroy(hFeat);
     475                 :             
     476               4 :             VSIUnlink(osTempFileName.c_str());
     477                 :             
     478                 : /* -------------------------------------------------------------------- */
     479                 : /*      Insert new entry into metadata table                            */
     480                 : /* -------------------------------------------------------------------- */
     481                 :             
     482               4 :             hFeat = OGR_F_Create( OGR_L_GetLayerDefn(hMetadataLayer) );
     483               4 :             OGR_F_SetFID(hFeat, nRasterID);
     484               4 :             OGR_F_SetFieldString(hFeat, 0, osSourceName);
     485               4 :             OGR_F_SetFieldInteger(hFeat, 1, nTileId ++);
     486               4 :             OGR_F_SetFieldInteger(hFeat, 2, nReqXSize);
     487               4 :             OGR_F_SetFieldInteger(hFeat, 3, nReqYSize);
     488               4 :             OGR_F_SetFieldDouble(hFeat, 4, dfXResolution);
     489               4 :             OGR_F_SetFieldDouble(hFeat, 5, dfYResolution);
     490                 :             
     491                 :             double minx, maxx, maxy, miny;
     492               4 :             minx = adfGeoTransform[0] +
     493               4 :                 (nBlockXSize * nBlockXOff) * dfXResolution;
     494               4 :             maxx = adfGeoTransform[0] +
     495               4 :                 (nBlockXSize * nBlockXOff + nReqXSize) * dfXResolution;
     496               4 :             maxy = adfGeoTransform[3] +
     497               4 :                 (nBlockYSize * nBlockYOff) * (-dfYResolution);
     498               4 :             miny = adfGeoTransform[3] +
     499               4 :                 (nBlockYSize * nBlockYOff + nReqYSize) * (-dfYResolution);
     500                 :             
     501               4 :             OGRGeometryH hRectangle = OGR_G_CreateGeometry(wkbPolygon);
     502               4 :             OGRGeometryH hLinearRing = OGR_G_CreateGeometry(wkbLinearRing);
     503               4 :             OGR_G_AddPoint_2D(hLinearRing, minx, miny);
     504               4 :             OGR_G_AddPoint_2D(hLinearRing, minx, maxy);
     505               4 :             OGR_G_AddPoint_2D(hLinearRing, maxx, maxy);
     506               4 :             OGR_G_AddPoint_2D(hLinearRing, maxx, miny);
     507               4 :             OGR_G_AddPoint_2D(hLinearRing, minx, miny);
     508               4 :             OGR_G_AddGeometryDirectly(hRectangle, hLinearRing);
     509                 :             
     510               4 :             OGR_F_SetGeometryDirectly(hFeat, hRectangle);
     511                 :             
     512               4 :             OGR_L_CreateFeature(hMetadataLayer, hFeat);
     513               4 :             OGR_F_Destroy(hFeat);
     514                 :             
     515               4 :             nBlocks++;
     516               4 :             if (pfnProgress && !pfnProgress(1.0 * nBlocks / nTotalBlocks,
     517                 :                                             NULL, pProgressData))
     518               0 :                 eErr = CE_Failure;
     519                 :         }
     520                 :     }
     521                 :     
     522               4 :     nLimitOvrCount = -1;
     523                 :     
     524               4 :     if (eErr == CE_None)
     525               4 :         OGR_DS_ExecuteSQL(hDS, "COMMIT", NULL, NULL);
     526                 :     else
     527               0 :         OGR_DS_ExecuteSQL(hDS, "ROLLBACK", NULL, NULL);
     528                 :     
     529               4 :     VSIFree(pabyMEMDSBuffer);
     530                 :     
     531                 : /* -------------------------------------------------------------------- */
     532                 : /*      Update raster_pyramids table                                    */
     533                 : /* -------------------------------------------------------------------- */
     534               4 :     if (eErr == CE_None)
     535                 :     {
     536               4 :         OGRLayerH hRasterPyramidsLyr = OGR_DS_GetLayerByName(hDS, "raster_pyramids");
     537               4 :         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               2 :                             "tile_count INTEGER NOT NULL)");
     544               2 :             OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);
     545                 :             
     546                 :             /* Re-open the DB to take into account the new tables*/
     547               2 :             OGRReleaseDataSource(hDS);
     548                 :             
     549               2 :             CPLString osOldVal = CPLGetConfigOption("SQLITE_LIST_ALL_TABLES", "FALSE");
     550               2 :             CPLSetThreadLocalConfigOption("SQLITE_LIST_ALL_TABLES", "TRUE");
     551               2 :             hDS = OGROpen(osFileName.c_str(), TRUE, NULL);
     552               2 :             CPLSetThreadLocalConfigOption("SQLITE_LIST_ALL_TABLES", osOldVal.c_str());
     553                 :         }
     554                 : 
     555                 :         /* Insert base resolution into raster_pyramids if not already done */
     556               4 :         int bHasBaseResolution = FALSE;
     557                 :         osSQL.Printf("SELECT * FROM raster_pyramids WHERE "
     558                 :                      "table_prefix = '%s' AND pixel_x_size >= %.15f AND pixel_x_size <= %.15f AND "
     559                 :                      "pixel_y_size >= %.15f AND pixel_y_size <= %.15f",
     560                 :                      osTableName.c_str(),
     561               8 :                      padfXResolutions[0] - 1e-15, padfXResolutions[0] + 1e-15,
     562              12 :                      padfYResolutions[0] - 1e-15, padfYResolutions[0] + 1e-15);
     563               4 :         hSQLLyr = OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);
     564               4 :         if (hSQLLyr)
     565                 :         {
     566               2 :             OGRFeatureH hFeat = OGR_L_GetNextFeature(hSQLLyr);
     567               2 :             if (hFeat)
     568                 :             {
     569               2 :                 bHasBaseResolution = TRUE;
     570               2 :                 OGR_F_Destroy(hFeat);
     571                 :             }
     572               2 :             OGR_DS_ReleaseResultSet(hDS, hSQLLyr);
     573                 :         }
     574                 : 
     575               4 :         if (!bHasBaseResolution)
     576                 :         {
     577                 :             osSQL.Printf("SELECT COUNT(*) FROM \"%s\" WHERE "
     578                 :                           "pixel_x_size >= %.15f AND pixel_x_size <= %.15f AND "
     579                 :                           "pixel_y_size >= %.15f AND pixel_y_size <= %.15f",
     580                 :                           osMetatadataLayer.c_str(),
     581               4 :                           padfXResolutions[0] - 1e-15, padfXResolutions[0] + 1e-15,
     582               6 :                           padfYResolutions[0] - 1e-15, padfYResolutions[0] + 1e-15);
     583                 : 
     584               2 :             int nBlocksMainRes = 0;
     585                 : 
     586               2 :             hSQLLyr = OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);
     587               2 :             if (hSQLLyr)
     588                 :             {
     589               2 :                 OGRFeatureH hFeat = OGR_L_GetNextFeature(hSQLLyr);
     590               2 :                 if (hFeat)
     591                 :                 {
     592               2 :                     nBlocksMainRes = OGR_F_GetFieldAsInteger(hFeat, 0);
     593               2 :                     OGR_F_Destroy(hFeat);
     594                 :                 }
     595               2 :                 OGR_DS_ReleaseResultSet(hDS, hSQLLyr);
     596                 :             }
     597                 : 
     598                 :             osSQL.Printf("INSERT INTO raster_pyramids "
     599                 :                          "( table_prefix, pixel_x_size, pixel_y_size, tile_count ) "
     600                 :                          "VALUES ( '%s', %.18f, %.18f, %d )",
     601                 :                          osTableName.c_str(), padfXResolutions[0], padfYResolutions[0],
     602               2 :                          nBlocksMainRes);
     603               2 :             OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);
     604                 :         }
     605                 : 
     606                 :         osSQL.Printf("INSERT INTO raster_pyramids "
     607                 :                      "( table_prefix, pixel_x_size, pixel_y_size, tile_count ) "
     608                 :                      "VALUES ( '%s', %.18f, %.18f, %d )",
     609                 :                      osTableName.c_str(), dfXResolution, dfYResolution,
     610               4 :                      nTotalBlocks);
     611               4 :         OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);
     612                 :     }
     613                 : 
     614               4 :     return eErr;
     615                 : }
     616                 : 
     617                 : /************************************************************************/
     618                 : /*                          IBuildOverviews()                           */
     619                 : /************************************************************************/
     620                 : 
     621               4 : CPLErr RasterliteDataset::IBuildOverviews( const char * pszResampling, 
     622                 :                                            int nOverviews, int * panOverviewList,
     623                 :                                            int nBands, int * panBandList,
     624                 :                                            GDALProgressFunc pfnProgress,
     625                 :                                            void * pProgressData )
     626                 : {
     627               4 :     CPLErr eErr = CE_None;
     628                 :     
     629               4 :     if (nLevel != 0)
     630                 :     {
     631                 :         CPLError(CE_Failure, CPLE_AppDefined,
     632               0 :                  "Overviews can only be computed on the base dataset");
     633               0 :         return CE_Failure;
     634                 :     }
     635                 :         
     636               4 :     if (osTableName.size() == 0)
     637               0 :         return CE_Failure;
     638                 :     
     639                 : /* -------------------------------------------------------------------- */
     640                 : /*      If we don't have read access, then create the overviews         */
     641                 : /*      externally.                                                     */
     642                 : /* -------------------------------------------------------------------- */
     643               4 :     if( GetAccess() != GA_Update )
     644                 :     {
     645                 :         CPLDebug( "Rasterlite",
     646                 :                   "File open for read-only accessing, "
     647               0 :                   "creating overviews externally." );
     648                 :                   
     649               0 :         if (nResolutions != 1)
     650                 :         {
     651                 :             CPLError(CE_Failure, CPLE_NotSupported,
     652                 :                      "Cannot add external overviews to a "
     653               0 :                      "dataset with internal overviews");
     654               0 :             return CE_Failure;
     655                 :         }
     656                 : 
     657               0 :         bCheckForExistingOverview = FALSE;
     658                 :         eErr = GDALDataset::IBuildOverviews( 
     659                 :                             pszResampling, nOverviews, panOverviewList, 
     660               0 :                             nBands, panBandList, pfnProgress, pProgressData );
     661               0 :         bCheckForExistingOverview = TRUE;
     662               0 :         return eErr;
     663                 :     }
     664                 :     
     665                 : /* -------------------------------------------------------------------- */
     666                 : /*      If zero overviews were requested, we need to clear all          */
     667                 : /*      existing overviews.                                             */
     668                 : /* -------------------------------------------------------------------- */
     669               4 :     if (nOverviews == 0)
     670                 :     {
     671               2 :         return CleanOverviews();
     672                 :     }
     673                 :     
     674               2 :     if( nBands != GetRasterCount() )
     675                 :     {
     676                 :         CPLError( CE_Failure, CPLE_NotSupported,
     677                 :                   "Generation of overviews in RASTERLITE only"
     678                 :                   " supported when operating on all bands.\n" 
     679               0 :                   "Operation failed.\n" );
     680               0 :         return CE_Failure;
     681                 :     }
     682                 :     
     683               2 :     if( !EQUALN(pszResampling, "NEAR", 4))
     684                 :     {
     685                 :         CPLError( CE_Failure, CPLE_NotSupported,
     686                 :                   "Only NEAREST resampling is allowed for now "
     687               0 :                   "for RASTERLITE overviews");
     688               0 :         return CE_Failure;
     689                 :     }
     690                 :     
     691                 :     int i;
     692               6 :     for(i=0;i<nOverviews && eErr == CE_None;i++)
     693                 :     {
     694               4 :         if (panOverviewList[i] <= 1)
     695               0 :             continue;
     696                 : 
     697               4 :         eErr = CleanOverviewLevel(panOverviewList[i]);
     698               4 :         if (eErr == CE_None)
     699               4 :             eErr = CreateOverviewLevel(panOverviewList[i], pfnProgress, pProgressData);
     700                 :     
     701               4 :         ReloadOverviews();
     702                 :     }
     703                 :     
     704               2 :     return eErr;
     705                 : }

Generated by: LCOV version 1.7