在WPF上的Bing地图中加载自定义图块

时间:2012-07-31 19:03:18

标签: .net wpf bing-maps

我正在尝试使用Bing地图的自定义tileset。我想要做的是类似于the question here,但我正在尝试理解如何格式化URI,以便我可以在应用程序中托管切片。我试图在本地托管这个的原因是因为我想尽可能地限制我的应用程序中的网络流量。

是否有关于在本地托管地图图块的教程,或者有关如何将URI指向本地存储路径的更深入的教程?

提前感谢任何建议。

1 个答案:

答案 0 :(得分:22)

Bing地图(或Google地图或OpenStreetMap)平铺地图方案的中心点是每个地图图块由三个参数标识。这些是缩放级别(通常范围从0或1到大约20)以及缩放级别内的图块的x和y索引。在给定的缩放级别z中,x和y索引的范围从0到2 ^ z-1。在缩放级别0中有一个图块,在级别1中有2x2图块,在级别2中有4x4图块,依此类推。

大多数地图图块提供程序(如OpenStreetMap或Google Maps)直接在其图块URI中反映这三个参数。例如,OpenStreetMap通过URI http://tile.openstreetmap.org/z/x/y.png提供地图图块。

在派生的TileSource类中,您重写GetUri方法以为三个tile参数提供URI。对于OpenStreetMap,类似派生的TileSource可能看起来像这样:

public class MyTileSource : Microsoft.Maps.MapControl.WPF.TileSource
{
    public override Uri GetUri(int x, int y, int zoomLevel)
    {
        return new Uri(UriFormat.
                       Replace("{x}", x.ToString()).
                       Replace("{y}", y.ToString()).
                       Replace("{z}", zoomLevel.ToString()));
    }
}

对于Bing Maps WPF Control TileLayer类中的一些愚蠢的技术细节,您还必须派生自己的TileLayer类以在XAML中启用:

public class MyTileLayer : Microsoft.Maps.MapControl.WPF.MapTileLayer
{
    public MyTileLayer()
    {
        TileSource = new MyTileSource();
    }

    public string UriFormat
    {
        get { return TileSource.UriFormat; }
        set { TileSource.UriFormat = value; }
    }
}

然后,您将在下面的Map Control中使用它,其中XAML名称空间m引用Microsoft.Maps.MapControl.WPFlocal引用包含派生TileLayer的名称空间。

<m:Map>
    <m:Map.Mode>
        <!-- set empty map mode, i.e. remove default map layer -->
        <m:MercatorMode/>
    </m:Map.Mode>
    <local:MyTileLayer UriFormat="http://tile.openstreetmap.org/{z}/{x}/{y}.png"/>
</m:Map>

您现在也可以为本地文件创建URI,而不是创建http URI。例如,您可以在目录结构中组织地图图块,其中包含缩放级别的目录,x索引的子目录和y索引的文件名。您可以以指定本地路径的方式设置UriFormat属性:

<local:MyTileLayer UriFormat="file:///C:/Tiles/{z}/{x}/{y}.png"/>

重写的GetUri方法也可以直接创建适当的本地文件URI,而不使用UriFormat属性:

public override Uri GetUri(int x, int y, int zoomLevel)
{
    string rootDir = ...
    string path = Path.Combine(rootDir, zoomLevel.ToString(), x.ToString(), y.ToString());
    return new Uri(path);
}

您可能想要了解有关OpenStreetMap如何处理map tile names的更多信息。

相关问题