学习使用Bing Maps Silverlight Control(五):离线使用和自定义地图模式
6 離線使用
在筆記第一部分的時候就提到如果要使用Bing Maps Silverlight Control 進行開發,需要申請一個key,不讓會顯示一個錯誤提示出來。但是在實際開發或使用過程中,使用環境和地圖數據可能不是在線的,但控件因為驗證失敗仍然會顯示以下內容:
如何去掉這個提示?最簡單的方式就是自己擴展一個Map控件,在其構造方法中將錯誤提示層給干掉,然后再項目中使用自定義的Map控件,大致可以如下實現:
首先,自定義一個類型,繼承自Map類:
namespace CustomBingMaps {public class OfflineMap : Map{public OfflineMap(): base(){base.LoadingError += (sender, e) =>{base.RootLayer.Children.RemoveAt(5);};}} }
然后,在前臺引用剛才的自定義類型的命名空間,就可以使用這個擴展的OfflineMap控件了:
<UserControl x:Class="xwgmap_sl_client.MainPage"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d="http://schemas.microsoft.com/expression/blend/2008"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"xmlns:m="clr-namespace:Microsoft.Maps.MapControl;assembly=Microsoft.Maps.MapControl"xmlns:c="clr-namespace:CustomBingMaps"mc:Ignorable="d"d:DesignHeight="300" d:DesignWidth="400"><Grid x:Name="LayoutRoot" Background="White"><c:OfflineMap Name="map" LogoVisibility="Collapsed" CopyrightVisibility="Collapsed"></c:OfflineMap></Grid> </UserControl>
這樣在離線使用控件的時候就不會再顯示錯誤了。
(以上方法轉載自:http://www.cnblogs.com/beniao/archive/2010/05/28/1745896.html,相關原理沒有轉載,有興趣的話可以去原博客查看。)
7 自定義顯示范圍
如果使用自己的地圖數據進行加載使用,一般來說相對于全球只會覆蓋一部分的地區,剩下的地區都是空白,還有地圖數據不一定對應所有的縮放級別都有,如何限制可以查看的地圖范圍和縮放級別呢?答案就是自定義MapMode。
在這里,自定義MapMode來限制視野范圍主要是要重寫兩個方法:GetZoomRange 和 ConstrainView,前者用來限制縮放范圍,后者則將經緯度和縮放進行統一限制。
還有一個問題需要說明,Bing Maps自帶的RoadMode(普通地圖)和AerialMode(衛星地圖)都是繼承自MercatorMode(墨卡托投影),所以這里也將直接從MercatorMode派生出自定義MapMode(當然也可以擴展前兩個模式)。但是MercatorMode沒有任何TileSource,所以如果直接顯示出來就什么也看不到了,所以還要再給自定義類型加上Tile圖層。
首先是自定義了一個必應地圖(簡體中文)的TileSource類:
/// <summary> /// 必應地圖的Tile系統 /// </summary> public class BingDituTileSource : LocationRectTileSource {public BingDituTileSource(){//設定瓦片源Tile系統的Uri格式,其中的{quadkey}就是每個瓦片quadkey的對應位置//這里使用的是必應地圖(簡體中文)的Tile系統UriFormat = "http://r0.tiles.ditu.live.com/tiles/r{quadkey}.png?g=99&mkt=zh-cn";} }
下面就開始自定義ChinaMode類,為了方便以后的擴展,這里將對MercatorMode的擴展提取成CustomModeBase,在此基礎上再擴展出ChinaMode。所以首先是CustomModeBase的代碼:
/// <summary> /// 自定義地圖基類,實現了視野范圍的限制和自定義瓦片源。 /// 使用前請初始化: /// TileLayer(瓦片源) /// LatitudeRange(經度范圍) /// LongitudeRange(緯度范圍) /// MapZoomRange(縮放范圍) /// </summary> public class CustomModeBase : MercatorMode {/// <summary>/// 用于呈現Tile層/// </summary>public override UIElement Content{get{return this.TileLayer;}}/// <summary>/// 存儲Tile圖層/// </summary>public MapTileLayer TileLayer;/// <summary>/// 緯度范圍/// </summary>public Range<double> LatitudeRange;/// <summary>/// 經度范圍/// </summary>public Range<double> LongitudeRange;/// <summary>/// 縮放范圍/// </summary>public Range<double> MapZoomRange;/// <summary>/// 初始化基類字段/// </summary>public CustomModeBase(){this.TileLayer = new MapTileLayer();this.LatitudeRange = new Range<double>(-90, 90);this.LongitudeRange = new Range<double>(-180, 180);this.MapZoomRange = new Range<double>(1, 20);}/// <summary>/// 縮放范圍/// </summary>/// <param name="center"></param>/// <returns></returns>protected override Range<double> GetZoomRange(Location center){return MapZoomRange;}//當地圖視野改變時將調用該函數進行處理(即可達到限制地圖范圍的效果)public override bool ConstrainView(Location center, ref double zoomLevel, ref double heading, ref double pitch){bool isChanged = base.ConstrainView(center, ref zoomLevel, ref heading, ref pitch);double newLatitude = center.Latitude;double newLongitude = center.Longitude;//如果視野緯度超出范圍,則將視野范圍限制在邊界if (center.Longitude > LongitudeRange.To){newLongitude = LongitudeRange.To;}else if (center.Longitude < LongitudeRange.From){newLongitude = LongitudeRange.From;}//如果視野經度超出范圍,則將視野范圍限制在邊界if (center.Latitude > LatitudeRange.To){newLatitude = LatitudeRange.To;}else if (center.Latitude < LatitudeRange.From){newLatitude = LatitudeRange.From;}//設置新的地圖視野(限制在范圍中)if (newLatitude != center.Latitude || newLongitude != center.Longitude){center.Latitude = newLatitude;center.Longitude = newLongitude;isChanged = true;}//設置新的地圖縮放級別(限制在范圍中)Range<double> range = GetZoomRange(center);if (zoomLevel > range.To){zoomLevel = range.To;isChanged = true;}else if (zoomLevel < range.From){zoomLevel = range.From;isChanged = true;}return isChanged;} }
然后再新建ChinaMode類,繼承自CustomModeBase:
/// <summary> /// 中國地圖模式 /// </summary> public class ChinaMode : CustomModeBase {public ChinaMode(){//初始化必應地圖(簡體中文)瓦片源BingDituTileSource TileSource = new BingDituTileSource();//向瓦片圖層添加瓦片源base.TileLayer.TileSources.Add(TileSource);//向地圖添加限制范圍base.LatitudeRange = new Range<double>(0, 50);base.LongitudeRange = new Range<double>(70, 140);base.MapZoomRange = new Range<double>(5, 10);} }
需要說明的是:這里經緯度的限制范圍并不是邊界范圍,而是視野中心(Center)的邊界,可能是為了方便適應不同的分辨率和縮放級別吧,所以處理經緯度邊界的時候需要比較謹慎。縮放的級別就是可以縮放的級別,這個沒有問題,縮放級別設定后,界面工具條上的縮放工具欄也會自動的做出相應的改變。
如何使用MapMode就比較簡單了,比如在后臺代碼進行改變:
public MainPage() {InitializeComponent();map.Mode = new ChinaMode(); }
也可以在前臺直接設置Mode屬性:
<c:OfflineMap Name="map"CopyrightVisibility="Collapsed" LogoVisibility="Collapsed" ScaleVisibility="Collapsed"><c:OfflineMap.Mode><c:ChinaMode></c:ChinaMode></c:OfflineMap.Mode> </c:OfflineMap>
這時可以通過設計視圖的預覽直接看到效果。
最終效果(各種限制無法在截圖中展示,請自行體驗。。。):
(以上內容參考自:http://msdn.microsoft.com/en-us/library/ee681896.aspx,更多內容請參閱msdn。)
轉載于:https://www.cnblogs.com/xwgli/archive/2013/04/18/3029071.html
總結
以上是生活随笔為你收集整理的学习使用Bing Maps Silverlight Control(五):离线使用和自定义地图模式的全部內容,希望文章能夠幫你解決所遇到的問題。
                            
                        - 上一篇: 亚龙湾看日落最美的地方
 - 下一篇: 抬头向天笑下一句是什么呢?