1 : /******************************************************************************
2 : * $Id: rasterlitedataset.cpp 23344 2011-11-06 15:05:13Z 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 "gdal_frmts.h"
31 : #include "cpl_string.h"
32 : #include "ogr_api.h"
33 : #include "ogr_srs_api.h"
34 :
35 : #include "rasterlitedataset.h"
36 :
37 : CPL_CVSID("$Id: rasterlitedataset.cpp 23344 2011-11-06 15:05:13Z rouault $");
38 :
39 : /************************************************************************/
40 : /* RasterliteBand() */
41 : /************************************************************************/
42 :
43 53 : RasterliteBand::RasterliteBand(RasterliteDataset* poDS, int nBand,
44 : GDALDataType eDataType,
45 53 : int nBlockXSize, int nBlockYSize)
46 : {
47 53 : this->poDS = poDS;
48 53 : this->nBand = nBand;
49 53 : this->eDataType = eDataType;
50 53 : this->nBlockXSize = nBlockXSize;
51 53 : this->nBlockYSize = nBlockYSize;
52 53 : }
53 :
54 : /************************************************************************/
55 : /* IReadBlock() */
56 : /************************************************************************/
57 :
58 : //#define RASTERLITE_DEBUG
59 :
60 14 : CPLErr RasterliteBand::IReadBlock( int nBlockXOff, int nBlockYOff, void * pImage)
61 : {
62 14 : RasterliteDataset* poGDS = (RasterliteDataset*) poDS;
63 :
64 14 : double minx = poGDS->adfGeoTransform[0] +
65 14 : nBlockXOff * nBlockXSize * poGDS->adfGeoTransform[1];
66 14 : double maxx = poGDS->adfGeoTransform[0] +
67 14 : (nBlockXOff + 1) * nBlockXSize * poGDS->adfGeoTransform[1];
68 14 : double maxy = poGDS->adfGeoTransform[3] +
69 14 : nBlockYOff * nBlockYSize * poGDS->adfGeoTransform[5];
70 14 : double miny = poGDS->adfGeoTransform[3] +
71 14 : (nBlockYOff + 1) * nBlockYSize * poGDS->adfGeoTransform[5];
72 14 : int nDataTypeSize = GDALGetDataTypeSize(eDataType) / 8;
73 :
74 : #ifdef RASTERLITE_DEBUG
75 : if (nBand == 1)
76 : {
77 : printf("nBlockXOff = %d, nBlockYOff = %d, nBlockXSize = %d, nBlockYSize = %d\n"
78 : "minx=%.15f miny=%.15f maxx=%.15f maxy=%.15f\n",
79 : nBlockXOff, nBlockYOff, nBlockXSize, nBlockYSize, minx, miny, maxx, maxy);
80 : }
81 : #endif
82 :
83 14 : CPLString osSQL;
84 : osSQL.Printf("SELECT m.geometry, r.raster, m.id, m.width, m.height FROM \"%s_metadata\" AS m, "
85 : "\"%s_rasters\" AS r WHERE m.rowid IN "
86 : "(SELECT pkid FROM \"idx_%s_metadata_geometry\" "
87 : "WHERE xmin < %.15f AND xmax > %.15f "
88 : "AND ymin < %.15f AND ymax > %.15f) "
89 : "AND m.pixel_x_size >= %.15f AND m.pixel_x_size <= %.15f AND "
90 : "m.pixel_y_size >= %.15f AND m.pixel_y_size <= %.15f AND r.id = m.id",
91 : poGDS->osTableName.c_str(),
92 : poGDS->osTableName.c_str(),
93 : poGDS->osTableName.c_str(),
94 : maxx, minx, maxy, miny,
95 28 : poGDS->adfGeoTransform[1] - 1e-15, poGDS->adfGeoTransform[1] + 1e-15,
96 42 : - poGDS->adfGeoTransform[5] - 1e-15, - poGDS->adfGeoTransform[5] + 1e-15);
97 :
98 14 : OGRLayerH hSQLLyr = OGR_DS_ExecuteSQL(poGDS->hDS, osSQL.c_str(), NULL, NULL);
99 14 : if (hSQLLyr == NULL)
100 : {
101 2 : memset(pImage, 0, nBlockXSize * nBlockYSize * nDataTypeSize);
102 2 : return CE_None;
103 : }
104 :
105 12 : CPLString osMemFileName;
106 12 : osMemFileName.Printf("/vsimem/%p", this);
107 :
108 12 : int bHasFoundTile = FALSE;
109 12 : int bHasMemsetTile = FALSE;
110 :
111 : #ifdef RASTERLITE_DEBUG
112 : if (nBand == 1)
113 : {
114 : printf("nTiles = %d\n", OGR_L_GetFeatureCount(hSQLLyr, TRUE));
115 : }
116 : #endif
117 :
118 : OGRFeatureH hFeat;
119 36 : while( (hFeat = OGR_L_GetNextFeature(hSQLLyr)) != NULL )
120 : {
121 12 : OGRGeometryH hGeom = OGR_F_GetGeometryRef(hFeat);
122 12 : if (hGeom == NULL)
123 : {
124 0 : CPLError(CE_Failure, CPLE_AppDefined, "null geometry found");
125 0 : OGR_F_Destroy(hFeat);
126 0 : OGR_DS_ReleaseResultSet(poGDS->hDS, hSQLLyr);
127 0 : return CE_Failure;
128 : }
129 :
130 12 : OGREnvelope oEnvelope;
131 12 : OGR_G_GetEnvelope(hGeom, &oEnvelope);
132 :
133 12 : int nTileId = OGR_F_GetFieldAsInteger(hFeat, 1);
134 12 : int nTileXSize = OGR_F_GetFieldAsInteger(hFeat, 2);
135 12 : int nTileYSize = OGR_F_GetFieldAsInteger(hFeat, 3);
136 :
137 : int nDstXOff =
138 12 : (int)((oEnvelope.MinX - minx) / poGDS->adfGeoTransform[1] + 0.5);
139 : int nDstYOff =
140 12 : (int)((maxy - oEnvelope.MaxY) / (-poGDS->adfGeoTransform[5]) + 0.5);
141 :
142 12 : int nReqXSize = nTileXSize;
143 12 : int nReqYSize = nTileYSize;
144 :
145 : int nSrcXOff, nSrcYOff;
146 :
147 12 : if (nDstXOff >= 0)
148 : {
149 11 : nSrcXOff = 0;
150 : }
151 : else
152 : {
153 1 : nSrcXOff = -nDstXOff;
154 1 : nReqXSize += nDstXOff;
155 1 : nDstXOff = 0;
156 : }
157 :
158 :
159 12 : if (nDstYOff >= 0)
160 : {
161 11 : nSrcYOff = 0;
162 : }
163 : else
164 : {
165 1 : nSrcYOff = -nDstYOff;
166 1 : nReqYSize += nDstYOff;
167 1 : nDstYOff = 0;
168 : }
169 :
170 12 : if (nDstXOff + nReqXSize > nBlockXSize)
171 0 : nReqXSize = nBlockXSize - nDstXOff;
172 :
173 12 : if (nDstYOff + nReqYSize > nBlockYSize)
174 0 : nReqYSize = nBlockYSize - nDstYOff;
175 :
176 : #ifdef RASTERLITE_DEBUG
177 : if (nBand == 1)
178 : {
179 : printf("id = %d, minx=%.15f miny=%.15f maxx=%.15f maxy=%.15f\n"
180 : "nDstXOff = %d, nDstYOff = %d, nSrcXOff = %d, nSrcYOff = %d, "
181 : "nReqXSize=%d, nReqYSize=%d\n",
182 : nTileId,
183 : oEnvelope.MinX, oEnvelope.MinY, oEnvelope.MaxX, oEnvelope.MaxY,
184 : nDstXOff, nDstYOff,
185 : nSrcXOff, nSrcYOff, nReqXSize, nReqYSize);
186 : }
187 : #endif
188 :
189 12 : if (nReqXSize > 0 && nReqYSize > 0 &&
190 : nSrcXOff < nTileXSize && nSrcYOff < nTileYSize)
191 : {
192 :
193 : #ifdef RASTERLITE_DEBUG
194 : if (nBand == 1)
195 : {
196 : printf("id = %d, selected !\n", nTileId);
197 : }
198 : #endif
199 12 : int nDataSize = 0;
200 12 : GByte* pabyData = OGR_F_GetFieldAsBinary(hFeat, 0, &nDataSize);
201 :
202 : VSILFILE * fp = VSIFileFromMemBuffer( osMemFileName.c_str(), pabyData,
203 12 : nDataSize, FALSE);
204 12 : VSIFCloseL(fp);
205 :
206 12 : GDALDatasetH hDSTile = GDALOpen(osMemFileName.c_str(), GA_ReadOnly);
207 12 : int nTileBands = 0;
208 12 : if (hDSTile && (nTileBands = GDALGetRasterCount(hDSTile)) == 0)
209 : {
210 0 : GDALClose(hDSTile);
211 0 : hDSTile = NULL;
212 : }
213 12 : if (hDSTile == NULL)
214 : {
215 : CPLError(CE_Failure, CPLE_AppDefined, "Can't open tile %d",
216 0 : nTileId);
217 : }
218 :
219 12 : int nReqBand = 1;
220 12 : if (nTileBands == poGDS->nBands)
221 11 : nReqBand = nBand;
222 2 : else if (eDataType == GDT_Byte && nTileBands == 1 && poGDS->nBands == 3)
223 1 : nReqBand = 1;
224 : else
225 : {
226 0 : GDALClose(hDSTile);
227 0 : hDSTile = NULL;
228 : }
229 :
230 12 : if (hDSTile)
231 : {
232 12 : CPLAssert(GDALGetRasterXSize(hDSTile) == nTileXSize);
233 12 : CPLAssert(GDALGetRasterYSize(hDSTile) == nTileYSize);
234 :
235 12 : bHasFoundTile = TRUE;
236 :
237 12 : int bHasJustMemsetTileBand1 = FALSE;
238 :
239 : /* If the source tile doesn't fit the entire block size, then */
240 : /* we memset 0 before */
241 12 : if (!(nDstXOff == 0 && nDstYOff == 0 &&
242 : nReqXSize == nBlockXSize && nReqYSize == nBlockYSize) &&
243 : !bHasMemsetTile)
244 : {
245 5 : memset(pImage, 0, nBlockXSize * nBlockYSize * nDataTypeSize);
246 5 : bHasMemsetTile = TRUE;
247 5 : bHasJustMemsetTileBand1 = TRUE;
248 : }
249 :
250 : GDALColorTable* poTileCT =
251 12 : (GDALColorTable* )GDALGetRasterColorTable(GDALGetRasterBand(hDSTile, 1));
252 12 : unsigned char* pabyTranslationTable = NULL;
253 12 : if (poGDS->nBands == 1 && poGDS->poCT != NULL && poTileCT != NULL)
254 : {
255 : pabyTranslationTable =
256 : ((GDALRasterBand*)GDALGetRasterBand(hDSTile, 1))->
257 1 : GetIndexColorTranslationTo(this, NULL, NULL);
258 : }
259 :
260 : /* -------------------------------------------------------------------- */
261 : /* Read tile data */
262 : /* -------------------------------------------------------------------- */
263 : GDALRasterIO(GDALGetRasterBand(hDSTile, nReqBand), GF_Read,
264 : nSrcXOff, nSrcYOff, nReqXSize, nReqYSize,
265 : ((char*) pImage) + (nDstXOff + nDstYOff * nBlockXSize) * nDataTypeSize,
266 : nReqXSize, nReqYSize,
267 12 : eDataType, nDataTypeSize, nBlockXSize * nDataTypeSize);
268 :
269 12 : if (eDataType == GDT_Byte && pabyTranslationTable)
270 : {
271 : /* -------------------------------------------------------------------- */
272 : /* Convert from tile CT to band CT */
273 : /* -------------------------------------------------------------------- */
274 : int i, j;
275 0 : for(j=nDstYOff;j<nDstYOff + nReqYSize;j++)
276 : {
277 0 : for(i=nDstXOff;i<nDstXOff + nReqXSize;i++)
278 : {
279 0 : GByte* pPixel = ((GByte*) pImage) + i + j * nBlockXSize;
280 0 : *pPixel = pabyTranslationTable[*pPixel];
281 : }
282 : }
283 0 : CPLFree(pabyTranslationTable);
284 0 : pabyTranslationTable = NULL;
285 : }
286 12 : else if (eDataType == GDT_Byte && nTileBands == 1 &&
287 : poGDS->nBands == 3 && poTileCT != NULL)
288 : {
289 : /* -------------------------------------------------------------------- */
290 : /* Expand from PCT to RGB */
291 : /* -------------------------------------------------------------------- */
292 : int i, j;
293 : GByte abyCT[256];
294 1 : int nEntries = MIN(256, poTileCT->GetColorEntryCount());
295 257 : for(i=0;i<nEntries;i++)
296 : {
297 256 : const GDALColorEntry* psEntry = poTileCT->GetColorEntry(i);
298 256 : if (nBand == 1)
299 256 : abyCT[i] = (GByte)psEntry->c1;
300 0 : else if (nBand == 2)
301 0 : abyCT[i] = (GByte)psEntry->c2;
302 : else
303 0 : abyCT[i] = (GByte)psEntry->c3;
304 : }
305 1 : for(;i<256;i++)
306 0 : abyCT[i] = 0;
307 :
308 170 : for(j=nDstYOff;j<nDstYOff + nReqYSize;j++)
309 : {
310 57291 : for(i=nDstXOff;i<nDstXOff + nReqXSize;i++)
311 : {
312 57122 : GByte* pPixel = ((GByte*) pImage) + i + j * nBlockXSize;
313 57122 : *pPixel = abyCT[*pPixel];
314 : }
315 : }
316 : }
317 :
318 : /* -------------------------------------------------------------------- */
319 : /* Put in the block cache the data for this block into other bands */
320 : /* while the underlying dataset is opened */
321 : /* -------------------------------------------------------------------- */
322 12 : if (nBand == 1 && poGDS->nBands > 1)
323 : {
324 : int iOtherBand;
325 12 : for(iOtherBand=2;iOtherBand<=poGDS->nBands;iOtherBand++)
326 : {
327 : GDALRasterBlock *poBlock;
328 :
329 : poBlock = poGDS->GetRasterBand(iOtherBand)->
330 8 : GetLockedBlockRef(nBlockXOff,nBlockYOff, TRUE);
331 8 : if (poBlock == NULL)
332 0 : break;
333 :
334 8 : GByte* pabySrcBlock = (GByte *) poBlock->GetDataRef();
335 8 : if( pabySrcBlock == NULL )
336 : {
337 0 : poBlock->DropLock();
338 0 : break;
339 : }
340 :
341 8 : if (nTileBands == 1)
342 2 : nReqBand = 1;
343 : else
344 6 : nReqBand = iOtherBand;
345 :
346 8 : if (bHasJustMemsetTileBand1)
347 : memset(pabySrcBlock, 0,
348 2 : nBlockXSize * nBlockYSize * nDataTypeSize);
349 :
350 : /* -------------------------------------------------------------------- */
351 : /* Read tile data */
352 : /* -------------------------------------------------------------------- */
353 : GDALRasterIO(GDALGetRasterBand(hDSTile, nReqBand), GF_Read,
354 : nSrcXOff, nSrcYOff, nReqXSize, nReqYSize,
355 : ((char*) pabySrcBlock) +
356 : (nDstXOff + nDstYOff * nBlockXSize) * nDataTypeSize,
357 : nReqXSize, nReqYSize,
358 8 : eDataType, nDataTypeSize, nBlockXSize * nDataTypeSize);
359 :
360 8 : if (eDataType == GDT_Byte && nTileBands == 1 &&
361 : poGDS->nBands == 3 && poTileCT != NULL)
362 : {
363 : /* -------------------------------------------------------------------- */
364 : /* Expand from PCT to RGB */
365 : /* -------------------------------------------------------------------- */
366 :
367 : int i, j;
368 : GByte abyCT[256];
369 2 : int nEntries = MIN(256, poTileCT->GetColorEntryCount());
370 514 : for(i=0;i<nEntries;i++)
371 : {
372 512 : const GDALColorEntry* psEntry = poTileCT->GetColorEntry(i);
373 512 : if (iOtherBand == 1)
374 0 : abyCT[i] = (GByte)psEntry->c1;
375 512 : else if (iOtherBand == 2)
376 256 : abyCT[i] = (GByte)psEntry->c2;
377 : else
378 256 : abyCT[i] = (GByte)psEntry->c3;
379 : }
380 2 : for(;i<256;i++)
381 0 : abyCT[i] = 0;
382 :
383 340 : for(j=nDstYOff;j<nDstYOff + nReqYSize;j++)
384 : {
385 114582 : for(i=nDstXOff;i<nDstXOff + nReqXSize;i++)
386 : {
387 114244 : GByte* pPixel = ((GByte*) pabySrcBlock) + i + j * nBlockXSize;
388 114244 : *pPixel = abyCT[*pPixel];
389 : }
390 : }
391 : }
392 :
393 8 : poBlock->DropLock();
394 : }
395 :
396 : }
397 12 : GDALClose(hDSTile);
398 : }
399 :
400 12 : VSIUnlink(osMemFileName.c_str());
401 : }
402 : else
403 : {
404 : #ifdef RASTERLITE_DEBUG
405 : if (nBand == 1)
406 : {
407 : printf("id = %d, NOT selected !\n", nTileId);
408 : }
409 : #endif
410 : }
411 :
412 12 : OGR_F_Destroy(hFeat);
413 : }
414 :
415 12 : if (!bHasFoundTile)
416 : {
417 0 : memset(pImage, 0, nBlockXSize * nBlockYSize * nDataTypeSize);
418 : }
419 :
420 12 : OGR_DS_ReleaseResultSet(poGDS->hDS, hSQLLyr);
421 :
422 : #ifdef RASTERLITE_DEBUG
423 : if (nBand == 1)
424 : printf("\n");
425 : #endif
426 :
427 12 : return CE_None;
428 : }
429 :
430 : /************************************************************************/
431 : /* GetOverviewCount() */
432 : /************************************************************************/
433 :
434 7 : int RasterliteBand::GetOverviewCount()
435 : {
436 7 : RasterliteDataset* poGDS = (RasterliteDataset*) poDS;
437 :
438 7 : if (poGDS->nLimitOvrCount >= 0)
439 3 : return poGDS->nLimitOvrCount;
440 4 : else if (poGDS->nResolutions > 1)
441 1 : return poGDS->nResolutions - 1;
442 : else
443 3 : return GDALPamRasterBand::GetOverviewCount();
444 : }
445 :
446 : /************************************************************************/
447 : /* GetOverview() */
448 : /************************************************************************/
449 :
450 9 : GDALRasterBand* RasterliteBand::GetOverview(int nLevel)
451 : {
452 9 : RasterliteDataset* poGDS = (RasterliteDataset*) poDS;
453 :
454 9 : if (poGDS->nLimitOvrCount >= 0)
455 : {
456 2 : if (nLevel < 0 || nLevel >= poGDS->nLimitOvrCount)
457 0 : return NULL;
458 : }
459 :
460 9 : if (poGDS->nResolutions == 1)
461 0 : return GDALPamRasterBand::GetOverview(nLevel);
462 :
463 9 : if (nLevel < 0 || nLevel >= poGDS->nResolutions - 1)
464 0 : return NULL;
465 :
466 9 : GDALDataset* poOvrDS = poGDS->papoOverviews[nLevel];
467 9 : if (poOvrDS)
468 9 : return poOvrDS->GetRasterBand(nBand);
469 : else
470 0 : return NULL;
471 : }
472 :
473 : /************************************************************************/
474 : /* GetColorInterpretation() */
475 : /************************************************************************/
476 :
477 1 : GDALColorInterp RasterliteBand::GetColorInterpretation()
478 : {
479 1 : RasterliteDataset* poGDS = (RasterliteDataset*) poDS;
480 1 : if (poGDS->nBands == 1)
481 : {
482 1 : if (poGDS->poCT != NULL)
483 1 : return GCI_PaletteIndex;
484 : else
485 0 : return GCI_GrayIndex;
486 : }
487 0 : else if (poGDS->nBands == 3)
488 : {
489 0 : if (nBand == 1)
490 0 : return GCI_RedBand;
491 0 : else if (nBand == 2)
492 0 : return GCI_GreenBand;
493 0 : else if (nBand == 3)
494 0 : return GCI_BlueBand;
495 : }
496 :
497 0 : return GCI_Undefined;
498 : }
499 :
500 : /************************************************************************/
501 : /* GetColorTable() */
502 : /************************************************************************/
503 :
504 3 : GDALColorTable* RasterliteBand::GetColorTable()
505 : {
506 3 : RasterliteDataset* poGDS = (RasterliteDataset*) poDS;
507 3 : if (poGDS->nBands == 1)
508 2 : return poGDS->poCT;
509 : else
510 1 : return NULL;
511 : }
512 :
513 : /************************************************************************/
514 : /* RasterliteDataset() */
515 : /************************************************************************/
516 :
517 48 : RasterliteDataset::RasterliteDataset()
518 : {
519 48 : nLimitOvrCount = -1;
520 48 : bValidGeoTransform = FALSE;
521 48 : bMustFree = FALSE;
522 48 : nLevel = 0;
523 48 : poMainDS = NULL;
524 48 : nResolutions = 0;
525 48 : padfXResolutions = NULL;
526 48 : padfYResolutions = NULL;
527 48 : pszSRS = NULL;
528 48 : hDS = NULL;
529 48 : papoOverviews = NULL;
530 48 : papszMetadata = NULL;
531 48 : papszSubDatasets = NULL;
532 : papszImageStructure =
533 48 : CSLAddString(NULL, "INTERLEAVE=PIXEL");
534 48 : poCT = NULL;
535 48 : bCheckForExistingOverview = TRUE;
536 48 : }
537 :
538 : /************************************************************************/
539 : /* RasterliteDataset() */
540 : /************************************************************************/
541 :
542 8 : RasterliteDataset::RasterliteDataset(RasterliteDataset* poMainDS, int nLevel)
543 : {
544 8 : nLimitOvrCount = -1;
545 8 : bMustFree = FALSE;
546 8 : this->nLevel = nLevel;
547 8 : this->poMainDS = poMainDS;
548 8 : nResolutions = poMainDS->nResolutions - nLevel;
549 8 : padfXResolutions = poMainDS->padfXResolutions + nLevel;
550 8 : padfYResolutions = poMainDS->padfYResolutions + nLevel;
551 8 : pszSRS = poMainDS->pszSRS;
552 8 : hDS = poMainDS->hDS;
553 8 : papoOverviews = poMainDS->papoOverviews + nLevel;
554 8 : papszMetadata = poMainDS->papszMetadata;
555 8 : papszSubDatasets = poMainDS->papszSubDatasets;
556 8 : papszImageStructure = poMainDS->papszImageStructure;
557 8 : poCT = poMainDS->poCT;
558 8 : bCheckForExistingOverview = TRUE;
559 :
560 8 : osTableName = poMainDS->osTableName;
561 8 : osFileName = poMainDS->osFileName;
562 :
563 : nRasterXSize = (int)(poMainDS->nRasterXSize *
564 8 : (poMainDS->padfXResolutions[0] / padfXResolutions[0]) + 0.5);
565 : nRasterYSize = (int)(poMainDS->nRasterYSize *
566 8 : (poMainDS->padfYResolutions[0] / padfYResolutions[0]) + 0.5);
567 :
568 8 : bValidGeoTransform = TRUE;
569 8 : memcpy(adfGeoTransform, poMainDS->adfGeoTransform, 6 * sizeof(double));
570 8 : adfGeoTransform[1] = padfXResolutions[0];
571 8 : adfGeoTransform[5] = - padfYResolutions[0];
572 8 : }
573 :
574 : /************************************************************************/
575 : /* ~RasterliteDataset() */
576 : /************************************************************************/
577 :
578 56 : RasterliteDataset::~RasterliteDataset()
579 : {
580 56 : CloseDependentDatasets();
581 56 : }
582 :
583 : /************************************************************************/
584 : /* CloseDependentDatasets() */
585 : /************************************************************************/
586 :
587 56 : int RasterliteDataset::CloseDependentDatasets()
588 : {
589 56 : int bRet = GDALPamDataset::CloseDependentDatasets();
590 :
591 104 : if (poMainDS == NULL && !bMustFree)
592 : {
593 48 : CSLDestroy(papszMetadata);
594 48 : papszMetadata = NULL;
595 48 : CSLDestroy(papszSubDatasets);
596 48 : papszSubDatasets = NULL;
597 48 : CSLDestroy(papszImageStructure);
598 48 : papszImageStructure = NULL;
599 48 : CPLFree(pszSRS);
600 48 : pszSRS = NULL;
601 :
602 48 : if (papoOverviews)
603 : {
604 : int i;
605 8 : for(i=1;i<nResolutions;i++)
606 : {
607 10 : if (papoOverviews[i-1] != NULL &&
608 5 : papoOverviews[i-1]->bMustFree)
609 : {
610 0 : papoOverviews[i-1]->poMainDS = NULL;
611 : }
612 5 : delete papoOverviews[i-1];
613 : }
614 3 : CPLFree(papoOverviews);
615 3 : papoOverviews = NULL;
616 3 : nResolutions = 0;
617 3 : bRet = TRUE;
618 : }
619 :
620 48 : if (hDS != NULL)
621 25 : OGRReleaseDataSource(hDS);
622 48 : hDS = NULL;
623 :
624 48 : CPLFree(padfXResolutions);
625 48 : CPLFree(padfYResolutions);
626 48 : padfXResolutions = padfYResolutions = NULL;
627 :
628 48 : delete poCT;
629 48 : poCT = NULL;
630 : }
631 8 : else if (poMainDS != NULL && bMustFree)
632 : {
633 0 : poMainDS->papoOverviews[nLevel-1] = NULL;
634 0 : delete poMainDS;
635 0 : poMainDS = NULL;
636 0 : bRet = TRUE;
637 : }
638 :
639 56 : return bRet;
640 : }
641 :
642 : /************************************************************************/
643 : /* AddSubDataset() */
644 : /************************************************************************/
645 :
646 23 : void RasterliteDataset::AddSubDataset( const char* pszDSName)
647 : {
648 : char szName[80];
649 23 : int nCount = CSLCount(papszSubDatasets ) / 2;
650 :
651 23 : sprintf( szName, "SUBDATASET_%d_NAME", nCount+1 );
652 : papszSubDatasets =
653 23 : CSLSetNameValue( papszSubDatasets, szName, pszDSName);
654 :
655 23 : sprintf( szName, "SUBDATASET_%d_DESC", nCount+1 );
656 : papszSubDatasets =
657 23 : CSLSetNameValue( papszSubDatasets, szName, pszDSName);
658 23 : }
659 :
660 : /************************************************************************/
661 : /* GetMetadata() */
662 : /************************************************************************/
663 :
664 0 : char **RasterliteDataset::GetMetadata( const char *pszDomain )
665 :
666 : {
667 0 : if( pszDomain != NULL && EQUAL(pszDomain,"SUBDATASETS") )
668 0 : return papszSubDatasets;
669 :
670 0 : if( CSLCount(papszSubDatasets) < 2 &&
671 : pszDomain != NULL && EQUAL(pszDomain,"IMAGE_STRUCTURE") )
672 0 : return papszImageStructure;
673 :
674 0 : if ( pszDomain == NULL || EQUAL(pszDomain, "") )
675 0 : return papszMetadata;
676 :
677 0 : return GDALPamDataset::GetMetadata( pszDomain );
678 : }
679 :
680 : /************************************************************************/
681 : /* GetMetadataItem() */
682 : /************************************************************************/
683 :
684 2 : const char *RasterliteDataset::GetMetadataItem( const char *pszName,
685 : const char *pszDomain )
686 : {
687 2 : if (pszDomain != NULL &&EQUAL(pszDomain,"OVERVIEWS") )
688 : {
689 2 : if (nResolutions > 1 || CSLCount(papszSubDatasets) > 2)
690 0 : return NULL;
691 : else
692 : {
693 2 : osOvrFileName.Printf("%s_%s", osFileName.c_str(), osTableName.c_str());
694 2 : if (bCheckForExistingOverview == FALSE ||
695 : CPLCheckForFile((char*) osOvrFileName.c_str(), NULL))
696 0 : return osOvrFileName.c_str();
697 : else
698 2 : return NULL;
699 : }
700 : }
701 0 : return GDALPamDataset::GetMetadataItem(pszName, pszDomain);
702 : }
703 :
704 : /************************************************************************/
705 : /* GetGeoTransform() */
706 : /************************************************************************/
707 :
708 2 : CPLErr RasterliteDataset::GetGeoTransform( double* padfGeoTransform )
709 : {
710 2 : if (bValidGeoTransform)
711 : {
712 2 : memcpy(padfGeoTransform, adfGeoTransform, 6 * sizeof(double));
713 2 : return CE_None;
714 : }
715 : else
716 0 : return CE_Failure;
717 : }
718 :
719 : /************************************************************************/
720 : /* GetProjectionRef() */
721 : /************************************************************************/
722 :
723 2 : const char* RasterliteDataset::GetProjectionRef()
724 : {
725 2 : if (pszSRS)
726 2 : return pszSRS;
727 : else
728 0 : return "";
729 : }
730 :
731 : /************************************************************************/
732 : /* GetFileList() */
733 : /************************************************************************/
734 :
735 0 : char** RasterliteDataset::GetFileList()
736 : {
737 0 : char** papszFileList = NULL;
738 0 : papszFileList = CSLAddString(papszFileList, osFileName);
739 0 : return papszFileList;
740 : }
741 :
742 : /************************************************************************/
743 : /* GetBlockParams() */
744 : /************************************************************************/
745 :
746 33 : int RasterliteDataset::GetBlockParams(OGRLayerH hRasterLyr, int nLevel,
747 : int* pnBands, GDALDataType* peDataType,
748 : int* pnBlockXSize, int* pnBlockYSize)
749 : {
750 33 : CPLString osSQL;
751 :
752 : osSQL.Printf("SELECT m.geometry, r.raster, m.id "
753 : "FROM \"%s_metadata\" AS m, \"%s_rasters\" AS r "
754 : "WHERE m.pixel_x_size >= %.15f AND m.pixel_x_size <= %.15f AND "
755 : "m.pixel_y_size >= %.15f AND m.pixel_y_size <= %.15f AND r.id = m.id",
756 : osTableName.c_str(), osTableName.c_str(),
757 66 : padfXResolutions[nLevel] - 1e-15, padfXResolutions[nLevel] + 1e-15,
758 99 : padfYResolutions[nLevel] - 1e-15, padfYResolutions[nLevel] + 1e-15);
759 :
760 33 : OGRLayerH hSQLLyr = OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);
761 33 : if (hSQLLyr == NULL)
762 : {
763 0 : return FALSE;
764 : }
765 :
766 33 : OGRFeatureH hFeat = OGR_L_GetNextFeature(hRasterLyr);
767 33 : if (hFeat == NULL)
768 : {
769 0 : OGR_DS_ReleaseResultSet(hDS, hSQLLyr);
770 0 : return FALSE;
771 : }
772 :
773 : int nDataSize;
774 33 : GByte* pabyData = OGR_F_GetFieldAsBinary(hFeat, 0, &nDataSize);
775 :
776 33 : if (nDataSize > 32 &&
777 : EQUALN((const char*)pabyData, "StartWaveletsImage$$", strlen("StartWaveletsImage$$")))
778 : {
779 2 : if (GDALGetDriverByName("EPSILON") == NULL)
780 : {
781 : CPLError(CE_Failure, CPLE_NotSupported,
782 0 : "Rasterlite driver doesn't support WAVELET compressed images if EPSILON driver is not compiled");
783 0 : OGR_F_Destroy(hFeat);
784 0 : OGR_DS_ReleaseResultSet(hDS, hSQLLyr);
785 0 : return FALSE;
786 : }
787 : }
788 :
789 33 : CPLString osMemFileName;
790 33 : osMemFileName.Printf("/vsimem/%p", this);
791 : VSILFILE * fp = VSIFileFromMemBuffer( osMemFileName.c_str(), pabyData,
792 33 : nDataSize, FALSE);
793 33 : VSIFCloseL(fp);
794 :
795 33 : GDALDatasetH hDSTile = GDALOpen(osMemFileName.c_str(), GA_ReadOnly);
796 33 : if (hDSTile)
797 : {
798 33 : *pnBands = GDALGetRasterCount(hDSTile);
799 33 : if (*pnBands == 0)
800 : {
801 0 : GDALClose(hDSTile);
802 0 : hDSTile = NULL;
803 : }
804 : }
805 : else
806 : {
807 : CPLError(CE_Failure, CPLE_AppDefined, "Can't open tile %d",
808 0 : OGR_F_GetFieldAsInteger(hFeat, 1));
809 : }
810 :
811 33 : if (hDSTile)
812 : {
813 : int iBand;
814 33 : *peDataType = GDALGetRasterDataType(GDALGetRasterBand(hDSTile, 1));
815 :
816 51 : for(iBand=2;iBand<=*pnBands;iBand++)
817 : {
818 18 : if (*peDataType != GDALGetRasterDataType(GDALGetRasterBand(hDSTile, 1)))
819 : {
820 0 : CPLError(CE_Failure, CPLE_NotSupported, "Band types must be identical");
821 0 : GDALClose(hDSTile);
822 0 : hDSTile = NULL;
823 0 : goto end;
824 : }
825 : }
826 :
827 33 : *pnBlockXSize = GDALGetRasterXSize(hDSTile);
828 33 : *pnBlockYSize = GDALGetRasterYSize(hDSTile);
829 33 : if (CSLFindName(papszImageStructure, "COMPRESSION") == -1)
830 : {
831 : const char* pszCompression =
832 32 : GDALGetMetadataItem(hDSTile, "COMPRESSION", "IMAGE_STRUCTURE");
833 32 : if (pszCompression != NULL && EQUAL(pszCompression, "JPEG"))
834 : papszImageStructure =
835 2 : CSLAddString(papszImageStructure, "COMPRESSION=JPEG");
836 : }
837 :
838 33 : if (CSLFindName(papszMetadata, "TILE_FORMAT") == -1)
839 : {
840 : papszMetadata =
841 : CSLSetNameValue(papszMetadata, "TILE_FORMAT",
842 25 : GDALGetDriverShortName(GDALGetDatasetDriver(hDSTile)));
843 : }
844 :
845 :
846 33 : if (*pnBands == 1 && this->poCT == NULL)
847 : {
848 : GDALColorTable* poCT =
849 25 : (GDALColorTable*)GDALGetRasterColorTable(GDALGetRasterBand(hDSTile, 1));
850 25 : if (poCT)
851 2 : this->poCT = poCT->Clone();
852 : }
853 :
854 33 : GDALClose(hDSTile);
855 : }
856 : end:
857 33 : VSIUnlink(osMemFileName.c_str());
858 :
859 33 : OGR_F_Destroy(hFeat);
860 :
861 33 : OGR_DS_ReleaseResultSet(hDS, hSQLLyr);
862 :
863 33 : return hDSTile != NULL;
864 : }
865 :
866 : /************************************************************************/
867 : /* Identify() */
868 : /************************************************************************/
869 :
870 9245 : int RasterliteDataset::Identify(GDALOpenInfo* poOpenInfo)
871 : {
872 9245 : if (poOpenInfo->nHeaderBytes >= 1024 &&
873 : EQUALN((const char*)poOpenInfo->pabyHeader, "SQLite Format 3", 15))
874 : {
875 0 : return TRUE;
876 : }
877 9245 : else if (EQUALN(poOpenInfo->pszFilename, "RASTERLITE:", 11))
878 : {
879 1 : return TRUE;
880 : }
881 :
882 9244 : return FALSE;
883 : }
884 :
885 : /************************************************************************/
886 : /* Open() */
887 : /************************************************************************/
888 :
889 1433 : GDALDataset* RasterliteDataset::Open(GDALOpenInfo* poOpenInfo)
890 : {
891 1433 : CPLString osFileName;
892 1433 : CPLString osTableName;
893 1433 : char **papszTokens = NULL;
894 1433 : int nLevel = 0;
895 1433 : double minx = 0, miny = 0, maxx = 0, maxy = 0;
896 1433 : int bMinXSet = FALSE, bMinYSet = FALSE, bMaxXSet = FALSE, bMaxYSet = FALSE;
897 1433 : int nReqBands = 0;
898 :
899 : /* -------------------------------------------------------------------- */
900 : /* Parse "file name" */
901 : /* -------------------------------------------------------------------- */
902 1454 : if (poOpenInfo->nHeaderBytes >= 1024 &&
903 : EQUALN((const char*)poOpenInfo->pabyHeader, "SQLite Format 3", 15))
904 : {
905 21 : osFileName = poOpenInfo->pszFilename;
906 : }
907 1412 : else if (!EQUALN(poOpenInfo->pszFilename, "RASTERLITE:", 11))
908 : {
909 1408 : return NULL;
910 : }
911 : else
912 : {
913 : papszTokens = CSLTokenizeStringComplex(
914 4 : poOpenInfo->pszFilename + 11, ", ", FALSE, FALSE );
915 4 : int nTokens = CSLCount(papszTokens);
916 4 : if (nTokens == 0)
917 : {
918 0 : CSLDestroy(papszTokens);
919 0 : return NULL;
920 : }
921 :
922 4 : osFileName = papszTokens[0];
923 :
924 : int i;
925 11 : for(i=1;i<nTokens;i++)
926 : {
927 7 : if (EQUALN(papszTokens[i], "table=", 6))
928 2 : osTableName = papszTokens[i] + 6;
929 5 : else if (EQUALN(papszTokens[i], "level=", 6))
930 0 : nLevel = atoi(papszTokens[i] + 6);
931 5 : else if (EQUALN(papszTokens[i], "minx=", 5))
932 : {
933 1 : bMinXSet = TRUE;
934 1 : minx = atof(papszTokens[i] + 5);
935 : }
936 4 : else if (EQUALN(papszTokens[i], "miny=", 5))
937 : {
938 1 : bMinYSet = TRUE;
939 1 : miny = atof(papszTokens[i] + 5);
940 : }
941 3 : else if (EQUALN(papszTokens[i], "maxx=", 5))
942 : {
943 1 : bMaxXSet = TRUE;
944 1 : maxx = atof(papszTokens[i] + 5);
945 : }
946 2 : else if (EQUALN(papszTokens[i], "maxy=", 5))
947 : {
948 1 : bMaxYSet = TRUE;
949 1 : maxy = atof(papszTokens[i] + 5);
950 : }
951 1 : else if (EQUALN(papszTokens[i], "bands=", 6))
952 : {
953 1 : nReqBands = atoi(papszTokens[i] + 6);
954 : }
955 : else
956 : {
957 : CPLError(CE_Warning, CPLE_AppDefined,
958 0 : "Invalid option : %s", papszTokens[i]);
959 : }
960 : }
961 : }
962 :
963 25 : if (OGRGetDriverCount() == 0)
964 0 : OGRRegisterAll();
965 :
966 : /* -------------------------------------------------------------------- */
967 : /* Open underlying OGR DB */
968 : /* -------------------------------------------------------------------- */
969 :
970 : /* Set SQLITE_LIST_ALL_TABLES option as we wan't to be able to */
971 : /* fetch non spatial tables */
972 25 : CPLString osOldVal = CPLGetConfigOption("SQLITE_LIST_ALL_TABLES", "FALSE");
973 25 : CPLSetThreadLocalConfigOption("SQLITE_LIST_ALL_TABLES", "TRUE");
974 25 : OGRDataSourceH hDS = OGROpen(osFileName.c_str(), (poOpenInfo->eAccess == GA_Update) ? TRUE : FALSE, NULL);
975 25 : CPLSetThreadLocalConfigOption("SQLITE_LIST_ALL_TABLES", osOldVal.c_str());
976 25 : CPLDebug("RASTERLITE", "SQLite DB Open");
977 :
978 25 : RasterliteDataset* poDS = NULL;
979 :
980 25 : if (hDS == NULL)
981 0 : goto end;
982 :
983 25 : if (strlen(osTableName) == 0)
984 : {
985 23 : int nCountSubdataset = 0;
986 23 : int nLayers = OGR_DS_GetLayerCount(hDS);
987 : int i;
988 : /* -------------------------------------------------------------------- */
989 : /* Add raster layers as subdatasets */
990 : /* -------------------------------------------------------------------- */
991 355 : for(i=0;i<nLayers;i++)
992 : {
993 332 : OGRLayerH hLyr = OGR_DS_GetLayer(hDS, i);
994 332 : const char* pszLayerName = OGR_FD_GetName(OGR_L_GetLayerDefn(hLyr));
995 332 : if (strstr(pszLayerName, "_rasters"))
996 : {
997 23 : char* pszShortName = CPLStrdup(pszLayerName);
998 23 : *strstr(pszShortName, "_rasters") = '\0';
999 :
1000 23 : CPLString osMetadataTableName = pszShortName;
1001 23 : osMetadataTableName += "_metadata";
1002 :
1003 23 : if (OGR_DS_GetLayerByName(hDS, osMetadataTableName.c_str()) != NULL)
1004 : {
1005 23 : if (poDS == NULL)
1006 : {
1007 23 : poDS = new RasterliteDataset();
1008 46 : osTableName = pszShortName;
1009 : }
1010 :
1011 23 : CPLString osSubdatasetName;
1012 23 : if (!EQUALN(poOpenInfo->pszFilename, "RASTERLITE:", 11))
1013 21 : osSubdatasetName += "RASTERLITE:";
1014 23 : osSubdatasetName += poOpenInfo->pszFilename;
1015 23 : osSubdatasetName += ",table=";
1016 23 : osSubdatasetName += pszShortName;
1017 23 : poDS->AddSubDataset(osSubdatasetName.c_str());
1018 :
1019 23 : nCountSubdataset++;
1020 : }
1021 :
1022 23 : CPLFree(pszShortName);
1023 : }
1024 : }
1025 :
1026 23 : if (nCountSubdataset == 0)
1027 : {
1028 0 : goto end;
1029 : }
1030 23 : else if (nCountSubdataset != 1)
1031 : {
1032 0 : poDS->SetDescription( poOpenInfo->pszFilename );
1033 0 : goto end;
1034 : }
1035 :
1036 : /* -------------------------------------------------------------------- */
1037 : /* If just one subdataset, then open it */
1038 : /* -------------------------------------------------------------------- */
1039 23 : delete poDS;
1040 23 : poDS = NULL;
1041 : }
1042 :
1043 : /* -------------------------------------------------------------------- */
1044 : /* Build dataset */
1045 : /* -------------------------------------------------------------------- */
1046 : {
1047 25 : CPLString osMetadataTableName, osRasterTableName;
1048 25 : CPLString osSQL;
1049 : OGRLayerH hMetadataLyr, hRasterLyr, hRasterPyramidsLyr;
1050 : OGRLayerH hSQLLyr;
1051 : OGRFeatureH hFeat;
1052 : int i, nResolutions;
1053 : int iBand, nBands, nBlockXSize, nBlockYSize;
1054 : GDALDataType eDataType;
1055 :
1056 25 : osMetadataTableName = osTableName;
1057 25 : osMetadataTableName += "_metadata";
1058 :
1059 25 : hMetadataLyr = OGR_DS_GetLayerByName(hDS, osMetadataTableName.c_str());
1060 25 : if (hMetadataLyr == NULL)
1061 : goto end;
1062 :
1063 25 : osRasterTableName = osTableName;
1064 25 : osRasterTableName += "_rasters";
1065 :
1066 25 : hRasterLyr = OGR_DS_GetLayerByName(hDS, osRasterTableName.c_str());
1067 25 : if (hRasterLyr == NULL)
1068 : goto end;
1069 :
1070 : /* -------------------------------------------------------------------- */
1071 : /* Fetch resolutions */
1072 : /* -------------------------------------------------------------------- */
1073 :
1074 25 : hRasterPyramidsLyr = OGR_DS_GetLayerByName(hDS, "raster_pyramids");
1075 25 : if (hRasterPyramidsLyr)
1076 : {
1077 : osSQL.Printf("SELECT pixel_x_size, pixel_y_size "
1078 : "FROM raster_pyramids WHERE table_prefix = '%s' "
1079 : "ORDER BY pixel_x_size ASC",
1080 3 : osTableName.c_str());
1081 : }
1082 : else
1083 : {
1084 : osSQL.Printf("SELECT DISTINCT(pixel_x_size), pixel_y_size "
1085 : "FROM \"%s_metadata\" WHERE pixel_x_size != 0 "
1086 : "ORDER BY pixel_x_size ASC",
1087 22 : osTableName.c_str());
1088 : }
1089 :
1090 25 : hSQLLyr = OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);
1091 25 : if (hSQLLyr == NULL)
1092 : {
1093 0 : if (hRasterPyramidsLyr == NULL)
1094 : goto end;
1095 :
1096 : osSQL.Printf("SELECT DISTINCT(pixel_x_size), pixel_y_size "
1097 : "FROM \"%s_metadata\" WHERE pixel_x_size != 0 "
1098 : "ORDER BY pixel_x_size ASC",
1099 0 : osTableName.c_str());
1100 :
1101 0 : hSQLLyr = OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);
1102 0 : if (hSQLLyr == NULL)
1103 : goto end;
1104 : }
1105 :
1106 25 : nResolutions = OGR_L_GetFeatureCount(hSQLLyr, TRUE);
1107 :
1108 25 : if (nResolutions == 0)
1109 : {
1110 0 : OGR_DS_ReleaseResultSet(hDS, hSQLLyr);
1111 : goto end;
1112 : }
1113 :
1114 : /* -------------------------------------------------------------------- */
1115 : /* Set dataset attributes */
1116 : /* -------------------------------------------------------------------- */
1117 :
1118 25 : poDS = new RasterliteDataset();
1119 25 : poDS->SetDescription( poOpenInfo->pszFilename );
1120 25 : poDS->eAccess = poOpenInfo->eAccess;
1121 25 : poDS->osTableName = osTableName;
1122 25 : poDS->osFileName = osFileName;
1123 25 : poDS->hDS = hDS;
1124 :
1125 : /* poDS will release it from now */
1126 25 : hDS = NULL;
1127 :
1128 : /* -------------------------------------------------------------------- */
1129 : /* Fetch spatial extent or use the one provided by the user */
1130 : /* -------------------------------------------------------------------- */
1131 25 : OGREnvelope oEnvelope;
1132 26 : if (bMinXSet && bMinYSet && bMaxXSet && bMaxYSet)
1133 : {
1134 1 : oEnvelope.MinX = minx;
1135 1 : oEnvelope.MinY = miny;
1136 1 : oEnvelope.MaxX = maxx;
1137 1 : oEnvelope.MaxY = maxy;
1138 : }
1139 : else
1140 : {
1141 24 : OGR_L_GetExtent(hMetadataLyr, &oEnvelope, TRUE);
1142 : //printf("minx=%.15f miny=%.15f maxx=%.15f maxy=%.15f\n",
1143 : // oEnvelope.MinX, oEnvelope.MinY, oEnvelope.MaxX, oEnvelope.MaxY);
1144 : }
1145 :
1146 : /* -------------------------------------------------------------------- */
1147 : /* Store resolutions */
1148 : /* -------------------------------------------------------------------- */
1149 25 : poDS->nResolutions = nResolutions;
1150 : poDS->padfXResolutions =
1151 25 : (double*)CPLMalloc(sizeof(double) * poDS->nResolutions);
1152 : poDS->padfYResolutions =
1153 25 : (double*)CPLMalloc(sizeof(double) * poDS->nResolutions);
1154 :
1155 25 : i = 0;
1156 80 : while((hFeat = OGR_L_GetNextFeature(hSQLLyr)) != NULL)
1157 : {
1158 30 : poDS->padfXResolutions[i] = OGR_F_GetFieldAsDouble(hFeat, 0);
1159 30 : poDS->padfYResolutions[i] = OGR_F_GetFieldAsDouble(hFeat, 1);
1160 :
1161 30 : OGR_F_Destroy(hFeat);
1162 :
1163 : //printf("[%d] xres=%.15f yres=%.15f\n", i,
1164 : // poDS->padfXResolutions[i], poDS->padfYResolutions[i]);
1165 :
1166 30 : if (poDS->padfXResolutions[i] <= 0 || poDS->padfXResolutions[i] <= 0)
1167 : {
1168 : CPLError(CE_Failure, CPLE_NotSupported,
1169 : "res=%d, xres=%.15f, yres=%.15f",
1170 0 : i, poDS->padfXResolutions[i], poDS->padfYResolutions[i]);
1171 0 : OGR_DS_ReleaseResultSet(hDS, hSQLLyr);
1172 0 : delete poDS;
1173 0 : poDS = NULL;
1174 : goto end;
1175 : }
1176 30 : i ++;
1177 : }
1178 :
1179 25 : OGR_DS_ReleaseResultSet(poDS->hDS, hSQLLyr);
1180 25 : hSQLLyr = NULL;
1181 :
1182 : /* -------------------------------------------------------------------- */
1183 : /* Compute raster size, geotransform and projection */
1184 : /* -------------------------------------------------------------------- */
1185 : poDS->nRasterXSize =
1186 25 : (int)((oEnvelope.MaxX - oEnvelope.MinX) / poDS->padfXResolutions[0] + 0.5);
1187 : poDS->nRasterYSize =
1188 25 : (int)((oEnvelope.MaxY - oEnvelope.MinY) / poDS->padfYResolutions[0] + 0.5);
1189 :
1190 25 : poDS->bValidGeoTransform = TRUE;
1191 25 : poDS->adfGeoTransform[0] = oEnvelope.MinX;
1192 25 : poDS->adfGeoTransform[1] = poDS->padfXResolutions[0];
1193 25 : poDS->adfGeoTransform[2] = 0;
1194 25 : poDS->adfGeoTransform[3] = oEnvelope.MaxY;
1195 25 : poDS->adfGeoTransform[4] = 0;
1196 25 : poDS->adfGeoTransform[5] = - poDS->padfYResolutions[0];
1197 :
1198 25 : OGRSpatialReferenceH hSRS = OGR_L_GetSpatialRef(hMetadataLyr);
1199 25 : if (hSRS)
1200 : {
1201 25 : OSRExportToWkt(hSRS, &poDS->pszSRS);
1202 : }
1203 :
1204 : /* -------------------------------------------------------------------- */
1205 : /* Get number of bands and block size */
1206 : /* -------------------------------------------------------------------- */
1207 :
1208 25 : if (poDS->GetBlockParams(hRasterLyr, 0, &nBands, &eDataType,
1209 : &nBlockXSize, &nBlockYSize) == FALSE)
1210 : {
1211 0 : CPLError(CE_Failure, CPLE_AppDefined, "Cannot find block characteristics");
1212 0 : delete poDS;
1213 0 : poDS = NULL;
1214 : goto end;
1215 : }
1216 :
1217 26 : if (eDataType == GDT_Byte && nBands == 1 && nReqBands == 3)
1218 1 : nBands = 3;
1219 24 : else if (nReqBands != 0)
1220 : {
1221 : CPLError(CE_Warning, CPLE_NotSupported,
1222 0 : "Parameters bands=%d ignored", nReqBands);
1223 : }
1224 :
1225 : /* -------------------------------------------------------------------- */
1226 : /* Add bands */
1227 : /* -------------------------------------------------------------------- */
1228 :
1229 68 : for(iBand=0;iBand<nBands;iBand++)
1230 : poDS->SetBand(iBand+1, new RasterliteBand(poDS, iBand+1, eDataType,
1231 43 : nBlockXSize, nBlockYSize));
1232 :
1233 : /* -------------------------------------------------------------------- */
1234 : /* Add overview levels as internal datasets */
1235 : /* -------------------------------------------------------------------- */
1236 25 : if (nResolutions > 1)
1237 : {
1238 : poDS->papoOverviews = (RasterliteDataset**)
1239 3 : CPLCalloc(nResolutions - 1, sizeof(RasterliteDataset*));
1240 : int nLev;
1241 8 : for(nLev=1;nLev<nResolutions;nLev++)
1242 : {
1243 : int nOvrBands;
1244 : GDALDataType eOvrDataType;
1245 5 : if (poDS->GetBlockParams(hRasterLyr, nLev, &nOvrBands, &eOvrDataType,
1246 : &nBlockXSize, &nBlockYSize) == FALSE)
1247 : {
1248 : CPLError(CE_Failure, CPLE_AppDefined,
1249 0 : "Cannot find block characteristics for overview %d", nLev);
1250 0 : delete poDS;
1251 0 : poDS = NULL;
1252 : goto end;
1253 : }
1254 :
1255 5 : if (eDataType == GDT_Byte && nOvrBands == 1 && nReqBands == 3)
1256 0 : nOvrBands = 3;
1257 :
1258 5 : if (nBands != nOvrBands || eDataType != eOvrDataType)
1259 : {
1260 : CPLError(CE_Failure, CPLE_AppDefined,
1261 0 : "Overview %d has not the same number characteristics as main band", nLev);
1262 0 : delete poDS;
1263 0 : poDS = NULL;
1264 : goto end;
1265 : }
1266 :
1267 5 : poDS->papoOverviews[nLev-1] = new RasterliteDataset(poDS, nLev);
1268 :
1269 12 : for(iBand=0;iBand<nBands;iBand++)
1270 : {
1271 7 : poDS->papoOverviews[nLev-1]->SetBand(iBand+1,
1272 : new RasterliteBand(poDS->papoOverviews[nLev-1], iBand+1, eDataType,
1273 14 : nBlockXSize, nBlockYSize));
1274 : }
1275 : }
1276 : }
1277 :
1278 : /* -------------------------------------------------------------------- */
1279 : /* Select an overview if the user has requested so */
1280 : /* -------------------------------------------------------------------- */
1281 25 : if (nLevel == 0)
1282 : {
1283 : }
1284 0 : else if (nLevel >= 1 && nLevel <= nResolutions - 1)
1285 : {
1286 0 : poDS->papoOverviews[nLevel-1]->bMustFree = TRUE;
1287 0 : poDS = poDS->papoOverviews[nLevel-1];
1288 : }
1289 : else
1290 : {
1291 : CPLError(CE_Failure, CPLE_AppDefined,
1292 : "Invalid requested level : %d. Must be >= 0 and <= %d",
1293 0 : nLevel, nResolutions - 1);
1294 0 : delete poDS;
1295 0 : poDS = NULL;
1296 0 : }
1297 :
1298 : }
1299 :
1300 25 : if (poDS)
1301 : {
1302 : /* -------------------------------------------------------------------- */
1303 : /* Setup PAM info for this subdatasets */
1304 : /* -------------------------------------------------------------------- */
1305 25 : poDS->SetPhysicalFilename( osFileName.c_str() );
1306 :
1307 25 : CPLString osSubdatasetName;
1308 : osSubdatasetName.Printf("RASTERLITE:%s:table=%s",
1309 25 : osFileName.c_str(), osTableName.c_str());
1310 25 : poDS->SetSubdatasetName( osSubdatasetName.c_str() );
1311 25 : poDS->TryLoadXML();
1312 25 : poDS->oOvManager.Initialize( poDS, ":::VIRTUAL:::" );
1313 : }
1314 :
1315 :
1316 : end:
1317 25 : if (hDS)
1318 0 : OGRReleaseDataSource(hDS);
1319 25 : CSLDestroy(papszTokens);
1320 :
1321 25 : return poDS;
1322 : }
1323 :
1324 : /************************************************************************/
1325 : /* GDALRegister_Rasterlite() */
1326 : /************************************************************************/
1327 :
1328 558 : void GDALRegister_Rasterlite()
1329 :
1330 : {
1331 : GDALDriver *poDriver;
1332 :
1333 558 : if (! GDAL_CHECK_VERSION("Rasterlite driver"))
1334 0 : return;
1335 :
1336 558 : if( GDALGetDriverByName( "Rasterlite" ) == NULL )
1337 : {
1338 537 : poDriver = new GDALDriver();
1339 :
1340 537 : poDriver->SetDescription( "Rasterlite" );
1341 : poDriver->SetMetadataItem( GDAL_DMD_LONGNAME,
1342 537 : "Rasterlite" );
1343 : poDriver->SetMetadataItem( GDAL_DMD_HELPTOPIC,
1344 537 : "frmt_rasterlite.html" );
1345 537 : poDriver->SetMetadataItem( GDAL_DMD_EXTENSION, "sqlite" );
1346 : poDriver->SetMetadataItem( GDAL_DMD_CREATIONDATATYPES,
1347 : "Byte UInt16 Int16 UInt32 Int32 Float32 "
1348 537 : "Float64 CInt16 CInt32 CFloat32 CFloat64" );
1349 : poDriver->SetMetadataItem( GDAL_DMD_CREATIONOPTIONLIST,
1350 : "<CreationOptionList>"
1351 : " <Option name='WIPE' type='boolean' default='NO' description='Erase all prexisting data in the specified table'/>"
1352 : " <Option name='TILED' type='boolean' default='YES' description='Use tiling'/>"
1353 : " <Option name='BLOCKXSIZE' type='int' default='256' description='Tile Width'/>"
1354 : " <Option name='BLOCKYSIZE' type='int' default='256' description='Tile Height'/>"
1355 : " <Option name='DRIVER' type='string' default='GTiff' description='GDAL driver to use for storing tiles' default='GTiff'/>"
1356 : " <Option name='COMPRESS' type='string' default='(GTiff driver) Compression method' default='NONE'/>"
1357 : " <Option name='QUALITY' type='int' description='(JPEG-compressed GTiff, JPEG and WEBP drivers) JPEG/WEBP Quality 1-100' default='75'/>"
1358 : " <Option name='PHOTOMETRIC' type='string-select' description='(GTiff driver) Photometric interpretation'>"
1359 : " <Value>MINISBLACK</Value>"
1360 : " <Value>MINISWHITE</Value>"
1361 : " <Value>PALETTE</Value>"
1362 : " <Value>RGB</Value>"
1363 : " <Value>CMYK</Value>"
1364 : " <Value>YCBCR</Value>"
1365 : " <Value>CIELAB</Value>"
1366 : " <Value>ICCLAB</Value>"
1367 : " <Value>ITULAB</Value>"
1368 : " </Option>"
1369 : " <Option name='TARGET' type='int' description='(EPSILON driver) target size reduction as a percentage of the original (0-100)' default='96'/>"
1370 : " <Option name='FILTER' type='string' description='(EPSILON driver) Filter ID' default='daub97lift'/>"
1371 537 : "</CreationOptionList>" );
1372 :
1373 537 : poDriver->pfnOpen = RasterliteDataset::Open;
1374 537 : poDriver->pfnIdentify = RasterliteDataset::Identify;
1375 537 : poDriver->pfnCreateCopy = RasterliteCreateCopy;
1376 537 : poDriver->pfnDelete = RasterliteDelete;
1377 :
1378 537 : GetGDALDriverManager()->RegisterDriver( poDriver );
1379 : }
1380 : }
|