LTP GCOV extension - code coverage report
Current view: directory - frmts/rasterlite - rasterlitecreatecopy.cpp
Test: gdal_filtered.info
Date: 2010-07-12 Instrumented lines: 306
Code covered: 72.9 % Executed lines: 223

       1                 : /******************************************************************************
       2                 :  * $Id: rasterlitecreatecopy.cpp 18603 2010-01-19 23:10:31Z 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: rasterlitecreatecopy.cpp 18603 2010-01-19 23:10:31Z rouault $");
      37                 : 
      38                 : /************************************************************************/
      39                 : /*                  RasterliteGetTileDriverOptions ()                   */
      40                 : /************************************************************************/
      41                 : 
      42                 : static char** RasterliteAddTileDriverOptionsForDriver(char** papszOptions,
      43                 :                                                     char** papszTileDriverOptions,
      44                 :                                                     const char* pszOptionName,
      45              72 :                                                     const char* pszExpectedDriverName)

      46                 : {
      47              72 :     const char* pszVal = CSLFetchNameValue(papszOptions, pszOptionName);

      48              72 :     if (pszVal)

      49                 :     {
      50                 :         const char* pszDriverName =
      51               0 :             CSLFetchNameValueDef(papszOptions, "DRIVER", "GTiff");

      52               0 :         if (EQUAL(pszDriverName, pszExpectedDriverName))

      53                 :         {
      54                 :             papszTileDriverOptions =
      55               0 :                 CSLSetNameValue(papszTileDriverOptions, pszOptionName, pszVal);

      56                 :         }
      57                 :         else
      58                 :         {
      59                 :             CPLError(CE_Warning, CPLE_NotSupported,
      60                 :                      "Unexpected option '%s' for driver '%s'",
      61               0 :                      pszOptionName, pszDriverName);

      62                 :         }
      63                 :     }
      64              72 :     return papszTileDriverOptions;

      65                 : }
      66                 : 
      67              18 : static char** RasterliteGetTileDriverOptions(char** papszOptions)

      68                 : {
      69              18 :     char** papszTileDriverOptions = NULL;

      70                 : 
      71                 :     const char* pszDriverName =
      72              18 :         CSLFetchNameValueDef(papszOptions, "DRIVER", "GTiff");

      73                 :         
      74              18 :     if (EQUAL(pszDriverName, "EPSILON"))

      75                 :     {
      76                 :         papszTileDriverOptions = CSLSetNameValue(papszTileDriverOptions,
      77               2 :                                                 "RASTERLITE_OUTPUT", "YES");

      78                 :     }
      79                 :     
      80              18 :     const char* pszQuality = CSLFetchNameValue(papszOptions, "QUALITY");

      81              18 :     if (pszQuality)

      82                 :     {
      83               0 :         if (EQUAL(pszDriverName, "GTiff"))

      84                 :         {
      85                 :             papszTileDriverOptions =
      86               0 :                 CSLSetNameValue(papszTileDriverOptions, "JPEG_QUALITY", pszQuality);

      87                 :         }
      88               0 :         else if (EQUAL(pszDriverName, "JPEG"))

      89                 :         {
      90                 :             papszTileDriverOptions =
      91               0 :                 CSLSetNameValue(papszTileDriverOptions, "QUALITY", pszQuality);

      92                 :         }
      93                 :         else
      94                 :         {
      95                 :             CPLError(CE_Warning, CPLE_NotSupported,
      96                 :                      "Unexpected option '%s' for driver '%s'",
      97               0 :                      "QUALITY", pszDriverName);

      98                 :         }
      99                 :     }
     100                 :     
     101                 :     papszTileDriverOptions = RasterliteAddTileDriverOptionsForDriver(
     102              18 :                 papszOptions, papszTileDriverOptions, "COMPRESS", "GTiff");

     103                 :     papszTileDriverOptions = RasterliteAddTileDriverOptionsForDriver(
     104              18 :                 papszOptions, papszTileDriverOptions, "PHOTOMETRIC", "GTiff");

     105                 :     papszTileDriverOptions = RasterliteAddTileDriverOptionsForDriver(
     106              18 :                 papszOptions, papszTileDriverOptions, "TARGET", "EPSILON");

     107                 :     papszTileDriverOptions = RasterliteAddTileDriverOptionsForDriver(
     108              18 :                 papszOptions, papszTileDriverOptions, "FILTER", "EPSILON");

     109                 :     
     110              18 :     return papszTileDriverOptions;

     111                 : }
     112                 : 
     113                 : /************************************************************************/
     114                 : /*                      RasterliteInsertSRID ()                         */
     115                 : /************************************************************************/
     116                 : 
     117              18 : static int RasterliteInsertSRID(OGRDataSourceH hDS, const char* pszWKT)

     118                 : {
     119              18 :     CPLString osSQL;

     120                 :     
     121              18 :     int nAuthorityCode = 0;

     122              18 :     CPLString osAuthorityName, osProjCS, osProj4;

     123              18 :     if (pszWKT != NULL && strlen(pszWKT) != 0)

     124                 :     {
     125              18 :         OGRSpatialReferenceH hSRS = OSRNewSpatialReference(pszWKT);

     126              18 :         if (hSRS)

     127                 :         {
     128              18 :             const char* pszAuthorityName = OSRGetAuthorityName(hSRS, NULL);

     129              18 :             if (pszAuthorityName) osAuthorityName = pszAuthorityName;

     130                 :             
     131              18 :             const char* pszProjCS = OSRGetAttrValue(hSRS, "PROJCS", 0);

     132              18 :             if (pszProjCS) osProjCS = pszProjCS;

     133                 :             
     134              18 :             const char* pszAuthorityCode = OSRGetAuthorityCode(hSRS, NULL);

     135              18 :             if (pszAuthorityCode) nAuthorityCode = atoi(pszAuthorityCode);

     136                 :             
     137              18 :             char    *pszProj4 = NULL;

     138              18 :             if( OSRExportToProj4( hSRS, &pszProj4 ) != OGRERR_NONE )

     139               0 :                 pszProj4 = CPLStrdup("");

     140              18 :             osProj4 = pszProj4;

     141              18 :             CPLFree(pszProj4);

     142                 :         }
     143              18 :         OSRDestroySpatialReference(hSRS);

     144                 :     }
     145                 :         
     146              18 :     int nSRSId = -1;

     147              18 :     if (nAuthorityCode != 0 && osAuthorityName.size() != 0)

     148                 :     {
     149              18 :         osSQL.Printf   ("SELECT srid FROM spatial_ref_sys WHERE auth_srid = %d", nAuthorityCode);

     150              18 :         OGRLayerH hLyr = OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);

     151              18 :         if (hLyr == NULL)

     152                 :         {
     153              18 :             nSRSId = nAuthorityCode;

     154                 :             
     155              18 :             if ( osProjCS.size() != 0 )

     156                 :                 osSQL.Printf(
     157                 :                     "INSERT INTO spatial_ref_sys "
     158                 :                     "(srid, auth_name, auth_srid, ref_sys_name, proj4text) "
     159                 :                     "VALUES (%d, '%s', '%d', '%s', '%s')",
     160                 :                     nSRSId, osAuthorityName.c_str(),
     161               2 :                     nAuthorityCode, osProjCS.c_str(), osProj4.c_str() );

     162                 :             else
     163                 :                 osSQL.Printf(
     164                 :                     "INSERT INTO spatial_ref_sys "
     165                 :                     "(srid, auth_name, auth_srid, proj4text) "
     166                 :                     "VALUES (%d, '%s', '%d', '%s')",
     167                 :                     nSRSId, osAuthorityName.c_str(),
     168              16 :                     nAuthorityCode, osProj4.c_str() );

     169                 : 
     170                 :             
     171              18 :             OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);

     172                 :         }
     173                 :         else
     174                 :         {
     175               0 :             OGRFeatureH hFeat = OGR_L_GetNextFeature(hLyr);

     176               0 :             if (hFeat)

     177                 :             {
     178               0 :                 nSRSId = OGR_F_GetFieldAsInteger(hFeat, 0);

     179               0 :                 OGR_F_Destroy(hFeat);

     180                 :             }
     181               0 :             OGR_DS_ReleaseResultSet(hDS, hLyr);

     182                 :         }
     183                 :     }
     184                 :     
     185              18 :     return nSRSId;

     186                 : }
     187                 : 
     188                 : /************************************************************************/
     189                 : /*                     RasterliteCreateTables ()                        */
     190                 : /************************************************************************/
     191                 : 
     192                 : OGRDataSourceH RasterliteCreateTables(OGRDataSourceH hDS, const char* pszTableName,
     193              18 :                                       int nSRSId, int bWipeExistingData)

     194                 : {
     195              18 :     CPLString osSQL;

     196                 :     
     197              18 :     CPLString osOldVal = CPLGetConfigOption("SQLITE_LIST_ALL_TABLES", "FALSE");

     198              18 :     CPLString osDBName = OGR_DS_GetName(hDS);

     199                 :     
     200              18 :     CPLString osRasterLayer;

     201              18 :     osRasterLayer.Printf("%s_rasters", pszTableName);

     202                 :     
     203              18 :     CPLString osMetatadataLayer;

     204              18 :     osMetatadataLayer.Printf("%s_metadata", pszTableName);

     205                 : 
     206                 :     OGRLayerH hLyr;
     207                 : 
     208              18 :     if (OGR_DS_GetLayerByName(hDS, osRasterLayer.c_str()) == NULL)

     209                 :     {
     210                 : /* -------------------------------------------------------------------- */
     211                 : /*      The table don't exist. Create them                              */
     212                 : /* -------------------------------------------------------------------- */
     213                 : 
     214                 :         /* Create _rasters table */
     215                 :         osSQL.Printf   ("CREATE TABLE \"%s\" ("
     216                 :                         "id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,"
     217              18 :                         "raster BLOB NOT NULL)", osRasterLayer.c_str());

     218              18 :         OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);

     219                 :             
     220                 :         /* Create _metadata table */
     221                 :         osSQL.Printf   ("CREATE TABLE \"%s\" ("
     222                 :                         "id INTEGER NOT NULL PRIMARY KEY,"
     223                 :                         "source_name TEXT NOT NULL,"
     224                 :                         "tile_id INTEGER NOT NULL,"
     225                 :                         "width INTEGER NOT NULL,"
     226                 :                         "height INTEGER NOT NULL,"
     227                 :                         "pixel_x_size DOUBLE NOT NULL,"
     228                 :                         "pixel_y_size DOUBLE NOT NULL)",
     229              18 :                         osMetatadataLayer.c_str());

     230              18 :         OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);

     231                 : 
     232                 :         /* Add geometry column to _metadata table */
     233                 :         osSQL.Printf("SELECT AddGeometryColumn('%s', 'geometry', %d, 'POLYGON', 2)",
     234              18 :                       osMetatadataLayer.c_str(), nSRSId);

     235              18 :         if ((hLyr = OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL)) == NULL)

     236                 :         {
     237                 :             CPLError(CE_Failure, CPLE_AppDefined,
     238               0 :                      "Check that the OGR SQLite driver has Spatialite support");

     239               0 :             OGRReleaseDataSource(hDS);

     240               0 :             return NULL;

     241                 :         }
     242              18 :         OGR_DS_ReleaseResultSet(hDS, hLyr);

     243                 :                 
     244                 :         /* Create spatial index on _metadata table */
     245                 :         osSQL.Printf("SELECT CreateSpatialIndex('%s', 'geometry')",
     246              18 :                       osMetatadataLayer.c_str());

     247              18 :         if ((hLyr = OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL)) == NULL)

     248                 :         {
     249               0 :             OGRReleaseDataSource(hDS);

     250               0 :             return NULL;

     251                 :         }
     252              18 :         OGR_DS_ReleaseResultSet(hDS, hLyr);

     253                 :         
     254                 :         /* Re-open the DB to take into account the new tables*/
     255              18 :         OGRReleaseDataSource(hDS);

     256                 :         
     257              18 :         CPLSetConfigOption("SQLITE_LIST_ALL_TABLES", "TRUE");

     258              18 :         hDS = OGROpen(osDBName.c_str(), TRUE, NULL);

     259              18 :         CPLSetConfigOption("SQLITE_LIST_ALL_TABLES", osOldVal.c_str());

     260                 :     }
     261                 :     else
     262                 :     {
     263                 :         /* Check that the existing SRS is consistent with the one of the new */
     264                 :         /* data to be inserted */
     265                 :         osSQL.Printf("SELECT srid FROM geometry_columns WHERE f_table_name = '%s'",
     266               0 :                      osMetatadataLayer.c_str());

     267               0 :         hLyr = OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);

     268               0 :         if (hLyr)

     269                 :         {
     270               0 :             int nExistingSRID = -1;

     271               0 :             OGRFeatureH hFeat = OGR_L_GetNextFeature(hLyr);

     272               0 :             if (hFeat)

     273                 :             {
     274               0 :                 nExistingSRID = OGR_F_GetFieldAsInteger(hFeat, 0);

     275               0 :                 OGR_F_Destroy(hFeat);

     276                 :             }
     277               0 :             OGR_DS_ReleaseResultSet(hDS, hLyr);

     278                 : 
     279               0 :             if (nExistingSRID != nSRSId)

     280                 :             {
     281               0 :                 if (bWipeExistingData)

     282                 :                 {
     283                 :                     osSQL.Printf("UPDATE geometry_columns SET srid = %d "
     284                 :                                  "WHERE f_table_name = \"%s\"",
     285               0 :                                  nSRSId, osMetatadataLayer.c_str());

     286               0 :                     OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);

     287                 :         
     288                 :                     /* Re-open the DB to take into account the change of SRS */
     289               0 :                     OGRReleaseDataSource(hDS);

     290                 :                     
     291               0 :                     CPLSetConfigOption("SQLITE_LIST_ALL_TABLES", "TRUE");

     292               0 :                     hDS = OGROpen(osDBName.c_str(), TRUE, NULL);

     293               0 :                     CPLSetConfigOption("SQLITE_LIST_ALL_TABLES", osOldVal.c_str());

     294                 :                 }
     295                 :                 else
     296                 :                 {
     297                 :                     CPLError(CE_Failure, CPLE_NotSupported,
     298               0 :                              "New data has not the same SRS as existing data");

     299               0 :                     OGRReleaseDataSource(hDS);

     300               0 :                     return NULL;

     301                 :                 }
     302                 :             }            
     303                 :         }
     304                 :         
     305               0 :         if (bWipeExistingData)

     306                 :         {
     307               0 :             osSQL.Printf("DELETE FROM \"%s\"", osRasterLayer.c_str());

     308               0 :             OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);

     309                 :             
     310               0 :             osSQL.Printf("DELETE FROM \"%s\"", osMetatadataLayer.c_str());

     311               0 :             OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);

     312                 :         }
     313                 :     }
     314                 : 
     315              18 :     return hDS;

     316                 : }
     317                 : 
     318                 : /************************************************************************/
     319                 : /*                       RasterliteCreateCopy ()                        */
     320                 : /************************************************************************/
     321                 : 
     322                 : GDALDataset *
     323                 : RasterliteCreateCopy( const char * pszFilename, GDALDataset *poSrcDS, 
     324                 :                        int bStrict, char ** papszOptions, 
     325              19 :                        GDALProgressFunc pfnProgress, void * pProgressData )

     326                 : {
     327              19 :     int nBands = poSrcDS->GetRasterCount();

     328              19 :     if (nBands == 0)

     329                 :     {
     330               1 :         CPLError(CE_Failure, CPLE_NotSupported, "nBands == 0");

     331               1 :         return NULL;

     332                 :     }
     333                 :     
     334              18 :     const char* pszDriverName = CSLFetchNameValueDef(papszOptions, "DRIVER", "GTiff");

     335              18 :     GDALDriverH hTileDriver = GDALGetDriverByName(pszDriverName);

     336              18 :     if ( hTileDriver == NULL)

     337                 :     {
     338               0 :         CPLError(CE_Failure, CPLE_AppDefined, "Cannot load GDAL %s driver", pszDriverName);

     339               0 :         return NULL;

     340                 :     }
     341                 :     
     342              18 :     GDALDriverH hMemDriver = GDALGetDriverByName("MEM");

     343              18 :     if (hMemDriver == NULL)

     344                 :     {
     345               0 :         CPLError(CE_Failure, CPLE_AppDefined, "Cannot load GDAL MEM driver");

     346               0 :         return NULL;

     347                 :     }   
     348                 : 
     349              18 :     int nXSize = GDALGetRasterXSize(poSrcDS);

     350              18 :     int nYSize = GDALGetRasterYSize(poSrcDS);

     351                 :     
     352                 :     double adfGeoTransform[6];
     353              18 :     if (poSrcDS->GetGeoTransform(adfGeoTransform) != CE_None)

     354                 :     {
     355               0 :         adfGeoTransform[0] = 0;

     356               0 :         adfGeoTransform[1] = 1;

     357               0 :         adfGeoTransform[2] = 0;

     358               0 :         adfGeoTransform[3] = 0;

     359               0 :         adfGeoTransform[4] = 0;

     360               0 :         adfGeoTransform[5] = -1;

     361                 :     }
     362              18 :     else if (adfGeoTransform[2] != 0.0 || adfGeoTransform[4] != 0.0)

     363                 :     {
     364               0 :         CPLError(CE_Failure, CPLE_AppDefined, "Cannot use geotransform with rotational terms");

     365               0 :         return NULL;

     366                 :     }
     367                 : 
     368              18 :     int bTiled = CSLTestBoolean(CSLFetchNameValueDef(papszOptions, "TILED", "YES"));

     369                 :     int nBlockXSize, nBlockYSize;
     370              18 :     if (bTiled)

     371                 :     {
     372              18 :         nBlockXSize = atoi(CSLFetchNameValueDef(papszOptions, "BLOCKXSIZE", "256"));

     373              18 :         nBlockYSize = atoi(CSLFetchNameValueDef(papszOptions, "BLOCKYSIZE", "256"));

     374              18 :         if (nBlockXSize < 64) nBlockXSize = 64;

     375              18 :         else if (nBlockXSize > 4096)  nBlockXSize = 4096;

     376              18 :         if (nBlockYSize < 64) nBlockYSize = 64;

     377              18 :         else if (nBlockYSize > 4096)  nBlockYSize = 4096;

     378                 :     }
     379                 :     else
     380                 :     {
     381               0 :         nBlockXSize = nXSize;

     382               0 :         nBlockYSize = nYSize;

     383                 :     }
     384                 :     
     385                 : /* -------------------------------------------------------------------- */
     386                 : /*      Analyze arguments                                               */
     387                 : /* -------------------------------------------------------------------- */
     388                 :     
     389              18 :     CPLString osDBName;

     390              18 :     CPLString osTableName;

     391                 :     VSIStatBuf sBuf;
     392                 :     int bExists;
     393                 : 
     394                 :     /* Skip optionnal RASTERLITE: prefix */
     395              18 :     const char* pszFilenameWithoutPrefix = pszFilename;

     396              18 :     if (EQUALN(pszFilename, "RASTERLITE:", 11))

     397               1 :         pszFilenameWithoutPrefix += 11;

     398                 :     
     399                 :     char** papszTokens = CSLTokenizeStringComplex( 
     400              18 :                 pszFilenameWithoutPrefix, ", ", FALSE, FALSE );

     401              18 :     int nTokens = CSLCount(papszTokens);

     402              18 :     if (nTokens == 0)

     403                 :     {
     404               0 :         osDBName = pszFilenameWithoutPrefix;

     405               0 :         osTableName = CPLGetBasename(pszFilenameWithoutPrefix);

     406                 :     }
     407                 :     else
     408                 :     {
     409              18 :         osDBName = papszTokens[0];

     410                 :         
     411                 :         int i;
     412              19 :         for(i=1;i<nTokens;i++)

     413                 :         {
     414               1 :             if (EQUALN(papszTokens[i], "table=", 6))

     415               1 :                 osTableName = papszTokens[i] + 6;

     416                 :             else
     417                 :             {
     418                 :                 CPLError(CE_Warning, CPLE_AppDefined,
     419               0 :                          "Invalid option : %s", papszTokens[i]);

     420                 :             }
     421                 :         }
     422                 :     }
     423                 :     
     424              18 :     CSLDestroy(papszTokens);

     425              18 :     papszTokens = NULL;

     426                 :     
     427              18 :     bExists = (VSIStat(osDBName.c_str(), &sBuf) == 0);

     428                 : 
     429              18 :     if (osTableName.size() == 0)

     430                 :     {
     431              17 :         if (bExists)

     432                 :         {
     433                 :             CPLError(CE_Failure, CPLE_AppDefined,
     434               0 :                      "Database already exists. Explicit table name must be specified");

     435              18 :             return NULL;

     436                 :         }
     437              17 :         osTableName = CPLGetBasename(osDBName.c_str());

     438                 :     }    
     439                 :     
     440              18 :     CPLString osRasterLayer;

     441              18 :     osRasterLayer.Printf("%s_rasters", osTableName.c_str());

     442                 :     
     443              18 :     CPLString osMetatadataLayer;

     444              18 :     osMetatadataLayer.Printf("%s_metadata", osTableName.c_str());

     445                 : 
     446                 : /* -------------------------------------------------------------------- */
     447                 : /*      Create or open the SQLite DB                                    */
     448                 : /* -------------------------------------------------------------------- */
     449                 :     
     450              18 :     if (OGRGetDriverCount() == 0)

     451               0 :         OGRRegisterAll();

     452                 :         
     453              18 :     OGRSFDriverH hSQLiteDriver = OGRGetDriverByName("SQLite");

     454              18 :     if (hSQLiteDriver == NULL)

     455                 :     {
     456               0 :         CPLError(CE_Failure, CPLE_AppDefined, "Cannot load OGR SQLite driver");

     457               0 :         return NULL;

     458                 :     }   
     459                 :     
     460                 :     OGRDataSourceH hDS;
     461                 :     
     462                 :     CPLString osOldVal =
     463              18 :         CPLGetConfigOption("SQLITE_LIST_ALL_TABLES", "FALSE");

     464              18 :     CPLSetConfigOption("SQLITE_LIST_ALL_TABLES", "TRUE");

     465              18 :     if (!bExists)

     466                 :     {
     467              18 :         char** papszOGROptions = CSLAddString(NULL, "SPATIALITE=YES");

     468                 :         hDS = OGR_Dr_CreateDataSource(hSQLiteDriver,
     469              18 :                                       osDBName.c_str(), papszOGROptions);

     470              18 :         CSLDestroy(papszOGROptions);

     471                 :     }
     472                 :     else
     473                 :     {
     474               0 :         hDS = OGROpen(osDBName.c_str(), TRUE, NULL);

     475                 :     }
     476              18 :     CPLSetConfigOption("SQLITE_LIST_ALL_TABLES", osOldVal.c_str());

     477                 :     
     478              18 :     if (hDS == NULL)

     479                 :     {
     480                 :         CPLError(CE_Failure, CPLE_AppDefined,
     481               0 :                  "Cannot load or create SQLite database");

     482               0 :         return NULL;

     483                 :     }
     484                 : 
     485              18 :     CPLString osSQL;

     486                 :     
     487                 : /* -------------------------------------------------------------------- */
     488                 : /*      Get the SRID for the SRS                                        */
     489                 : /* -------------------------------------------------------------------- */
     490              18 :     int nSRSId = RasterliteInsertSRID(hDS, poSrcDS->GetProjectionRef());

     491                 : 
     492                 : /* -------------------------------------------------------------------- */
     493                 : /*      Create or wipe existing tables                                  */
     494                 : /* -------------------------------------------------------------------- */
     495                 :     int bWipeExistingData =
     496              18 :         CSLTestBoolean(CSLFetchNameValueDef(papszOptions, "WIPE", "NO"));

     497                 :         
     498                 :     hDS = RasterliteCreateTables(hDS, osTableName.c_str(),
     499              18 :                                  nSRSId, bWipeExistingData);

     500              18 :     if (hDS == NULL)

     501               0 :         return NULL;

     502                 : 
     503              18 :     OGRLayerH hRasterLayer = OGR_DS_GetLayerByName(hDS, osRasterLayer.c_str());

     504              18 :     OGRLayerH hMetadataLayer = OGR_DS_GetLayerByName(hDS, osMetatadataLayer.c_str());

     505              18 :     if (hRasterLayer == NULL || hMetadataLayer == NULL)

     506                 :     {
     507                 :         CPLError(CE_Failure, CPLE_AppDefined,
     508               0 :                  "Cannot find metadata and/or raster tables");

     509               0 :         OGRReleaseDataSource(hDS);

     510               0 :         return NULL;

     511                 :     }
     512                 : 
     513                 : /* -------------------------------------------------------------------- */
     514                 : /*      Check if there is overlapping data and warn the user            */
     515                 : /* -------------------------------------------------------------------- */
     516              18 :     double minx = adfGeoTransform[0];

     517              18 :     double maxx = adfGeoTransform[0] + nXSize * adfGeoTransform[1];

     518              18 :     double maxy = adfGeoTransform[3];

     519              18 :     double miny = adfGeoTransform[3] + nYSize * adfGeoTransform[5];

     520                 :     
     521                 :     osSQL.Printf("SELECT COUNT(geometry) FROM \"%s\" "
     522                 :                  "WHERE rowid IN "
     523                 :                  "(SELECT pkid FROM \"idx_%s_metadata_geometry\" "
     524                 :                   "WHERE xmin < %.15f AND xmax > %.15f "
     525                 :                   "AND ymin < %.15f  AND ymax > %.15f) "
     526                 :                  "AND pixel_x_size >= %.15f AND pixel_x_size <= %.15f AND "
     527                 :                  "pixel_y_size >= %.15f AND pixel_y_size <= %.15f",
     528                 :                   osMetatadataLayer.c_str(),
     529                 :                   osTableName.c_str(),
     530                 :                   maxx, minx, maxy, miny,
     531                 :                   adfGeoTransform[1] - 1e-15, adfGeoTransform[1] + 1e-15,
     532              18 :                   - adfGeoTransform[5] - 1e-15, - adfGeoTransform[5] + 1e-15);

     533                 :     
     534              18 :     int nOverlappingGeoms = 0;

     535              18 :     OGRLayerH hCountLyr = OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);

     536              18 :     if (hCountLyr)

     537                 :     {
     538              18 :         OGRFeatureH hFeat = OGR_L_GetNextFeature(hCountLyr);

     539              18 :         if (hFeat)

     540                 :         {
     541              18 :             nOverlappingGeoms = OGR_F_GetFieldAsInteger(hFeat, 0);

     542              18 :             OGR_F_Destroy(hFeat);

     543                 :         }
     544              18 :         OGR_DS_ReleaseResultSet(hDS, hCountLyr);

     545                 :     }
     546                 :     
     547              18 :     if (nOverlappingGeoms != 0)

     548                 :     {
     549                 :         CPLError(CE_Warning, CPLE_AppDefined,
     550                 :                  "Raster tiles already exist in the %s table within "
     551                 :                  "the extent of the data to be inserted in",
     552               0 :                  osTableName.c_str());

     553                 :     }
     554                 :    
     555                 : /* -------------------------------------------------------------------- */
     556                 : /*      Iterate over blocks to add data into raster and metadata tables */
     557                 : /* -------------------------------------------------------------------- */
     558              18 :     int nXBlocks = (nXSize + nBlockXSize - 1) / nBlockXSize;

     559              18 :     int nYBlocks = (nYSize + nBlockYSize - 1) / nBlockYSize;

     560                 : 
     561              18 :     GDALDataType eDataType = poSrcDS->GetRasterBand(1)->GetRasterDataType();

     562              18 :     int nDataTypeSize = GDALGetDataTypeSize(eDataType) / 8;

     563                 :     GByte* pabyMEMDSBuffer =
     564              18 :         (GByte*)VSIMalloc3(nBlockXSize, nBlockYSize, nBands * nDataTypeSize);

     565              18 :     if (pabyMEMDSBuffer == NULL)

     566                 :     {
     567               0 :         OGRReleaseDataSource(hDS);

     568               0 :         return NULL;

     569                 :     }
     570                 :     
     571              18 :     CPLString osTempFileName;

     572              18 :     osTempFileName.Printf("/vsimem/%p", hDS);

     573                 :     
     574              18 :     int nTileId = 0;

     575              18 :     int nBlocks = 0;

     576              18 :     int nTotalBlocks = nXBlocks * nYBlocks;

     577                 : 
     578              18 :     char** papszTileDriverOptions = RasterliteGetTileDriverOptions(papszOptions);

     579                 :     
     580              18 :     OGR_DS_ExecuteSQL(hDS, "BEGIN", NULL, NULL);

     581                 :     
     582              18 :     CPLErr eErr = CE_None;

     583                 :     int nBlockXOff, nBlockYOff;
     584              36 :     for(nBlockYOff=0;eErr == CE_None && nBlockYOff<nYBlocks;nBlockYOff++)

     585                 :     {
     586              36 :         for(nBlockXOff=0;eErr == CE_None && nBlockXOff<nXBlocks;nBlockXOff++)

     587                 :         {
     588                 : /* -------------------------------------------------------------------- */
     589                 : /*      Create in-memory tile                                           */
     590                 : /* -------------------------------------------------------------------- */
     591              18 :             int nReqXSize = nBlockXSize, nReqYSize = nBlockYSize;

     592              18 :             if ((nBlockXOff+1) * nBlockXSize > nXSize)

     593              18 :                 nReqXSize = nXSize - nBlockXOff * nBlockXSize;

     594              18 :             if ((nBlockYOff+1) * nBlockYSize > nYSize)

     595              18 :                 nReqYSize = nYSize - nBlockYOff * nBlockYSize;

     596                 : 
     597                 :             eErr = poSrcDS->RasterIO(GF_Read,
     598                 :                                      nBlockXOff * nBlockXSize,
     599                 :                                      nBlockYOff * nBlockYSize,
     600                 :                                      nReqXSize, nReqYSize,
     601                 :                                      pabyMEMDSBuffer, nReqXSize, nReqYSize,
     602                 :                                      eDataType, nBands, NULL,
     603              18 :                                      0, 0, 0);

     604              18 :             if (eErr != CE_None)

     605                 :             {
     606               0 :                 break;

     607                 :             }
     608                 :             
     609                 :             GDALDatasetH hMemDS = GDALCreate(hMemDriver, "MEM:::",
     610                 :                                               nReqXSize, nReqYSize, 0, 
     611              18 :                                               eDataType, NULL);

     612              18 :             if (hMemDS == NULL)

     613                 :             {
     614               0 :                 eErr = CE_Failure;

     615               0 :                 break;

     616                 :             }
     617                 :             
     618                 :             int iBand;
     619              48 :             for(iBand = 0; iBand < nBands; iBand ++)

     620                 :             {
     621              30 :                 char** papszMEMDSOptions = NULL;

     622                 :                 char szTmp[64];
     623              30 :                 memset(szTmp, 0, sizeof(szTmp));

     624                 :                 CPLPrintPointer(szTmp,
     625                 :                                 pabyMEMDSBuffer + iBand * nDataTypeSize *
     626              30 :                                 nReqXSize * nReqYSize, sizeof(szTmp));

     627              30 :                 papszMEMDSOptions = CSLSetNameValue(papszMEMDSOptions, "DATAPOINTER", szTmp);

     628              30 :                 GDALAddBand(hMemDS, eDataType, papszMEMDSOptions);

     629              30 :                 CSLDestroy(papszMEMDSOptions);

     630                 :             }
     631                 :             
     632                 :             GDALDatasetH hOutDS = GDALCreateCopy(hTileDriver,
     633                 :                                         osTempFileName.c_str(), hMemDS, FALSE,
     634              18 :                                         papszTileDriverOptions, NULL, NULL);

     635                 : 
     636              18 :             GDALClose(hMemDS);

     637              18 :             if (hOutDS)

     638              18 :                 GDALClose(hOutDS);

     639                 :             else
     640                 :             {
     641               0 :                 eErr = CE_Failure;

     642               0 :                 break;

     643                 :             }
     644                 : 
     645                 : /* -------------------------------------------------------------------- */
     646                 : /*      Insert new entry into raster table                              */
     647                 : /* -------------------------------------------------------------------- */
     648                 : 
     649                 :             vsi_l_offset nDataLength;
     650                 :             GByte *pabyData = VSIGetMemFileBuffer( osTempFileName.c_str(),
     651              36 :                                                    &nDataLength, FALSE);

     652                 : 
     653              18 :             OGRFeatureH hFeat = OGR_F_Create( OGR_L_GetLayerDefn(hRasterLayer) );

     654              18 :             OGR_F_SetFieldBinary(hFeat, 0, (int)nDataLength, pabyData);

     655                 :             
     656              18 :             OGR_L_CreateFeature(hRasterLayer, hFeat);

     657                 :             /* Query raster ID to set it as the ID of the associated metadata */
     658              18 :             int nRasterID = (int)OGR_F_GetFID(hFeat);

     659                 :             
     660              18 :             OGR_F_Destroy(hFeat);

     661                 :             
     662              18 :             VSIUnlink(osTempFileName.c_str());

     663                 :             
     664                 : /* -------------------------------------------------------------------- */
     665                 : /*      Insert new entry into metadata table                            */
     666                 : /* -------------------------------------------------------------------- */
     667                 :             
     668              18 :             hFeat = OGR_F_Create( OGR_L_GetLayerDefn(hMetadataLayer) );

     669              18 :             OGR_F_SetFID(hFeat, nRasterID);

     670              18 :             OGR_F_SetFieldString(hFeat, 0, GDALGetDescription(poSrcDS));

     671              18 :             OGR_F_SetFieldInteger(hFeat, 1, nTileId ++);

     672              18 :             OGR_F_SetFieldInteger(hFeat, 2, nReqXSize);

     673              18 :             OGR_F_SetFieldInteger(hFeat, 3, nReqYSize);

     674              18 :             OGR_F_SetFieldDouble(hFeat, 4, adfGeoTransform[1]);

     675              18 :             OGR_F_SetFieldDouble(hFeat, 5, -adfGeoTransform[5]);

     676                 :             
     677                 :             minx = adfGeoTransform[0] +
     678              18 :                 (nBlockXSize * nBlockXOff) * adfGeoTransform[1];

     679                 :             maxx = adfGeoTransform[0] +
     680              18 :                 (nBlockXSize * nBlockXOff + nReqXSize) * adfGeoTransform[1];

     681                 :             maxy = adfGeoTransform[3] +
     682              18 :                 (nBlockYSize * nBlockYOff) * adfGeoTransform[5];

     683                 :             miny = adfGeoTransform[3] +
     684              18 :                 (nBlockYSize * nBlockYOff + nReqYSize) * adfGeoTransform[5];

     685                 :             
     686              18 :             OGRGeometryH hRectangle = OGR_G_CreateGeometry(wkbPolygon);

     687              18 :             OGRGeometryH hLinearRing = OGR_G_CreateGeometry(wkbLinearRing);

     688              18 :             OGR_G_AddPoint_2D(hLinearRing, minx, miny);

     689              18 :             OGR_G_AddPoint_2D(hLinearRing, minx, maxy);

     690              18 :             OGR_G_AddPoint_2D(hLinearRing, maxx, maxy);

     691              18 :             OGR_G_AddPoint_2D(hLinearRing, maxx, miny);

     692              18 :             OGR_G_AddPoint_2D(hLinearRing, minx, miny);

     693              18 :             OGR_G_AddGeometryDirectly(hRectangle, hLinearRing);

     694                 :             
     695              18 :             OGR_F_SetGeometryDirectly(hFeat, hRectangle);

     696                 :             
     697              18 :             OGR_L_CreateFeature(hMetadataLayer, hFeat);

     698              18 :             OGR_F_Destroy(hFeat);

     699                 :             
     700              18 :             nBlocks++;

     701              18 :             if (pfnProgress && !pfnProgress(1.0 * nBlocks / nTotalBlocks,

     702                 :                                             NULL, pProgressData))
     703               0 :                 eErr = CE_Failure;

     704                 :         }
     705                 :     }
     706                 :     
     707              18 :     if (eErr == CE_None)

     708              18 :         OGR_DS_ExecuteSQL(hDS, "COMMIT", NULL, NULL);

     709                 :     else
     710               0 :         OGR_DS_ExecuteSQL(hDS, "ROLLBACK", NULL, NULL);

     711                 :     
     712              18 :     CSLDestroy(papszTileDriverOptions);

     713                 :     
     714              18 :     VSIFree(pabyMEMDSBuffer);

     715                 :     
     716              18 :     OGRReleaseDataSource(hDS);

     717                 :         
     718              18 :     return (GDALDataset*) GDALOpen(pszFilename, GA_Update);

     719                 : }
     720                 : 
     721                 : /************************************************************************/
     722                 : /*                         RasterliteDelete ()                          */
     723                 : /************************************************************************/
     724                 : 
     725               3 : CPLErr RasterliteDelete(const char* pszFilename)

     726                 : {
     727               3 :     return CE_None;

     728                 : }

Generated by: LTP GCOV extension version 1.5