ultimatepp/bazaar/plugin/gdal/frmts/rasterlite/rasterlitecreatecopy.cpp
cxl 23ff1e7e82 .gdal moved to bazaar
git-svn-id: svn://ultimatepp.org/upp/trunk@9273 f0d560ea-af0d-0410-9eb7-867de7ffcac7
2015-12-07 13:36:24 +00:00

730 lines
28 KiB
C++

/******************************************************************************
* $Id: rasterlitecreatecopy.cpp 28053 2014-12-04 09:31:07Z rouault $
*
* Project: GDAL Rasterlite driver
* Purpose: Implement GDAL Rasterlite support using OGR SQLite driver
* Author: Even Rouault, <even dot rouault at mines dash paris dot org>
*
**********************************************************************
* Copyright (c) 2009-2012, Even Rouault <even dot rouault at mines-paris dot org>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
****************************************************************************/
#include "cpl_string.h"
#include "ogr_api.h"
#include "ogr_srs_api.h"
#include "rasterlitedataset.h"
CPL_CVSID("$Id: rasterlitecreatecopy.cpp 28053 2014-12-04 09:31:07Z rouault $");
/************************************************************************/
/* RasterliteGetTileDriverOptions () */
/************************************************************************/
static char** RasterliteAddTileDriverOptionsForDriver(char** papszOptions,
char** papszTileDriverOptions,
const char* pszOptionName,
const char* pszExpectedDriverName)
{
const char* pszVal = CSLFetchNameValue(papszOptions, pszOptionName);
if (pszVal)
{
const char* pszDriverName =
CSLFetchNameValueDef(papszOptions, "DRIVER", "GTiff");
if (EQUAL(pszDriverName, pszExpectedDriverName))
{
papszTileDriverOptions =
CSLSetNameValue(papszTileDriverOptions, pszOptionName, pszVal);
}
else
{
CPLError(CE_Warning, CPLE_NotSupported,
"Unexpected option '%s' for driver '%s'",
pszOptionName, pszDriverName);
}
}
return papszTileDriverOptions;
}
char** RasterliteGetTileDriverOptions(char** papszOptions)
{
char** papszTileDriverOptions = NULL;
const char* pszDriverName =
CSLFetchNameValueDef(papszOptions, "DRIVER", "GTiff");
if (EQUAL(pszDriverName, "EPSILON"))
{
papszTileDriverOptions = CSLSetNameValue(papszTileDriverOptions,
"RASTERLITE_OUTPUT", "YES");
}
const char* pszQuality = CSLFetchNameValue(papszOptions, "QUALITY");
if (pszQuality)
{
if (EQUAL(pszDriverName, "GTiff"))
{
papszTileDriverOptions =
CSLSetNameValue(papszTileDriverOptions, "JPEG_QUALITY", pszQuality);
}
else if (EQUAL(pszDriverName, "JPEG") || EQUAL(pszDriverName, "WEBP"))
{
papszTileDriverOptions =
CSLSetNameValue(papszTileDriverOptions, "QUALITY", pszQuality);
}
else
{
CPLError(CE_Warning, CPLE_NotSupported,
"Unexpected option '%s' for driver '%s'",
"QUALITY", pszDriverName);
}
}
papszTileDriverOptions = RasterliteAddTileDriverOptionsForDriver(
papszOptions, papszTileDriverOptions, "COMPRESS", "GTiff");
papszTileDriverOptions = RasterliteAddTileDriverOptionsForDriver(
papszOptions, papszTileDriverOptions, "PHOTOMETRIC", "GTiff");
papszTileDriverOptions = RasterliteAddTileDriverOptionsForDriver(
papszOptions, papszTileDriverOptions, "TARGET", "EPSILON");
papszTileDriverOptions = RasterliteAddTileDriverOptionsForDriver(
papszOptions, papszTileDriverOptions, "FILTER", "EPSILON");
return papszTileDriverOptions;
}
/************************************************************************/
/* RasterliteInsertSRID () */
/************************************************************************/
static int RasterliteInsertSRID(OGRDataSourceH hDS, const char* pszWKT)
{
CPLString osSQL;
int nAuthorityCode = 0;
CPLString osAuthorityName, osProjCS, osProj4;
if (pszWKT != NULL && strlen(pszWKT) != 0)
{
OGRSpatialReferenceH hSRS = OSRNewSpatialReference(pszWKT);
if (hSRS)
{
const char* pszAuthorityName = OSRGetAuthorityName(hSRS, NULL);
if (pszAuthorityName) osAuthorityName = pszAuthorityName;
const char* pszProjCS = OSRGetAttrValue(hSRS, "PROJCS", 0);
if (pszProjCS) osProjCS = pszProjCS;
const char* pszAuthorityCode = OSRGetAuthorityCode(hSRS, NULL);
if (pszAuthorityCode) nAuthorityCode = atoi(pszAuthorityCode);
char *pszProj4 = NULL;
if( OSRExportToProj4( hSRS, &pszProj4 ) != OGRERR_NONE )
pszProj4 = CPLStrdup("");
osProj4 = pszProj4;
CPLFree(pszProj4);
}
OSRDestroySpatialReference(hSRS);
}
int nSRSId = -1;
if (nAuthorityCode != 0 && osAuthorityName.size() != 0)
{
osSQL.Printf ("SELECT srid FROM spatial_ref_sys WHERE auth_srid = %d", nAuthorityCode);
OGRLayerH hLyr = OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);
if (hLyr == NULL)
{
nSRSId = nAuthorityCode;
if ( osProjCS.size() != 0 )
osSQL.Printf(
"INSERT INTO spatial_ref_sys "
"(srid, auth_name, auth_srid, ref_sys_name, proj4text) "
"VALUES (%d, '%s', '%d', '%s', '%s')",
nSRSId, osAuthorityName.c_str(),
nAuthorityCode, osProjCS.c_str(), osProj4.c_str() );
else
osSQL.Printf(
"INSERT INTO spatial_ref_sys "
"(srid, auth_name, auth_srid, proj4text) "
"VALUES (%d, '%s', '%d', '%s')",
nSRSId, osAuthorityName.c_str(),
nAuthorityCode, osProj4.c_str() );
OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);
}
else
{
OGRFeatureH hFeat = OGR_L_GetNextFeature(hLyr);
if (hFeat)
{
nSRSId = OGR_F_GetFieldAsInteger(hFeat, 0);
OGR_F_Destroy(hFeat);
}
OGR_DS_ReleaseResultSet(hDS, hLyr);
}
}
return nSRSId;
}
/************************************************************************/
/* RasterliteCreateTables () */
/************************************************************************/
OGRDataSourceH RasterliteCreateTables(OGRDataSourceH hDS, const char* pszTableName,
int nSRSId, int bWipeExistingData)
{
CPLString osSQL;
CPLString osDBName = OGR_DS_GetName(hDS);
CPLString osRasterLayer;
osRasterLayer.Printf("%s_rasters", pszTableName);
CPLString osMetatadataLayer;
osMetatadataLayer.Printf("%s_metadata", pszTableName);
OGRLayerH hLyr;
if (OGR_DS_GetLayerByName(hDS, osRasterLayer.c_str()) == NULL)
{
/* -------------------------------------------------------------------- */
/* The table don't exist. Create them */
/* -------------------------------------------------------------------- */
/* Create _rasters table */
osSQL.Printf ("CREATE TABLE \"%s\" ("
"id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,"
"raster BLOB NOT NULL)", osRasterLayer.c_str());
OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);
/* Create _metadata table */
osSQL.Printf ("CREATE TABLE \"%s\" ("
"id INTEGER NOT NULL PRIMARY KEY,"
"source_name TEXT NOT NULL,"
"tile_id INTEGER NOT NULL,"
"width INTEGER NOT NULL,"
"height INTEGER NOT NULL,"
"pixel_x_size DOUBLE NOT NULL,"
"pixel_y_size DOUBLE NOT NULL)",
osMetatadataLayer.c_str());
OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);
/* Add geometry column to _metadata table */
osSQL.Printf("SELECT AddGeometryColumn('%s', 'geometry', %d, 'POLYGON', 2)",
osMetatadataLayer.c_str(), nSRSId);
if ((hLyr = OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL)) == NULL)
{
CPLError(CE_Failure, CPLE_AppDefined,
"Check that the OGR SQLite driver has Spatialite support");
OGRReleaseDataSource(hDS);
return NULL;
}
OGR_DS_ReleaseResultSet(hDS, hLyr);
/* Create spatial index on _metadata table */
osSQL.Printf("SELECT CreateSpatialIndex('%s', 'geometry')",
osMetatadataLayer.c_str());
if ((hLyr = OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL)) == NULL)
{
OGRReleaseDataSource(hDS);
return NULL;
}
OGR_DS_ReleaseResultSet(hDS, hLyr);
/* Create statistics tables */
osSQL.Printf("SELECT UpdateLayerStatistics()");
CPLPushErrorHandler(CPLQuietErrorHandler);
hLyr = OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);
CPLPopErrorHandler();
OGR_DS_ReleaseResultSet(hDS, hLyr);
/* Re-open the DB to take into account the new tables*/
OGRReleaseDataSource(hDS);
hDS = RasterliteOpenSQLiteDB(osDBName.c_str(), GA_Update);
}
else
{
/* Check that the existing SRS is consistent with the one of the new */
/* data to be inserted */
osSQL.Printf("SELECT srid FROM geometry_columns WHERE f_table_name = '%s'",
osMetatadataLayer.c_str());
hLyr = OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);
if (hLyr)
{
int nExistingSRID = -1;
OGRFeatureH hFeat = OGR_L_GetNextFeature(hLyr);
if (hFeat)
{
nExistingSRID = OGR_F_GetFieldAsInteger(hFeat, 0);
OGR_F_Destroy(hFeat);
}
OGR_DS_ReleaseResultSet(hDS, hLyr);
if (nExistingSRID != nSRSId)
{
if (bWipeExistingData)
{
osSQL.Printf("UPDATE geometry_columns SET srid = %d "
"WHERE f_table_name = \"%s\"",
nSRSId, osMetatadataLayer.c_str());
OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);
/* Re-open the DB to take into account the change of SRS */
OGRReleaseDataSource(hDS);
hDS = RasterliteOpenSQLiteDB(osDBName.c_str(), GA_Update);
}
else
{
CPLError(CE_Failure, CPLE_NotSupported,
"New data has not the same SRS as existing data");
OGRReleaseDataSource(hDS);
return NULL;
}
}
}
if (bWipeExistingData)
{
osSQL.Printf("DELETE FROM \"%s\"", osRasterLayer.c_str());
OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);
osSQL.Printf("DELETE FROM \"%s\"", osMetatadataLayer.c_str());
OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);
}
}
return hDS;
}
/************************************************************************/
/* RasterliteCreateCopy () */
/************************************************************************/
GDALDataset *
RasterliteCreateCopy( const char * pszFilename, GDALDataset *poSrcDS,
CPL_UNUSED int bStrict,
char ** papszOptions,
GDALProgressFunc pfnProgress, void * pProgressData )
{
int nBands = poSrcDS->GetRasterCount();
if (nBands == 0)
{
CPLError(CE_Failure, CPLE_NotSupported, "nBands == 0");
return NULL;
}
const char* pszDriverName = CSLFetchNameValueDef(papszOptions, "DRIVER", "GTiff");
if (EQUAL(pszDriverName, "MEM") || EQUAL(pszDriverName, "VRT"))
{
CPLError(CE_Failure, CPLE_AppDefined, "GDAL %s driver cannot be used as underlying driver",
pszDriverName);
return NULL;
}
GDALDriverH hTileDriver = GDALGetDriverByName(pszDriverName);
if ( hTileDriver == NULL)
{
CPLError(CE_Failure, CPLE_AppDefined, "Cannot load GDAL %s driver", pszDriverName);
return NULL;
}
GDALDriverH hMemDriver = GDALGetDriverByName("MEM");
if (hMemDriver == NULL)
{
CPLError(CE_Failure, CPLE_AppDefined, "Cannot load GDAL MEM driver");
return NULL;
}
int nXSize = GDALGetRasterXSize(poSrcDS);
int nYSize = GDALGetRasterYSize(poSrcDS);
double adfGeoTransform[6];
if (poSrcDS->GetGeoTransform(adfGeoTransform) != CE_None)
{
adfGeoTransform[0] = 0;
adfGeoTransform[1] = 1;
adfGeoTransform[2] = 0;
adfGeoTransform[3] = 0;
adfGeoTransform[4] = 0;
adfGeoTransform[5] = -1;
}
else if (adfGeoTransform[2] != 0.0 || adfGeoTransform[4] != 0.0)
{
CPLError(CE_Failure, CPLE_AppDefined, "Cannot use geotransform with rotational terms");
return NULL;
}
int bTiled = CSLTestBoolean(CSLFetchNameValueDef(papszOptions, "TILED", "YES"));
int nBlockXSize, nBlockYSize;
if (bTiled)
{
nBlockXSize = atoi(CSLFetchNameValueDef(papszOptions, "BLOCKXSIZE", "256"));
nBlockYSize = atoi(CSLFetchNameValueDef(papszOptions, "BLOCKYSIZE", "256"));
if (nBlockXSize < 64) nBlockXSize = 64;
else if (nBlockXSize > 4096) nBlockXSize = 4096;
if (nBlockYSize < 64) nBlockYSize = 64;
else if (nBlockYSize > 4096) nBlockYSize = 4096;
}
else
{
nBlockXSize = nXSize;
nBlockYSize = nYSize;
}
/* -------------------------------------------------------------------- */
/* Analyze arguments */
/* -------------------------------------------------------------------- */
CPLString osDBName;
CPLString osTableName;
VSIStatBuf sBuf;
int bExists;
/* Skip optionnal RASTERLITE: prefix */
const char* pszFilenameWithoutPrefix = pszFilename;
if (EQUALN(pszFilename, "RASTERLITE:", 11))
pszFilenameWithoutPrefix += 11;
char** papszTokens = CSLTokenizeStringComplex(
pszFilenameWithoutPrefix, ",", FALSE, FALSE );
int nTokens = CSLCount(papszTokens);
if (nTokens == 0)
{
osDBName = pszFilenameWithoutPrefix;
osTableName = CPLGetBasename(pszFilenameWithoutPrefix);
}
else
{
osDBName = papszTokens[0];
int i;
for(i=1;i<nTokens;i++)
{
if (EQUALN(papszTokens[i], "table=", 6))
osTableName = papszTokens[i] + 6;
else
{
CPLError(CE_Warning, CPLE_AppDefined,
"Invalid option : %s", papszTokens[i]);
}
}
}
CSLDestroy(papszTokens);
papszTokens = NULL;
bExists = (VSIStat(osDBName.c_str(), &sBuf) == 0);
if (osTableName.size() == 0)
{
if (bExists)
{
CPLError(CE_Failure, CPLE_AppDefined,
"Database already exists. Explicit table name must be specified");
return NULL;
}
osTableName = CPLGetBasename(osDBName.c_str());
}
CPLString osRasterLayer;
osRasterLayer.Printf("%s_rasters", osTableName.c_str());
CPLString osMetatadataLayer;
osMetatadataLayer.Printf("%s_metadata", osTableName.c_str());
/* -------------------------------------------------------------------- */
/* Create or open the SQLite DB */
/* -------------------------------------------------------------------- */
if (OGRGetDriverCount() == 0)
OGRRegisterAll();
OGRSFDriverH hSQLiteDriver = OGRGetDriverByName("SQLite");
if (hSQLiteDriver == NULL)
{
CPLError(CE_Failure, CPLE_AppDefined, "Cannot load OGR SQLite driver");
return NULL;
}
OGRDataSourceH hDS;
if (!bExists)
{
char** papszOGROptions = CSLAddString(NULL, "SPATIALITE=YES");
hDS = OGR_Dr_CreateDataSource(hSQLiteDriver,
osDBName.c_str(), papszOGROptions);
CSLDestroy(papszOGROptions);
}
else
{
hDS = RasterliteOpenSQLiteDB(osDBName.c_str(), GA_Update);
}
if (hDS == NULL)
{
CPLError(CE_Failure, CPLE_AppDefined,
"Cannot load or create SQLite database");
return NULL;
}
CPLString osSQL;
/* -------------------------------------------------------------------- */
/* Get the SRID for the SRS */
/* -------------------------------------------------------------------- */
int nSRSId = RasterliteInsertSRID(hDS, poSrcDS->GetProjectionRef());
/* -------------------------------------------------------------------- */
/* Create or wipe existing tables */
/* -------------------------------------------------------------------- */
int bWipeExistingData =
CSLTestBoolean(CSLFetchNameValueDef(papszOptions, "WIPE", "NO"));
hDS = RasterliteCreateTables(hDS, osTableName.c_str(),
nSRSId, bWipeExistingData);
if (hDS == NULL)
return NULL;
OGRLayerH hRasterLayer = OGR_DS_GetLayerByName(hDS, osRasterLayer.c_str());
OGRLayerH hMetadataLayer = OGR_DS_GetLayerByName(hDS, osMetatadataLayer.c_str());
if (hRasterLayer == NULL || hMetadataLayer == NULL)
{
CPLError(CE_Failure, CPLE_AppDefined,
"Cannot find metadata and/or raster tables");
OGRReleaseDataSource(hDS);
return NULL;
}
/* -------------------------------------------------------------------- */
/* Check if there is overlapping data and warn the user */
/* -------------------------------------------------------------------- */
double minx = adfGeoTransform[0];
double maxx = adfGeoTransform[0] + nXSize * adfGeoTransform[1];
double maxy = adfGeoTransform[3];
double miny = adfGeoTransform[3] + nYSize * adfGeoTransform[5];
osSQL.Printf("SELECT COUNT(geometry) FROM \"%s\" "
"WHERE rowid IN "
"(SELECT pkid FROM \"idx_%s_metadata_geometry\" "
"WHERE %s) AND %s",
osMetatadataLayer.c_str(),
osTableName.c_str(),
RasterliteGetSpatialFilterCond(minx, miny, maxx, maxy).c_str(),
RasterliteGetPixelSizeCond(adfGeoTransform[1], -adfGeoTransform[5]).c_str());
int nOverlappingGeoms = 0;
OGRLayerH hCountLyr = OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);
if (hCountLyr)
{
OGRFeatureH hFeat = OGR_L_GetNextFeature(hCountLyr);
if (hFeat)
{
nOverlappingGeoms = OGR_F_GetFieldAsInteger(hFeat, 0);
OGR_F_Destroy(hFeat);
}
OGR_DS_ReleaseResultSet(hDS, hCountLyr);
}
if (nOverlappingGeoms != 0)
{
CPLError(CE_Warning, CPLE_AppDefined,
"Raster tiles already exist in the %s table within "
"the extent of the data to be inserted in",
osTableName.c_str());
}
/* -------------------------------------------------------------------- */
/* Iterate over blocks to add data into raster and metadata tables */
/* -------------------------------------------------------------------- */
int nXBlocks = (nXSize + nBlockXSize - 1) / nBlockXSize;
int nYBlocks = (nYSize + nBlockYSize - 1) / nBlockYSize;
GDALDataType eDataType = poSrcDS->GetRasterBand(1)->GetRasterDataType();
int nDataTypeSize = GDALGetDataTypeSize(eDataType) / 8;
GByte* pabyMEMDSBuffer =
(GByte*)VSIMalloc3(nBlockXSize, nBlockYSize, nBands * nDataTypeSize);
if (pabyMEMDSBuffer == NULL)
{
OGRReleaseDataSource(hDS);
return NULL;
}
CPLString osTempFileName;
osTempFileName.Printf("/vsimem/%p", hDS);
int nTileId = 0;
int nBlocks = 0;
int nTotalBlocks = nXBlocks * nYBlocks;
char** papszTileDriverOptions = RasterliteGetTileDriverOptions(papszOptions);
OGR_DS_ExecuteSQL(hDS, "BEGIN", NULL, NULL);
CPLErr eErr = CE_None;
int nBlockXOff, nBlockYOff;
for(nBlockYOff=0;eErr == CE_None && nBlockYOff<nYBlocks;nBlockYOff++)
{
for(nBlockXOff=0;eErr == CE_None && nBlockXOff<nXBlocks;nBlockXOff++)
{
/* -------------------------------------------------------------------- */
/* Create in-memory tile */
/* -------------------------------------------------------------------- */
int nReqXSize = nBlockXSize, nReqYSize = nBlockYSize;
if ((nBlockXOff+1) * nBlockXSize > nXSize)
nReqXSize = nXSize - nBlockXOff * nBlockXSize;
if ((nBlockYOff+1) * nBlockYSize > nYSize)
nReqYSize = nYSize - nBlockYOff * nBlockYSize;
eErr = poSrcDS->RasterIO(GF_Read,
nBlockXOff * nBlockXSize,
nBlockYOff * nBlockYSize,
nReqXSize, nReqYSize,
pabyMEMDSBuffer, nReqXSize, nReqYSize,
eDataType, nBands, NULL,
0, 0, 0, NULL);
if (eErr != CE_None)
{
break;
}
GDALDatasetH hMemDS = GDALCreate(hMemDriver, "MEM:::",
nReqXSize, nReqYSize, 0,
eDataType, NULL);
if (hMemDS == NULL)
{
eErr = CE_Failure;
break;
}
int iBand;
for(iBand = 0; iBand < nBands; iBand ++)
{
char** papszMEMDSOptions = NULL;
char szTmp[64];
memset(szTmp, 0, sizeof(szTmp));
CPLPrintPointer(szTmp,
pabyMEMDSBuffer + iBand * nDataTypeSize *
nReqXSize * nReqYSize, sizeof(szTmp));
papszMEMDSOptions = CSLSetNameValue(papszMEMDSOptions, "DATAPOINTER", szTmp);
GDALAddBand(hMemDS, eDataType, papszMEMDSOptions);
CSLDestroy(papszMEMDSOptions);
}
GDALDatasetH hOutDS = GDALCreateCopy(hTileDriver,
osTempFileName.c_str(), hMemDS, FALSE,
papszTileDriverOptions, NULL, NULL);
GDALClose(hMemDS);
if (hOutDS)
GDALClose(hOutDS);
else
{
eErr = CE_Failure;
break;
}
/* -------------------------------------------------------------------- */
/* Insert new entry into raster table */
/* -------------------------------------------------------------------- */
vsi_l_offset nDataLength = 0;
GByte *pabyData = VSIGetMemFileBuffer( osTempFileName.c_str(),
&nDataLength, FALSE);
OGRFeatureH hFeat = OGR_F_Create( OGR_L_GetLayerDefn(hRasterLayer) );
OGR_F_SetFieldBinary(hFeat, 0, (int)nDataLength, pabyData);
OGR_L_CreateFeature(hRasterLayer, hFeat);
/* Query raster ID to set it as the ID of the associated metadata */
int nRasterID = (int)OGR_F_GetFID(hFeat);
OGR_F_Destroy(hFeat);
VSIUnlink(osTempFileName.c_str());
/* -------------------------------------------------------------------- */
/* Insert new entry into metadata table */
/* -------------------------------------------------------------------- */
hFeat = OGR_F_Create( OGR_L_GetLayerDefn(hMetadataLayer) );
OGR_F_SetFID(hFeat, nRasterID);
OGR_F_SetFieldString(hFeat, 0, GDALGetDescription(poSrcDS));
OGR_F_SetFieldInteger(hFeat, 1, nTileId ++);
OGR_F_SetFieldInteger(hFeat, 2, nReqXSize);
OGR_F_SetFieldInteger(hFeat, 3, nReqYSize);
OGR_F_SetFieldDouble(hFeat, 4, adfGeoTransform[1]);
OGR_F_SetFieldDouble(hFeat, 5, -adfGeoTransform[5]);
minx = adfGeoTransform[0] +
(nBlockXSize * nBlockXOff) * adfGeoTransform[1];
maxx = adfGeoTransform[0] +
(nBlockXSize * nBlockXOff + nReqXSize) * adfGeoTransform[1];
maxy = adfGeoTransform[3] +
(nBlockYSize * nBlockYOff) * adfGeoTransform[5];
miny = adfGeoTransform[3] +
(nBlockYSize * nBlockYOff + nReqYSize) * adfGeoTransform[5];
OGRGeometryH hRectangle = OGR_G_CreateGeometry(wkbPolygon);
OGRGeometryH hLinearRing = OGR_G_CreateGeometry(wkbLinearRing);
OGR_G_AddPoint_2D(hLinearRing, minx, miny);
OGR_G_AddPoint_2D(hLinearRing, minx, maxy);
OGR_G_AddPoint_2D(hLinearRing, maxx, maxy);
OGR_G_AddPoint_2D(hLinearRing, maxx, miny);
OGR_G_AddPoint_2D(hLinearRing, minx, miny);
OGR_G_AddGeometryDirectly(hRectangle, hLinearRing);
OGR_F_SetGeometryDirectly(hFeat, hRectangle);
OGR_L_CreateFeature(hMetadataLayer, hFeat);
OGR_F_Destroy(hFeat);
nBlocks++;
if (pfnProgress && !pfnProgress(1.0 * nBlocks / nTotalBlocks,
NULL, pProgressData))
eErr = CE_Failure;
}
}
if (eErr == CE_None)
OGR_DS_ExecuteSQL(hDS, "COMMIT", NULL, NULL);
else
OGR_DS_ExecuteSQL(hDS, "ROLLBACK", NULL, NULL);
CSLDestroy(papszTileDriverOptions);
VSIFree(pabyMEMDSBuffer);
OGRReleaseDataSource(hDS);
return (GDALDataset*) GDALOpen(pszFilename, GA_Update);
}
/************************************************************************/
/* RasterliteDelete () */
/************************************************************************/
CPLErr RasterliteDelete(CPL_UNUSED const char* pszFilename)
{
return CE_None;
}