2

我正在尝试为 Bing 地图使用自定义图块集。我想做的与这里的问题类似,但我试图了解 URI 的格式,以便我可以在应用程序中托管磁贴。我试图在本地托管它的原因是因为我想尽可能地限制来自我的应用程序的网络流量。

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

提前感谢您的任何建议。

4

1 回答 1

23

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

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

在派生的TileSource类中,您重写 GetUri 方法以提供三个切片参数的 URI。对于 OpenStreetMap 类似的瓦片,这样的派生瓦片源可能如下所示:

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>

除了创建 http URI,您现在还可以为本地文件创建 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 如何处理地图图块名称的信息。

于 2012-08-01T20:13:27.520 回答