I have been trying to write a TiledMapSource that reads from the mbtiles format https://github.com/mapbox/mbtiles-spec/blob/master/1.1/spec.md
using
System;
using
System.Collections.Generic;
using
System.Linq;
using
System.Text;
using
System.Threading.Tasks;
namespace
RadMapMbtilesDemo
{
using
System.Data.SQLite;
using
System.Diagnostics;
using
System.IO;
using
System.Security.AccessControl;
using
System.Windows.Media.Imaging;
using
Telerik.Windows.Controls.Map;
public
class
MbTileSource : TiledMapSource
{
private
readonly
string
mbtilefilepath;
/// <summary>
/// Initializes a new instance of the MyMapSource class.
/// </summary>
public
MbTileSource(
string
mbtilefilepath,
int
minZoom,
int
maxZoom)
:
base
(minZoom, maxZoom, 256, 256)
{
this
.mbtilefilepath = mbtilefilepath;
}
/// <summary>
/// Initialize provider.
/// </summary>
public
override
void
Initialize()
{
// Raise provider initialized event.
this
.RaiseIntializeCompleted();
}
/// <summary>
/// Gets the image URI.
/// </summary>
/// <param name="tileLevel">Tile level.</param>
/// <param name="tilePositionX">Tile X.</param>
/// <param name="tilePositionY">Tile Y.</param>
/// <returns>URI of image.</returns>
protected
override
Uri GetTile(
int
tileLevel,
int
tilePositionX,
int
tilePositionY)
{
return
null
;
}
protected
override
Stream GetCachedTile(
int
tileLevel,
int
tilePositionX,
int
tilePositionY)
{
var zoomLevel =
this
.ConvertTileToZoomLevel(tileLevel);
try
{
using
(var conn =
new
SQLiteConnection(String.Format(
"Data Source={0};Version=3;"
,
this
.mbtilefilepath)))
{
conn.Open();
var sqlquery = String.Format(
"SELECT tile_data FROM tiles WHERE tile_column = {0} and tile_row = {1} and zoom_level = {2};"
, tilePositionX, tilePositionY, zoomLevel);
Debug.WriteLine(sqlquery);
using
(var cmd =
new
SQLiteCommand() { Connection = conn, CommandText = sqlquery })
{
var reader = cmd.ExecuteReader();
if
(reader.Read())
{
var bytes = reader[
"tile_data"
]
as
byte
[];
if
(bytes !=
null
)
{
return
new
MemoryStream(bytes);
}
}
}
}
}
catch
{
return
null
;
}
return
null
;
}
}
}
This works and reads the files from the mbtiles (sqlite underneath the mbtiles spec) but the map is requesting the wrong tiles and I cannot see why. My understanding is:
1) Radmap is requesting tiles in a TMS format
2) MbTiles are stored in a TMS format
So the XYZ values passed into GetCachedTile(int tileLevel, int tilePositionX, int tilePositionY) should be the same I use in my sqlite query. Things I have checked:
1) I wondered if my mbtiles files was actually using OSMs style XYZ and tried the code to flip the Y value, this still gives incorrect tile values
2) I checked my mbtile file with https://viswaug.wordpress.com/2011/06/28/mbtilesviewer/ and it works fine
So I can only assume that Radmap and mbtiles are using a different format or different projection hence the issues lining the two up. Can anyone help?