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;
}