LCOV - code coverage report
Current view: directory - frmts/rasterlite - rasterlitecreatecopy.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 320 237 74.1 %
Date: 2012-12-26 Functions: 6 6 100.0 %

       1                 : /******************************************************************************
       2                 :  * $Id: rasterlitecreatecopy.cpp 24801 2012-08-18 14:29:41Z 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 24801 2012-08-18 14:29:41Z rouault $");
      37                 : 
      38                 : /************************************************************************/
      39                 : /*                  RasterliteGetTileDriverOptions ()                   */
      40                 : /************************************************************************/
      41                 : 
      42              88 : static char** RasterliteAddTileDriverOptionsForDriver(char** papszOptions,
      43                 :                                                     char** papszTileDriverOptions,
      44                 :                                                     const char* pszOptionName,
      45                 :                                                     const char* pszExpectedDriverName)
      46                 : {
      47              88 :     const char* pszVal = CSLFetchNameValue(papszOptions, pszOptionName);
      48              88 :     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              88 :     return papszTileDriverOptions;
      65                 : }
      66                 : 
      67              22 : char** RasterliteGetTileDriverOptions(char** papszOptions)
      68                 : {
      69              22 :     char** papszTileDriverOptions = NULL;
      70                 : 
      71                 :     const char* pszDriverName =
      72              22 :         CSLFetchNameValueDef(papszOptions, "DRIVER", "GTiff");
      73                 :         
      74              22 :     if (EQUAL(pszDriverName, "EPSILON"))
      75                 :     {
      76                 :         papszTileDriverOptions = CSLSetNameValue(papszTileDriverOptions,
      77               2 :                                                 "RASTERLITE_OUTPUT", "YES");
      78                 :     }
      79                 :     
      80              22 :     const char* pszQuality = CSLFetchNameValue(papszOptions, "QUALITY");
      81              22 :     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") || EQUAL(pszDriverName, "WEBP"))
      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              22 :                 papszOptions, papszTileDriverOptions, "COMPRESS", "GTiff");
     103                 :     papszTileDriverOptions = RasterliteAddTileDriverOptionsForDriver(
     104              22 :                 papszOptions, papszTileDriverOptions, "PHOTOMETRIC", "GTiff");
     105                 :     papszTileDriverOptions = RasterliteAddTileDriverOptionsForDriver(
     106              22 :                 papszOptions, papszTileDriverOptions, "TARGET", "EPSILON");
     107                 :     papszTileDriverOptions = RasterliteAddTileDriverOptionsForDriver(
     108              22 :                 papszOptions, papszTileDriverOptions, "FILTER", "EPSILON");
     109                 :     
     110              22 :     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               0 :             nSRSId = nAuthorityCode;
     154                 :             
     155               0 :             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               0 :                     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               0 :                     nAuthorityCode, osProj4.c_str() );
     169                 : 
     170                 :             
     171               0 :             OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);
     172                 :         }
     173                 :         else
     174                 :         {
     175              18 :             OGRFeatureH hFeat = OGR_L_GetNextFeature(hLyr);
     176              18 :             if (hFeat)
     177                 :             {
     178              18 :                 nSRSId = OGR_F_GetFieldAsInteger(hFeat, 0);
     179              18 :                 OGR_F_Destroy(hFeat);
     180                 :             }
     181              18 :             OGR_DS_ReleaseResultSet(hDS, hLyr);
     182                 :         }
     183                 :     }
     184                 :     
     185              18 :     return nSRSId;
     186                 : }
     187                 : 
     188                 : /************************************************************************/
     189                 : /*                     RasterliteCreateTables ()                        */
     190                 : /************************************************************************/
     191                 : 
     192              18 : OGRDataSourceH RasterliteCreateTables(OGRDataSourceH hDS, const char* pszTableName,
     193                 :                                       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                 :         /* Create statistics tables */
     255              18 :         osSQL.Printf("SELECT UpdateLayerStatistics()");
     256              18 :         CPLPushErrorHandler(CPLQuietErrorHandler);
     257              18 :         hLyr = OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);
     258              18 :         CPLPopErrorHandler();
     259              18 :         OGR_DS_ReleaseResultSet(hDS, hLyr);
     260                 : 
     261                 :         /* Re-open the DB to take into account the new tables*/
     262              18 :         OGRReleaseDataSource(hDS);
     263                 :         
     264              18 :         CPLSetThreadLocalConfigOption("SQLITE_LIST_ALL_TABLES", "TRUE");
     265              18 :         hDS = OGROpen(osDBName.c_str(), TRUE, NULL);
     266              18 :         CPLSetThreadLocalConfigOption("SQLITE_LIST_ALL_TABLES", osOldVal.c_str());
     267                 :     }
     268                 :     else
     269                 :     {
     270                 :         /* Check that the existing SRS is consistent with the one of the new */
     271                 :         /* data to be inserted */
     272                 :         osSQL.Printf("SELECT srid FROM geometry_columns WHERE f_table_name = '%s'",
     273               0 :                      osMetatadataLayer.c_str());
     274               0 :         hLyr = OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);
     275               0 :         if (hLyr)
     276                 :         {
     277               0 :             int nExistingSRID = -1;
     278               0 :             OGRFeatureH hFeat = OGR_L_GetNextFeature(hLyr);
     279               0 :             if (hFeat)
     280                 :             {
     281               0 :                 nExistingSRID = OGR_F_GetFieldAsInteger(hFeat, 0);
     282               0 :                 OGR_F_Destroy(hFeat);
     283                 :             }
     284               0 :             OGR_DS_ReleaseResultSet(hDS, hLyr);
     285                 : 
     286               0 :             if (nExistingSRID != nSRSId)
     287                 :             {
     288               0 :                 if (bWipeExistingData)
     289                 :                 {
     290                 :                     osSQL.Printf("UPDATE geometry_columns SET srid = %d "
     291                 :                                  "WHERE f_table_name = \"%s\"",
     292               0 :                                  nSRSId, osMetatadataLayer.c_str());
     293               0 :                     OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);
     294                 :         
     295                 :                     /* Re-open the DB to take into account the change of SRS */
     296               0 :                     OGRReleaseDataSource(hDS);
     297                 :                     
     298               0 :                     CPLSetThreadLocalConfigOption("SQLITE_LIST_ALL_TABLES", "TRUE");
     299               0 :                     hDS = OGROpen(osDBName.c_str(), TRUE, NULL);
     300               0 :                     CPLSetThreadLocalConfigOption("SQLITE_LIST_ALL_TABLES", osOldVal.c_str());
     301                 :                 }
     302                 :                 else
     303                 :                 {
     304                 :                     CPLError(CE_Failure, CPLE_NotSupported,
     305               0 :                              "New data has not the same SRS as existing data");
     306               0 :                     OGRReleaseDataSource(hDS);
     307               0 :                     return NULL;
     308                 :                 }
     309                 :             }            
     310                 :         }
     311                 :         
     312               0 :         if (bWipeExistingData)
     313                 :         {
     314               0 :             osSQL.Printf("DELETE FROM \"%s\"", osRasterLayer.c_str());
     315               0 :             OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);
     316                 :             
     317               0 :             osSQL.Printf("DELETE FROM \"%s\"", osMetatadataLayer.c_str());
     318               0 :             OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);
     319                 :         }
     320                 :     }
     321                 : 
     322              18 :     return hDS;
     323                 : }
     324                 : 
     325                 : /************************************************************************/
     326                 : /*                       RasterliteCreateCopy ()                        */
     327                 : /************************************************************************/
     328                 : 
     329                 : GDALDataset *
     330              36 : RasterliteCreateCopy( const char * pszFilename, GDALDataset *poSrcDS, 
     331                 :                        int bStrict, char ** papszOptions, 
     332                 :                        GDALProgressFunc pfnProgress, void * pProgressData )
     333                 : {
     334              36 :     int nBands = poSrcDS->GetRasterCount();
     335              36 :     if (nBands == 0)
     336                 :     {
     337               1 :         CPLError(CE_Failure, CPLE_NotSupported, "nBands == 0");
     338               1 :         return NULL;
     339                 :     }
     340                 :     
     341              35 :     const char* pszDriverName = CSLFetchNameValueDef(papszOptions, "DRIVER", "GTiff");
     342              35 :     if (EQUAL(pszDriverName, "MEM") || EQUAL(pszDriverName, "VRT"))
     343                 :     {
     344                 :         CPLError(CE_Failure, CPLE_AppDefined, "GDAL %s driver cannot be used as underlying driver",
     345               0 :                  pszDriverName);
     346               0 :         return NULL;
     347                 :     }
     348                 : 
     349              35 :     GDALDriverH hTileDriver = GDALGetDriverByName(pszDriverName);
     350              35 :     if ( hTileDriver == NULL)
     351                 :     {
     352               0 :         CPLError(CE_Failure, CPLE_AppDefined, "Cannot load GDAL %s driver", pszDriverName);
     353               0 :         return NULL;
     354                 :     }
     355                 :     
     356              35 :     GDALDriverH hMemDriver = GDALGetDriverByName("MEM");
     357              35 :     if (hMemDriver == NULL)
     358                 :     {
     359               0 :         CPLError(CE_Failure, CPLE_AppDefined, "Cannot load GDAL MEM driver");
     360               0 :         return NULL;
     361                 :     }   
     362                 : 
     363              35 :     int nXSize = GDALGetRasterXSize(poSrcDS);
     364              35 :     int nYSize = GDALGetRasterYSize(poSrcDS);
     365                 :     
     366                 :     double adfGeoTransform[6];
     367              35 :     if (poSrcDS->GetGeoTransform(adfGeoTransform) != CE_None)
     368                 :     {
     369               0 :         adfGeoTransform[0] = 0;
     370               0 :         adfGeoTransform[1] = 1;
     371               0 :         adfGeoTransform[2] = 0;
     372               0 :         adfGeoTransform[3] = 0;
     373               0 :         adfGeoTransform[4] = 0;
     374               0 :         adfGeoTransform[5] = -1;
     375                 :     }
     376              35 :     else if (adfGeoTransform[2] != 0.0 || adfGeoTransform[4] != 0.0)
     377                 :     {
     378               0 :         CPLError(CE_Failure, CPLE_AppDefined, "Cannot use geotransform with rotational terms");
     379               0 :         return NULL;
     380                 :     }
     381                 : 
     382              35 :     int bTiled = CSLTestBoolean(CSLFetchNameValueDef(papszOptions, "TILED", "YES"));
     383                 :     int nBlockXSize, nBlockYSize;
     384              35 :     if (bTiled)
     385                 :     {
     386              35 :         nBlockXSize = atoi(CSLFetchNameValueDef(papszOptions, "BLOCKXSIZE", "256"));
     387              35 :         nBlockYSize = atoi(CSLFetchNameValueDef(papszOptions, "BLOCKYSIZE", "256"));
     388              35 :         if (nBlockXSize < 64) nBlockXSize = 64;
     389              35 :         else if (nBlockXSize > 4096)  nBlockXSize = 4096;
     390              35 :         if (nBlockYSize < 64) nBlockYSize = 64;
     391              35 :         else if (nBlockYSize > 4096)  nBlockYSize = 4096;
     392                 :     }
     393                 :     else
     394                 :     {
     395               0 :         nBlockXSize = nXSize;
     396               0 :         nBlockYSize = nYSize;
     397                 :     }
     398                 :     
     399                 : /* -------------------------------------------------------------------- */
     400                 : /*      Analyze arguments                                               */
     401                 : /* -------------------------------------------------------------------- */
     402                 :     
     403              35 :     CPLString osDBName;
     404              35 :     CPLString osTableName;
     405                 :     VSIStatBuf sBuf;
     406                 :     int bExists;
     407                 : 
     408                 :     /* Skip optionnal RASTERLITE: prefix */
     409              35 :     const char* pszFilenameWithoutPrefix = pszFilename;
     410              35 :     if (EQUALN(pszFilename, "RASTERLITE:", 11))
     411               1 :         pszFilenameWithoutPrefix += 11;
     412                 :     
     413                 :     char** papszTokens = CSLTokenizeStringComplex( 
     414              35 :                 pszFilenameWithoutPrefix, ", ", FALSE, FALSE );
     415              35 :     int nTokens = CSLCount(papszTokens);
     416              35 :     if (nTokens == 0)
     417                 :     {
     418               0 :         osDBName = pszFilenameWithoutPrefix;
     419               0 :         osTableName = CPLGetBasename(pszFilenameWithoutPrefix);
     420                 :     }
     421                 :     else
     422                 :     {
     423              35 :         osDBName = papszTokens[0];
     424                 :         
     425                 :         int i;
     426              36 :         for(i=1;i<nTokens;i++)
     427                 :         {
     428               1 :             if (EQUALN(papszTokens[i], "table=", 6))
     429               1 :                 osTableName = papszTokens[i] + 6;
     430                 :             else
     431                 :             {
     432                 :                 CPLError(CE_Warning, CPLE_AppDefined,
     433               0 :                          "Invalid option : %s", papszTokens[i]);
     434                 :             }
     435                 :         }
     436                 :     }
     437                 :     
     438              35 :     CSLDestroy(papszTokens);
     439              35 :     papszTokens = NULL;
     440                 :     
     441              35 :     bExists = (VSIStat(osDBName.c_str(), &sBuf) == 0);
     442                 : 
     443              35 :     if (osTableName.size() == 0)
     444                 :     {
     445              34 :         if (bExists)
     446                 :         {
     447                 :             CPLError(CE_Failure, CPLE_AppDefined,
     448               0 :                      "Database already exists. Explicit table name must be specified");
     449               0 :             return NULL;
     450                 :         }
     451              34 :         osTableName = CPLGetBasename(osDBName.c_str());
     452                 :     }    
     453                 :     
     454              35 :     CPLString osRasterLayer;
     455              35 :     osRasterLayer.Printf("%s_rasters", osTableName.c_str());
     456                 :     
     457              35 :     CPLString osMetatadataLayer;
     458              35 :     osMetatadataLayer.Printf("%s_metadata", osTableName.c_str());
     459                 : 
     460                 : /* -------------------------------------------------------------------- */
     461                 : /*      Create or open the SQLite DB                                    */
     462                 : /* -------------------------------------------------------------------- */
     463                 :     
     464              35 :     if (OGRGetDriverCount() == 0)
     465               1 :         OGRRegisterAll();
     466                 :         
     467              35 :     OGRSFDriverH hSQLiteDriver = OGRGetDriverByName("SQLite");
     468              35 :     if (hSQLiteDriver == NULL)
     469                 :     {
     470               0 :         CPLError(CE_Failure, CPLE_AppDefined, "Cannot load OGR SQLite driver");
     471               0 :         return NULL;
     472                 :     }   
     473                 :     
     474                 :     OGRDataSourceH hDS;
     475                 :     
     476                 :     CPLString osOldVal =
     477              35 :         CPLGetConfigOption("SQLITE_LIST_ALL_TABLES", "FALSE");
     478              35 :     CPLSetThreadLocalConfigOption("SQLITE_LIST_ALL_TABLES", "TRUE");
     479              35 :     if (!bExists)
     480                 :     {
     481              35 :         char** papszOGROptions = CSLAddString(NULL, "SPATIALITE=YES");
     482                 :         hDS = OGR_Dr_CreateDataSource(hSQLiteDriver,
     483              35 :                                       osDBName.c_str(), papszOGROptions);
     484              35 :         CSLDestroy(papszOGROptions);
     485                 :     }
     486                 :     else
     487                 :     {
     488               0 :         hDS = OGROpen(osDBName.c_str(), TRUE, NULL);
     489                 :     }
     490              35 :     CPLSetThreadLocalConfigOption("SQLITE_LIST_ALL_TABLES", osOldVal.c_str());
     491                 :     
     492              35 :     if (hDS == NULL)
     493                 :     {
     494                 :         CPLError(CE_Failure, CPLE_AppDefined,
     495              17 :                  "Cannot load or create SQLite database");
     496              17 :         return NULL;
     497                 :     }
     498                 : 
     499              18 :     CPLString osSQL;
     500                 :     
     501                 : /* -------------------------------------------------------------------- */
     502                 : /*      Get the SRID for the SRS                                        */
     503                 : /* -------------------------------------------------------------------- */
     504              18 :     int nSRSId = RasterliteInsertSRID(hDS, poSrcDS->GetProjectionRef());
     505                 : 
     506                 : /* -------------------------------------------------------------------- */
     507                 : /*      Create or wipe existing tables                                  */
     508                 : /* -------------------------------------------------------------------- */
     509                 :     int bWipeExistingData =
     510              18 :         CSLTestBoolean(CSLFetchNameValueDef(papszOptions, "WIPE", "NO"));
     511                 :         
     512                 :     hDS = RasterliteCreateTables(hDS, osTableName.c_str(),
     513              18 :                                  nSRSId, bWipeExistingData);
     514              18 :     if (hDS == NULL)
     515               0 :         return NULL;
     516                 : 
     517              18 :     OGRLayerH hRasterLayer = OGR_DS_GetLayerByName(hDS, osRasterLayer.c_str());
     518              18 :     OGRLayerH hMetadataLayer = OGR_DS_GetLayerByName(hDS, osMetatadataLayer.c_str());
     519              18 :     if (hRasterLayer == NULL || hMetadataLayer == NULL)
     520                 :     {
     521                 :         CPLError(CE_Failure, CPLE_AppDefined,
     522               0 :                  "Cannot find metadata and/or raster tables");
     523               0 :         OGRReleaseDataSource(hDS);
     524               0 :         return NULL;
     525                 :     }
     526                 : 
     527                 : /* -------------------------------------------------------------------- */
     528                 : /*      Check if there is overlapping data and warn the user            */
     529                 : /* -------------------------------------------------------------------- */
     530              18 :     double minx = adfGeoTransform[0];
     531              18 :     double maxx = adfGeoTransform[0] + nXSize * adfGeoTransform[1];
     532              18 :     double maxy = adfGeoTransform[3];
     533              18 :     double miny = adfGeoTransform[3] + nYSize * adfGeoTransform[5];
     534                 :     
     535                 :     osSQL.Printf("SELECT COUNT(geometry) FROM \"%s\" "
     536                 :                  "WHERE rowid IN "
     537                 :                  "(SELECT pkid FROM \"idx_%s_metadata_geometry\" "
     538                 :                   "WHERE xmin < %.15f AND xmax > %.15f "
     539                 :                   "AND ymin < %.15f  AND ymax > %.15f) "
     540                 :                  "AND pixel_x_size >= %.15f AND pixel_x_size <= %.15f AND "
     541                 :                  "pixel_y_size >= %.15f AND pixel_y_size <= %.15f",
     542                 :                   osMetatadataLayer.c_str(),
     543                 :                   osTableName.c_str(),
     544                 :                   maxx, minx, maxy, miny,
     545              36 :                   adfGeoTransform[1] - 1e-15, adfGeoTransform[1] + 1e-15,
     546              54 :                   - adfGeoTransform[5] - 1e-15, - adfGeoTransform[5] + 1e-15);
     547                 :     
     548              18 :     int nOverlappingGeoms = 0;
     549              18 :     OGRLayerH hCountLyr = OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);
     550              18 :     if (hCountLyr)
     551                 :     {
     552              18 :         OGRFeatureH hFeat = OGR_L_GetNextFeature(hCountLyr);
     553              18 :         if (hFeat)
     554                 :         {
     555              18 :             nOverlappingGeoms = OGR_F_GetFieldAsInteger(hFeat, 0);
     556              18 :             OGR_F_Destroy(hFeat);
     557                 :         }
     558              18 :         OGR_DS_ReleaseResultSet(hDS, hCountLyr);
     559                 :     }
     560                 :     
     561              18 :     if (nOverlappingGeoms != 0)
     562                 :     {
     563                 :         CPLError(CE_Warning, CPLE_AppDefined,
     564                 :                  "Raster tiles already exist in the %s table within "
     565                 :                  "the extent of the data to be inserted in",
     566               0 :                  osTableName.c_str());
     567                 :     }
     568                 :    
     569                 : /* -------------------------------------------------------------------- */
     570                 : /*      Iterate over blocks to add data into raster and metadata tables */
     571                 : /* -------------------------------------------------------------------- */
     572              18 :     int nXBlocks = (nXSize + nBlockXSize - 1) / nBlockXSize;
     573              18 :     int nYBlocks = (nYSize + nBlockYSize - 1) / nBlockYSize;
     574                 : 
     575              18 :     GDALDataType eDataType = poSrcDS->GetRasterBand(1)->GetRasterDataType();
     576              18 :     int nDataTypeSize = GDALGetDataTypeSize(eDataType) / 8;
     577                 :     GByte* pabyMEMDSBuffer =
     578              18 :         (GByte*)VSIMalloc3(nBlockXSize, nBlockYSize, nBands * nDataTypeSize);
     579              18 :     if (pabyMEMDSBuffer == NULL)
     580                 :     {
     581               0 :         OGRReleaseDataSource(hDS);
     582               0 :         return NULL;
     583                 :     }
     584                 :     
     585              18 :     CPLString osTempFileName;
     586              18 :     osTempFileName.Printf("/vsimem/%p", hDS);
     587                 :     
     588              18 :     int nTileId = 0;
     589              18 :     int nBlocks = 0;
     590              18 :     int nTotalBlocks = nXBlocks * nYBlocks;
     591                 : 
     592              18 :     char** papszTileDriverOptions = RasterliteGetTileDriverOptions(papszOptions);
     593                 :     
     594              18 :     OGR_DS_ExecuteSQL(hDS, "BEGIN", NULL, NULL);
     595                 :     
     596              18 :     CPLErr eErr = CE_None;
     597                 :     int nBlockXOff, nBlockYOff;
     598              36 :     for(nBlockYOff=0;eErr == CE_None && nBlockYOff<nYBlocks;nBlockYOff++)
     599                 :     {
     600              36 :         for(nBlockXOff=0;eErr == CE_None && nBlockXOff<nXBlocks;nBlockXOff++)
     601                 :         {
     602                 : /* -------------------------------------------------------------------- */
     603                 : /*      Create in-memory tile                                           */
     604                 : /* -------------------------------------------------------------------- */
     605              18 :             int nReqXSize = nBlockXSize, nReqYSize = nBlockYSize;
     606              18 :             if ((nBlockXOff+1) * nBlockXSize > nXSize)
     607              18 :                 nReqXSize = nXSize - nBlockXOff * nBlockXSize;
     608              18 :             if ((nBlockYOff+1) * nBlockYSize > nYSize)
     609              18 :                 nReqYSize = nYSize - nBlockYOff * nBlockYSize;
     610                 : 
     611                 :             eErr = poSrcDS->RasterIO(GF_Read,
     612                 :                                      nBlockXOff * nBlockXSize,
     613                 :                                      nBlockYOff * nBlockYSize,
     614                 :                                      nReqXSize, nReqYSize,
     615                 :                                      pabyMEMDSBuffer, nReqXSize, nReqYSize,
     616                 :                                      eDataType, nBands, NULL,
     617              18 :                                      0, 0, 0);
     618              18 :             if (eErr != CE_None)
     619                 :             {
     620               0 :                 break;
     621                 :             }
     622                 :             
     623                 :             GDALDatasetH hMemDS = GDALCreate(hMemDriver, "MEM:::",
     624                 :                                               nReqXSize, nReqYSize, 0, 
     625              18 :                                               eDataType, NULL);
     626              18 :             if (hMemDS == NULL)
     627                 :             {
     628               0 :                 eErr = CE_Failure;
     629               0 :                 break;
     630                 :             }
     631                 :             
     632                 :             int iBand;
     633              48 :             for(iBand = 0; iBand < nBands; iBand ++)
     634                 :             {
     635              30 :                 char** papszMEMDSOptions = NULL;
     636                 :                 char szTmp[64];
     637              30 :                 memset(szTmp, 0, sizeof(szTmp));
     638                 :                 CPLPrintPointer(szTmp,
     639                 :                                 pabyMEMDSBuffer + iBand * nDataTypeSize *
     640              30 :                                 nReqXSize * nReqYSize, sizeof(szTmp));
     641              30 :                 papszMEMDSOptions = CSLSetNameValue(papszMEMDSOptions, "DATAPOINTER", szTmp);
     642              30 :                 GDALAddBand(hMemDS, eDataType, papszMEMDSOptions);
     643              30 :                 CSLDestroy(papszMEMDSOptions);
     644                 :             }
     645                 :             
     646                 :             GDALDatasetH hOutDS = GDALCreateCopy(hTileDriver,
     647                 :                                         osTempFileName.c_str(), hMemDS, FALSE,
     648              18 :                                         papszTileDriverOptions, NULL, NULL);
     649                 : 
     650              18 :             GDALClose(hMemDS);
     651              18 :             if (hOutDS)
     652              18 :                 GDALClose(hOutDS);
     653                 :             else
     654                 :             {
     655               0 :                 eErr = CE_Failure;
     656               0 :                 break;
     657                 :             }
     658                 : 
     659                 : /* -------------------------------------------------------------------- */
     660                 : /*      Insert new entry into raster table                              */
     661                 : /* -------------------------------------------------------------------- */
     662                 : 
     663              18 :             vsi_l_offset nDataLength = 0;
     664                 :             GByte *pabyData = VSIGetMemFileBuffer( osTempFileName.c_str(),
     665              36 :                                                    &nDataLength, FALSE);
     666                 : 
     667              18 :             OGRFeatureH hFeat = OGR_F_Create( OGR_L_GetLayerDefn(hRasterLayer) );
     668              18 :             OGR_F_SetFieldBinary(hFeat, 0, (int)nDataLength, pabyData);
     669                 :             
     670              18 :             OGR_L_CreateFeature(hRasterLayer, hFeat);
     671                 :             /* Query raster ID to set it as the ID of the associated metadata */
     672              18 :             int nRasterID = (int)OGR_F_GetFID(hFeat);
     673                 :             
     674              18 :             OGR_F_Destroy(hFeat);
     675                 :             
     676              18 :             VSIUnlink(osTempFileName.c_str());
     677                 :             
     678                 : /* -------------------------------------------------------------------- */
     679                 : /*      Insert new entry into metadata table                            */
     680                 : /* -------------------------------------------------------------------- */
     681                 :             
     682              18 :             hFeat = OGR_F_Create( OGR_L_GetLayerDefn(hMetadataLayer) );
     683              18 :             OGR_F_SetFID(hFeat, nRasterID);
     684              18 :             OGR_F_SetFieldString(hFeat, 0, GDALGetDescription(poSrcDS));
     685              18 :             OGR_F_SetFieldInteger(hFeat, 1, nTileId ++);
     686              18 :             OGR_F_SetFieldInteger(hFeat, 2, nReqXSize);
     687              18 :             OGR_F_SetFieldInteger(hFeat, 3, nReqYSize);
     688              18 :             OGR_F_SetFieldDouble(hFeat, 4, adfGeoTransform[1]);
     689              18 :             OGR_F_SetFieldDouble(hFeat, 5, -adfGeoTransform[5]);
     690                 :             
     691              18 :             minx = adfGeoTransform[0] +
     692              18 :                 (nBlockXSize * nBlockXOff) * adfGeoTransform[1];
     693              18 :             maxx = adfGeoTransform[0] +
     694              18 :                 (nBlockXSize * nBlockXOff + nReqXSize) * adfGeoTransform[1];
     695              18 :             maxy = adfGeoTransform[3] +
     696              18 :                 (nBlockYSize * nBlockYOff) * adfGeoTransform[5];
     697              18 :             miny = adfGeoTransform[3] +
     698              18 :                 (nBlockYSize * nBlockYOff + nReqYSize) * adfGeoTransform[5];
     699                 :             
     700              18 :             OGRGeometryH hRectangle = OGR_G_CreateGeometry(wkbPolygon);
     701              18 :             OGRGeometryH hLinearRing = OGR_G_CreateGeometry(wkbLinearRing);
     702              18 :             OGR_G_AddPoint_2D(hLinearRing, minx, miny);
     703              18 :             OGR_G_AddPoint_2D(hLinearRing, minx, maxy);
     704              18 :             OGR_G_AddPoint_2D(hLinearRing, maxx, maxy);
     705              18 :             OGR_G_AddPoint_2D(hLinearRing, maxx, miny);
     706              18 :             OGR_G_AddPoint_2D(hLinearRing, minx, miny);
     707              18 :             OGR_G_AddGeometryDirectly(hRectangle, hLinearRing);
     708                 :             
     709              18 :             OGR_F_SetGeometryDirectly(hFeat, hRectangle);
     710                 :             
     711              18 :             OGR_L_CreateFeature(hMetadataLayer, hFeat);
     712              18 :             OGR_F_Destroy(hFeat);
     713                 :             
     714              18 :             nBlocks++;
     715              18 :             if (pfnProgress && !pfnProgress(1.0 * nBlocks / nTotalBlocks,
     716                 :                                             NULL, pProgressData))
     717               0 :                 eErr = CE_Failure;
     718                 :         }
     719                 :     }
     720                 :     
     721              18 :     if (eErr == CE_None)
     722              18 :         OGR_DS_ExecuteSQL(hDS, "COMMIT", NULL, NULL);
     723                 :     else
     724               0 :         OGR_DS_ExecuteSQL(hDS, "ROLLBACK", NULL, NULL);
     725                 :     
     726              18 :     CSLDestroy(papszTileDriverOptions);
     727                 :     
     728              18 :     VSIFree(pabyMEMDSBuffer);
     729                 :     
     730              18 :     OGRReleaseDataSource(hDS);
     731                 :         
     732              18 :     return (GDALDataset*) GDALOpen(pszFilename, GA_Update);
     733                 : }
     734                 : 
     735                 : /************************************************************************/
     736                 : /*                         RasterliteDelete ()                          */
     737                 : /************************************************************************/
     738                 : 
     739               3 : CPLErr RasterliteDelete(const char* pszFilename)
     740                 : {
     741               3 :     return CE_None;
     742                 : }

Generated by: LCOV version 1.7