使用Microsoft.Maps.MapControl.WPF,如何避免暴露Bing API Key并加载OSM瓦片?
解决Microsoft.Maps.MapControl.WPF加载OpenStreetMap瓦片无需Bing API Key的问题
核心问题分析
- 你现在的思路走偏了:
Microsoft.Maps.MapControl.WPF的CredentialsProvider是专门为Bing地图服务设计的,哪怕拿到session key,控件仍会验证该密钥是否绑定Bing服务,所以才会弹出“无效密钥”提示。 - 要加载OpenStreetMap瓦片,根本不需要碰Bing的密钥体系,直接自定义瓦片图层就能搞定。
正确实现步骤
1. 自定义OpenStreetMap瓦片源
写一个继承自MapTileSource的类,指定OSM的瓦片URL模板:
public class OpenStreetMapTileSource : MapTileSource { public OpenStreetMapTileSource() { // OSM官方瓦片地址,也可替换为其他第三方OSM瓦片源 UriFormat = "https://tile.openstreetmap.org/{zoom}/{x}/{y}.png"; // 设置瓦片支持的缩放范围(OSM支持1-19级) ZoomLevelRange = new Range<double>(1, 19); TileSize = 256; } }
2. 添加自定义图层到地图
方式一:XAML直接配置
<Window x:Class="OSMMapDemo.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:maps="clr-namespace:Microsoft.Maps.MapControl.WPF;assembly=Microsoft.Maps.MapControl.WPF" xmlns:local="clr-namespace:OSMMapDemo" Title="OSM地图" Height="450" Width="800"> <Grid> <!-- Mode设为None,禁用默认Bing图层,避免触发密钥验证 --> <maps:Map x:Name="myMap" Mode="None"> <maps:MapTileLayer> <local:OpenStreetMapTileSource /> </maps:MapTileLayer> </maps:Map> </Grid> </Window>
方式二:后台代码动态添加
如果要在代码里配置,窗口加载事件里这么写:
private void OnLoad(object sender, RoutedEventArgs e) { // 关掉默认的Bing地图图层 myMap.Mode = MapMode.None; // 创建OSM瓦片图层并加到地图上 var osmTileLayer = new MapTileLayer(); osmTileLayer.TileSources.Add(new OpenStreetMapTileSource()); myMap.Children.Add(osmTileLayer); }
3. 删掉没用的密钥代码
你之前写的获取session key的代码完全不需要,直接删除即可,现在我们已经绕开了Bing的密钥验证体系。
注意事项
- 遵守OSM的使用规则:不要短时间内大量请求瓦片,避免给服务器添负担,有需要可以做本地缓存。
- 如果要加标注、路线这类功能,直接用WPF的UI元素叠在地图控件上就行,不用依赖Bing的接口。
内容的提问来源于stack exchange,提问作者Oren Geva
相关产品推荐
相关产品推荐

