Line data Source code
1 : /******************************************************************************
2 : *
3 : * Project: OpenGIS Simple Features Reference Implementation
4 : * Purpose: Implements RasterLite2 support class.
5 : * Author: Even Rouault <even.rouault at spatialys.com>
6 : *
7 : ******************************************************************************
8 : *
9 : * CREDITS: The RasterLite2 module has been completely funded by:
10 : * Regione Toscana - Settore Sistema Informativo Territoriale ed
11 : * Ambientale (GDAL/RasterLite2 driver)
12 : * CIG: 644544015A
13 : *
14 : ******************************************************************************
15 : * Copyright (c) 2016, Even Rouault <even.rouault at spatialys.com>
16 : *
17 : * Permission is hereby granted, free of charge, to any person obtaining a
18 : * copy of this software and associated documentation files (the "Software"),
19 : * to deal in the Software without restriction, including without limitation
20 : * the rights to use, copy, modify, merge, publish, distribute, sublicense,
21 : * and/or sell copies of the Software, and to permit persons to whom the
22 : * Software is furnished to do so, subject to the following conditions:
23 : *
24 : * The above copyright notice and this permission notice shall be included
25 : * in all copies or substantial portions of the Software.
26 : *
27 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
28 : * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
29 : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
30 : * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
31 : * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
32 : * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
33 : * DEALINGS IN THE SOFTWARE.
34 : ****************************************************************************/
35 :
36 : #include "cpl_port.h"
37 : #include "ogr_sqlite.h"
38 : #include "ogrsqliteutility.h"
39 : #include "rasterlite2_header.h"
40 :
41 : #include <cstring>
42 : #include <algorithm>
43 :
44 : #include "cpl_error.h"
45 : #include "cpl_string.h"
46 :
47 : #ifdef HAVE_RASTERLITE2
48 :
49 : static CPLString EscapeNameAndQuoteIfNeeded(const char *pszName)
50 : {
51 : if (strchr(pszName, '"') == nullptr && strchr(pszName, ':') == nullptr)
52 : return pszName;
53 : return '"' + SQLEscapeName(pszName) + '"';
54 : }
55 :
56 : #endif
57 :
58 : /************************************************************************/
59 : /* OpenRaster() */
60 : /************************************************************************/
61 :
62 3 : bool OGRSQLiteDataSource::OpenRaster()
63 : {
64 : #ifdef HAVE_RASTERLITE2
65 : /* -------------------------------------------------------------------- */
66 : /* Detect RasterLite2 coverages. */
67 : /* -------------------------------------------------------------------- */
68 : char **papszResults = nullptr;
69 : int nRowCount = 0, nColCount = 0;
70 : int rc = sqlite3_get_table(hDB,
71 : "SELECT name FROM sqlite_master WHERE "
72 : "type = 'table' AND name = 'raster_coverages'",
73 : &papszResults, &nRowCount, &nColCount, nullptr);
74 : sqlite3_free_table(papszResults);
75 : if (!(rc == SQLITE_OK && nRowCount == 1))
76 : {
77 : return false;
78 : }
79 :
80 : papszResults = nullptr;
81 : nRowCount = 0;
82 : nColCount = 0;
83 : rc = sqlite3_get_table(hDB,
84 : "SELECT coverage_name, title, abstract "
85 : "FROM raster_coverages "
86 : "LIMIT 10000",
87 : &papszResults, &nRowCount, &nColCount, nullptr);
88 : if (!(rc == SQLITE_OK && nRowCount > 0))
89 : {
90 : sqlite3_free_table(papszResults);
91 : return false;
92 : }
93 : for (int i = 0; i < nRowCount; ++i)
94 : {
95 : const char *const *papszRow = papszResults + i * 3 + 3;
96 : const char *pszCoverageName = papszRow[0];
97 : const char *pszTitle = papszRow[1];
98 : const char *pszAbstract = papszRow[2];
99 : if (pszCoverageName != nullptr)
100 : {
101 : rl2CoveragePtr cvg =
102 : rl2_create_coverage_from_dbms(hDB, nullptr, pszCoverageName);
103 : if (cvg != nullptr)
104 : {
105 : const int nIdx = m_aosSubDatasets.size() / 2 + 1;
106 : m_aosSubDatasets.AddNameValue(
107 : CPLSPrintf("SUBDATASET_%d_NAME", nIdx),
108 : CPLSPrintf(
109 : "RASTERLITE2:%s:%s",
110 : EscapeNameAndQuoteIfNeeded(m_pszFilename).c_str(),
111 : EscapeNameAndQuoteIfNeeded(pszCoverageName).c_str()));
112 : CPLString osDesc("Coverage ");
113 : osDesc += pszCoverageName;
114 : if (pszTitle != nullptr && pszTitle[0] != '\0' &&
115 : !EQUAL(pszTitle, "*** missing Title ***"))
116 : {
117 : osDesc += ", title = ";
118 : osDesc += pszTitle;
119 : }
120 : if (pszAbstract != nullptr && pszAbstract[0] != '\0' &&
121 : !EQUAL(pszAbstract, "*** missing Abstract ***"))
122 : {
123 : osDesc += ", abstract = ";
124 : osDesc += pszAbstract;
125 : }
126 : m_aosSubDatasets.AddNameValue(
127 : CPLSPrintf("SUBDATASET_%d_DESC", nIdx), osDesc.c_str());
128 :
129 : rl2_destroy_coverage(cvg);
130 : }
131 : }
132 : }
133 : sqlite3_free_table(papszResults);
134 :
135 : if (m_aosSubDatasets.size() == 2)
136 : {
137 : const char *pszSubDSName =
138 : m_aosSubDatasets.FetchNameValue("SUBDATASET_1_NAME");
139 : if (pszSubDSName)
140 : {
141 : return OpenRasterSubDataset(pszSubDSName);
142 : }
143 : }
144 :
145 : return !m_aosSubDatasets.empty();
146 : #else
147 3 : return false;
148 : #endif
149 : }
150 :
151 : /************************************************************************/
152 : /* OpenRasterSubDataset() */
153 : /************************************************************************/
154 :
155 0 : bool OGRSQLiteDataSource::OpenRasterSubDataset(
156 : CPL_UNUSED const char *pszConnectionId)
157 : {
158 : #ifdef HAVE_RASTERLITE2
159 : if (!STARTS_WITH_CI(pszConnectionId, "RASTERLITE2:"))
160 : return false;
161 :
162 : char **papszTokens =
163 : CSLTokenizeString2(pszConnectionId, ":", CSLT_HONOURSTRINGS);
164 : if (CSLCount(papszTokens) < 3)
165 : {
166 : CSLDestroy(papszTokens);
167 : return false;
168 : }
169 :
170 : m_aosSubDatasets.Clear();
171 :
172 : m_osCoverageName = SQLUnescape(papszTokens[2]);
173 : m_nSectionId =
174 : (CSLCount(papszTokens) >= 4) ? CPLAtoGIntBig(papszTokens[3]) : -1;
175 :
176 : CSLDestroy(papszTokens);
177 :
178 : m_pRL2Coverage =
179 : rl2_create_coverage_from_dbms(hDB, nullptr, m_osCoverageName);
180 : if (m_pRL2Coverage == nullptr)
181 : {
182 : CPLError(CE_Failure, CPLE_AppDefined, "Invalid coverage: %s",
183 : m_osCoverageName.c_str());
184 : return false;
185 : }
186 :
187 : bool bSingleSection = false;
188 : if (m_nSectionId < 0)
189 : {
190 : CPLString osSectionTableName(
191 : CPLSPrintf("%s_sections", m_osCoverageName.c_str()));
192 : int nRowCount2 = 0;
193 : int nColCount2 = 0;
194 : char **papszResults2 = nullptr;
195 : char *pszSQL =
196 : sqlite3_mprintf("SELECT section_id, section_name FROM \"%w\" "
197 : "ORDER BY section_id "
198 : "LIMIT 1000000",
199 : osSectionTableName.c_str());
200 : int rc = sqlite3_get_table(hDB, pszSQL, &papszResults2, &nRowCount2,
201 : &nColCount2, nullptr);
202 : sqlite3_free(pszSQL);
203 : if (rc == SQLITE_OK)
204 : {
205 : for (int j = 0; j < nRowCount2; ++j)
206 : {
207 : const char *const *papszRow2 = papszResults2 + j * 2 + 2;
208 : const char *pszSectionId = papszRow2[0];
209 : const char *pszSectionName = papszRow2[1];
210 : if (pszSectionName != nullptr && pszSectionId != nullptr)
211 : {
212 : if (nRowCount2 > 1)
213 : {
214 : const int nIdx = m_aosSubDatasets.size() / 2 + 1;
215 : m_aosSubDatasets.AddNameValue(
216 : CPLSPrintf("SUBDATASET_%d_NAME", nIdx),
217 : CPLSPrintf(
218 : "RASTERLITE2:%s:%s:%s:%s",
219 : EscapeNameAndQuoteIfNeeded(m_pszFilename)
220 : .c_str(),
221 : EscapeNameAndQuoteIfNeeded(m_osCoverageName)
222 : .c_str(),
223 : pszSectionId,
224 : EscapeNameAndQuoteIfNeeded(pszSectionName)
225 : .c_str()));
226 : m_aosSubDatasets.AddNameValue(
227 : CPLSPrintf("SUBDATASET_%d_DESC", nIdx),
228 : CPLSPrintf("Coverage %s, section %s / %s",
229 : m_osCoverageName.c_str(), pszSectionName,
230 : pszSectionId));
231 : }
232 : else
233 : {
234 : m_nSectionId = CPLAtoGIntBig(pszSectionId);
235 : bSingleSection = true;
236 : }
237 : }
238 : }
239 : }
240 : sqlite3_free_table(papszResults2);
241 : }
242 :
243 : double dfXRes = 0.0;
244 : double dfYRes = 0.0;
245 :
246 : double dfMinX = 0.0;
247 : double dfMinY = 0.0;
248 : double dfMaxX = 0.0;
249 : double dfMaxY = 0.0;
250 : unsigned int nWidth = 0;
251 : unsigned int nHeight = 0;
252 :
253 : // Get extent and resolution
254 : if (m_nSectionId >= 0)
255 : {
256 : int ret = rl2_resolve_base_resolution_from_dbms(
257 : hDB, nullptr, m_osCoverageName,
258 : TRUE, // by_section
259 : m_nSectionId, &dfXRes, &dfYRes);
260 : if (ret != RL2_OK)
261 : {
262 : CPLError(CE_Failure, CPLE_AppDefined,
263 : "rl2_resolve_base_resolution_from_dbms() failed / "
264 : "Invalid section: " CPL_FRMT_GIB,
265 : m_nSectionId);
266 : return false;
267 : }
268 :
269 : ret = rl2_resolve_full_section_from_dbms(
270 : hDB, nullptr, m_osCoverageName, m_nSectionId, dfXRes, dfYRes,
271 : &dfMinX, &dfMinY, &dfMaxX, &dfMaxY, &nWidth, &nHeight);
272 : if (ret != RL2_OK || nWidth == 0 || nWidth > INT_MAX || nHeight == 0 ||
273 : nHeight > INT_MAX)
274 : {
275 : CPLError(CE_Failure, CPLE_AppDefined,
276 : "rl2_resolve_full_section_from_dbms() failed / "
277 : "Invalid section: " CPL_FRMT_GIB,
278 : m_nSectionId);
279 : return false;
280 : }
281 : }
282 : else
283 : {
284 : rl2_get_coverage_resolution(m_pRL2Coverage, &dfXRes, &dfYRes);
285 :
286 : char *pszSQL = sqlite3_mprintf(
287 : "SELECT extent_minx, extent_miny, extent_maxx, extent_maxy "
288 : "FROM raster_coverages WHERE "
289 : "Lower(coverage_name) = Lower('%q') "
290 : "LIMIT 1",
291 : m_osCoverageName.c_str());
292 : char **papszResults = nullptr;
293 : int nRowCount = 0;
294 : int nColCount = 0;
295 : int rc = sqlite3_get_table(hDB, pszSQL, &papszResults, &nRowCount,
296 : &nColCount, nullptr);
297 : sqlite3_free(pszSQL);
298 : if (rc == SQLITE_OK)
299 : {
300 : if (nRowCount == 1)
301 : {
302 : const char *pszMinX = papszResults[4 + 0];
303 : const char *pszMinY = papszResults[4 + 1];
304 : const char *pszMaxX = papszResults[4 + 2];
305 : const char *pszMaxY = papszResults[4 + 3];
306 : if (pszMinX != nullptr && pszMinY != nullptr &&
307 : pszMaxX != nullptr && pszMaxY != nullptr)
308 : {
309 : dfMinX = CPLAtof(pszMinX);
310 : dfMinY = CPLAtof(pszMinY);
311 : dfMaxX = CPLAtof(pszMaxX);
312 : dfMaxY = CPLAtof(pszMaxY);
313 : }
314 : }
315 : sqlite3_free_table(papszResults);
316 : }
317 : double dfWidth = 0.5 + (dfMaxX - dfMinX) / dfXRes;
318 : double dfHeight = 0.5 + (dfMaxY - dfMinY) / dfYRes;
319 : if (dfWidth <= 0.5 || dfHeight <= 0.5 || dfWidth > INT_MAX ||
320 : dfHeight > INT_MAX)
321 : {
322 : CPLError(CE_Failure, CPLE_AppDefined, "Invalid dimensions");
323 : return false;
324 : }
325 : nWidth = static_cast<int>(dfWidth);
326 : nHeight = static_cast<int>(dfHeight);
327 : }
328 :
329 : // Compute dimension and geotransform
330 : nRasterXSize = static_cast<int>(nWidth);
331 : nRasterYSize = static_cast<int>(nHeight);
332 : m_bGeoTransformValid = true;
333 : m_adfGeoTransform[0] = dfMinX;
334 : m_adfGeoTransform[1] = (dfMaxX - dfMinX) / nRasterXSize;
335 : m_adfGeoTransform[2] = 0.0;
336 : m_adfGeoTransform[3] = dfMaxY;
337 : m_adfGeoTransform[4] = 0.0;
338 : m_adfGeoTransform[5] = -(dfMaxY - dfMinY) / nRasterYSize;
339 :
340 : // Get SRS
341 : int nSRID = 0;
342 : if (rl2_get_coverage_srid(m_pRL2Coverage, &nSRID) == RL2_OK)
343 : {
344 : OGRSpatialReference *poSRS = FetchSRS(nSRID);
345 : if (poSRS != nullptr)
346 : {
347 : m_oSRS = *poSRS;
348 : m_oSRS.SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER);
349 : }
350 : }
351 :
352 : // Get pixel information and number of bands
353 : unsigned char nSampleType = 0;
354 : unsigned char nPixelType = 0;
355 : unsigned char l_nBands = 0;
356 : rl2_get_coverage_type(m_pRL2Coverage, &nSampleType, &nPixelType, &l_nBands);
357 : if (!GDALCheckBandCount(l_nBands, FALSE))
358 : return false;
359 : int nBits = 0;
360 : GDALDataType eDT = GDT_Unknown;
361 : switch (nSampleType)
362 : {
363 : default:
364 : case RL2_SAMPLE_UNKNOWN:
365 : {
366 : CPLError(CE_Failure, CPLE_AppDefined, "Unknown sample type");
367 : return false;
368 : }
369 : case RL2_SAMPLE_1_BIT:
370 : {
371 : if (nPixelType == RL2_PIXEL_MONOCHROME)
372 : {
373 : m_bPromote1BitAs8Bit =
374 : CPLFetchBool(papszOpenOptions, "1BIT_AS_8BIT", true);
375 : }
376 : nBits = 1;
377 : eDT = GDT_Byte;
378 : break;
379 : }
380 : case RL2_SAMPLE_2_BIT:
381 : {
382 : nBits = 2;
383 : eDT = GDT_Byte;
384 : break;
385 : }
386 : case RL2_SAMPLE_4_BIT:
387 : {
388 : nBits = 4;
389 : eDT = GDT_Byte;
390 : break;
391 : }
392 : case RL2_SAMPLE_INT8:
393 : {
394 : nBits = 8;
395 : eDT = GDT_Int8;
396 : break;
397 : }
398 : case RL2_SAMPLE_UINT8:
399 : {
400 : nBits = 8;
401 : eDT = GDT_Byte;
402 : break;
403 : }
404 : case RL2_SAMPLE_INT16:
405 : {
406 : nBits = 16;
407 : eDT = GDT_Int16;
408 : break;
409 : }
410 : case RL2_SAMPLE_UINT16:
411 : {
412 : nBits = 16;
413 : eDT = GDT_UInt16;
414 : break;
415 : }
416 : case RL2_SAMPLE_INT32:
417 : {
418 : nBits = 32;
419 : eDT = GDT_Int32;
420 : break;
421 : }
422 : case RL2_SAMPLE_UINT32:
423 : {
424 : nBits = 32;
425 : eDT = GDT_UInt32;
426 : break;
427 : }
428 : case RL2_SAMPLE_FLOAT:
429 : {
430 : nBits = 32;
431 : eDT = GDT_Float32;
432 : break;
433 : }
434 : case RL2_SAMPLE_DOUBLE:
435 : {
436 : nBits = 64;
437 : eDT = GDT_Float64;
438 : break;
439 : }
440 : }
441 :
442 : // Get information about compression (informative)
443 : unsigned char nCompression = 0;
444 : int nQuality = 0;
445 : rl2_get_coverage_compression(m_pRL2Coverage, &nCompression, &nQuality);
446 : const char *pszCompression = nullptr;
447 : switch (nCompression)
448 : {
449 : case RL2_COMPRESSION_DEFLATE:
450 : case RL2_COMPRESSION_DEFLATE_NO:
451 : pszCompression = "DEFLATE";
452 : break;
453 : case RL2_COMPRESSION_LZMA:
454 : case RL2_COMPRESSION_LZMA_NO:
455 : pszCompression = "LZMA";
456 : break;
457 : case RL2_COMPRESSION_GIF:
458 : pszCompression = "GIF";
459 : break;
460 : case RL2_COMPRESSION_JPEG:
461 : pszCompression = "JPEG";
462 : break;
463 : case RL2_COMPRESSION_PNG:
464 : pszCompression = "PNG";
465 : break;
466 : case RL2_COMPRESSION_LOSSY_WEBP:
467 : pszCompression = "WEBP";
468 : break;
469 : case RL2_COMPRESSION_LOSSLESS_WEBP:
470 : pszCompression = "WEBP_LOSSLESS";
471 : break;
472 : case RL2_COMPRESSION_CCITTFAX3:
473 : pszCompression = "CCITTFAX3";
474 : break;
475 : case RL2_COMPRESSION_CCITTFAX4:
476 : pszCompression = "CCITTFAX4";
477 : break;
478 : case RL2_COMPRESSION_LZW:
479 : pszCompression = "LZW";
480 : break;
481 : case RL2_COMPRESSION_LOSSY_JP2:
482 : pszCompression = "JPEG2000";
483 : break;
484 : case RL2_COMPRESSION_LOSSLESS_JP2:
485 : pszCompression = "JPEG2000_LOSSLESS";
486 : break;
487 : default:
488 : break;
489 : }
490 :
491 : if (pszCompression != nullptr)
492 : {
493 : GDALDataset::SetMetadataItem("COMPRESSION", pszCompression,
494 : "IMAGE_STRUCTURE");
495 : }
496 :
497 : if (nQuality != 0 && (nCompression == RL2_COMPRESSION_JPEG ||
498 : nCompression == RL2_COMPRESSION_LOSSY_WEBP ||
499 : nCompression == RL2_COMPRESSION_LOSSY_JP2))
500 : {
501 : GDALDataset::SetMetadataItem("QUALITY", CPLSPrintf("%d", nQuality),
502 : "IMAGE_STRUCTURE");
503 : }
504 :
505 : // Get tile dimensions
506 : unsigned int nTileWidth = 0;
507 : unsigned int nTileHeight = 0;
508 : rl2_get_coverage_tile_size(m_pRL2Coverage, &nTileWidth, &nTileHeight);
509 : if (nTileWidth == 0 || nTileHeight == 0 || nTileWidth > INT_MAX ||
510 : nTileHeight > INT_MAX)
511 : {
512 : CPLError(CE_Failure, CPLE_AppDefined, "Invalid block size");
513 : return false;
514 : }
515 : const int nBlockXSize = static_cast<int>(nTileWidth);
516 : const int nBlockYSize = static_cast<int>(nTileHeight);
517 :
518 : // Fetch nodata values
519 : std::vector<double> adfNoDataValues;
520 : rl2PixelPtr noDataPtr = rl2_get_coverage_no_data(m_pRL2Coverage);
521 : if (noDataPtr != nullptr)
522 : {
523 : unsigned char noDataSampleType = 0;
524 : unsigned char noDataPixelType = 0;
525 : unsigned char noDataBands = 0;
526 : if (rl2_get_pixel_type(noDataPtr, &noDataSampleType, &noDataPixelType,
527 : &noDataBands) == RL2_OK &&
528 : noDataSampleType == nSampleType && noDataPixelType == nPixelType &&
529 : noDataBands == l_nBands)
530 : {
531 : for (int i = 0; i < l_nBands; ++i)
532 : {
533 : double dfNoDataValue = 0.0;
534 : switch (nSampleType)
535 : {
536 : default:
537 : {
538 : break;
539 : }
540 : case RL2_SAMPLE_1_BIT:
541 : {
542 : unsigned char nVal = 0;
543 : rl2_get_pixel_sample_1bit(noDataPtr, &nVal);
544 : dfNoDataValue = nVal;
545 : break;
546 : }
547 : case RL2_SAMPLE_2_BIT:
548 : {
549 : unsigned char nVal = 0;
550 : rl2_get_pixel_sample_2bit(noDataPtr, &nVal);
551 : dfNoDataValue = nVal;
552 : break;
553 : }
554 : case RL2_SAMPLE_4_BIT:
555 : {
556 : unsigned char nVal = 0;
557 : rl2_get_pixel_sample_4bit(noDataPtr, &nVal);
558 : dfNoDataValue = nVal;
559 : break;
560 : }
561 : case RL2_SAMPLE_INT8:
562 : {
563 : char nVal = 0;
564 : rl2_get_pixel_sample_int8(noDataPtr, &nVal);
565 : dfNoDataValue = nVal;
566 : break;
567 : }
568 : case RL2_SAMPLE_UINT8:
569 : {
570 : unsigned char nVal = 0;
571 : rl2_get_pixel_sample_uint8(noDataPtr, i, &nVal);
572 : dfNoDataValue = nVal;
573 : break;
574 : }
575 : case RL2_SAMPLE_INT16:
576 : {
577 : short nVal = 0;
578 : rl2_get_pixel_sample_int16(noDataPtr, &nVal);
579 : dfNoDataValue = nVal;
580 : break;
581 : }
582 : case RL2_SAMPLE_UINT16:
583 : {
584 : unsigned short nVal = 0;
585 : rl2_get_pixel_sample_uint16(noDataPtr, i, &nVal);
586 : dfNoDataValue = nVal;
587 : break;
588 : }
589 : case RL2_SAMPLE_INT32:
590 : {
591 : int nVal = 0;
592 : rl2_get_pixel_sample_int32(noDataPtr, &nVal);
593 : dfNoDataValue = nVal;
594 : break;
595 : }
596 : case RL2_SAMPLE_UINT32:
597 : {
598 : unsigned int nVal = 0;
599 : rl2_get_pixel_sample_uint32(noDataPtr, &nVal);
600 : dfNoDataValue = nVal;
601 : break;
602 : }
603 : case RL2_SAMPLE_FLOAT:
604 : {
605 : float fVal = 0.0f;
606 : rl2_get_pixel_sample_float(noDataPtr, &fVal);
607 : dfNoDataValue = fVal;
608 : break;
609 : }
610 : case RL2_SAMPLE_DOUBLE:
611 : {
612 : double dfVal = 0.0;
613 : rl2_get_pixel_sample_double(noDataPtr, &dfVal);
614 : dfNoDataValue = dfVal;
615 : break;
616 : }
617 : }
618 :
619 : adfNoDataValues.push_back(dfNoDataValue);
620 : }
621 : }
622 :
623 : // Do not destroy noDataPtr. It belongs to m_pRL2Coverage
624 : }
625 :
626 : // The nodata concept in RasterLite2 is equivalent to the NODATA_VALUES
627 : // one of GDAL: the nodata value must be matched simultaneously on all
628 : // bands.
629 : if (adfNoDataValues.size() == l_nBands && l_nBands > 1)
630 : {
631 : CPLString osNoDataValues;
632 : for (int i = 0; i < l_nBands; i++)
633 : {
634 : if (!osNoDataValues.empty())
635 : osNoDataValues += " ";
636 : osNoDataValues += CPLSPrintf("%g", adfNoDataValues[i]);
637 : }
638 : GDALDataset::SetMetadataItem("NODATA_VALUES", osNoDataValues.c_str());
639 : }
640 :
641 : for (int iBand = 1; iBand <= l_nBands; ++iBand)
642 : {
643 : const bool bHasNoData = adfNoDataValues.size() == 1 && l_nBands == 1;
644 : const double dfNoDataValue = bHasNoData ? adfNoDataValues[0] : 0.0;
645 : SetBand(iBand,
646 : new RL2RasterBand(iBand, nPixelType, eDT, nBits,
647 : m_bPromote1BitAs8Bit, nBlockXSize,
648 : nBlockYSize, bHasNoData, dfNoDataValue));
649 : }
650 :
651 : // Fetch statistics
652 : if (m_nSectionId < 0 || bSingleSection)
653 : {
654 : rl2RasterStatisticsPtr pStatistics =
655 : rl2_create_raster_statistics_from_dbms(hDB, nullptr,
656 : m_osCoverageName);
657 : if (pStatistics != nullptr)
658 : {
659 : for (int iBand = 1; iBand <= l_nBands; ++iBand)
660 : {
661 : GDALRasterBand *poBand = GetRasterBand(iBand);
662 : double dfMin = 0.0;
663 : double dfMax = 0.0;
664 : double dfMean = 0.0;
665 : double dfVariance = 0.0;
666 : double dfStdDev = 0.0;
667 : if (!(nBits == 1 && m_bPromote1BitAs8Bit) &&
668 : rl2_get_band_statistics(
669 : pStatistics, static_cast<unsigned char>(iBand - 1),
670 : &dfMin, &dfMax, &dfMean, &dfVariance,
671 : &dfStdDev) == RL2_OK)
672 : {
673 : poBand->GDALRasterBand::SetMetadataItem(
674 : "STATISTICS_MINIMUM", CPLSPrintf("%.16g", dfMin));
675 : poBand->GDALRasterBand::SetMetadataItem(
676 : "STATISTICS_MAXIMUM", CPLSPrintf("%.16g", dfMax));
677 : poBand->GDALRasterBand::SetMetadataItem(
678 : "STATISTICS_MEAN", CPLSPrintf("%.16g", dfMean));
679 : poBand->GDALRasterBand::SetMetadataItem(
680 : "STATISTICS_STDDEV", CPLSPrintf("%.16g", dfStdDev));
681 : }
682 : }
683 : rl2_destroy_raster_statistics(pStatistics);
684 : }
685 : }
686 :
687 : // Fetch other metadata
688 : char *pszSQL =
689 : sqlite3_mprintf("SELECT title, abstract FROM raster_coverages WHERE "
690 : "Lower(coverage_name) = Lower('%q') LIMIT 1",
691 : m_osCoverageName.c_str());
692 : char **papszResults = nullptr;
693 : int nRowCount = 0;
694 : int nColCount = 0;
695 : int rc = sqlite3_get_table(hDB, pszSQL, &papszResults, &nRowCount,
696 : &nColCount, nullptr);
697 : sqlite3_free(pszSQL);
698 : if (rc == SQLITE_OK)
699 : {
700 : if (nRowCount == 1)
701 : {
702 : const char *pszTitle = papszResults[2 + 0];
703 : const char *pszAbstract = papszResults[2 + 1];
704 : if (pszTitle != nullptr && pszTitle[0] != '\0' &&
705 : !EQUAL(pszTitle, "*** missing Title ***"))
706 : {
707 : GDALDataset::SetMetadataItem("COVERAGE_TITLE", pszTitle);
708 : }
709 : if (pszAbstract != nullptr && pszAbstract[0] != '\0' &&
710 : !EQUAL(pszAbstract, "*** missing Abstract ***"))
711 : {
712 : GDALDataset::SetMetadataItem("COVERAGE_ABSTRACT", pszAbstract);
713 : }
714 : }
715 : sqlite3_free_table(papszResults);
716 : }
717 :
718 : if (m_nSectionId >= 0)
719 : {
720 : papszResults = nullptr;
721 : nRowCount = 0;
722 : nColCount = 0;
723 : pszSQL =
724 : sqlite3_mprintf("SELECT summary FROM \"%w\" WHERE "
725 : "section_id = %d LIMIT 1",
726 : CPLSPrintf("%s_sections", m_osCoverageName.c_str()),
727 : static_cast<int>(m_nSectionId));
728 : rc = sqlite3_get_table(hDB, pszSQL, &papszResults, &nRowCount,
729 : &nColCount, nullptr);
730 : sqlite3_free(pszSQL);
731 : if (rc == SQLITE_OK)
732 : {
733 : if (nRowCount == 1)
734 : {
735 : const char *pszSummary = papszResults[1 + 0];
736 : if (pszSummary != nullptr && pszSummary[0] != '\0')
737 : {
738 : GDALDataset::SetMetadataItem("SECTION_SUMMARY", pszSummary);
739 : }
740 : }
741 : sqlite3_free_table(papszResults);
742 : }
743 : }
744 :
745 : // Instantiate overviews
746 : int nStrictResolution = 0;
747 : int nMixedResolutions = 0;
748 : int nSectionPaths = 0;
749 : int nSectionMD5 = 0;
750 : int nSectionSummary = 0;
751 : rl2_get_coverage_policies(m_pRL2Coverage, &nStrictResolution,
752 : &nMixedResolutions, &nSectionPaths, &nSectionMD5,
753 : &nSectionSummary);
754 : m_bRL2MixedResolutions = CPL_TO_BOOL(nMixedResolutions);
755 :
756 : ListOverviews();
757 :
758 : return true;
759 : #else // !defined(HAVE_RASTERLITE2)
760 0 : return false;
761 : #endif // HAVE_RASTERLITE2
762 : }
763 :
764 : #ifdef HAVE_RASTERLITE2
765 :
766 : /************************************************************************/
767 : /* ListOverviews() */
768 : /************************************************************************/
769 :
770 : void OGRSQLiteDataSource::ListOverviews()
771 : {
772 : if (!m_bRL2MixedResolutions || m_nSectionId >= 0)
773 : {
774 : char *pszSQL;
775 : if (!m_bRL2MixedResolutions)
776 : {
777 : pszSQL = sqlite3_mprintf(
778 : "SELECT x_resolution_1_1, y_resolution_1_1, "
779 : "x_resolution_1_2, y_resolution_1_2, "
780 : "x_resolution_1_4, y_resolution_1_4,"
781 : "x_resolution_1_8, y_resolution_1_8 "
782 : "FROM \"%w\" ORDER BY pyramid_level "
783 : "LIMIT 1000",
784 : CPLSPrintf("%s_levels", m_osCoverageName.c_str()));
785 : }
786 : else
787 : {
788 : pszSQL = sqlite3_mprintf(
789 : "SELECT x_resolution_1_1, y_resolution_1_1, "
790 : "x_resolution_1_2, y_resolution_1_2, "
791 : "x_resolution_1_4, y_resolution_1_4,"
792 : "x_resolution_1_8, y_resolution_1_8 "
793 : "FROM \"%w\" WHERE section_id = %d "
794 : "ORDER BY pyramid_level "
795 : "LIMIT 1000",
796 : CPLSPrintf("%s_section_levels", m_osCoverageName.c_str()),
797 : static_cast<int>(m_nSectionId));
798 : }
799 : char **papszResults = nullptr;
800 : int nRowCount = 0;
801 : int nColCount = 0;
802 : char *pszErrMsg = nullptr;
803 : int rc = sqlite3_get_table(hDB, pszSQL, &papszResults, &nRowCount,
804 : &nColCount, &pszErrMsg);
805 : sqlite3_free(pszSQL);
806 : if (pszErrMsg)
807 : CPLDebug("SQLite", "%s", pszErrMsg);
808 : sqlite3_free(pszErrMsg);
809 : if (rc == SQLITE_OK)
810 : {
811 : for (int i = 0; i < nRowCount; ++i)
812 : {
813 : const char *const *papszRow = papszResults + i * 8 + 8;
814 : const char *pszXRes1 = papszRow[0];
815 : const char *pszYRes1 = papszRow[1];
816 : const char *pszXRes2 = papszRow[2];
817 : const char *pszYRes2 = papszRow[3];
818 : const char *pszXRes4 = papszRow[4];
819 : const char *pszYRes4 = papszRow[5];
820 : const char *pszXRes8 = papszRow[6];
821 : const char *pszYRes8 = papszRow[7];
822 : if (pszXRes1 != nullptr && pszYRes1 != nullptr)
823 : {
824 : CreateRL2OverviewDatasetIfNeeded(CPLAtof(pszXRes1),
825 : CPLAtof(pszYRes1));
826 : }
827 : if (pszXRes2 != nullptr && pszYRes2 != nullptr)
828 : {
829 : CreateRL2OverviewDatasetIfNeeded(CPLAtof(pszXRes2),
830 : CPLAtof(pszYRes2));
831 : }
832 : if (pszXRes4 != nullptr && pszYRes4 != nullptr)
833 : {
834 : CreateRL2OverviewDatasetIfNeeded(CPLAtof(pszXRes4),
835 : CPLAtof(pszYRes4));
836 : }
837 : if (pszXRes8 != nullptr && pszYRes8 != nullptr)
838 : {
839 : CreateRL2OverviewDatasetIfNeeded(CPLAtof(pszXRes8),
840 : CPLAtof(pszYRes8));
841 : }
842 : }
843 : sqlite3_free_table(papszResults);
844 : }
845 : }
846 : }
847 :
848 : /************************************************************************/
849 : /* CreateRL2OverviewDatasetIfNeeded() */
850 : /************************************************************************/
851 :
852 : void OGRSQLiteDataSource::CreateRL2OverviewDatasetIfNeeded(double dfXRes,
853 : double dfYRes)
854 : {
855 : if (fabs(dfXRes - m_adfGeoTransform[1]) < 1e-5 * m_adfGeoTransform[1])
856 : return;
857 :
858 : for (size_t i = 0; i < m_apoOverviewDS.size(); ++i)
859 : {
860 : if (fabs(dfXRes - m_apoOverviewDS[i]->m_adfGeoTransform[1]) <
861 : 1e-5 * m_apoOverviewDS[i]->m_adfGeoTransform[1])
862 : {
863 : return;
864 : }
865 : }
866 :
867 : OGRSQLiteDataSource *poOvrDS = new OGRSQLiteDataSource();
868 : poOvrDS->bIsInternal = true;
869 : poOvrDS->m_poParentDS = this;
870 : poOvrDS->m_osCoverageName = m_osCoverageName;
871 : poOvrDS->m_nSectionId = m_nSectionId;
872 : poOvrDS->m_bPromote1BitAs8Bit = m_bPromote1BitAs8Bit;
873 : poOvrDS->m_bRL2MixedResolutions = m_bRL2MixedResolutions;
874 : poOvrDS->m_adfGeoTransform[0] = m_adfGeoTransform[0];
875 : poOvrDS->m_adfGeoTransform[1] = dfXRes;
876 : poOvrDS->m_adfGeoTransform[3] = m_adfGeoTransform[3];
877 : poOvrDS->m_adfGeoTransform[5] = -dfYRes;
878 : const double dfMinX = m_adfGeoTransform[0];
879 : const double dfMaxX = dfMinX + m_adfGeoTransform[1] * nRasterXSize;
880 : const double dfMaxY = m_adfGeoTransform[3];
881 : const double dfMinY = dfMaxY + m_adfGeoTransform[5] * nRasterYSize;
882 : poOvrDS->nRasterXSize = static_cast<int>(0.5 + (dfMaxX - dfMinX) / dfXRes);
883 : poOvrDS->nRasterYSize = static_cast<int>(0.5 + (dfMaxY - dfMinY) / dfYRes);
884 : if (poOvrDS->nRasterXSize <= 1 || poOvrDS->nRasterYSize <= 1 ||
885 : (poOvrDS->nRasterXSize < 64 && poOvrDS->nRasterYSize < 64 &&
886 : !CPLTestBool(CPLGetConfigOption("RL2_SHOW_ALL_PYRAMID_LEVELS", "NO"))))
887 : {
888 : delete poOvrDS;
889 : return;
890 : }
891 : for (int iBand = 1; iBand <= nBands; ++iBand)
892 : {
893 : poOvrDS->SetBand(iBand,
894 : new RL2RasterBand(reinterpret_cast<RL2RasterBand *>(
895 : GetRasterBand(iBand))));
896 : }
897 : m_apoOverviewDS.push_back(poOvrDS);
898 : }
899 :
900 : /************************************************************************/
901 : /* RL2RasterBand() */
902 : /************************************************************************/
903 :
904 : RL2RasterBand::RL2RasterBand(int nBandIn, int nPixelType, GDALDataType eDT,
905 : int nBits, bool bPromote1BitAs8Bit,
906 : int nBlockXSizeIn, int nBlockYSizeIn,
907 : bool bHasNoDataIn, double dfNoDataValueIn)
908 : : m_bHasNoData(bHasNoDataIn), m_dfNoDataValue(dfNoDataValueIn),
909 : m_eColorInterp(GCI_Undefined), m_poCT(nullptr)
910 : {
911 : eDataType = eDT;
912 : nBlockXSize = nBlockXSizeIn;
913 : nBlockYSize = nBlockYSizeIn;
914 : if ((nBits % 8) != 0)
915 : {
916 : GDALRasterBand::SetMetadataItem(
917 : (nBits == 1 && bPromote1BitAs8Bit) ? "SOURCE_NBITS" : "NBITS",
918 : CPLSPrintf("%d", nBits), "IMAGE_STRUCTURE");
919 : }
920 :
921 : if (nPixelType == RL2_PIXEL_MONOCHROME || nPixelType == RL2_PIXEL_GRAYSCALE)
922 : {
923 : m_eColorInterp = GCI_GrayIndex;
924 : }
925 : else if (nPixelType == RL2_PIXEL_PALETTE)
926 : {
927 : m_eColorInterp = GCI_PaletteIndex;
928 : }
929 : else if (nPixelType == RL2_PIXEL_RGB)
930 : {
931 : m_eColorInterp =
932 : static_cast<GDALColorInterp>(GCI_RedBand + nBandIn - 1);
933 : }
934 : }
935 :
936 : /************************************************************************/
937 : /* RL2RasterBand() */
938 : /************************************************************************/
939 :
940 : RL2RasterBand::RL2RasterBand(const RL2RasterBand *poOther)
941 : {
942 : eDataType = poOther->eDataType;
943 : nBlockXSize = poOther->nBlockXSize;
944 : nBlockYSize = poOther->nBlockYSize;
945 : GDALRasterBand::SetMetadataItem(
946 : "NBITS",
947 : const_cast<RL2RasterBand *>(poOther)->GetMetadataItem(
948 : "NBITS", "IMAGE_STRUCTURE"),
949 : "IMAGE_STRUCTURE");
950 : m_eColorInterp = poOther->m_eColorInterp;
951 : m_bHasNoData = poOther->m_bHasNoData;
952 : m_dfNoDataValue = poOther->m_dfNoDataValue;
953 : m_poCT = nullptr;
954 : }
955 :
956 : /************************************************************************/
957 : /* ~RL2RasterBand() */
958 : /************************************************************************/
959 :
960 : RL2RasterBand::~RL2RasterBand()
961 : {
962 : delete m_poCT;
963 : }
964 :
965 : /************************************************************************/
966 : /* GetColorTable() */
967 : /************************************************************************/
968 :
969 : GDALColorTable *RL2RasterBand::GetColorTable()
970 : {
971 : OGRSQLiteDataSource *poGDS = reinterpret_cast<OGRSQLiteDataSource *>(poDS);
972 : if (m_poCT == nullptr && m_eColorInterp == GCI_PaletteIndex)
973 : {
974 : rl2PalettePtr palettePtr = rl2_get_dbms_palette(
975 : poGDS->GetDB(), nullptr,
976 : rl2_get_coverage_name(poGDS->GetRL2CoveragePtr()));
977 : if (palettePtr)
978 : {
979 : m_poCT = new GDALColorTable();
980 : unsigned short nEntries = 0;
981 : unsigned char *pabyR = nullptr;
982 : unsigned char *pabyG = nullptr;
983 : unsigned char *pabyB = nullptr;
984 : if (rl2_get_palette_colors(palettePtr, &nEntries, &pabyR, &pabyG,
985 : &pabyB) == RL2_OK)
986 : {
987 : for (int i = 0; i < nEntries; ++i)
988 : {
989 : GDALColorEntry sEntry;
990 : sEntry.c1 = pabyR[i];
991 : sEntry.c2 = pabyG[i];
992 : sEntry.c3 = pabyB[i];
993 : sEntry.c4 =
994 : (m_bHasNoData && i == m_dfNoDataValue) ? 0 : 255;
995 : m_poCT->SetColorEntry(i, &sEntry);
996 : }
997 : rl2_free(pabyR);
998 : rl2_free(pabyG);
999 : rl2_free(pabyB);
1000 : }
1001 : rl2_destroy_palette(palettePtr);
1002 : }
1003 : }
1004 : return m_poCT;
1005 : }
1006 :
1007 : /************************************************************************/
1008 : /* GetOverviewCount() */
1009 : /************************************************************************/
1010 :
1011 : int RL2RasterBand::GetOverviewCount()
1012 : {
1013 : OGRSQLiteDataSource *poGDS = reinterpret_cast<OGRSQLiteDataSource *>(poDS);
1014 : int nRet = static_cast<int>(poGDS->GetOverviews().size());
1015 : if (nRet > 0)
1016 : return nRet;
1017 : return GDALPamRasterBand::GetOverviewCount();
1018 : }
1019 :
1020 : /************************************************************************/
1021 : /* GetOverview() */
1022 : /************************************************************************/
1023 :
1024 : GDALRasterBand *RL2RasterBand::GetOverview(int nIdx)
1025 : {
1026 : OGRSQLiteDataSource *poGDS = reinterpret_cast<OGRSQLiteDataSource *>(poDS);
1027 : int nOvr = static_cast<int>(poGDS->GetOverviews().size());
1028 : if (nOvr > 0)
1029 : {
1030 : if (nIdx < 0 || nIdx >= nOvr)
1031 : return nullptr;
1032 : return poGDS->GetOverviews()[nIdx]->GetRasterBand(nBand);
1033 : }
1034 : return GDALPamRasterBand::GetOverview(nIdx);
1035 : }
1036 :
1037 : /************************************************************************/
1038 : /* GetNoDataValue() */
1039 : /************************************************************************/
1040 :
1041 : double RL2RasterBand::GetNoDataValue(int *pbSuccess)
1042 : {
1043 : if (m_bHasNoData)
1044 : {
1045 : if (pbSuccess)
1046 : *pbSuccess = TRUE;
1047 : return m_dfNoDataValue;
1048 : }
1049 : return GDALPamRasterBand::GetNoDataValue(pbSuccess);
1050 : }
1051 :
1052 : /************************************************************************/
1053 : /* IReadBlock() */
1054 : /************************************************************************/
1055 :
1056 : CPLErr RL2RasterBand::IReadBlock(int nBlockXOff, int nBlockYOff, void *pData)
1057 : {
1058 : OGRSQLiteDataSource *poGDS = reinterpret_cast<OGRSQLiteDataSource *>(poDS);
1059 : #ifdef DEBUG_VERBOSE
1060 : CPLDebug("SQLite", "IReadBlock(ds=%p, band=%d, x=%d, y=%d)", poGDS, nBand,
1061 : nBlockXOff, nBlockYOff);
1062 : #endif
1063 :
1064 : const int nMaxThreads = 1;
1065 : const double *padfGeoTransform = poGDS->GetGeoTransform();
1066 : const double dfMinX =
1067 : padfGeoTransform[0] + nBlockXOff * nBlockXSize * padfGeoTransform[1];
1068 : const double dfMaxX = dfMinX + nBlockXSize * padfGeoTransform[1];
1069 : const double dfMaxY =
1070 : padfGeoTransform[3] + nBlockYOff * nBlockYSize * padfGeoTransform[5];
1071 : const double dfMinY = dfMaxY + nBlockYSize * padfGeoTransform[5];
1072 : unsigned char *pBuffer = nullptr;
1073 : int nBufSize = 0;
1074 :
1075 : sqlite3 *hDB =
1076 : poGDS->GetParentDS() ? poGDS->GetParentDS()->GetDB() : poGDS->GetDB();
1077 : rl2CoveragePtr cov = poGDS->GetParentDS()
1078 : ? poGDS->GetParentDS()->GetRL2CoveragePtr()
1079 : : poGDS->GetRL2CoveragePtr();
1080 : unsigned char nSampleType = 0;
1081 : unsigned char nPixelType = 0;
1082 : unsigned char l_nBands = 0;
1083 : rl2_get_coverage_type(cov, &nSampleType, &nPixelType, &l_nBands);
1084 :
1085 : unsigned char nOutPixel = nPixelType;
1086 : if (nPixelType == RL2_PIXEL_MONOCHROME && nSampleType == RL2_SAMPLE_1_BIT)
1087 : {
1088 : nOutPixel = RL2_PIXEL_GRAYSCALE;
1089 : }
1090 :
1091 : const GIntBig nSectionId = poGDS->GetSectionId();
1092 : if (nSectionId >= 0 &&
1093 : (poGDS->IsRL2MixedResolutions() || poGDS->GetParentDS() == nullptr))
1094 : {
1095 : int ret = rl2_get_section_raw_raster_data(
1096 : hDB, nMaxThreads, cov, nSectionId, nBlockXSize, nBlockYSize, dfMinX,
1097 : dfMinY, dfMaxX, dfMaxY, padfGeoTransform[1],
1098 : fabs(padfGeoTransform[5]), &pBuffer, &nBufSize,
1099 : nullptr, // palette
1100 : nOutPixel);
1101 : if (ret != RL2_OK)
1102 : return CE_Failure;
1103 : }
1104 : else
1105 : {
1106 : int ret = rl2_get_raw_raster_data(
1107 : hDB, nMaxThreads, cov, nBlockXSize, nBlockYSize, dfMinX, dfMinY,
1108 : dfMaxX, dfMaxY, padfGeoTransform[1], fabs(padfGeoTransform[5]),
1109 : &pBuffer, &nBufSize,
1110 : nullptr, // palette
1111 : nOutPixel);
1112 : if (ret != RL2_OK)
1113 : return CE_Failure;
1114 : }
1115 :
1116 : const int nDTSize = GDALGetDataTypeSizeBytes(eDataType);
1117 : const int nExpectedBytesOnBand = nBlockXSize * nBlockYSize * nDTSize;
1118 : const int nBands = poGDS->GetRasterCount();
1119 : const int nExpectedBytesAllBands = nExpectedBytesOnBand * nBands;
1120 : if (nBufSize != nExpectedBytesAllBands)
1121 : {
1122 : CPLDebug("SQLite", "Got %d bytes instead of %d", nBufSize,
1123 : nExpectedBytesAllBands);
1124 : rl2_free(pBuffer);
1125 : return CE_Failure;
1126 : }
1127 :
1128 : if (nPixelType == RL2_PIXEL_MONOCHROME && nSampleType == RL2_SAMPLE_1_BIT &&
1129 : !poGDS->HasPromote1BitAS8Bit() && poGDS->GetParentDS() != nullptr)
1130 : {
1131 : GByte *pabyDstData = static_cast<GByte *>(pData);
1132 : for (int i = 0; i < nExpectedBytesAllBands; i++)
1133 : {
1134 : pabyDstData[i] = (pBuffer[i] > 127) ? 1 : 0;
1135 : }
1136 : }
1137 : else
1138 : {
1139 : GDALCopyWords(pBuffer + (nBand - 1) * nDTSize, eDataType,
1140 : nDTSize * nBands, pData, eDataType, nDTSize,
1141 : nBlockXSize * nBlockYSize);
1142 : }
1143 :
1144 : if (nBands > 1)
1145 : {
1146 : for (int iBand = 1; iBand <= nBands; ++iBand)
1147 : {
1148 : if (iBand == nBand)
1149 : continue;
1150 :
1151 : GDALRasterBlock *poBlock =
1152 : reinterpret_cast<RL2RasterBand *>(poGDS->GetRasterBand(iBand))
1153 : ->TryGetLockedBlockRef(nBlockXOff, nBlockYOff);
1154 : if (poBlock != nullptr)
1155 : {
1156 : poBlock->DropLock();
1157 : continue;
1158 : }
1159 : poBlock =
1160 : reinterpret_cast<RL2RasterBand *>(poGDS->GetRasterBand(iBand))
1161 : ->GetLockedBlockRef(nBlockXOff, nBlockYOff, TRUE);
1162 : if (poBlock == nullptr)
1163 : continue;
1164 : void *pDest = poBlock->GetDataRef();
1165 : GDALCopyWords(pBuffer + (iBand - 1) * nDTSize, eDataType,
1166 : nDTSize * nBands, pDest, eDataType, nDTSize,
1167 : nBlockXSize * nBlockYSize);
1168 :
1169 : poBlock->DropLock();
1170 : }
1171 : }
1172 :
1173 : rl2_free(pBuffer);
1174 :
1175 : return CE_None;
1176 : }
1177 :
1178 : /************************************************************************/
1179 : /* GetNoDataValue() */
1180 : /************************************************************************/
1181 :
1182 : template <class T>
1183 : static T GetNoDataValue(GDALDataset *poSrcDS, int nBand, T nDefault)
1184 : {
1185 : int bHasNoData = FALSE;
1186 : double dfNoData =
1187 : poSrcDS->GetRasterBand(nBand)->GetNoDataValue(&bHasNoData);
1188 : if (bHasNoData)
1189 : return static_cast<T>(dfNoData);
1190 : return static_cast<T>(nDefault);
1191 : }
1192 :
1193 : /************************************************************************/
1194 : /* CreateNoData() */
1195 : /************************************************************************/
1196 :
1197 : static rl2PixelPtr CreateNoData(unsigned char nSampleType,
1198 : unsigned char nPixelType,
1199 : unsigned char nBandCount, GDALDataset *poSrcDS)
1200 : {
1201 : // creating a default NO-DATA value
1202 : rl2PixelPtr pxl = rl2_create_pixel(nSampleType, nPixelType, nBandCount);
1203 : if (pxl == nullptr)
1204 : return nullptr;
1205 : switch (nPixelType)
1206 : {
1207 : case RL2_PIXEL_MONOCHROME:
1208 : rl2_set_pixel_sample_1bit(pxl,
1209 : GetNoDataValue<GByte>(poSrcDS, 1, 0));
1210 : break;
1211 : case RL2_PIXEL_PALETTE:
1212 : switch (nSampleType)
1213 : {
1214 : case RL2_SAMPLE_1_BIT:
1215 : rl2_set_pixel_sample_1bit(
1216 : pxl, GetNoDataValue<GByte>(poSrcDS, 1, 0));
1217 : break;
1218 : case RL2_SAMPLE_2_BIT:
1219 : rl2_set_pixel_sample_2bit(
1220 : pxl, GetNoDataValue<GByte>(poSrcDS, 1, 0));
1221 : break;
1222 : case RL2_SAMPLE_4_BIT:
1223 : rl2_set_pixel_sample_4bit(
1224 : pxl, GetNoDataValue<GByte>(poSrcDS, 1, 0));
1225 : break;
1226 : case RL2_SAMPLE_UINT8:
1227 : rl2_set_pixel_sample_uint8(
1228 : pxl, 0, GetNoDataValue<GByte>(poSrcDS, 1, 0));
1229 : break;
1230 : default:
1231 : CPLAssert(false);
1232 : break;
1233 : }
1234 : break;
1235 : case RL2_PIXEL_GRAYSCALE:
1236 : switch (nSampleType)
1237 : {
1238 : case RL2_SAMPLE_1_BIT:
1239 : rl2_set_pixel_sample_1bit(
1240 : pxl, GetNoDataValue<GByte>(poSrcDS, 1, 1));
1241 : break;
1242 : case RL2_SAMPLE_2_BIT:
1243 : rl2_set_pixel_sample_2bit(
1244 : pxl, GetNoDataValue<GByte>(poSrcDS, 1, 3));
1245 : break;
1246 : case RL2_SAMPLE_4_BIT:
1247 : rl2_set_pixel_sample_4bit(
1248 : pxl, GetNoDataValue<GByte>(poSrcDS, 1, 15));
1249 : break;
1250 : case RL2_SAMPLE_UINT8:
1251 : rl2_set_pixel_sample_uint8(
1252 : pxl, 0, GetNoDataValue<GByte>(poSrcDS, 1, 255));
1253 : break;
1254 : case RL2_SAMPLE_UINT16:
1255 : rl2_set_pixel_sample_uint16(
1256 : pxl, 0, GetNoDataValue<GUInt16>(poSrcDS, 1, 0));
1257 : break;
1258 : default:
1259 : CPLAssert(false);
1260 : break;
1261 : }
1262 : break;
1263 : case RL2_PIXEL_RGB:
1264 : switch (nSampleType)
1265 : {
1266 : case RL2_SAMPLE_UINT8:
1267 : rl2_set_pixel_sample_uint8(
1268 : pxl, 0, GetNoDataValue<GByte>(poSrcDS, 1, 255));
1269 : rl2_set_pixel_sample_uint8(
1270 : pxl, 1, GetNoDataValue<GByte>(poSrcDS, 2, 255));
1271 : rl2_set_pixel_sample_uint8(
1272 : pxl, 2, GetNoDataValue<GByte>(poSrcDS, 3, 255));
1273 : break;
1274 : case RL2_SAMPLE_UINT16:
1275 : rl2_set_pixel_sample_uint16(
1276 : pxl, 0, GetNoDataValue<GUInt16>(poSrcDS, 1, 0));
1277 : rl2_set_pixel_sample_uint16(
1278 : pxl, 1, GetNoDataValue<GUInt16>(poSrcDS, 2, 0));
1279 : rl2_set_pixel_sample_uint16(
1280 : pxl, 2, GetNoDataValue<GUInt16>(poSrcDS, 3, 0));
1281 : break;
1282 : default:
1283 : CPLAssert(false);
1284 : break;
1285 : }
1286 : break;
1287 : case RL2_PIXEL_DATAGRID:
1288 : switch (nSampleType)
1289 : {
1290 : case RL2_SAMPLE_INT8:
1291 : rl2_set_pixel_sample_int8(
1292 : pxl, GetNoDataValue<char>(poSrcDS, 1, 0));
1293 : break;
1294 : case RL2_SAMPLE_UINT8:
1295 : rl2_set_pixel_sample_uint8(
1296 : pxl, 0, GetNoDataValue<GByte>(poSrcDS, 1, 0));
1297 : break;
1298 : case RL2_SAMPLE_INT16:
1299 : rl2_set_pixel_sample_int16(
1300 : pxl, GetNoDataValue<GInt16>(poSrcDS, 1, 0));
1301 : break;
1302 : case RL2_SAMPLE_UINT16:
1303 : rl2_set_pixel_sample_uint16(
1304 : pxl, 0, GetNoDataValue<GUInt16>(poSrcDS, 1, 0));
1305 : break;
1306 : case RL2_SAMPLE_INT32:
1307 : rl2_set_pixel_sample_int32(
1308 : pxl, GetNoDataValue<GInt32>(poSrcDS, 1, 0));
1309 : break;
1310 : case RL2_SAMPLE_UINT32:
1311 : rl2_set_pixel_sample_uint32(
1312 : pxl, GetNoDataValue<GUInt32>(poSrcDS, 1, 0));
1313 : break;
1314 : case RL2_SAMPLE_FLOAT:
1315 : rl2_set_pixel_sample_float(
1316 : pxl, GetNoDataValue<float>(poSrcDS, 1, 0));
1317 : break;
1318 : case RL2_SAMPLE_DOUBLE:
1319 : rl2_set_pixel_sample_double(
1320 : pxl, GetNoDataValue<double>(poSrcDS, 1, 0));
1321 : break;
1322 : default:
1323 : CPLAssert(false);
1324 : break;
1325 : }
1326 : break;
1327 : case RL2_PIXEL_MULTIBAND:
1328 : switch (nSampleType)
1329 : {
1330 : case RL2_SAMPLE_UINT8:
1331 : for (unsigned int nb = 0; nb < nBandCount; nb++)
1332 : rl2_set_pixel_sample_uint8(
1333 : pxl, nb,
1334 : GetNoDataValue<GByte>(poSrcDS, nb + 1, 255));
1335 : break;
1336 : case RL2_SAMPLE_UINT16:
1337 : for (unsigned int nb = 0; nb < nBandCount; nb++)
1338 : rl2_set_pixel_sample_uint16(
1339 : pxl, nb,
1340 : GetNoDataValue<GUInt16>(poSrcDS, nb + 1, 0));
1341 : break;
1342 : default:
1343 : CPLAssert(false);
1344 : break;
1345 : }
1346 : break;
1347 : default:
1348 : CPLAssert(false);
1349 : break;
1350 : }
1351 : return pxl;
1352 : }
1353 :
1354 : /************************************************************************/
1355 : /* RasterLite2Callback() */
1356 : /************************************************************************/
1357 :
1358 : typedef struct
1359 : {
1360 : GDALDataset *poSrcDS;
1361 : unsigned char nPixelType;
1362 : unsigned char nSampleType;
1363 : rl2PalettePtr pPalette;
1364 : GDALProgressFunc pfnProgress;
1365 : void *pProgressData;
1366 : double adfGeoTransform[6];
1367 : } RasterLite2CallbackData;
1368 :
1369 : static int RasterLite2Callback(void *data, double dfTileMinX, double dfTileMinY,
1370 : double dfTileMaxX, double dfTileMaxY,
1371 : unsigned char *pabyBuffer,
1372 : rl2PalettePtr *pOutPalette)
1373 : {
1374 : #ifdef DEBUG_VERBOSE
1375 : CPLDebug("SQLite", "RasterLite2Callback(%f %f %f %f)", dfTileMinX,
1376 : dfTileMinY, dfTileMaxX, dfTileMaxY);
1377 : #endif
1378 : RasterLite2CallbackData *pCbkData =
1379 : static_cast<RasterLite2CallbackData *>(data);
1380 : if (pOutPalette)
1381 : {
1382 : if (pCbkData->pPalette)
1383 : *pOutPalette = rl2_clone_palette(pCbkData->pPalette);
1384 : else
1385 : *pOutPalette = nullptr;
1386 : }
1387 : int nXOff =
1388 : static_cast<int>(0.5 + (dfTileMinX - pCbkData->adfGeoTransform[0]) /
1389 : pCbkData->adfGeoTransform[1]);
1390 : int nXOff2 =
1391 : static_cast<int>(0.5 + (dfTileMaxX - pCbkData->adfGeoTransform[0]) /
1392 : pCbkData->adfGeoTransform[1]);
1393 : int nYOff =
1394 : static_cast<int>(0.5 + (dfTileMaxY - pCbkData->adfGeoTransform[3]) /
1395 : pCbkData->adfGeoTransform[5]);
1396 : int nYOff2 =
1397 : static_cast<int>(0.5 + (dfTileMinY - pCbkData->adfGeoTransform[3]) /
1398 : pCbkData->adfGeoTransform[5]);
1399 : int nReqXSize = nXOff2 - nXOff;
1400 : bool bZeroInitialize = false;
1401 : if (nXOff2 > pCbkData->poSrcDS->GetRasterXSize())
1402 : {
1403 : bZeroInitialize = true;
1404 : nReqXSize = pCbkData->poSrcDS->GetRasterXSize() - nXOff;
1405 : }
1406 : int nReqYSize = nYOff2 - nYOff;
1407 : if (nYOff2 > pCbkData->poSrcDS->GetRasterYSize())
1408 : {
1409 : bZeroInitialize = true;
1410 : nReqYSize = pCbkData->poSrcDS->GetRasterYSize() - nYOff;
1411 : }
1412 :
1413 : GDALDataType eDT = pCbkData->poSrcDS->GetRasterBand(1)->GetRasterDataType();
1414 : int nDTSize = GDALGetDataTypeSizeBytes(eDT);
1415 : int nBands = pCbkData->poSrcDS->GetRasterCount();
1416 : if (bZeroInitialize)
1417 : {
1418 : memset(pabyBuffer, 0,
1419 : static_cast<size_t>(nXOff2 - nXOff) * (nYOff2 - nYOff) * nBands *
1420 : nDTSize);
1421 : }
1422 :
1423 : const GSpacing nPixelSpacing = static_cast<GSpacing>(nDTSize) * nBands;
1424 : const GSpacing nLineSpacing = nPixelSpacing * (nXOff2 - nXOff);
1425 : CPLErr eErr = pCbkData->poSrcDS->RasterIO(
1426 : GF_Read, nXOff, nYOff, nReqXSize, nReqYSize, pabyBuffer, nReqXSize,
1427 : nReqYSize, eDT, nBands, nullptr, nPixelSpacing, nLineSpacing, nDTSize,
1428 : nullptr);
1429 : if (eErr != CE_None)
1430 : return FALSE;
1431 :
1432 : if (pCbkData->pfnProgress &&
1433 : !pCbkData->pfnProgress(static_cast<double>(nYOff + nReqYSize) /
1434 : pCbkData->poSrcDS->GetRasterYSize(),
1435 : "", pCbkData->pProgressData))
1436 : {
1437 : return FALSE;
1438 : }
1439 :
1440 : int nMaxVal = 0;
1441 : if (pCbkData->nSampleType == RL2_SAMPLE_1_BIT)
1442 : {
1443 : nMaxVal = 1;
1444 : }
1445 : else if (pCbkData->nSampleType == RL2_SAMPLE_2_BIT)
1446 : {
1447 : nMaxVal = 3;
1448 : }
1449 : else if (pCbkData->nSampleType == RL2_SAMPLE_4_BIT)
1450 : {
1451 : nMaxVal = 7;
1452 : }
1453 : if (nMaxVal != 0)
1454 : {
1455 : bool bClamped = false;
1456 : for (int iY = 0; iY < nReqYSize; ++iY)
1457 : {
1458 : for (int iX = 0; iX < nReqXSize; ++iX)
1459 : {
1460 : GByte *pbyVal = pabyBuffer +
1461 : static_cast<size_t>(iY) * (nXOff2 - nXOff) + iX;
1462 : if (*pbyVal > nMaxVal)
1463 : {
1464 : if (!bClamped)
1465 : {
1466 : bClamped = true;
1467 : CPLError(CE_Warning, CPLE_AppDefined,
1468 : "One or several values above %d have "
1469 : "been clamped",
1470 : nMaxVal);
1471 : }
1472 : *pbyVal = nMaxVal;
1473 : }
1474 : }
1475 : }
1476 : }
1477 :
1478 : return TRUE;
1479 : }
1480 :
1481 : /************************************************************************/
1482 : /* OGRSQLiteDriverCreateCopy() */
1483 : /************************************************************************/
1484 :
1485 : GDALDataset *OGRSQLiteDriverCreateCopy(const char *pszName,
1486 : GDALDataset *poSrcDS, int /* bStrict */,
1487 : char **papszOptions,
1488 : GDALProgressFunc pfnProgress,
1489 : void *pProgressData)
1490 : {
1491 : if (poSrcDS->GetRasterCount() == 0 || poSrcDS->GetRasterCount() > 255)
1492 : {
1493 : CPLError(CE_Failure, CPLE_NotSupported, "Unsupported band count");
1494 : return nullptr;
1495 : }
1496 :
1497 : double adfGeoTransform[6];
1498 : if (poSrcDS->GetGeoTransform(adfGeoTransform) == CE_None &&
1499 : (adfGeoTransform[2] != 0.0 || adfGeoTransform[4] != 0.0))
1500 : {
1501 : CPLError(CE_Failure, CPLE_NotSupported,
1502 : "Raster with rotation/shearing geotransform terms "
1503 : "are not supported");
1504 : return nullptr;
1505 : }
1506 :
1507 : if (CSLFetchNameValue(papszOptions, "APPEND_SUBDATASET") &&
1508 : !CSLFetchNameValue(papszOptions, "COVERAGE"))
1509 : {
1510 : CPLError(CE_Failure, CPLE_AppDefined,
1511 : "COVERAGE must be specified with APPEND_SUBDATASET=YES");
1512 : return nullptr;
1513 : }
1514 :
1515 : GDALDataType eDT = poSrcDS->GetRasterBand(1)->GetRasterDataType();
1516 :
1517 : unsigned char nSampleType = RL2_SAMPLE_UINT8;
1518 : unsigned char nPixelType = RL2_PIXEL_GRAYSCALE;
1519 : unsigned char nBandCount =
1520 : static_cast<unsigned char>(poSrcDS->GetRasterCount());
1521 :
1522 : const char *pszPixelType = CSLFetchNameValue(papszOptions, "PIXEL_TYPE");
1523 : if (pszPixelType)
1524 : {
1525 : if (EQUAL(pszPixelType, "MONOCHROME"))
1526 : nPixelType = RL2_PIXEL_MONOCHROME;
1527 : else if (EQUAL(pszPixelType, "PALETTE"))
1528 : nPixelType = RL2_PIXEL_PALETTE;
1529 : else if (EQUAL(pszPixelType, "GRAYSCALE"))
1530 : nPixelType = RL2_PIXEL_GRAYSCALE;
1531 : else if (EQUAL(pszPixelType, "RGB"))
1532 : nPixelType = RL2_PIXEL_RGB;
1533 : else if (EQUAL(pszPixelType, "MULTIBAND"))
1534 : nPixelType = RL2_PIXEL_MULTIBAND;
1535 : else if (EQUAL(pszPixelType, "DATAGRID"))
1536 : nPixelType = RL2_PIXEL_DATAGRID;
1537 : }
1538 : else
1539 : {
1540 : // Guess a reasonable pixel type from band characteristics
1541 : if (nBandCount == 1 &&
1542 : poSrcDS->GetRasterBand(1)->GetColorTable() != nullptr)
1543 : {
1544 : nPixelType = RL2_PIXEL_PALETTE;
1545 : }
1546 : else if (nBandCount == 3 && (eDT == GDT_Byte || eDT == GDT_UInt16) &&
1547 : poSrcDS->GetRasterBand(1)->GetColorInterpretation() ==
1548 : GCI_RedBand &&
1549 : poSrcDS->GetRasterBand(2)->GetColorInterpretation() ==
1550 : GCI_GreenBand &&
1551 : poSrcDS->GetRasterBand(3)->GetColorInterpretation() ==
1552 : GCI_BlueBand)
1553 : {
1554 : nPixelType = RL2_PIXEL_RGB;
1555 : }
1556 : else if (nBandCount > 1 && (eDT == GDT_Byte || eDT == GDT_UInt16))
1557 : {
1558 : nPixelType = RL2_PIXEL_MULTIBAND;
1559 : }
1560 : else if (nBandCount == 1 && eDT != GDT_Byte)
1561 : {
1562 : nPixelType = RL2_PIXEL_DATAGRID;
1563 : }
1564 : }
1565 :
1566 : // Deal with NBITS
1567 : const char *pszNBITS = CSLFetchNameValue(papszOptions, "NBITS");
1568 : int nBITS = 0;
1569 : if (pszNBITS != nullptr)
1570 : {
1571 : nBITS = atoi(pszNBITS);
1572 : if (nBITS != 1 && nBITS != 2 && nBITS != 4 && nBITS != 8)
1573 : {
1574 : CPLError(CE_Failure, CPLE_NotSupported, "Unsupported NBITS value");
1575 : return nullptr;
1576 : }
1577 : }
1578 : else
1579 : {
1580 : pszNBITS = poSrcDS->GetRasterBand(1)->GetMetadataItem(
1581 : "NBITS", "IMAGE_STRUCTURE");
1582 : if (pszNBITS != nullptr)
1583 : {
1584 : nBITS = atoi(pszNBITS);
1585 : }
1586 : }
1587 :
1588 : if (nBITS > 0 && nBITS <= 8 && eDT != GDT_Byte)
1589 : {
1590 : CPLError(CE_Failure, CPLE_NotSupported,
1591 : "NBITS <= 8 only compatible with Byte data type");
1592 : return nullptr;
1593 : }
1594 :
1595 : if (nBITS == 1)
1596 : {
1597 : nSampleType = RL2_SAMPLE_1_BIT;
1598 : if (nPixelType != RL2_PIXEL_PALETTE && pszPixelType == nullptr)
1599 : nPixelType = RL2_PIXEL_MONOCHROME;
1600 : }
1601 : else if (nBITS == 2)
1602 : {
1603 : nSampleType = RL2_SAMPLE_2_BIT;
1604 : if (nPixelType != RL2_PIXEL_PALETTE && pszPixelType == nullptr)
1605 : nPixelType = RL2_PIXEL_GRAYSCALE;
1606 : }
1607 : else if (nBITS == 4)
1608 : {
1609 : nSampleType = RL2_SAMPLE_4_BIT;
1610 : if (nPixelType != RL2_PIXEL_PALETTE && pszPixelType == nullptr)
1611 : nPixelType = RL2_PIXEL_GRAYSCALE;
1612 : }
1613 :
1614 : if (nPixelType == RL2_PIXEL_MONOCHROME)
1615 : {
1616 : if (eDT != GDT_Byte)
1617 : {
1618 : CPLError(CE_Failure, CPLE_NotSupported,
1619 : "Incompatible data type for MONOCHROME");
1620 : return nullptr;
1621 : }
1622 : // Force 1 bit
1623 : nSampleType = RL2_SAMPLE_1_BIT;
1624 : }
1625 :
1626 : // Guess sample type in other cases
1627 : if (eDT == GDT_Int8)
1628 : nSampleType = RL2_SAMPLE_INT8;
1629 : else if (eDT == GDT_UInt16)
1630 : nSampleType = RL2_SAMPLE_UINT16;
1631 : else if (eDT == GDT_Int16)
1632 : nSampleType = RL2_SAMPLE_INT16;
1633 : else if (eDT == GDT_UInt32)
1634 : nSampleType = RL2_SAMPLE_UINT32;
1635 : else if (eDT == GDT_Int32)
1636 : nSampleType = RL2_SAMPLE_INT32;
1637 : else if (eDT == GDT_Float32)
1638 : nSampleType = RL2_SAMPLE_FLOAT;
1639 : else if (eDT == GDT_Float64)
1640 : nSampleType = RL2_SAMPLE_DOUBLE;
1641 : else if (eDT != GDT_Byte)
1642 : {
1643 : CPLError(CE_Failure, CPLE_NotSupported, "Unsupported data type");
1644 : return nullptr;
1645 : }
1646 :
1647 : unsigned char nCompression = RL2_COMPRESSION_NONE;
1648 : int nQuality = 100;
1649 : const char *pszCompression = CSLFetchNameValue(papszOptions, "COMPRESS");
1650 : if (pszCompression)
1651 : {
1652 : if (EQUAL(pszCompression, "NONE"))
1653 : nCompression = RL2_COMPRESSION_NONE;
1654 : else if (EQUAL(pszCompression, "DEFLATE"))
1655 : nCompression = RL2_COMPRESSION_DEFLATE;
1656 : else if (EQUAL(pszCompression, "LZMA"))
1657 : nCompression = RL2_COMPRESSION_LZMA;
1658 : else if (EQUAL(pszCompression, "PNG"))
1659 : nCompression = RL2_COMPRESSION_PNG;
1660 : else if (EQUAL(pszCompression, "CCITTFAX4"))
1661 : nCompression = RL2_COMPRESSION_CCITTFAX4;
1662 : else if (EQUAL(pszCompression, "JPEG"))
1663 : {
1664 : nCompression = RL2_COMPRESSION_JPEG;
1665 : nQuality = 75;
1666 : }
1667 : else if (EQUAL(pszCompression, "WEBP"))
1668 : {
1669 : nCompression = RL2_COMPRESSION_LOSSY_WEBP;
1670 : nQuality = 75;
1671 : }
1672 : else if (EQUAL(pszCompression, "JPEG2000"))
1673 : {
1674 : nCompression = RL2_COMPRESSION_LOSSY_JP2;
1675 : nQuality = 20;
1676 : }
1677 : else
1678 : {
1679 : CPLError(CE_Failure, CPLE_NotSupported, "Unsupported compression");
1680 : return nullptr;
1681 : }
1682 : if (!rl2_is_supported_codec(nCompression))
1683 : {
1684 : CPLError(CE_Failure, CPLE_NotSupported,
1685 : "librasterlite2 is not built with support for "
1686 : "this compression method.");
1687 : return nullptr;
1688 : }
1689 : }
1690 :
1691 : // Compatibility checks:
1692 : // see
1693 : // https://www.gaia-gis.it/fossil/librasterlite2/wiki?name=reference_table
1694 : if (nPixelType == RL2_PIXEL_MONOCHROME)
1695 : {
1696 : if (nBandCount != 1)
1697 : {
1698 : CPLError(CE_Failure, CPLE_NotSupported,
1699 : "Unsupported band count with MONOCHROME");
1700 : return nullptr;
1701 : }
1702 : CPLAssert(nSampleType == RL2_SAMPLE_1_BIT);
1703 : }
1704 : else if (nPixelType == RL2_PIXEL_PALETTE)
1705 : {
1706 : if (nBandCount != 1)
1707 : {
1708 : CPLError(CE_Failure, CPLE_NotSupported,
1709 : "Unsupported band count with PALETTE");
1710 : return nullptr;
1711 : }
1712 : if (nSampleType != RL2_SAMPLE_1_BIT &&
1713 : nSampleType != RL2_SAMPLE_2_BIT &&
1714 : nSampleType != RL2_SAMPLE_4_BIT && nSampleType != RL2_SAMPLE_UINT8)
1715 : {
1716 : CPLError(CE_Failure, CPLE_NotSupported,
1717 : "Unsupported sample type with PALETTE");
1718 : return nullptr;
1719 : }
1720 : }
1721 : else if (nPixelType == RL2_PIXEL_GRAYSCALE)
1722 : {
1723 : if (nBandCount != 1)
1724 : {
1725 : CPLError(CE_Failure, CPLE_NotSupported,
1726 : "Unsupported band count with GRAYSCALE");
1727 : return nullptr;
1728 : }
1729 : if (nSampleType != RL2_SAMPLE_2_BIT &&
1730 : nSampleType != RL2_SAMPLE_4_BIT && nSampleType != RL2_SAMPLE_UINT8)
1731 : {
1732 : CPLError(CE_Failure, CPLE_NotSupported,
1733 : "Unsupported sample type with GRAYSCALE");
1734 : return nullptr;
1735 : }
1736 : }
1737 : else if (nPixelType == RL2_PIXEL_RGB)
1738 : {
1739 : if (nBandCount != 3)
1740 : {
1741 : CPLError(CE_Failure, CPLE_NotSupported,
1742 : "Unsupported band count with RGB");
1743 : return nullptr;
1744 : }
1745 : if (nSampleType != RL2_SAMPLE_UINT8 && nSampleType != RL2_SAMPLE_UINT16)
1746 : {
1747 : CPLError(CE_Failure, CPLE_NotSupported,
1748 : "Unsupported sample type with RGB");
1749 : return nullptr;
1750 : }
1751 : }
1752 : else if (nPixelType == RL2_PIXEL_MULTIBAND)
1753 : {
1754 : if (nBandCount == 1)
1755 : {
1756 : CPLError(CE_Failure, CPLE_NotSupported,
1757 : "Unsupported band count with MULTIBAND");
1758 : return nullptr;
1759 : }
1760 : if (nSampleType != RL2_SAMPLE_UINT8 && nSampleType != RL2_SAMPLE_UINT16)
1761 : {
1762 : CPLError(CE_Failure, CPLE_NotSupported,
1763 : "Unsupported sample type with MULTIBAND");
1764 : return nullptr;
1765 : }
1766 : }
1767 : else if (nPixelType == RL2_PIXEL_DATAGRID)
1768 : {
1769 : if (nBandCount != 1)
1770 : {
1771 : CPLError(CE_Failure, CPLE_NotSupported,
1772 : "Unsupported band count with DATAGRID");
1773 : return nullptr;
1774 : }
1775 : if (nSampleType != RL2_SAMPLE_INT8 && nSampleType != RL2_SAMPLE_UINT8 &&
1776 : nSampleType != RL2_SAMPLE_INT16 &&
1777 : nSampleType != RL2_SAMPLE_UINT16 &&
1778 : nSampleType != RL2_SAMPLE_INT32 &&
1779 : nSampleType != RL2_SAMPLE_UINT32 &&
1780 : nSampleType != RL2_SAMPLE_FLOAT && nSampleType != RL2_SAMPLE_DOUBLE)
1781 : {
1782 : CPLError(CE_Failure, CPLE_NotSupported,
1783 : "Unsupported sample type with DATAGRID");
1784 : return nullptr;
1785 : }
1786 : }
1787 :
1788 : // Other compatibility checks based on compression
1789 : if (nPixelType == RL2_PIXEL_MONOCHROME)
1790 : {
1791 : if (nCompression != RL2_COMPRESSION_NONE &&
1792 : nCompression != RL2_COMPRESSION_DEFLATE &&
1793 : nCompression != RL2_COMPRESSION_DEFLATE_NO &&
1794 : nCompression != RL2_COMPRESSION_LZMA &&
1795 : nCompression != RL2_COMPRESSION_LZMA_NO &&
1796 : nCompression != RL2_COMPRESSION_CCITTFAX4 &&
1797 : nCompression != RL2_COMPRESSION_PNG)
1798 : {
1799 : CPLError(CE_Failure, CPLE_NotSupported,
1800 : "Unsupported compression with MONOCHROME");
1801 : return nullptr;
1802 : }
1803 : }
1804 : else if (nPixelType == RL2_PIXEL_PALETTE)
1805 : {
1806 : if (nCompression != RL2_COMPRESSION_NONE &&
1807 : nCompression != RL2_COMPRESSION_DEFLATE &&
1808 : nCompression != RL2_COMPRESSION_DEFLATE_NO &&
1809 : nCompression != RL2_COMPRESSION_LZMA &&
1810 : nCompression != RL2_COMPRESSION_LZMA_NO &&
1811 : nCompression != RL2_COMPRESSION_PNG)
1812 : {
1813 : CPLError(CE_Failure, CPLE_NotSupported,
1814 : "Unsupported compression with PALETTE");
1815 : return nullptr;
1816 : }
1817 : }
1818 : else if (nPixelType == RL2_PIXEL_GRAYSCALE)
1819 : {
1820 : if (nCompression == RL2_COMPRESSION_CCITTFAX4)
1821 : {
1822 : CPLError(CE_Failure, CPLE_NotSupported,
1823 : "Unsupported compression with GRAYSCALE");
1824 : return nullptr;
1825 : }
1826 : }
1827 : else if (nPixelType == RL2_PIXEL_RGB && nSampleType == RL2_SAMPLE_UINT8)
1828 : {
1829 : if (nCompression == RL2_COMPRESSION_CCITTFAX4)
1830 : {
1831 : CPLError(CE_Failure, CPLE_NotSupported,
1832 : "Unsupported compression with RGB UINT8");
1833 : return nullptr;
1834 : }
1835 : }
1836 : else if (nPixelType == RL2_PIXEL_RGB && nSampleType == RL2_SAMPLE_UINT16)
1837 : {
1838 : if (nCompression == RL2_COMPRESSION_CCITTFAX4 ||
1839 : nCompression == RL2_COMPRESSION_JPEG ||
1840 : nCompression == RL2_COMPRESSION_LOSSY_WEBP ||
1841 : nCompression == RL2_COMPRESSION_LOSSLESS_WEBP)
1842 : {
1843 : CPLError(CE_Failure, CPLE_NotSupported,
1844 : "Unsupported compression with RGB UINT16");
1845 : return nullptr;
1846 : }
1847 : }
1848 : else if (nPixelType == RL2_PIXEL_MULTIBAND &&
1849 : nSampleType == RL2_SAMPLE_UINT8 &&
1850 : (nBandCount == 3 || nBandCount == 4))
1851 : {
1852 : if (nCompression == RL2_COMPRESSION_CCITTFAX4 ||
1853 : nCompression == RL2_COMPRESSION_JPEG)
1854 : {
1855 : CPLError(CE_Failure, CPLE_NotSupported,
1856 : "Unsupported compression with MULTIBAND UINT8 %d bands",
1857 : nBandCount);
1858 : return nullptr;
1859 : }
1860 : }
1861 : else if (nPixelType == RL2_PIXEL_MULTIBAND &&
1862 : nSampleType == RL2_SAMPLE_UINT16 &&
1863 : (nBandCount == 3 || nBandCount == 4))
1864 : {
1865 : if (nCompression == RL2_COMPRESSION_CCITTFAX4 ||
1866 : nCompression == RL2_COMPRESSION_JPEG ||
1867 : nCompression == RL2_COMPRESSION_LOSSY_WEBP ||
1868 : nCompression == RL2_COMPRESSION_LOSSLESS_WEBP)
1869 : {
1870 : CPLError(CE_Failure, CPLE_NotSupported,
1871 : "Unsupported compression with MULTIBAND UINT16 %d bands",
1872 : nBandCount);
1873 : return nullptr;
1874 : }
1875 : }
1876 : else if (nPixelType == RL2_PIXEL_MULTIBAND)
1877 : {
1878 : if (nCompression != RL2_COMPRESSION_NONE &&
1879 : nCompression != RL2_COMPRESSION_DEFLATE &&
1880 : nCompression != RL2_COMPRESSION_DEFLATE_NO &&
1881 : nCompression != RL2_COMPRESSION_LZMA &&
1882 : nCompression != RL2_COMPRESSION_LZMA_NO)
1883 : {
1884 : CPLError(CE_Failure, CPLE_NotSupported,
1885 : "Unsupported compression with MULTIBAND %s %d bands",
1886 : (nSampleType == RL2_SAMPLE_UINT8) ? "UINT8" : "UINT16",
1887 : nBandCount);
1888 : return nullptr;
1889 : }
1890 : }
1891 : else if (nPixelType == RL2_PIXEL_DATAGRID &&
1892 : (nSampleType == RL2_SAMPLE_UINT8 ||
1893 : nSampleType == RL2_SAMPLE_UINT16))
1894 : {
1895 : if (nCompression == RL2_COMPRESSION_CCITTFAX4 ||
1896 : nCompression == RL2_COMPRESSION_JPEG ||
1897 : nCompression == RL2_COMPRESSION_LOSSY_WEBP ||
1898 : nCompression == RL2_COMPRESSION_LOSSLESS_WEBP)
1899 : {
1900 : CPLError(CE_Failure, CPLE_NotSupported,
1901 : "Unsupported compression with DATAGRID %s",
1902 : (nSampleType == RL2_SAMPLE_UINT8) ? "UINT8" : "UINT16");
1903 : return nullptr;
1904 : }
1905 : }
1906 : else if (nPixelType == RL2_PIXEL_DATAGRID &&
1907 : nSampleType != RL2_SAMPLE_UINT8 &&
1908 : nSampleType != RL2_SAMPLE_UINT16)
1909 : {
1910 : if (nCompression != RL2_COMPRESSION_NONE &&
1911 : nCompression != RL2_COMPRESSION_DEFLATE &&
1912 : nCompression != RL2_COMPRESSION_DEFLATE_NO &&
1913 : nCompression != RL2_COMPRESSION_LZMA &&
1914 : nCompression != RL2_COMPRESSION_LZMA_NO)
1915 : {
1916 : CPLError(CE_Failure, CPLE_NotSupported,
1917 : "Unsupported compression with DATAGRID %s",
1918 : GDALGetDataTypeName(eDT));
1919 : return nullptr;
1920 : }
1921 : }
1922 :
1923 : const char *pszQuality = CSLFetchNameValue(papszOptions, "QUALITY");
1924 : if (pszQuality)
1925 : {
1926 : nQuality = atoi(pszQuality);
1927 : if (nQuality == 100 && nCompression == RL2_COMPRESSION_LOSSY_JP2)
1928 : nCompression = RL2_COMPRESSION_LOSSLESS_JP2;
1929 : else if (nQuality == 100 && nCompression == RL2_COMPRESSION_LOSSY_WEBP)
1930 : nCompression = RL2_COMPRESSION_LOSSLESS_WEBP;
1931 : }
1932 :
1933 : unsigned int nTileWidth =
1934 : atoi(CSLFetchNameValueDef(papszOptions, "BLOCKXSIZE", "512"));
1935 : unsigned int nTileHeight =
1936 : atoi(CSLFetchNameValueDef(papszOptions, "BLOCKYSIZE", "512"));
1937 :
1938 : /* -------------------------------------------------------------------- */
1939 : /* Try to create datasource. */
1940 : /* -------------------------------------------------------------------- */
1941 : OGRSQLiteDataSource *poDS = new OGRSQLiteDataSource();
1942 :
1943 : if (CSLFetchNameValue(papszOptions, "APPEND_SUBDATASET"))
1944 : {
1945 : GDALOpenInfo oOpenInfo(pszName, GDAL_OF_RASTER | GDAL_OF_VECTOR |
1946 : GDAL_OF_UPDATE);
1947 : if (!poDS->Open(&oOpenInfo))
1948 : {
1949 : delete poDS;
1950 : return nullptr;
1951 : }
1952 : }
1953 : else
1954 : {
1955 : char **papszNewOptions = CSLDuplicate(papszOptions);
1956 : papszNewOptions = CSLSetNameValue(papszNewOptions, "SPATIALITE", "YES");
1957 : if (!poDS->Create(pszName, papszNewOptions))
1958 : {
1959 : CSLDestroy(papszNewOptions);
1960 : delete poDS;
1961 : return nullptr;
1962 : }
1963 : CSLDestroy(papszNewOptions);
1964 : }
1965 :
1966 : /* -------------------------------------------------------------------- */
1967 : /* Try to get the SRS Id of this spatial reference system, */
1968 : /* adding to the srs table if needed. */
1969 : /* -------------------------------------------------------------------- */
1970 : int nSRSId = 0;
1971 : const char *pszSRID = CSLFetchNameValue(papszOptions, "SRID");
1972 :
1973 : if (pszSRID != nullptr)
1974 : {
1975 : nSRSId = atoi(pszSRID);
1976 : if (nSRSId > 0)
1977 : {
1978 : OGRSpatialReference *poSRSFetched = poDS->FetchSRS(nSRSId);
1979 : if (poSRSFetched == nullptr)
1980 : {
1981 : CPLError(CE_Warning, CPLE_AppDefined,
1982 : "SRID %d will be used, but no matching SRS is "
1983 : "defined in spatial_ref_sys",
1984 : nSRSId);
1985 : }
1986 : }
1987 : }
1988 : else
1989 : {
1990 : const OGRSpatialReference *poSRS = poSrcDS->GetSpatialRef();
1991 : if (poSRS)
1992 : {
1993 : nSRSId = poDS->FetchSRSId(poSRS);
1994 : }
1995 : }
1996 :
1997 : poDS->StartTransaction();
1998 :
1999 : char **papszResults = nullptr;
2000 : int nRowCount = 0;
2001 : int nColCount = 0;
2002 : sqlite3_get_table(poDS->GetDB(),
2003 : "SELECT * FROM sqlite_master WHERE "
2004 : "name = 'raster_coverages' AND type = 'table'",
2005 : &papszResults, &nRowCount, &nColCount, nullptr);
2006 : sqlite3_free_table(papszResults);
2007 : if (nRowCount == 0)
2008 : {
2009 : char *pszErrMsg = nullptr;
2010 : int ret =
2011 : sqlite3_exec(poDS->GetDB(), "SELECT CreateRasterCoveragesTable()",
2012 : nullptr, nullptr, &pszErrMsg);
2013 : if (ret != SQLITE_OK)
2014 : {
2015 : CPLError(CE_Failure, CPLE_AppDefined,
2016 : "CreateRasterCoveragesTable() failed: %s", pszErrMsg);
2017 : sqlite3_free(pszErrMsg);
2018 : delete poDS;
2019 : return nullptr;
2020 : }
2021 : }
2022 :
2023 : CPLString osCoverageName(CSLFetchNameValueDef(papszOptions, "COVERAGE",
2024 : CPLGetBasename(pszName)));
2025 : // Check if the coverage already exists
2026 : rl2CoveragePtr cvg = nullptr;
2027 : char *pszSQL = sqlite3_mprintf(
2028 : "SELECT coverage_name "
2029 : "FROM raster_coverages WHERE coverage_name = '%q' LIMIT 1",
2030 : osCoverageName.c_str());
2031 : sqlite3_get_table(poDS->GetDB(), pszSQL, &papszResults, &nRowCount,
2032 : &nColCount, nullptr);
2033 : sqlite3_free(pszSQL);
2034 : sqlite3_free_table(papszResults);
2035 : if (nRowCount == 1)
2036 : {
2037 : cvg = rl2_create_coverage_from_dbms(poDS->GetDB(), nullptr,
2038 : osCoverageName);
2039 : if (cvg == nullptr)
2040 : {
2041 : delete poDS;
2042 : return nullptr;
2043 : }
2044 : }
2045 :
2046 : rl2PalettePtr pPalette = nullptr;
2047 : if (nPixelType == RL2_PIXEL_PALETTE)
2048 : {
2049 : GDALColorTable *poCT = poSrcDS->GetRasterBand(1)->GetColorTable();
2050 : if (poCT == nullptr)
2051 : {
2052 : CPLError(CE_Failure, CPLE_AppDefined, "Missing color table");
2053 : delete poDS;
2054 : return nullptr;
2055 : }
2056 :
2057 : const int nColors = poCT->GetColorEntryCount();
2058 : pPalette = rl2_create_palette(nColors);
2059 : for (int i = 0; i < nColors; ++i)
2060 : {
2061 : const GDALColorEntry *poCE = poCT->GetColorEntry(i);
2062 : rl2_set_palette_color(pPalette, i, static_cast<GByte>(poCE->c1),
2063 : static_cast<GByte>(poCE->c2),
2064 : static_cast<GByte>(poCE->c3));
2065 : }
2066 : }
2067 :
2068 : if (cvg == nullptr)
2069 : {
2070 : const double dfXRes = adfGeoTransform[1];
2071 : const double dfYRes = fabs(adfGeoTransform[5]);
2072 : const bool bStrictResolution = true;
2073 : const bool bMixedResolutions = false;
2074 : const bool bSectionPaths = false;
2075 : const bool bSectionMD5 = false;
2076 : const bool bSectionSummary = false;
2077 : const bool bIsQueryable = false;
2078 :
2079 : rl2PixelPtr pNoData =
2080 : CreateNoData(nSampleType, nPixelType, nBandCount, poSrcDS);
2081 : if (pNoData == nullptr)
2082 : {
2083 : delete poDS;
2084 : if (pPalette)
2085 : rl2_destroy_palette(pPalette);
2086 : return nullptr;
2087 : }
2088 :
2089 : if (rl2_create_dbms_coverage(
2090 : poDS->GetDB(), osCoverageName, nSampleType, nPixelType,
2091 : nBandCount, nCompression, nQuality, nTileWidth, nTileHeight,
2092 : nSRSId, dfXRes, dfYRes, pNoData, pPalette, bStrictResolution,
2093 : bMixedResolutions, bSectionPaths, bSectionMD5, bSectionSummary,
2094 : bIsQueryable) != RL2_OK)
2095 : {
2096 : CPLError(CE_Failure, CPLE_AppDefined,
2097 : "rl2_create_dbms_coverage() failed");
2098 : rl2_destroy_pixel(pNoData);
2099 : if (pPalette)
2100 : rl2_destroy_palette(pPalette);
2101 : delete poDS;
2102 : return nullptr;
2103 : }
2104 :
2105 : rl2_destroy_pixel(pNoData);
2106 : }
2107 :
2108 : if (cvg == nullptr)
2109 : {
2110 : cvg = rl2_create_coverage_from_dbms(poDS->GetDB(), nullptr,
2111 : osCoverageName);
2112 : if (cvg == nullptr)
2113 : {
2114 : if (pPalette)
2115 : rl2_destroy_palette(pPalette);
2116 : delete poDS;
2117 : return nullptr;
2118 : }
2119 : }
2120 :
2121 : if (adfGeoTransform[5] > 0)
2122 : adfGeoTransform[5] = -adfGeoTransform[5];
2123 : double dfXMin = adfGeoTransform[0];
2124 : double dfXMax = dfXMin + adfGeoTransform[1] * poSrcDS->GetRasterXSize();
2125 : double dfYMax = adfGeoTransform[3];
2126 : double dfYMin = dfYMax + adfGeoTransform[5] * poSrcDS->GetRasterYSize();
2127 :
2128 : CPLString osSectionName(
2129 : CSLFetchNameValueDef(papszOptions, "SECTION", CPLGetBasename(pszName)));
2130 : const bool bPyramidize = CPLFetchBool(papszOptions, "PYRAMIDIZE", false);
2131 : RasterLite2CallbackData cbk_data;
2132 : cbk_data.poSrcDS = poSrcDS;
2133 : cbk_data.nPixelType = nPixelType;
2134 : cbk_data.nSampleType = nSampleType;
2135 : cbk_data.pPalette = pPalette;
2136 : cbk_data.pfnProgress = pfnProgress;
2137 : cbk_data.pProgressData = pProgressData;
2138 : memcpy(&cbk_data.adfGeoTransform, adfGeoTransform, sizeof(adfGeoTransform));
2139 :
2140 : if (rl2_load_raw_tiles_into_dbms(
2141 : poDS->GetDB(), poDS->GetRL2Context(), cvg, osSectionName,
2142 : poSrcDS->GetRasterXSize(), poSrcDS->GetRasterYSize(), nSRSId,
2143 : dfXMin, dfYMin, dfXMax, dfYMax, RasterLite2Callback, &cbk_data,
2144 : bPyramidize) != RL2_OK)
2145 : {
2146 : CPLError(CE_Failure, CPLE_AppDefined,
2147 : "rl2_load_raw_tiles_into_dbms() failed");
2148 : delete poDS;
2149 : rl2_destroy_coverage(cvg);
2150 : if (pPalette)
2151 : rl2_destroy_palette(pPalette);
2152 : return nullptr;
2153 : }
2154 :
2155 : rl2_destroy_coverage(cvg);
2156 : if (pPalette)
2157 : rl2_destroy_palette(pPalette);
2158 :
2159 : poDS->CommitTransaction();
2160 :
2161 : delete poDS;
2162 :
2163 : poDS = new OGRSQLiteDataSource();
2164 : GDALOpenInfo oOpenInfo(
2165 : CPLSPrintf("RASTERLITE2:%s:%s",
2166 : EscapeNameAndQuoteIfNeeded(pszName).c_str(),
2167 : EscapeNameAndQuoteIfNeeded(osCoverageName).c_str()),
2168 : GDAL_OF_RASTER | GDAL_OF_UPDATE);
2169 : poDS->Open(&oOpenInfo);
2170 : return poDS;
2171 : }
2172 :
2173 : /************************************************************************/
2174 : /* IBuildOverviews() */
2175 : /************************************************************************/
2176 :
2177 : CPLErr OGRSQLiteDataSource::IBuildOverviews(
2178 : const char *pszResampling, int nOverviews, const int *panOverviewList,
2179 : int nBandsIn, const int * /*panBandList */,
2180 : GDALProgressFunc /*pfnProgress*/, void * /*pProgressData*/,
2181 : CSLConstList /* papszOptions */)
2182 :
2183 : {
2184 : if (nBandsIn != nBands)
2185 : {
2186 : CPLError(CE_Failure, CPLE_AppDefined,
2187 : "Only build of all bands is supported");
2188 : }
2189 :
2190 : if (nOverviews == 0)
2191 : {
2192 : int ret;
2193 : if (m_bRL2MixedResolutions && m_nSectionId >= 0)
2194 : {
2195 : ret =
2196 : rl2_delete_section_pyramid(hDB, m_osCoverageName, m_nSectionId);
2197 : }
2198 : else
2199 : {
2200 : ret = rl2_delete_all_pyramids(hDB, m_osCoverageName);
2201 : }
2202 : if (ret != RL2_OK)
2203 : {
2204 : CPLError(CE_Failure, CPLE_AppDefined,
2205 : "Deletion of pyramids failed");
2206 : return CE_Failure;
2207 : }
2208 : }
2209 : else
2210 : {
2211 : if (!STARTS_WITH_CI(pszResampling, "NEAR"))
2212 : {
2213 : CPLError(CE_Warning, CPLE_AppDefined,
2214 : "Resampling method is ignored. Using librasterlite2 own "
2215 : "method");
2216 : }
2217 : for (int i = 0; i < nOverviews; ++i)
2218 : {
2219 : if (!CPLIsPowerOfTwo(panOverviewList[i]))
2220 : {
2221 : CPLError(CE_Failure, CPLE_NotSupported,
2222 : "Only power-of-two overview factors are supported");
2223 : return CE_Failure;
2224 : }
2225 : }
2226 :
2227 : const int bForcedRebuild = 1;
2228 : const int bVerbose = 0;
2229 : const int bVirtualLevels = 1;
2230 : int ret;
2231 : if (m_bRL2MixedResolutions)
2232 : {
2233 : if (m_nSectionId >= 0)
2234 : {
2235 : ret = rl2_build_section_pyramid(hDB, GetRL2Context(),
2236 : m_osCoverageName, m_nSectionId,
2237 : bForcedRebuild, bVerbose);
2238 : }
2239 : else
2240 : {
2241 : ret = rl2_build_monolithic_pyramid(hDB, GetRL2Context(),
2242 : m_osCoverageName,
2243 : bVirtualLevels, bVerbose);
2244 : }
2245 : }
2246 : else
2247 : {
2248 : ret = rl2_build_monolithic_pyramid(hDB, GetRL2Context(),
2249 : m_osCoverageName, bVirtualLevels,
2250 : bVerbose);
2251 : }
2252 : if (ret != RL2_OK)
2253 : {
2254 : CPLError(CE_Failure, CPLE_AppDefined, "Build of pyramids failed");
2255 : return CE_Failure;
2256 : }
2257 : }
2258 :
2259 : for (size_t i = 0; i < m_apoOverviewDS.size(); ++i)
2260 : delete m_apoOverviewDS[i];
2261 : m_apoOverviewDS.clear();
2262 : ListOverviews();
2263 :
2264 : return CE_None;
2265 : }
2266 :
2267 : #endif // HAVE_RASTERLITE2
2268 :
2269 : /************************************************************************/
2270 : /* GetMetadata() */
2271 : /************************************************************************/
2272 :
2273 5 : char **OGRSQLiteDataSource::GetMetadata(const char *pszDomain)
2274 : {
2275 5 : if (pszDomain != nullptr && EQUAL(pszDomain, "SUBDATASETS") &&
2276 0 : m_aosSubDatasets.size() > 2)
2277 : {
2278 0 : return m_aosSubDatasets.List();
2279 : }
2280 5 : return GDALPamDataset::GetMetadata(pszDomain);
2281 : }
2282 :
2283 : /************************************************************************/
2284 : /* GetGeoTransform() */
2285 : /************************************************************************/
2286 :
2287 0 : CPLErr OGRSQLiteDataSource::GetGeoTransform(double *padfGeoTransform)
2288 : {
2289 0 : if (m_bGeoTransformValid)
2290 : {
2291 0 : memcpy(padfGeoTransform, m_adfGeoTransform, 6 * sizeof(double));
2292 0 : return CE_None;
2293 : }
2294 0 : return GDALPamDataset::GetGeoTransform(padfGeoTransform);
2295 : }
2296 :
2297 : /************************************************************************/
2298 : /* GetSpatialRef() */
2299 : /************************************************************************/
2300 :
2301 0 : const OGRSpatialReference *OGRSQLiteDataSource::GetSpatialRef() const
2302 : {
2303 0 : if (!m_oSRS.IsEmpty())
2304 0 : return &m_oSRS;
2305 0 : return GDALPamDataset::GetSpatialRef();
2306 : }
|