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