Ticket #2946 (closed defect: fixed)

Opened 4 years ago

Georaster - Pyramid Levels mismatch

Reported by: Owned by: ilucena ilucena normal 1.6.1 GDAL_Raster svn-trunk major georaster, overviews warmerdam

Description

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.

Change History

Changed 4 years ago by ilucena

• status changed from new to closed
• resolution set to fixed

Fixed r16811.

It turns out that the rounding technique in Oracle Spatial is different from GDAL but it is consistent for pyramid level smaller than half of the block and for pyramid level larger than the block. The code on the driver was fixed accordantly.

The other conclusion is that GDAL support the different rounding technique quite well. It could be possible that a little performance issue would occur dependent on the client application strategy.

Note: See TracTickets for help on using tickets.