代码之家  ›  专栏  ›  技术社区  ›  Seb

在WPF上加载Bing地图中的自定义互动程序

  •  2
  • Seb  · 技术社区  · 12 年前

    我正在尝试为Bing地图使用自定义波浪形符集。我想做的事情与 the question here ,但我正在尝试了解URI是如何格式化的,以便在应用程序中托管瓦片。我之所以尝试在本地托管它,是因为我想尽可能地限制应用程序的网络流量。

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

    提前谢谢你的建议。

    1 回复  |  直到 7 年前
        1
  •  23
  •   Clemens    10 年前

    Bing地图(或谷歌地图或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的tile,这样一个派生的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类中的一些愚蠢的技术细节,您还必须派生自己的TileLaye类才能在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; }
        }
    }
    

    然后,您可以在映射控件中使用它,如下所示,其中XAML命名空间 m 参考文献 Microsoft.Maps.MapControl.WPF local 引用包含派生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,而不使用 小便器格式 属性:

    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