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