1 /******************************************************************************
2 * $Id: rasterliteoverviews.cpp 28053 2014-12-04 09:31:07Z 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-2012, Even Rouault <even dot rouault at mines-paris dot org>
10 *
11 * Permission is hereby granted, free of charge, to any person obtaining a
12 * copy of this software and associated documentation files (the "Software"),
13 * to deal in the Software without restriction, including without limitation
14 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
15 * and/or sell copies of the Software, and to permit persons to whom the
16 * Software is furnished to do so, subject to the following conditions:
17 *
18 * The above copyright notice and this permission notice shall be included
19 * in all copies or substantial portions of the Software.
20 *
21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
22 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
24 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
27 * DEALINGS IN THE SOFTWARE.
28 ****************************************************************************/
29
30 #include "cpl_string.h"
31 #include "ogr_api.h"
32 #include "ogr_srs_api.h"
33
34 #include "rasterlitedataset.h"
35
36 CPL_CVSID("$Id: rasterliteoverviews.cpp 28053 2014-12-04 09:31:07Z rouault $");
37
38 /************************************************************************/
39 /* ReloadOverviews() */
40 /************************************************************************/
41
ReloadOverviews()42 CPLErr RasterliteDataset::ReloadOverviews()
43 {
44 if (nLevel != 0)
45 return CE_Failure;
46
47 /* -------------------------------------------------------------------- */
48 /* Fetch resolutions */
49 /* -------------------------------------------------------------------- */
50
51 CPLString osSQL;
52 OGRLayerH hRasterPyramidsLyr = OGR_DS_GetLayerByName(hDS, "raster_pyramids");
53 if (hRasterPyramidsLyr)
54 {
55 osSQL.Printf("SELECT pixel_x_size, pixel_y_size "
56 "FROM raster_pyramids WHERE table_prefix = '%s' "
57 "ORDER BY pixel_x_size ASC",
58 osTableName.c_str());
59 }
60 else
61 {
62 osSQL.Printf("SELECT DISTINCT(pixel_x_size), pixel_y_size "
63 "FROM \"%s_metadata\" WHERE pixel_x_size != 0 "
64 "ORDER BY pixel_x_size ASC",
65 osTableName.c_str());
66 }
67
68 OGRLayerH hSQLLyr = OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);
69 if (hSQLLyr == NULL)
70 {
71 if (hRasterPyramidsLyr == NULL)
72 return CE_Failure;
73
74 osSQL.Printf("SELECT DISTINCT(pixel_x_size), pixel_y_size "
75 "FROM \"%s_metadata\" WHERE pixel_x_size != 0 "
76 "ORDER BY pixel_x_size ASC",
77 osTableName.c_str());
78
79 hSQLLyr = OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);
80 if (hSQLLyr == NULL)
81 return CE_Failure;
82 }
83
84 /* -------------------------------------------------------------------- */
85 /* Cleanup */
86 /* -------------------------------------------------------------------- */
87
88 int i;
89 for(i=1;i<nResolutions;i++)
90 delete papoOverviews[i-1];
91 CPLFree(papoOverviews);
92 papoOverviews = NULL;
93 CPLFree(padfXResolutions);
94 padfXResolutions = NULL;
95 CPLFree(padfYResolutions);
96 padfYResolutions = NULL;
97
98 /* -------------------------------------------------------------------- */
99 /* Rebuild arrays */
100 /* -------------------------------------------------------------------- */
101
102 nResolutions = OGR_L_GetFeatureCount(hSQLLyr, TRUE);
103
104 padfXResolutions =
105 (double*)CPLMalloc(sizeof(double) * nResolutions);
106 padfYResolutions =
107 (double*)CPLMalloc(sizeof(double) * nResolutions);
108
109 i = 0;
110 OGRFeatureH hFeat;
111 while((hFeat = OGR_L_GetNextFeature(hSQLLyr)) != NULL)
112 {
113 padfXResolutions[i] = OGR_F_GetFieldAsDouble(hFeat, 0);
114 padfYResolutions[i] = OGR_F_GetFieldAsDouble(hFeat, 1);
115
116 OGR_F_Destroy(hFeat);
117
118 i ++;
119 }
120
121 OGR_DS_ReleaseResultSet(hDS, hSQLLyr);
122 hSQLLyr = NULL;
123
124 /* -------------------------------------------------------------------- */
125 /* Add overview levels as internal datasets */
126 /* -------------------------------------------------------------------- */
127 if (nResolutions > 1)
128 {
129 CPLString osRasterTableName = osTableName;
130 osRasterTableName += "_rasters";
131
132 OGRLayerH hRasterLyr = OGR_DS_GetLayerByName(hDS, osRasterTableName.c_str());
133
134 papoOverviews = (RasterliteDataset**)
135 CPLCalloc(nResolutions - 1, sizeof(RasterliteDataset*));
136 int nLev;
137 for(nLev=1;nLev<nResolutions;nLev++)
138 {
139 int nOvrBands;
140 GDALDataType eOvrDataType;
141 int nBlockXSize, nBlockYSize;
142 if (GetBlockParams(hRasterLyr, nLev, &nOvrBands, &eOvrDataType,
143 &nBlockXSize, &nBlockYSize))
144 {
145 if (eOvrDataType == GDT_Byte && nOvrBands == 1 && nBands == 3)
146 nOvrBands = 3;
147
148 papoOverviews[nLev-1] = new RasterliteDataset(this, nLev);
149
150 int iBand;
151 for(iBand=0;iBand<nBands;iBand++)
152 {
153 papoOverviews[nLev-1]->SetBand(iBand+1,
154 new RasterliteBand(papoOverviews[nLev-1], iBand+1, eOvrDataType,
155 nBlockXSize, nBlockYSize));
156 }
157 }
158 else
159 {
160 CPLError(CE_Failure, CPLE_AppDefined,
161 "Cannot find block characteristics for overview %d", nLev);
162 papoOverviews[nLev-1] = NULL;
163 }
164 }
165 }
166
167 return CE_None;
168 }
169
170 /************************************************************************/
171 /* CleanOverviews() */
172 /************************************************************************/
173
CleanOverviews()174 CPLErr RasterliteDataset::CleanOverviews()
175 {
176 CPLString osSQL;
177
178 if (nLevel != 0)
179 return CE_Failure;
180
181 osSQL.Printf("BEGIN");
182 OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);
183
184 CPLString osResolutionCond =
185 "NOT " + RasterliteGetPixelSizeCond(padfXResolutions[0], padfYResolutions[0]);
186
187 osSQL.Printf("DELETE FROM \"%s_rasters\" WHERE id "
188 "IN(SELECT id FROM \"%s_metadata\" WHERE %s)",
189 osTableName.c_str(), osTableName.c_str(),
190 osResolutionCond.c_str());
191 OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);
192
193 osSQL.Printf("DELETE FROM \"%s_metadata\" WHERE %s",
194 osTableName.c_str(), osResolutionCond.c_str());
195 OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);
196
197 OGRLayerH hRasterPyramidsLyr = OGR_DS_GetLayerByName(hDS, "raster_pyramids");
198 if (hRasterPyramidsLyr)
199 {
200 osSQL.Printf("DELETE FROM raster_pyramids WHERE table_prefix = '%s' AND %s",
201 osTableName.c_str(), osResolutionCond.c_str());
202 OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);
203 }
204
205 osSQL.Printf("COMMIT");
206 OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);
207
208 int i;
209 for(i=1;i<nResolutions;i++)
210 delete papoOverviews[i-1];
211 CPLFree(papoOverviews);
212 papoOverviews = NULL;
213 nResolutions = 1;
214
215 return CE_None;
216 }
217
218 /************************************************************************/
219 /* CleanOverviewLevel() */
220 /************************************************************************/
221
CleanOverviewLevel(int nOvrFactor)222 CPLErr RasterliteDataset::CleanOverviewLevel(int nOvrFactor)
223 {
224 CPLString osSQL;
225
226 if (nLevel != 0)
227 return CE_Failure;
228
229 /* -------------------------------------------------------------------- */
230 /* Find the index of the overview matching the overview factor */
231 /* -------------------------------------------------------------------- */
232 int iLev;
233 for(iLev=1;iLev<nResolutions;iLev++)
234 {
235 if (fabs(padfXResolutions[0] * nOvrFactor - padfXResolutions[iLev]) < 1e-15 &&
236 fabs(padfYResolutions[0] * nOvrFactor - padfYResolutions[iLev]) < 1e-15)
237 break;
238 }
239
240 if (iLev == nResolutions)
241 return CE_None;
242
243 /* -------------------------------------------------------------------- */
244 /* Now clean existing overviews at that resolution */
245 /* -------------------------------------------------------------------- */
246
247 osSQL.Printf("BEGIN");
248 OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);
249
250 CPLString osResolutionCond =
251 RasterliteGetPixelSizeCond(padfXResolutions[iLev], padfYResolutions[iLev]);
252
253 osSQL.Printf("DELETE FROM \"%s_rasters\" WHERE id "
254 "IN(SELECT id FROM \"%s_metadata\" WHERE %s)",
255 osTableName.c_str(), osTableName.c_str(),
256 osResolutionCond.c_str());
257 OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);
258
259 osSQL.Printf("DELETE FROM \"%s_metadata\" WHERE %s",
260 osTableName.c_str(), osResolutionCond.c_str());
261 OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);
262
263 OGRLayerH hRasterPyramidsLyr = OGR_DS_GetLayerByName(hDS, "raster_pyramids");
264 if (hRasterPyramidsLyr)
265 {
266 osSQL.Printf("DELETE FROM raster_pyramids WHERE table_prefix = '%s' AND %s",
267 osTableName.c_str(), osResolutionCond.c_str());
268 OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);
269 }
270
271 osSQL.Printf("COMMIT");
272 OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);
273
274 return CE_None;
275 }
276
277 /************************************************************************/
278 /* CleanOverviewLevel() */
279 /************************************************************************/
280
CreateOverviewLevel(const char * pszResampling,int nOvrFactor,char ** papszOptions,GDALProgressFunc pfnProgress,void * pProgressData)281 CPLErr RasterliteDataset::CreateOverviewLevel(const char * pszResampling,
282 int nOvrFactor,
283 char** papszOptions,
284 GDALProgressFunc pfnProgress,
285 void * pProgressData)
286 {
287
288 double dfXResolution = padfXResolutions[0] * nOvrFactor;
289 double dfYResolution = padfXResolutions[0] * nOvrFactor;
290
291 CPLString osSQL;
292
293 int nOvrXSize = nRasterXSize / nOvrFactor;
294 int nOvrYSize = nRasterYSize / nOvrFactor;
295
296 if (nOvrXSize == 0 || nOvrYSize == 0)
297 return CE_Failure;
298
299 int bTiled = CSLTestBoolean(CSLFetchNameValueDef(papszOptions, "TILED", "YES"));
300 int nBlockXSize, nBlockYSize;
301 if (bTiled)
302 {
303 nBlockXSize = atoi(CSLFetchNameValueDef(papszOptions, "BLOCKXSIZE", "256"));
304 nBlockYSize = atoi(CSLFetchNameValueDef(papszOptions, "BLOCKYSIZE", "256"));
305 if (nBlockXSize < 64) nBlockXSize = 64;
306 else if (nBlockXSize > 4096) nBlockXSize = 4096;
307 if (nBlockYSize < 64) nBlockYSize = 64;
308 else if (nBlockYSize > 4096) nBlockYSize = 4096;
309 }
310 else
311 {
312 nBlockXSize = nOvrXSize;
313 nBlockYSize = nOvrYSize;
314 }
315
316 int nXBlocks = (nOvrXSize + nBlockXSize - 1) / nBlockXSize;
317 int nYBlocks = (nOvrYSize + nBlockYSize - 1) / nBlockYSize;
318
319 const char* pszDriverName = CSLFetchNameValueDef(papszOptions, "DRIVER", "GTiff");
320 if (EQUAL(pszDriverName, "MEM") || EQUAL(pszDriverName, "VRT"))
321 {
322 CPLError(CE_Failure, CPLE_AppDefined, "GDAL %s driver cannot be used as underlying driver",
323 pszDriverName);
324 return CE_Failure;
325 }
326 GDALDriverH hTileDriver = GDALGetDriverByName(pszDriverName);
327 if (hTileDriver == NULL)
328 {
329 CPLError(CE_Failure, CPLE_AppDefined, "Cannot load GDAL %s driver", pszDriverName);
330 return CE_Failure;
331 }
332
333 GDALDriverH hMemDriver = GDALGetDriverByName("MEM");
334 if (hMemDriver == NULL)
335 {
336 CPLError(CE_Failure, CPLE_AppDefined, "Cannot load GDAL MEM driver");
337 return CE_Failure;
338 }
339
340 GDALDataType eDataType = GetRasterBand(1)->GetRasterDataType();
341 int nDataTypeSize = GDALGetDataTypeSize(eDataType) / 8;
342 GByte* pabyMEMDSBuffer =
343 (GByte*)VSIMalloc3(nBlockXSize, nBlockYSize, nBands * nDataTypeSize);
344 if (pabyMEMDSBuffer == NULL)
345 {
346 return CE_Failure;
347 }
348
349 CPLString osTempFileName;
350 osTempFileName.Printf("/vsimem/%p", hDS);
351
352 int nTileId = 0;
353 int nBlocks = 0;
354 int nTotalBlocks = nXBlocks * nYBlocks;
355
356 CPLString osRasterLayer;
357 osRasterLayer.Printf("%s_rasters", osTableName.c_str());
358
359 CPLString osMetatadataLayer;
360 osMetatadataLayer.Printf("%s_metadata", osTableName.c_str());
361
362 OGRLayerH hRasterLayer = OGR_DS_GetLayerByName(hDS, osRasterLayer.c_str());
363 OGRLayerH hMetadataLayer = OGR_DS_GetLayerByName(hDS, osMetatadataLayer.c_str());
364
365 CPLString osSourceName = "unknown";
366
367 osSQL.Printf("SELECT source_name FROM \"%s\" WHERE "
368 "%s LIMIT 1",
369 osMetatadataLayer.c_str(),
370 RasterliteGetPixelSizeCond(padfXResolutions[0], padfYResolutions[0]).c_str());
371 OGRLayerH hSQLLyr = OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);
372 if (hSQLLyr)
373 {
374 OGRFeatureH hFeat = OGR_L_GetNextFeature(hSQLLyr);
375 if (hFeat)
376 {
377 const char* pszVal = OGR_F_GetFieldAsString(hFeat, 0);
378 if (pszVal)
379 osSourceName = pszVal;
380 OGR_F_Destroy(hFeat);
381 }
382 OGR_DS_ReleaseResultSet(hDS, hSQLLyr);
383 }
384
385 /* -------------------------------------------------------------------- */
386 /* Compute up to which existing overview level we can use for */
387 /* computing the requested overview */
388 /* -------------------------------------------------------------------- */
389 int iLev;
390 nLimitOvrCount = 0;
391 for(iLev=1;iLev<nResolutions;iLev++)
392 {
393 if (!(padfXResolutions[iLev] < dfXResolution - 1e-10 &&
394 padfYResolutions[iLev] < dfYResolution - 1e-10))
395 {
396 break;
397 }
398 nLimitOvrCount++;
399 }
400 /* -------------------------------------------------------------------- */
401 /* Allocate buffer for tile of previous overview level */
402 /* -------------------------------------------------------------------- */
403
404 GDALDataset* poPrevOvrLevel =
405 (papoOverviews != NULL && iLev >= 2 && iLev <= nResolutions && papoOverviews[iLev-2]) ?
406 papoOverviews[iLev-2] : this;
407 double dfRatioPrevOvr = poPrevOvrLevel->GetRasterBand(1)->GetXSize() / nOvrXSize;
408 int nPrevOvrBlockXSize = (int)(nBlockXSize * dfRatioPrevOvr + 0.5);
409 int nPrevOvrBlockYSize = (int)(nBlockYSize * dfRatioPrevOvr + 0.5);
410 GByte* pabyPrevOvrMEMDSBuffer = NULL;
411
412 if( !EQUALN(pszResampling, "NEAR", 4))
413 {
414 pabyPrevOvrMEMDSBuffer =
415 (GByte*)VSIMalloc3(nPrevOvrBlockXSize, nPrevOvrBlockYSize, nBands * nDataTypeSize);
416 if (pabyPrevOvrMEMDSBuffer == NULL)
417 {
418 VSIFree(pabyMEMDSBuffer);
419 return CE_Failure;
420 }
421 }
422
423 /* -------------------------------------------------------------------- */
424 /* Iterate over blocks to add data into raster and metadata tables */
425 /* -------------------------------------------------------------------- */
426
427 char** papszTileDriverOptions = RasterliteGetTileDriverOptions(papszOptions);
428
429 OGR_DS_ExecuteSQL(hDS, "BEGIN", NULL, NULL);
430
431 CPLErr eErr = CE_None;
432 int nBlockXOff, nBlockYOff;
433 for(nBlockYOff=0;eErr == CE_None && nBlockYOff<nYBlocks;nBlockYOff++)
434 {
435 for(nBlockXOff=0;eErr == CE_None && nBlockXOff<nXBlocks;nBlockXOff++)
436 {
437 GDALDatasetH hPrevOvrMemDS = NULL;
438
439 /* -------------------------------------------------------------------- */
440 /* Create in-memory tile */
441 /* -------------------------------------------------------------------- */
442 int nReqXSize = nBlockXSize, nReqYSize = nBlockYSize;
443 if ((nBlockXOff+1) * nBlockXSize > nOvrXSize)
444 nReqXSize = nOvrXSize - nBlockXOff * nBlockXSize;
445 if ((nBlockYOff+1) * nBlockYSize > nOvrYSize)
446 nReqYSize = nOvrYSize - nBlockYOff * nBlockYSize;
447
448 if( pabyPrevOvrMEMDSBuffer != NULL )
449 {
450 int nPrevOvrReqXSize =
451 (int)(nReqXSize * dfRatioPrevOvr + 0.5);
452 int nPrevOvrReqYSize =
453 (int)(nReqYSize * dfRatioPrevOvr + 0.5);
454
455 eErr = RasterIO(GF_Read,
456 nBlockXOff * nBlockXSize * nOvrFactor,
457 nBlockYOff * nBlockYSize * nOvrFactor,
458 nReqXSize * nOvrFactor, nReqYSize * nOvrFactor,
459 pabyPrevOvrMEMDSBuffer, nPrevOvrReqXSize, nPrevOvrReqYSize,
460 eDataType, nBands, NULL,
461 0, 0, 0, NULL);
462
463 if (eErr != CE_None)
464 {
465 break;
466 }
467
468 hPrevOvrMemDS = GDALCreate(hMemDriver, "MEM:::",
469 nPrevOvrReqXSize, nPrevOvrReqYSize, 0,
470 eDataType, NULL);
471
472 if (hPrevOvrMemDS == NULL)
473 {
474 eErr = CE_Failure;
475 break;
476 }
477
478 int iBand;
479 for(iBand = 0; iBand < nBands; iBand ++)
480 {
481 char** papszOptions = NULL;
482 char szTmp[64];
483 memset(szTmp, 0, sizeof(szTmp));
484 CPLPrintPointer(szTmp,
485 pabyPrevOvrMEMDSBuffer + iBand * nDataTypeSize *
486 nPrevOvrReqXSize * nPrevOvrReqYSize, sizeof(szTmp));
487 papszOptions = CSLSetNameValue(papszOptions, "DATAPOINTER", szTmp);
488 GDALAddBand(hPrevOvrMemDS, eDataType, papszOptions);
489 CSLDestroy(papszOptions);
490 }
491 }
492 else
493 {
494 eErr = RasterIO(GF_Read,
495 nBlockXOff * nBlockXSize * nOvrFactor,
496 nBlockYOff * nBlockYSize * nOvrFactor,
497 nReqXSize * nOvrFactor, nReqYSize * nOvrFactor,
498 pabyMEMDSBuffer, nReqXSize, nReqYSize,
499 eDataType, nBands, NULL,
500 0, 0, 0, NULL);
501 if (eErr != CE_None)
502 {
503 break;
504 }
505 }
506
507 GDALDatasetH hMemDS = GDALCreate(hMemDriver, "MEM:::",
508 nReqXSize, nReqYSize, 0,
509 eDataType, NULL);
510 if (hMemDS == NULL)
511 {
512 eErr = CE_Failure;
513 break;
514 }
515
516 int iBand;
517 for(iBand = 0; iBand < nBands; iBand ++)
518 {
519 char** papszOptions = NULL;
520 char szTmp[64];
521 memset(szTmp, 0, sizeof(szTmp));
522 CPLPrintPointer(szTmp,
523 pabyMEMDSBuffer + iBand * nDataTypeSize *
524 nReqXSize * nReqYSize, sizeof(szTmp));
525 papszOptions = CSLSetNameValue(papszOptions, "DATAPOINTER", szTmp);
526 GDALAddBand(hMemDS, eDataType, papszOptions);
527 CSLDestroy(papszOptions);
528 }
529
530 if( hPrevOvrMemDS != NULL )
531 {
532 for(iBand = 0; iBand < nBands; iBand ++)
533 {
534 GDALRasterBandH hDstOvrBand = GDALGetRasterBand(hMemDS, iBand+1);
535
536 eErr = GDALRegenerateOverviews( GDALGetRasterBand(hPrevOvrMemDS, iBand+1),
537 1, &hDstOvrBand,
538 pszResampling,
539 NULL, NULL );
540 if( eErr != CE_None )
541 break;
542 }
543
544 GDALClose(hPrevOvrMemDS);
545 }
546
547 GDALDatasetH hOutDS = GDALCreateCopy(hTileDriver,
548 osTempFileName.c_str(), hMemDS, FALSE,
549 papszTileDriverOptions, NULL, NULL);
550
551 GDALClose(hMemDS);
552 if (hOutDS)
553 GDALClose(hOutDS);
554 else
555 {
556 eErr = CE_Failure;
557 break;
558 }
559
560 /* -------------------------------------------------------------------- */
561 /* Insert new entry into raster table */
562 /* -------------------------------------------------------------------- */
563
564 vsi_l_offset nDataLength;
565 GByte *pabyData = VSIGetMemFileBuffer( osTempFileName.c_str(),
566 &nDataLength, FALSE);
567
568 OGRFeatureH hFeat = OGR_F_Create( OGR_L_GetLayerDefn(hRasterLayer) );
569 OGR_F_SetFieldBinary(hFeat, 0, (int)nDataLength, pabyData);
570
571 OGR_L_CreateFeature(hRasterLayer, hFeat);
572 /* Query raster ID to set it as the ID of the associated metadata */
573 int nRasterID = (int)OGR_F_GetFID(hFeat);
574
575 OGR_F_Destroy(hFeat);
576
577 VSIUnlink(osTempFileName.c_str());
578
579 /* -------------------------------------------------------------------- */
580 /* Insert new entry into metadata table */
581 /* -------------------------------------------------------------------- */
582
583 hFeat = OGR_F_Create( OGR_L_GetLayerDefn(hMetadataLayer) );
584 OGR_F_SetFID(hFeat, nRasterID);
585 OGR_F_SetFieldString(hFeat, 0, osSourceName);
586 OGR_F_SetFieldInteger(hFeat, 1, nTileId ++);
587 OGR_F_SetFieldInteger(hFeat, 2, nReqXSize);
588 OGR_F_SetFieldInteger(hFeat, 3, nReqYSize);
589 OGR_F_SetFieldDouble(hFeat, 4, dfXResolution);
590 OGR_F_SetFieldDouble(hFeat, 5, dfYResolution);
591
592 double minx, maxx, maxy, miny;
593 minx = adfGeoTransform[0] +
594 (nBlockXSize * nBlockXOff) * dfXResolution;
595 maxx = adfGeoTransform[0] +
596 (nBlockXSize * nBlockXOff + nReqXSize) * dfXResolution;
597 maxy = adfGeoTransform[3] +
598 (nBlockYSize * nBlockYOff) * (-dfYResolution);
599 miny = adfGeoTransform[3] +
600 (nBlockYSize * nBlockYOff + nReqYSize) * (-dfYResolution);
601
602 OGRGeometryH hRectangle = OGR_G_CreateGeometry(wkbPolygon);
603 OGRGeometryH hLinearRing = OGR_G_CreateGeometry(wkbLinearRing);
604 OGR_G_AddPoint_2D(hLinearRing, minx, miny);
605 OGR_G_AddPoint_2D(hLinearRing, minx, maxy);
606 OGR_G_AddPoint_2D(hLinearRing, maxx, maxy);
607 OGR_G_AddPoint_2D(hLinearRing, maxx, miny);
608 OGR_G_AddPoint_2D(hLinearRing, minx, miny);
609 OGR_G_AddGeometryDirectly(hRectangle, hLinearRing);
610
611 OGR_F_SetGeometryDirectly(hFeat, hRectangle);
612
613 OGR_L_CreateFeature(hMetadataLayer, hFeat);
614 OGR_F_Destroy(hFeat);
615
616 nBlocks++;
617 if (pfnProgress && !pfnProgress(1.0 * nBlocks / nTotalBlocks,
618 NULL, pProgressData))
619 eErr = CE_Failure;
620 }
621 }
622
623 nLimitOvrCount = -1;
624
625 if (eErr == CE_None)
626 OGR_DS_ExecuteSQL(hDS, "COMMIT", NULL, NULL);
627 else
628 OGR_DS_ExecuteSQL(hDS, "ROLLBACK", NULL, NULL);
629
630 VSIFree(pabyMEMDSBuffer);
631 VSIFree(pabyPrevOvrMEMDSBuffer);
632
633 CSLDestroy(papszTileDriverOptions);
634 papszTileDriverOptions = NULL;
635
636 /* -------------------------------------------------------------------- */
637 /* Update raster_pyramids table */
638 /* -------------------------------------------------------------------- */
639 if (eErr == CE_None)
640 {
641 OGRLayerH hRasterPyramidsLyr = OGR_DS_GetLayerByName(hDS, "raster_pyramids");
642 if (hRasterPyramidsLyr == NULL)
643 {
644 osSQL.Printf ("CREATE TABLE raster_pyramids ("
645 "table_prefix TEXT NOT NULL,"
646 "pixel_x_size DOUBLE NOT NULL,"
647 "pixel_y_size DOUBLE NOT NULL,"
648 "tile_count INTEGER NOT NULL)");
649 OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);
650
651 /* Re-open the DB to take into account the new tables*/
652 OGRReleaseDataSource(hDS);
653
654 hDS = RasterliteOpenSQLiteDB(osFileName.c_str(), GA_Update);
655
656 hRasterPyramidsLyr = OGR_DS_GetLayerByName(hDS, "raster_pyramids");
657 if (hRasterPyramidsLyr == NULL)
658 return CE_Failure;
659 }
660 OGRFeatureDefnH hFDefn = OGR_L_GetLayerDefn(hRasterPyramidsLyr);
661
662 /* Insert base resolution into raster_pyramids if not already done */
663 int bHasBaseResolution = FALSE;
664 osSQL.Printf("SELECT * FROM raster_pyramids WHERE "
665 "table_prefix = '%s' AND %s",
666 osTableName.c_str(),
667 RasterliteGetPixelSizeCond(padfXResolutions[0], padfYResolutions[0]).c_str());
668 hSQLLyr = OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);
669 if (hSQLLyr)
670 {
671 OGRFeatureH hFeat = OGR_L_GetNextFeature(hSQLLyr);
672 if (hFeat)
673 {
674 bHasBaseResolution = TRUE;
675 OGR_F_Destroy(hFeat);
676 }
677 OGR_DS_ReleaseResultSet(hDS, hSQLLyr);
678 }
679
680 if (!bHasBaseResolution)
681 {
682 osSQL.Printf("SELECT COUNT(*) FROM \"%s\" WHERE %s",
683 osMetatadataLayer.c_str(),
684 RasterliteGetPixelSizeCond(padfXResolutions[0], padfYResolutions[0]).c_str());
685
686 int nBlocksMainRes = 0;
687
688 hSQLLyr = OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);
689 if (hSQLLyr)
690 {
691 OGRFeatureH hFeat = OGR_L_GetNextFeature(hSQLLyr);
692 if (hFeat)
693 {
694 nBlocksMainRes = OGR_F_GetFieldAsInteger(hFeat, 0);
695 OGR_F_Destroy(hFeat);
696 }
697 OGR_DS_ReleaseResultSet(hDS, hSQLLyr);
698 }
699
700 OGRFeatureH hFeat = OGR_F_Create( hFDefn );
701 OGR_F_SetFieldString(hFeat, OGR_FD_GetFieldIndex(hFDefn, "table_prefix"), osTableName.c_str());
702 OGR_F_SetFieldDouble(hFeat, OGR_FD_GetFieldIndex(hFDefn, "pixel_x_size"), padfXResolutions[0]);
703 OGR_F_SetFieldDouble(hFeat, OGR_FD_GetFieldIndex(hFDefn, "pixel_y_size"), padfYResolutions[0]);
704 OGR_F_SetFieldInteger(hFeat, OGR_FD_GetFieldIndex(hFDefn, "tile_count"), nBlocksMainRes);
705 OGR_L_CreateFeature(hRasterPyramidsLyr, hFeat);
706 OGR_F_Destroy(hFeat);
707 }
708
709 OGRFeatureH hFeat = OGR_F_Create( hFDefn );
710 OGR_F_SetFieldString(hFeat, OGR_FD_GetFieldIndex(hFDefn, "table_prefix"), osTableName.c_str());
711 OGR_F_SetFieldDouble(hFeat, OGR_FD_GetFieldIndex(hFDefn, "pixel_x_size"), dfXResolution);
712 OGR_F_SetFieldDouble(hFeat, OGR_FD_GetFieldIndex(hFDefn, "pixel_y_size"), dfYResolution);
713 OGR_F_SetFieldInteger(hFeat, OGR_FD_GetFieldIndex(hFDefn, "tile_count"), nTotalBlocks);
714 OGR_L_CreateFeature(hRasterPyramidsLyr, hFeat);
715 OGR_F_Destroy(hFeat);
716 }
717
718 return eErr;
719 }
720
721 /************************************************************************/
722 /* IBuildOverviews() */
723 /************************************************************************/
724
IBuildOverviews(const char * pszResampling,int nOverviews,int * panOverviewList,int nBands,int * panBandList,GDALProgressFunc pfnProgress,void * pProgressData)725 CPLErr RasterliteDataset::IBuildOverviews( const char * pszResampling,
726 int nOverviews, int * panOverviewList,
727 int nBands, int * panBandList,
728 GDALProgressFunc pfnProgress,
729 void * pProgressData )
730 {
731 CPLErr eErr = CE_None;
732
733 if (nLevel != 0)
734 {
735 CPLError(CE_Failure, CPLE_AppDefined,
736 "Overviews can only be computed on the base dataset");
737 return CE_Failure;
738 }
739
740 if (osTableName.size() == 0)
741 return CE_Failure;
742
743 /* -------------------------------------------------------------------- */
744 /* If we don't have read access, then create the overviews */
745 /* externally. */
746 /* -------------------------------------------------------------------- */
747 if( GetAccess() != GA_Update )
748 {
749 CPLDebug( "Rasterlite",
750 "File open for read-only accessing, "
751 "creating overviews externally." );
752
753 if (nResolutions != 1)
754 {
755 CPLError(CE_Failure, CPLE_NotSupported,
756 "Cannot add external overviews to a "
757 "dataset with internal overviews");
758 return CE_Failure;
759 }
760
761 bCheckForExistingOverview = FALSE;
762 eErr = GDALDataset::IBuildOverviews(
763 pszResampling, nOverviews, panOverviewList,
764 nBands, panBandList, pfnProgress, pProgressData );
765 bCheckForExistingOverview = TRUE;
766 return eErr;
767 }
768
769 /* -------------------------------------------------------------------- */
770 /* If zero overviews were requested, we need to clear all */
771 /* existing overviews. */
772 /* -------------------------------------------------------------------- */
773 if (nOverviews == 0)
774 {
775 return CleanOverviews();
776 }
777
778 if( nBands != GetRasterCount() )
779 {
780 CPLError( CE_Failure, CPLE_NotSupported,
781 "Generation of overviews in RASTERLITE only"
782 " supported when operating on all bands.\n"
783 "Operation failed.\n" );
784 return CE_Failure;
785 }
786
787 const char* pszOvrOptions = CPLGetConfigOption("RASTERLITE_OVR_OPTIONS", NULL);
788 char** papszOptions = (pszOvrOptions) ? CSLTokenizeString2( pszOvrOptions, ",", 0) : NULL;
789 GDALValidateCreationOptions( GetDriver(), papszOptions);
790
791 int i;
792 for(i=0;i<nOverviews && eErr == CE_None;i++)
793 {
794 if (panOverviewList[i] <= 1)
795 continue;
796
797 eErr = CleanOverviewLevel(panOverviewList[i]);
798 if (eErr == CE_None)
799 eErr = CreateOverviewLevel(pszResampling, panOverviewList[i], papszOptions, pfnProgress, pProgressData);
800
801 ReloadOverviews();
802 }
803
804 CSLDestroy(papszOptions);
805
806 return eErr;
807 }
808