GDAL Reporting: Invalid value for 'bounds' metadata and Cannot find min and max tile numbers

313 views
Skip to first unread message

Geospatial Information Technology Solutions

unread,
Apr 15, 2016, 2:09:00 PM4/15/16
to MapTiler Community
I generated some mbtiles with Map Tiler Pro

some of the datasets are unable to open in QGIS Desktop or do a GDALINFO or GDALBUILDVRT.  
I'm getting the following message:

ERROR 1: Invalid value for 'bounds' metadata
ERROR 1: Cannot find min and max tile numbers
gdalinfo failed - unable to open 'nameoffile.mbtiles'. 


if dragging mbtiles into QGIS then message is select vector layer to add and shows a dialog with the tables/views of the mbtiles
if adding raster layer then Raster layer: N:\1605\MovingMap\RC1\mm_nga_ifr_eea-2016-04-28.mbtiles is not a supported raster data source Cannot find min and max tile numbers

from the metadata.json file if I do TMS or Google Tiles -- Bounds is the same if I do mbtiles
{
  "name": "EEA",
  "version": "1.1.0",
  "description": "",
  "type": "overlay",
  "format": "png",
  "minzoom": "0",
  "maxzoom": "10",
  "scheme": "tms",
  "bounds": [18.77524804, 17.33951027, -152.27795411, 78.48683230],
  "scale": "1",
  "profile": "mercator",
  "crs": "EPSG:900913",
  "proj4": "+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +wktext  +no_defs",
  "extent": [2090051.05165703, 1960382.10403241, 23123512.37530854, 14634698.93334485],

according to the spec:
  • bounds: The maximum extent of the rendered map area. Bounds must define an area covered by all zoom levels. The bounds are represented in WGS:84 - latitude and longitude values, in the OpenLayers Bounds format - left, bottom, right, top. Example of the full earth: -180.0,-85,180,85.
When I remove the bounds record. I can open the data and perform the gdalinfo, gdalbuildvrt.  
What's going on. Is the bounds information wrong? Or GDAL is wrong?
thanks

----------------------------------------------------------------------------------------------------------------------------------------------------------

static
bool MBTilesGetBounds(OGRDataSourceH hDS, bool bUseBounds,
                     int nMaxLevel,
                     double& minX, double& minY,
                     double& maxX, double& maxY)
{
    const char* pszSQL;
    bool bHasBounds = false;
    OGRLayerH hSQLLyr;
    OGRFeatureH hFeat;

    if( bUseBounds )
    {
        pszSQL = "SELECT value FROM metadata WHERE name = 'bounds'";
        CPLDebug("MBTILES", "%s", pszSQL);
        hSQLLyr = OGR_DS_ExecuteSQL(hDS, pszSQL, NULL, NULL);
        if (hSQLLyr)
        {
            hFeat = OGR_L_GetNextFeature(hSQLLyr);
            if (hFeat != NULL)
            {
                const char* pszBounds = OGR_F_GetFieldAsString(hFeat, 0);
                char** papszTokens = CSLTokenizeString2(pszBounds, ",", 0);
                if (CSLCount(papszTokens) != 4 ||
                    fabs(CPLAtof(papszTokens[0])) > 180 ||
                    fabs(CPLAtof(papszTokens[1])) >= 89.99 ||
                    fabs(CPLAtof(papszTokens[2])) > 180 ||
                    fabs(CPLAtof(papszTokens[3])) >= 89.99 ||
                    CPLAtof(papszTokens[0]) > CPLAtof(papszTokens[2]) ||
                    CPLAtof(papszTokens[1]) > CPLAtof(papszTokens[3]))
                {
                    CPLError(CE_Warning, CPLE_AppDefined, "Invalid value for 'bounds' metadata. Ignoring it and fall back to present tile extent");
                }
                else
                {
                    minX = CPLAtof(papszTokens[0]);
                    minY = CPLAtof(papszTokens[1]);
                    maxX = CPLAtof(papszTokens[2]);
                    maxY = CPLAtof(papszTokens[3]);
                    LongLatToSphericalMercator(&minX, &minY);
                    LongLatToSphericalMercator(&maxX, &maxY);

                    bHasBounds = true;
                }

                CSLDestroy(papszTokens);

                OGR_F_Destroy(hFeat);
            }
            OGR_DS_ReleaseResultSet(hDS, hSQLLyr);
        }
    }

    if (!bHasBounds)
    {
        pszSQL = CPLSPrintf("SELECT min(tile_column), max(tile_column), "
                            "min(tile_row), max(tile_row) FROM tiles "
                            "WHERE zoom_level = %d", nMaxLevel);
        CPLDebug("MBTILES", "%s", pszSQL);
        hSQLLyr = OGR_DS_ExecuteSQL(hDS, pszSQL, NULL, NULL);
        if (hSQLLyr == NULL)
        {
            return false;
        }

        hFeat = OGR_L_GetNextFeature(hSQLLyr);
        if (hFeat == NULL)
        {
            OGR_DS_ReleaseResultSet(hDS, hSQLLyr);
            return false;
        }

        if (OGR_F_IsFieldSet(hFeat, 0) &&
            OGR_F_IsFieldSet(hFeat, 1) &&
            OGR_F_IsFieldSet(hFeat, 2) &&
            OGR_F_IsFieldSet(hFeat, 3))
        {
            int nMinTileCol = OGR_F_GetFieldAsInteger(hFeat, 0);
            int nMaxTileCol = OGR_F_GetFieldAsInteger(hFeat, 1);
            int nMinTileRow = OGR_F_GetFieldAsInteger(hFeat, 2);
            int nMaxTileRow = OGR_F_GetFieldAsInteger(hFeat, 3);
            minX = MBTilesTileCoordToWorldCoord(nMinTileCol, nMaxLevel);
            minY = MBTilesTileCoordToWorldCoord(nMinTileRow, nMaxLevel);
            maxX = MBTilesTileCoordToWorldCoord(nMaxTileCol + 1, nMaxLevel);
            maxY = MBTilesTileCoordToWorldCoord(nMaxTileRow + 1, nMaxLevel);
            bHasBounds = true;
        }

        OGR_F_Destroy(hFeat);
        OGR_DS_ReleaseResultSet(hDS, hSQLLyr);
    }

    return bHasBounds;
}

eea_screenshot_issue_atm.png

Klokan Technologies GmbH

unread,
Apr 15, 2016, 4:49:56 PM4/15/16
to mapt...@googlegroups.com
Your dataset is crossing dateline.

Petr

--
Klokan Technologies GmbH
Hofnerstrasse 96, Unterägeri 6314, Switzerland
Tel: +41 (0)41 511 26 12
Email: in...@klokantech.com
Web: http://www.klokantech.com/

--
You received this message because you are subscribed to the Google Groups "MapTiler Community" group.
To unsubscribe from this group and stop receiving emails from it, send an email to maptiler+u...@googlegroups.com.
To post to this group, send email to mapt...@googlegroups.com.
Visit this group at https://groups.google.com/group/maptiler.
For more options, visit https://groups.google.com/d/optout.

Geospatial Information Technology Solutions

unread,
Apr 15, 2016, 4:54:32 PM4/15/16
to MapTiler Community
Thanks for your Reply
Yes, it does cross 180 degrees Longitude 

It works fine in our mobile apps but we share the mbtiles with other users that try to load it in other mobile apps and desktop GIS software.
Should we just tell them to remove the bounds record in the metadata table?

It's not a Map Tiler Issue but why is GDAL having an issue
Thanks
Enjoy your weekend
We love your product!
Keep up the great work!

Klokan Technologies GmbH

unread,
Apr 15, 2016, 5:33:05 PM4/15/16
to mapt...@googlegroups.com
MBTiles spec does not define exact behaviour for dateline crossing tilesets.

Implementations, therefore, differs in various software tools.

Most universal behaviour would be probably to include full extent (longitude -180,180) in the bounds metadata. It would ensure compatibility with almost all of the viewers, but it degrades the performance of viewers which can interpret dateline crossing data correctly.
By setting longitude range to -180,180 information about the included tiles and the real area of the data get lost and the viewer will request tiles everywhere and will not be able to zoom to the map bounds correctly, but it should run.

Petr

--
Klokan Technologies GmbH
Hofnerstrasse 96, Unterägeri 6314, Switzerland
Tel: +41 (0)41 511 26 12
Email: in...@klokantech.com
Web: http://www.klokantech.com/

Reply all
Reply to author
Forward
0 new messages