Ticket #2946 (closed defect: fixed)
Georaster - Pyramid Levels mismatch
|Reported by:||ilucena||Owned by:||ilucena|
Given a dataset with this dimensions 2867x2867, if we generate pyramids with gdaladdo:
$ gdaladdo -r average geor:usr/pwd@db,rdt,rid 2 4 8 16 32 64
That will ultimately call a PL/SQL statement like that:
sdo_geor.generatePyramid(gr, 'rlevel=6 resampling=AVERAGE4');
And the resulting overviews dimensions, as reported by gdalinfo, will be:
Overviews: 1434x1434, 717x717, 359x359, 180x180, 90x90, 45x45
The problem is that according to the Oracle Spatial Georaster manual the formula to calculate pyramid dimensions is as following:
r(n) = (int)(r(0) / 2^n) c(n) = (int)(c(0) / 2^n) r(0) and c(0) are the original row and column dimension size. r(n) and c(n) are the row and column dimension size of pyramid level n.
And that will result in different sizes
r_0 = 2867 for n in range(1,7): print n, (int) (r_0 / ( 2 ** n)) 1 1433 2 716 3 358 4 179 5 89 6 44
than the GDAL's formula:
d = 2.0 for n in range(1,7): print n, (int) ( math.ceil( r_0 / d ) ) d = d * 2.0 1 1434 2 717 3 359 4 180 5 90 6 45
As far as I have tested, it looks like it is not possible for a GDALRasterBand object to tell GDAL core that his overview dimension is 89x89 when there is a presumption that it should be 90x90. That would be a easy solution.
To make the problem worse, by looking at the sizes of the BLOB generated by the PL/SQL script, it seams like the pyramids have those dimensions.
1434x1434, 717x717, 359x359, 180x180, 89x89, 44x44
Note that the the dimensions of the 4 first levels are rounded up while for the two last one it is rounded down.
One clue: This dataset was recorded with 256x256 blocking dimension and accord to the manual, smaller dimensions require special attention:
If the original GeoRaster object is blocked (even if blocked as one block), the cell data of each pyramid level is blocked in the same way as for the original level data, and each block is stored in a different BLOB object as long as the maximum dimension size of the actual pyramid level image is larger than the block sizes. However, if lower-resolution pyramids are generated (that is, if both the row and column dimension sizes of the pyramid level are less than or equal to one-half the row block size and column block size, respectively), the cell data of each such pyramid level is stored in one BLOB object and its size is the same as that of the actual pyramid level image.
The solution for that problem doesn't seams to be trivial and so far I could only add code to prevent memory leak as the BLOB size are smaller than expected.