[gdal-dev] Fwd: MBTiles Write support

Even Rouault even.rouault at spatialys.com
Mon Apr 18 08:55:57 PDT 2016


Lorenzo,

> The command I used is:
> 
> \>gdal_translate mosaic.tif full_def9.mbtiles -of MBTILES -expand rgb -co
> TILE_FORMAT=PNG8 -co ZLEVEL=9
> Input file size is 645661, 308112
> 0...10...20...30...40...50...60...70...80ERROR 1: Failure when inserting
> partial tile (row=759306,col=1099566) at zoom_level=21 : database or disk
> is full
> ERROR 1: full_def9.mbtiles, band 4: An error occurred while writing a dirty
> block
> ERROR 1: Failure when inserting partial tile (row=759306,col=1099566) at
> zoom_level=21 : database disk image is malformed
> ERROR 1: Failure when inserting partial tile (row=759306,col=1099566) at
> zoom_level=21 : database disk image is malformed
> ERROR 1: Failure when inserting partial tile (row=759306,col=1099566) at
> zoom_level=21 : database disk image is malformed
> ERROR 1: Failure when inserting partial tile (row=759306,col=1099576) at
> zoom_level=21 : database disk image is malformed
> 
> NOTE: without the "-expand rgb" option, all the output tiles will be black,
> gdal_translate will warn you.
> 
> The process failed due to insufficient disk space (70Gb free was not
> enough) but the resulting incomplete file (7Gb) looks good.
> Most of the space was used by the "partial_tiles" database, is there any
> settings I can use to force a more frequent "flush" of the tiles in the
> main database?

I've pushed a fix for that per https://trac.osgeo.org/gdal/ticket/6462

> 
> The file was created with zoom level = 21, that is more than we need, so I
> tried to use ZOOM_LEVEL_STRATEGY to generate a level 20.
> My plan was to generate a level 20 file with gdal_translate and then add
> the level 19 with gdaladdo but both ZOOM_LEVEL_STRATEGY=UPPER and
> ZOOM_LEVEL_STRATEGY=LOWER seems to compute the same zoom level 21.
> How is the zoom level computed?

Hum, I couldn't reproduce that. With ZOOM_LEVEL_STRATEGY=LOWER, tiles at zoom 
level 20 are produced.
Another way of forcing the resolution to the lower zoom level would be to use 
"-outsize 50% 50% -r bilinear"

The zoom level is computing by using the "guess extent and resolution" 
function used by gdalwarp (and the MBTiles driver now) when you give it a 
source raster and a target projection. Then the MBTiles driver compare this 
theoretical target resolution to the fixed resolutions imposed by the MBTiles 
tiling scheme and zoom level.  And then it does ... (hopefully code will be 
clearer that my attempt at transposing it to English)  :

    double dfPrevRes = 0, dfRes = 0;
    const double dfPixelXSizeZoomLevel0 = 2 * MAX_GM / 256;
    for(nZoomLevel = 0; nZoomLevel < 25; nZoomLevel++)
    {
        dfRes = dfPixelXSizeZoomLevel0 / (1 << nZoomLevel);
        if( dfComputedRes > dfRes )
            break;
        dfPrevRes = dfRes;
    }

    const char* pszZoomLevelStrategy = CSLFetchNameValueDef(papszOptions,
                                                            "ZOOM_LEVEL_STRATEGY",
                                                            "AUTO");
    if( fabs( dfComputedRes - dfRes ) / dfRes > 1e-8 )
    {
        if( EQUAL(pszZoomLevelStrategy, "LOWER") )
        {
            if( nZoomLevel > 0 )
                nZoomLevel --;
        }
        else if( EQUAL(pszZoomLevelStrategy, "UPPER") )
        {
            /* do nothing */
        }
        else if( nZoomLevel > 0 )
        {
            if( dfPrevRes / dfComputedRes < dfComputedRes / dfRes )
                nZoomLevel --;
        }
    }

where dfComputedRes is the theoretical pixel size computed by the function, 
dfPrevRes the resolution of the lower zoom level (nZoomLevel - 1) and dfRes 
the resolution of the upper zoom level ( nZoomLevel )

Even

-- 
Spatialys - Geospatial professional services
http://www.spatialys.com


More information about the gdal-dev mailing list