LCOV - code coverage report
Current view: directory - frmts/rasterlite - rasterlitecreatecopy.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 312 231 74.0 %
Date: 2013-03-30 Functions: 6 6 100.0 %

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

Generated by: LCOV version 1.7