1 : /******************************************************************************
2 : * $Id: rasterliteoverviews.cpp 19563 2010-04-28 21:02:05Z 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: rasterliteoverviews.cpp 19563 2010-04-28 21:02:05Z rouault $");
37 :
38 : /************************************************************************/
39 : /* ReloadOverviews() */
40 : /************************************************************************/
41 :
42 2 : CPLErr RasterliteDataset::ReloadOverviews()
43 : {
44 2 : if (nLevel != 0)
45 0 : return CE_Failure;
46 :
47 : /* -------------------------------------------------------------------- */
48 : /* Fetch resolutions */
49 : /* -------------------------------------------------------------------- */
50 :
51 2 : CPLString osSQL;
52 2 : OGRLayerH hRasterPyramidsLyr = OGR_DS_GetLayerByName(hDS, "raster_pyramids");
53 2 : 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 2 : 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 0 : osTableName.c_str());
66 : }
67 :
68 2 : OGRLayerH hSQLLyr = OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);
69 2 : if (hSQLLyr == NULL)
70 : {
71 0 : if (hRasterPyramidsLyr == NULL)
72 0 : 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 0 : osTableName.c_str());
78 :
79 0 : hSQLLyr = OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);
80 0 : if (hSQLLyr == NULL)
81 0 : return CE_Failure;
82 : }
83 :
84 : /* -------------------------------------------------------------------- */
85 : /* Cleanup */
86 : /* -------------------------------------------------------------------- */
87 :
88 : int i;
89 3 : for(i=1;i<nResolutions;i++)
90 1 : delete papoOverviews[i-1];
91 2 : CPLFree(papoOverviews);
92 2 : papoOverviews = NULL;
93 2 : CPLFree(padfXResolutions);
94 2 : padfXResolutions = NULL;
95 2 : CPLFree(padfYResolutions);
96 2 : padfYResolutions = NULL;
97 :
98 : /* -------------------------------------------------------------------- */
99 : /* Rebuild arrays */
100 : /* -------------------------------------------------------------------- */
101 :
102 2 : nResolutions = OGR_L_GetFeatureCount(hSQLLyr, TRUE);
103 :
104 : padfXResolutions =
105 2 : (double*)CPLMalloc(sizeof(double) * nResolutions);
106 : padfYResolutions =
107 2 : (double*)CPLMalloc(sizeof(double) * nResolutions);
108 :
109 2 : i = 0;
110 : OGRFeatureH hFeat;
111 9 : while((hFeat = OGR_L_GetNextFeature(hSQLLyr)) != NULL)
112 : {
113 5 : padfXResolutions[i] = OGR_F_GetFieldAsDouble(hFeat, 0);
114 5 : padfYResolutions[i] = OGR_F_GetFieldAsDouble(hFeat, 1);
115 :
116 5 : OGR_F_Destroy(hFeat);
117 :
118 5 : i ++;
119 : }
120 :
121 2 : OGR_DS_ReleaseResultSet(hDS, hSQLLyr);
122 2 : hSQLLyr = NULL;
123 :
124 : /* -------------------------------------------------------------------- */
125 : /* Add overview levels as internal datasets */
126 : /* -------------------------------------------------------------------- */
127 2 : if (nResolutions > 1)
128 : {
129 2 : CPLString osRasterTableName = osTableName;
130 2 : osRasterTableName += "_rasters";
131 :
132 2 : OGRLayerH hRasterLyr = OGR_DS_GetLayerByName(hDS, osRasterTableName.c_str());
133 :
134 : papoOverviews = (RasterliteDataset**)
135 2 : CPLCalloc(nResolutions - 1, sizeof(RasterliteDataset*));
136 : int nLev;
137 5 : for(nLev=1;nLev<nResolutions;nLev++)
138 : {
139 : int nOvrBands;
140 : GDALDataType eOvrDataType;
141 : int nBlockXSize, nBlockYSize;
142 3 : if (GetBlockParams(hRasterLyr, nLev, &nOvrBands, &eOvrDataType,
143 : &nBlockXSize, &nBlockYSize))
144 : {
145 3 : if (eOvrDataType == GDT_Byte && nOvrBands == 1 && nBands == 3)
146 0 : nOvrBands = 3;
147 :
148 3 : papoOverviews[nLev-1] = new RasterliteDataset(this, nLev);
149 :
150 : int iBand;
151 6 : for(iBand=0;iBand<nBands;iBand++)
152 : {
153 : papoOverviews[nLev-1]->SetBand(iBand+1,
154 : new RasterliteBand(papoOverviews[nLev-1], iBand+1, eOvrDataType,
155 3 : nBlockXSize, nBlockYSize));
156 : }
157 : }
158 : else
159 : {
160 : CPLError(CE_Failure, CPLE_AppDefined,
161 0 : "Cannot find block characteristics for overview %d", nLev);
162 0 : papoOverviews[nLev-1] = NULL;
163 : }
164 2 : }
165 : }
166 :
167 2 : return CE_None;
168 : }
169 :
170 : /************************************************************************/
171 : /* CleanOverviews() */
172 : /************************************************************************/
173 :
174 1 : CPLErr RasterliteDataset::CleanOverviews()
175 : {
176 1 : CPLString osSQL;
177 :
178 1 : if (nLevel != 0)
179 0 : return CE_Failure;
180 :
181 1 : osSQL.Printf("BEGIN");
182 1 : OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);
183 :
184 1 : CPLString osResolutionCond;
185 : osResolutionCond.Printf(
186 : "(pixel_x_size < %.15f OR pixel_x_size > %.15f) AND "
187 : "(pixel_y_size < %.15f OR pixel_y_size > %.15f)",
188 : padfXResolutions[0] - 1e-15, padfXResolutions[0] + 1e-15,
189 1 : padfYResolutions[0] - 1e-15, padfYResolutions[0] + 1e-15);
190 :
191 : osSQL.Printf("DELETE FROM \"%s_rasters\" WHERE id "
192 : "IN(SELECT id FROM \"%s_metadata\" WHERE %s)",
193 : osTableName.c_str(), osTableName.c_str(),
194 1 : osResolutionCond.c_str());
195 1 : OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);
196 :
197 : osSQL.Printf("DELETE FROM \"%s_metadata\" WHERE %s",
198 1 : osTableName.c_str(), osResolutionCond.c_str());
199 1 : OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);
200 :
201 1 : OGRLayerH hRasterPyramidsLyr = OGR_DS_GetLayerByName(hDS, "raster_pyramids");
202 1 : if (hRasterPyramidsLyr)
203 : {
204 : osSQL.Printf("DELETE FROM raster_pyramids WHERE table_prefix = '%s' AND %s",
205 1 : osTableName.c_str(), osResolutionCond.c_str());
206 1 : OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);
207 : }
208 :
209 1 : osSQL.Printf("COMMIT");
210 1 : OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);
211 :
212 : int i;
213 3 : for(i=1;i<nResolutions;i++)
214 2 : delete papoOverviews[i-1];
215 1 : CPLFree(papoOverviews);
216 1 : papoOverviews = NULL;
217 1 : nResolutions = 1;
218 :
219 1 : return CE_None;
220 : }
221 :
222 : /************************************************************************/
223 : /* CleanOverviewLevel() */
224 : /************************************************************************/
225 :
226 2 : CPLErr RasterliteDataset::CleanOverviewLevel(int nOvrFactor)
227 : {
228 2 : CPLString osSQL;
229 :
230 2 : if (nLevel != 0)
231 0 : return CE_Failure;
232 :
233 : /* -------------------------------------------------------------------- */
234 : /* Find the index of the overview matching the overview factor */
235 : /* -------------------------------------------------------------------- */
236 : int iLev;
237 3 : for(iLev=1;iLev<nResolutions;iLev++)
238 : {
239 1 : if (fabs(padfXResolutions[0] * nOvrFactor - padfXResolutions[iLev]) < 1e-15 &&
240 : fabs(padfYResolutions[0] * nOvrFactor - padfYResolutions[iLev]) < 1e-15)
241 0 : break;
242 : }
243 :
244 2 : if (iLev == nResolutions)
245 2 : return CE_None;
246 :
247 : /* -------------------------------------------------------------------- */
248 : /* Now clean existing overviews at that resolution */
249 : /* -------------------------------------------------------------------- */
250 :
251 0 : osSQL.Printf("BEGIN");
252 0 : OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);
253 :
254 0 : CPLString osResolutionCond;
255 : osResolutionCond.Printf(
256 : "pixel_x_size >= %.15f AND pixel_x_size <= %.15f AND "
257 : "pixel_y_size >= %.15f AND pixel_y_size <= %.15f",
258 : padfXResolutions[iLev] - 1e-15, padfXResolutions[iLev] + 1e-15,
259 0 : padfYResolutions[iLev] - 1e-15, padfYResolutions[iLev] + 1e-15);
260 :
261 : osSQL.Printf("DELETE FROM \"%s_rasters\" WHERE id "
262 : "IN(SELECT id FROM \"%s_metadata\" WHERE %s)",
263 : osTableName.c_str(), osTableName.c_str(),
264 0 : osResolutionCond.c_str());
265 0 : OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);
266 :
267 : osSQL.Printf("DELETE FROM \"%s_metadata\" WHERE %s",
268 0 : osTableName.c_str(), osResolutionCond.c_str());
269 0 : OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);
270 :
271 0 : OGRLayerH hRasterPyramidsLyr = OGR_DS_GetLayerByName(hDS, "raster_pyramids");
272 0 : if (hRasterPyramidsLyr)
273 : {
274 : osSQL.Printf("DELETE FROM raster_pyramids WHERE table_prefix = '%s' AND %s",
275 0 : osTableName.c_str(), osResolutionCond.c_str());
276 0 : OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);
277 : }
278 :
279 0 : osSQL.Printf("COMMIT");
280 0 : OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);
281 :
282 0 : return CE_None;
283 : }
284 :
285 : /************************************************************************/
286 : /* CleanOverviewLevel() */
287 : /************************************************************************/
288 :
289 : CPLErr RasterliteDataset::CreateOverviewLevel(int nOvrFactor,
290 : GDALProgressFunc pfnProgress,
291 2 : void * pProgressData)
292 : {
293 :
294 2 : double dfXResolution = padfXResolutions[0] * nOvrFactor;
295 2 : double dfYResolution = padfXResolutions[0] * nOvrFactor;
296 :
297 2 : CPLString osSQL;
298 :
299 2 : int nBlockXSize = 256;
300 2 : int nBlockYSize = 256;
301 2 : int nOvrXSize = nRasterXSize / nOvrFactor;
302 2 : int nOvrYSize = nRasterYSize / nOvrFactor;
303 :
304 2 : if (nOvrXSize == 0 || nOvrYSize == 0)
305 0 : return CE_Failure;
306 :
307 2 : int nXBlocks = (nOvrXSize + nBlockXSize - 1) / nBlockXSize;
308 2 : int nYBlocks = (nOvrYSize + nBlockYSize - 1) / nBlockYSize;
309 :
310 2 : const char* pszDriverName = "GTiff";
311 2 : GDALDriverH hTileDriver = GDALGetDriverByName(pszDriverName);
312 2 : if (hTileDriver == NULL)
313 : {
314 0 : CPLError(CE_Failure, CPLE_AppDefined, "Cannot load GDAL %s driver", pszDriverName);
315 0 : return CE_Failure;
316 : }
317 :
318 2 : GDALDriverH hMemDriver = GDALGetDriverByName("MEM");
319 2 : if (hMemDriver == NULL)
320 : {
321 0 : CPLError(CE_Failure, CPLE_AppDefined, "Cannot load GDAL MEM driver");
322 0 : return CE_Failure;
323 : }
324 :
325 2 : GDALDataType eDataType = GetRasterBand(1)->GetRasterDataType();
326 2 : int nDataTypeSize = GDALGetDataTypeSize(eDataType) / 8;
327 : GByte* pabyMEMDSBuffer =
328 2 : (GByte*)VSIMalloc3(nBlockXSize, nBlockYSize, nBands * nDataTypeSize);
329 2 : if (pabyMEMDSBuffer == NULL)
330 : {
331 0 : return CE_Failure;
332 : }
333 :
334 2 : char** papszTileDriverOptions = NULL;
335 :
336 2 : CPLString osTempFileName;
337 2 : osTempFileName.Printf("/vsimem/%p", hDS);
338 :
339 2 : int nTileId = 0;
340 2 : int nBlocks = 0;
341 2 : int nTotalBlocks = nXBlocks * nYBlocks;
342 :
343 2 : CPLString osRasterLayer;
344 2 : osRasterLayer.Printf("%s_rasters", osTableName.c_str());
345 :
346 2 : CPLString osMetatadataLayer;
347 2 : osMetatadataLayer.Printf("%s_metadata", osTableName.c_str());
348 :
349 2 : OGRLayerH hRasterLayer = OGR_DS_GetLayerByName(hDS, osRasterLayer.c_str());
350 2 : OGRLayerH hMetadataLayer = OGR_DS_GetLayerByName(hDS, osMetatadataLayer.c_str());
351 :
352 2 : CPLString osSourceName = "unknown";
353 :
354 : osSQL.Printf("SELECT source_name FROM \"%s\" WHERE "
355 : "pixel_x_size >= %.15f AND pixel_x_size <= %.15f AND "
356 : "pixel_y_size >= %.15f AND pixel_y_size <= %.15f LIMIT 1",
357 : osMetatadataLayer.c_str(),
358 : padfXResolutions[0] - 1e-15, padfXResolutions[0] + 1e-15,
359 2 : padfYResolutions[0] - 1e-15, padfYResolutions[0] + 1e-15);
360 2 : OGRLayerH hSQLLyr = OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);
361 2 : if (hSQLLyr)
362 : {
363 2 : OGRFeatureH hFeat = OGR_L_GetNextFeature(hSQLLyr);
364 2 : if (hFeat)
365 : {
366 2 : const char* pszVal = OGR_F_GetFieldAsString(hFeat, 0);
367 2 : if (pszVal)
368 2 : osSourceName = pszVal;
369 2 : OGR_F_Destroy(hFeat);
370 : }
371 2 : OGR_DS_ReleaseResultSet(hDS, hSQLLyr);
372 : }
373 :
374 : /* -------------------------------------------------------------------- */
375 : /* Compute up to which existing overview level we can use for */
376 : /* computing the requested overview */
377 : /* -------------------------------------------------------------------- */
378 : int iLev;
379 2 : nLimitOvrCount = 0;
380 3 : for(iLev=1;iLev<nResolutions;iLev++)
381 : {
382 1 : if (!(padfXResolutions[iLev] < dfXResolution - 1e-10 &&
383 : padfYResolutions[iLev] < dfYResolution - 1e-10))
384 : {
385 0 : break;
386 : }
387 1 : nLimitOvrCount++;
388 : }
389 :
390 : /* -------------------------------------------------------------------- */
391 : /* Iterate over blocks to add data into raster and metadata tables */
392 : /* -------------------------------------------------------------------- */
393 :
394 2 : OGR_DS_ExecuteSQL(hDS, "BEGIN", NULL, NULL);
395 :
396 2 : CPLErr eErr = CE_None;
397 : int nBlockXOff, nBlockYOff;
398 4 : for(nBlockYOff=0;eErr == CE_None && nBlockYOff<nYBlocks;nBlockYOff++)
399 : {
400 4 : for(nBlockXOff=0;eErr == CE_None && nBlockXOff<nXBlocks;nBlockXOff++)
401 : {
402 : /* -------------------------------------------------------------------- */
403 : /* Create in-memory tile */
404 : /* -------------------------------------------------------------------- */
405 2 : int nReqXSize = nBlockXSize, nReqYSize = nBlockYSize;
406 2 : if ((nBlockXOff+1) * nBlockXSize > nOvrXSize)
407 2 : nReqXSize = nOvrXSize - nBlockXOff * nBlockXSize;
408 2 : if ((nBlockYOff+1) * nBlockYSize > nOvrYSize)
409 2 : nReqYSize = nOvrYSize - nBlockYOff * nBlockYSize;
410 :
411 : eErr = RasterIO(GF_Read,
412 : nBlockXOff * nBlockXSize * nOvrFactor,
413 : nBlockYOff * nBlockYSize * nOvrFactor,
414 : nReqXSize * nOvrFactor, nReqYSize * nOvrFactor,
415 : pabyMEMDSBuffer, nReqXSize, nReqYSize,
416 : eDataType, nBands, NULL,
417 2 : 0, 0, 0);
418 2 : if (eErr != CE_None)
419 : {
420 0 : break;
421 : }
422 :
423 : GDALDatasetH hMemDS = GDALCreate(hMemDriver, "MEM:::",
424 : nReqXSize, nReqYSize, 0,
425 2 : eDataType, NULL);
426 2 : if (hMemDS == NULL)
427 : {
428 0 : eErr = CE_Failure;
429 0 : break;
430 : }
431 :
432 : int iBand;
433 4 : for(iBand = 0; iBand < nBands; iBand ++)
434 : {
435 2 : char** papszOptions = NULL;
436 : char szTmp[64];
437 2 : memset(szTmp, 0, sizeof(szTmp));
438 : CPLPrintPointer(szTmp,
439 : pabyMEMDSBuffer + iBand * nDataTypeSize *
440 2 : nReqXSize * nReqYSize, sizeof(szTmp));
441 2 : papszOptions = CSLSetNameValue(papszOptions, "DATAPOINTER", szTmp);
442 2 : GDALAddBand(hMemDS, eDataType, papszOptions);
443 2 : CSLDestroy(papszOptions);
444 : }
445 :
446 : GDALDatasetH hOutDS = GDALCreateCopy(hTileDriver,
447 : osTempFileName.c_str(), hMemDS, FALSE,
448 2 : papszTileDriverOptions, NULL, NULL);
449 :
450 2 : GDALClose(hMemDS);
451 2 : if (hOutDS)
452 2 : GDALClose(hOutDS);
453 : else
454 : {
455 0 : eErr = CE_Failure;
456 0 : break;
457 : }
458 :
459 : /* -------------------------------------------------------------------- */
460 : /* Insert new entry into raster table */
461 : /* -------------------------------------------------------------------- */
462 :
463 : vsi_l_offset nDataLength;
464 : GByte *pabyData = VSIGetMemFileBuffer( osTempFileName.c_str(),
465 4 : &nDataLength, FALSE);
466 :
467 2 : OGRFeatureH hFeat = OGR_F_Create( OGR_L_GetLayerDefn(hRasterLayer) );
468 2 : OGR_F_SetFieldBinary(hFeat, 0, (int)nDataLength, pabyData);
469 :
470 2 : OGR_L_CreateFeature(hRasterLayer, hFeat);
471 : /* Query raster ID to set it as the ID of the associated metadata */
472 2 : int nRasterID = (int)OGR_F_GetFID(hFeat);
473 :
474 2 : OGR_F_Destroy(hFeat);
475 :
476 2 : VSIUnlink(osTempFileName.c_str());
477 :
478 : /* -------------------------------------------------------------------- */
479 : /* Insert new entry into metadata table */
480 : /* -------------------------------------------------------------------- */
481 :
482 2 : hFeat = OGR_F_Create( OGR_L_GetLayerDefn(hMetadataLayer) );
483 2 : OGR_F_SetFID(hFeat, nRasterID);
484 2 : OGR_F_SetFieldString(hFeat, 0, osSourceName);
485 2 : OGR_F_SetFieldInteger(hFeat, 1, nTileId ++);
486 2 : OGR_F_SetFieldInteger(hFeat, 2, nReqXSize);
487 2 : OGR_F_SetFieldInteger(hFeat, 3, nReqYSize);
488 2 : OGR_F_SetFieldDouble(hFeat, 4, dfXResolution);
489 2 : OGR_F_SetFieldDouble(hFeat, 5, dfYResolution);
490 :
491 : double minx, maxx, maxy, miny;
492 : minx = adfGeoTransform[0] +
493 2 : (nBlockXSize * nBlockXOff) * dfXResolution;
494 : maxx = adfGeoTransform[0] +
495 2 : (nBlockXSize * nBlockXOff + nReqXSize) * dfXResolution;
496 : maxy = adfGeoTransform[3] +
497 2 : (nBlockYSize * nBlockYOff) * (-dfYResolution);
498 : miny = adfGeoTransform[3] +
499 2 : (nBlockYSize * nBlockYOff + nReqYSize) * (-dfYResolution);
500 :
501 2 : OGRGeometryH hRectangle = OGR_G_CreateGeometry(wkbPolygon);
502 2 : OGRGeometryH hLinearRing = OGR_G_CreateGeometry(wkbLinearRing);
503 2 : OGR_G_AddPoint_2D(hLinearRing, minx, miny);
504 2 : OGR_G_AddPoint_2D(hLinearRing, minx, maxy);
505 2 : OGR_G_AddPoint_2D(hLinearRing, maxx, maxy);
506 2 : OGR_G_AddPoint_2D(hLinearRing, maxx, miny);
507 2 : OGR_G_AddPoint_2D(hLinearRing, minx, miny);
508 2 : OGR_G_AddGeometryDirectly(hRectangle, hLinearRing);
509 :
510 2 : OGR_F_SetGeometryDirectly(hFeat, hRectangle);
511 :
512 2 : OGR_L_CreateFeature(hMetadataLayer, hFeat);
513 2 : OGR_F_Destroy(hFeat);
514 :
515 2 : nBlocks++;
516 2 : if (pfnProgress && !pfnProgress(1.0 * nBlocks / nTotalBlocks,
517 : NULL, pProgressData))
518 0 : eErr = CE_Failure;
519 : }
520 : }
521 :
522 2 : nLimitOvrCount = -1;
523 :
524 2 : if (eErr == CE_None)
525 2 : OGR_DS_ExecuteSQL(hDS, "COMMIT", NULL, NULL);
526 : else
527 0 : OGR_DS_ExecuteSQL(hDS, "ROLLBACK", NULL, NULL);
528 :
529 2 : VSIFree(pabyMEMDSBuffer);
530 :
531 : /* -------------------------------------------------------------------- */
532 : /* Update raster_pyramids table */
533 : /* -------------------------------------------------------------------- */
534 2 : if (eErr == CE_None)
535 : {
536 2 : OGRLayerH hRasterPyramidsLyr = OGR_DS_GetLayerByName(hDS, "raster_pyramids");
537 2 : if (hRasterPyramidsLyr == NULL)
538 : {
539 : osSQL.Printf ("CREATE TABLE raster_pyramids ("
540 : "table_prefix TEXT NOT NULL,"
541 : "pixel_x_size DOUBLE NOT NULL,"
542 : "pixel_y_size DOUBLE NOT NULL,"
543 1 : "tile_count INTEGER NOT NULL)");
544 1 : OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);
545 :
546 : /* Re-open the DB to take into account the new tables*/
547 1 : OGRReleaseDataSource(hDS);
548 :
549 1 : CPLString osOldVal = CPLGetConfigOption("SQLITE_LIST_ALL_TABLES", "FALSE");
550 1 : CPLSetConfigOption("SQLITE_LIST_ALL_TABLES", "TRUE");
551 1 : hDS = OGROpen(osFileName.c_str(), TRUE, NULL);
552 1 : CPLSetConfigOption("SQLITE_LIST_ALL_TABLES", osOldVal.c_str());
553 :
554 : osSQL.Printf("SELECT COUNT(*) FROM \"%s\" WHERE "
555 : "pixel_x_size >= %.15f AND pixel_x_size <= %.15f AND "
556 : "pixel_y_size >= %.15f AND pixel_y_size <= %.15f",
557 : osMetatadataLayer.c_str(),
558 : padfXResolutions[0] - 1e-15, padfXResolutions[0] + 1e-15,
559 1 : padfYResolutions[0] - 1e-15, padfYResolutions[0] + 1e-15);
560 :
561 1 : int nBlocksMainRes = 0;
562 :
563 1 : hSQLLyr = OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);
564 1 : if (hSQLLyr)
565 : {
566 1 : OGRFeatureH hFeat = OGR_L_GetNextFeature(hSQLLyr);
567 1 : if (hFeat)
568 : {
569 1 : nBlocksMainRes = OGR_F_GetFieldAsInteger(hFeat, 0);
570 1 : OGR_F_Destroy(hFeat);
571 : }
572 1 : OGR_DS_ReleaseResultSet(hDS, hSQLLyr);
573 : }
574 :
575 : osSQL.Printf("INSERT INTO raster_pyramids "
576 : "( table_prefix, pixel_x_size, pixel_y_size, tile_count ) "
577 : "VALUES ( '%s', %.18f, %.18f, %d )",
578 : osTableName.c_str(), padfXResolutions[0], padfYResolutions[0],
579 1 : nBlocksMainRes);
580 1 : OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);
581 : }
582 :
583 : osSQL.Printf("INSERT INTO raster_pyramids "
584 : "( table_prefix, pixel_x_size, pixel_y_size, tile_count ) "
585 : "VALUES ( '%s', %.18f, %.18f, %d )",
586 : osTableName.c_str(), dfXResolution, dfYResolution,
587 2 : nTotalBlocks);
588 2 : OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);
589 : }
590 :
591 2 : return eErr;
592 : }
593 :
594 : /************************************************************************/
595 : /* IBuildOverviews() */
596 : /************************************************************************/
597 :
598 : CPLErr RasterliteDataset::IBuildOverviews( const char * pszResampling,
599 : int nOverviews, int * panOverviewList,
600 : int nBands, int * panBandList,
601 : GDALProgressFunc pfnProgress,
602 2 : void * pProgressData )
603 : {
604 2 : CPLErr eErr = CE_None;
605 :
606 2 : if (nLevel != 0)
607 : {
608 : CPLError(CE_Failure, CPLE_AppDefined,
609 0 : "Overviews can only be computed on the base dataset");
610 0 : return CE_Failure;
611 : }
612 :
613 2 : if (osTableName.size() == 0)
614 0 : return CE_Failure;
615 :
616 : /* -------------------------------------------------------------------- */
617 : /* If we don't have read access, then create the overviews */
618 : /* externally. */
619 : /* -------------------------------------------------------------------- */
620 2 : if( GetAccess() != GA_Update )
621 : {
622 : CPLDebug( "Rasterlite",
623 : "File open for read-only accessing, "
624 0 : "creating overviews externally." );
625 :
626 0 : if (nResolutions != 1)
627 : {
628 : CPLError(CE_Failure, CPLE_NotSupported,
629 : "Cannot add external overviews to a "
630 0 : "dataset with internal overviews");
631 0 : return CE_Failure;
632 : }
633 :
634 0 : bCheckForExistingOverview = FALSE;
635 : eErr = GDALDataset::IBuildOverviews(
636 : pszResampling, nOverviews, panOverviewList,
637 0 : nBands, panBandList, pfnProgress, pProgressData );
638 0 : bCheckForExistingOverview = TRUE;
639 0 : return eErr;
640 : }
641 :
642 : /* -------------------------------------------------------------------- */
643 : /* If zero overviews were requested, we need to clear all */
644 : /* existing overviews. */
645 : /* -------------------------------------------------------------------- */
646 2 : if (nOverviews == 0)
647 : {
648 1 : return CleanOverviews();
649 : }
650 :
651 1 : if( nBands != GetRasterCount() )
652 : {
653 : CPLError( CE_Failure, CPLE_NotSupported,
654 : "Generation of overviews in RASTERLITE only"
655 : " supported when operating on all bands.\n"
656 0 : "Operation failed.\n" );
657 0 : return CE_Failure;
658 : }
659 :
660 1 : if( !EQUALN(pszResampling, "NEAR", 4))
661 : {
662 : CPLError( CE_Failure, CPLE_NotSupported,
663 : "Only NEAREST resampling is allowed for now "
664 0 : "for RASTERLITE overviews");
665 0 : return CE_Failure;
666 : }
667 :
668 : int i;
669 3 : for(i=0;i<nOverviews && eErr == CE_None;i++)
670 : {
671 2 : if (panOverviewList[i] <= 1)
672 0 : continue;
673 :
674 2 : eErr = CleanOverviewLevel(panOverviewList[i]);
675 2 : if (eErr == CE_None)
676 2 : eErr = CreateOverviewLevel(panOverviewList[i], pfnProgress, pProgressData);
677 :
678 2 : ReloadOverviews();
679 : }
680 :
681 1 : return eErr;
682 : }
|