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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11747160/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 04:47:13  来源:igfitidea点击:

Load custom tiles in Bing maps on WPF

.netwpfbing-maps

提问by Seb

I am trying to use a custom tileset for Bing maps. What I am trying to do is similar to the question here, but I'm trying to understand how a URI is formatted so that I can host the tiles within the application. The reason I am trying to host this locally is because I want to limit network traffic out from my application as much as possible.

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

Are there any tutorials on hosting the map tiles locally or a more in depth tutorial on how to have the URI point to a local storage path?

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

Thanks in advance for any advice.

提前感谢您的任何建议。

回答by Clemens

The central point in the Bing Maps (or Google Maps or OpenStreetMap) tiled map scheme is that each map tile is identified by three parameters. These are the zoom level (that typically ranges from 0 or 1 to about 20) and the x and y index of a tile within a zoom level. In a given zoom level z the x and y index range from 0 to 2^z-1. In zoom level 0 there is one tile, in level 1 there are 2x2 tile, in level 2 there are 4x4 tiles and so on.

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

Most map tile providers like OpenStreetMap or Google Maps directly reflect these three parameters in their tile URIs. OpenStreetMap for example provides map tiles by the URI http://tile.openstreetmap.org/z/x/y.png.

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

In a derived TileSourceclass you override the GetUri method to provide an URI for the three tile parameters. For OpenStreetMap alike tiles such a derived TileSource might look like this:

在派生的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()));
    }
}

For some stupid technical detail in the Bing Maps WPF Control TileLayer class you would also have to derive your own TileLayer class to enable usage in XAML:

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

You would then use it in the Map Control like below where the XAML namespace mreferences Microsoft.Maps.MapControl.WPFand localreferences the namespace that contains the derived TileLayer.

然后,您将在 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>

Instead of creating a http URI you might now also create an URI for a local file. You could for example organize the map tiles in a directory structure with a directory for the zoom level, a subdirectory for the x index and a file name for the y index. You could set the UriFormatproperty in a way that specifies a local path:

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

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

The overridden GetUri method might also directly create an appropriate local file URI, without using the UriFormatproperty:

重写的 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);
}

You may want to read more about how OpenStreetMap handles map tile names.

您可能想阅读更多关于 OpenStreetMap 如何处理地图图块名称的信息