Map控件,是基于Microsoft的Bing map的地图控件,在WP7能很好的使用bing map实现地图的呈现,缩放,标注和定位等功能。
首先,介绍一下Map控件的简单应用吧。
在使用Map控件之前,我们必须先注册地图获得一个Register Key才能够使用bing map,注册地址:https://www.bingmapsportal.com 。新建一个Sliverlight for Windows Phone的工程,就可以开始练习使用Map控件了。在xaml里添加一个地图控件
在.cs文件里添加register key的代码(或者不使用Binding直接写在xaml中也行)
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0"> <my:Map Height="623" HorizontalAlignment="Left" CredentialsProvider="{Binding CredentialsProvider}" Margin="12,-22,0,0" Name="map1" VerticalAlignment="Top" Width="425"/> </Grid>
note:应该添加一个namespace:
1 using Microsoft.Phone.Controls.Maps; 2 3 namespace MapExample 4 { 5 public partial class MainPage : PhoneApplicationPage 6 { 7 const String BingMapsId = "Al7xKT8k0tvRNSCTc0uQs6AM1k-gREOdyigcbbbL4z932ynL42ySQuht1Ur6hpLI"; 8 private readonly CredentialsProvider credentialsProvider = new ApplicationIdCredentialsProvider(BingMapsId); 9 public CredentialsProvider CredentialsProvider 10 { 11 get { return credentialsProvider; } 12 } 13 // Constructor 14 public MainPage() 15 { 16 InitializeComponent(); 17 } 18 } 19 }
这样就可以运行一个最基本的map控件了。
下面,我们看看如何设置map的中心点以及Zoomlevel以及显示模式。
这个很简单只需要改变Center、 Zoomlevel和Map.Mode这几个属性的值,同样可以在xaml直接设置,或者在.cs文件里设置,当然,更高级点的用法就是对Center,zoomlevel等进行Binding了。
Map控件还有很多其他的属性,比如ZoomBarVisibility,ScaleVisibility,LogoVisibility等,这些都可以简单的进行设置或者通过Binding技术实现动态的属性值的改变。
然而,Map控件还提供添加标注,添加图片,绘制多边形,多边线等功能。
下面讲讲如何添加一个标记吧。
首先,我们可以在MainPage()里建立并初始化一个标记( 记得添加namespace: using System.Device.Location; )
1 Pushpin pin = new Pushpin(); 2 pin.Location = new GeoCoordinate(30, 120); 3 pin.Background = new SolidColorBrush(Colors.Black); 4 pin.Content = "Example"; 5 pin.Height = 40; 6 pin.Width = 80; 7 map1.Children.Add(pin); // 一定要记得添加到map1这个控件中哦~
对于多边线,我们用到的是Polyline这样一个类,多边形的绘制使用Polygon这个类,插入图片使用MapLayer类,它们的使用跟Pushpin这个类异曲同工。
以上就是一些简单的应用,那么来点实际点的。
我在开发过程中需要使用Map控件实现动态定位,找到自己的所在位置以及某个会议要举行的位置,并在切换过程中在地图中标注出相应的位置,并支持WP7.1的多点触控进行Zoomin和Zoomout。
这需要写一个page,我把它叫做MapPage,然后它的入口接收在页面Navigate时候传过来的三个值,一个是会议举行地点的经度,一个是纬度,还有一个是label,显示在标注上的文字。下面给出源代码仅供参考。
创建一个MapPage,xaml文件如下:
<phone:PhoneApplicationPage x:Class="Client.MapPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone" xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:System="clr-namespace:System;assembly=mscorlib" FontFamily="{StaticResource PhoneFontFamilyNormal}" FontSize="{StaticResource PhoneFontSizeNormal}" Foreground="{StaticResource MyPhoneForegroundBrush}" SupportedOrientations="Portrait" Orientation="Portrait" mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="728" shell:SystemTray.IsVisible="False" xmlns:my="clr-namespace:Microsoft.Phone.Controls.Maps;assembly=Microsoft.Phone.Controls.Maps" > <Canvas x:Name="LayoutRoot"> <!-- Map View --> <Border x:Name="Mapw" Height="768" Width="480"> <my:Map Name="Map" CredentialsProvider="{Binding CredentialsProvider}" CopyrightVisibility="Collapsed" LogoVisibility="Collapsed" ZoomLevel="{Binding Zoom, Mode=TwoWay}" Center="{Binding Center, Mode=TwoWay}" > <my:Map.Mode> <my:RoadMode /> </my:Map.Mode> <my:MapItemsControl x:Name="mapControl"/> </my:Map> <!-- TODO : Add map control --> </Border> </Canvas> <phone:PhoneApplicationPage.ApplicationBar> <shell:ApplicationBar IsVisible="True" IsMenuEnabled="False"> <shell:ApplicationBarIconButton IconUri="/Images/appbar.location.rest.png" Text="current" Click="CurrentLocation_Click"/> <shell:ApplicationBarIconButton IconUri="/Images/appbar.next.rest.png" Text="venue" Click="VenueLocation_Click"/> </shell:ApplicationBar> </phone:PhoneApplicationPage.ApplicationBar> </phone:PhoneApplicationPage>
在MapPage.cs文件里完成相应的处理:
using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Shapes; using Microsoft.Phone.Controls; using Microsoft.Phone.Controls.Maps; using System.Device.Location; using System.ComponentModel; using Microsoft.Phone.Controls.Maps.Core; namespace Client { public partial class MapPage : PhoneApplicationPage, INotifyPropertyChanged { public MapPage() { this.Loaded += new RoutedEventHandler(MapPage_Loaded); InitializeComponent(); InitializeDefaults(); DataContext = this; } private readonly CredentialsProvider credentialsProvider = new ApplicationIdCredentialsProvider(AcademicSearch.App.BingMapsId); public CredentialsProvider CredentialsProvider { get { return credentialsProvider; } } private MapLayer pushpinLayer; private string pushpinLabel; private Pushpin locationMark; void MapPage_Loaded(object sender, RoutedEventArgs e) { NotifyPropertyChanged("Zoom"); NotifyPropertyChanged("Center"); pushpinLayer = new MapLayer(); Map.Children.Add(pushpinLayer); pushpinLayer.AddChild( new Pushpin() {Content =new Border() { Child = new TextBlock() { Text = pushpinLabel }, Background=new SolidColorBrush(Colors.Black)}}, Center); locationMark = new Pushpin() { Content = new Border() { Child = new TextBlock() { Text = "You Are Here!" }, Background = new SolidColorBrush(Colors.Black) } }; pushpinLayer.AddChild(locationMark, new GeoCoordinate(0, 0)); } protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e) { base.OnNavigatedTo(e); string longitudeStr; string latitudeStr; if (NavigationContext.QueryString.TryGetValue("longitude", out longitudeStr) && NavigationContext.QueryString.TryGetValue("latitude", out latitudeStr)) { double latitude; double longitude; if (Double.TryParse(latitudeStr, out latitude) && Double.TryParse(longitudeStr, out longitude)) { Center = new GeoCoordinate(latitude, longitude); Venue = new GeoCoordinate(latitude, longitude); Zoom = DefaultZoomLevel; } string label; if (NavigationContext.QueryString.TryGetValue("label", out label)) { pushpinLabel = label; } else { pushpinLabel = ""; } } } public void AddPushpin(GeoCoordinate location) { Pushpin pushpin = new Pushpin(); pushpin.Content = "Test"; pushpinLayer.AddChild(pushpin, location); } ///<summary> /// Gets or sets the map zoom level. ///</summary> private const double DefaultZoomLevel = 17.0; private const double MaxZoomLevel = 21.0; private const double MinZoomLevel = 1.0; private double _zoom = DefaultZoomLevel; public double Zoom { get { return _zoom; } set { var coercedZoom = Math.Max(MinZoomLevel, Math.Min(MaxZoomLevel, value)); if (_zoom != coercedZoom) { _zoom = value; NotifyPropertyChanged("Zoom"); } } } private GeoCoordinateWatcher loc = null; private void CurrentLocation_Click(object sender, EventArgs e) { //Zoom += 1; if (loc == null) { loc = new GeoCoordinateWatcher(GeoPositionAccuracy.Default); loc.StatusChanged += loc_StatusChanged; } if (loc.Status == GeoPositionStatus.Disabled) { loc.StatusChanged -= loc_StatusChanged; MessageBox.Show("Location services must be enabled on your phone."); return; } loc.Start(); } void loc_StatusChanged(object sender, GeoPositionStatusChangedEventArgs e) { if (e.Status == GeoPositionStatus.Ready) { locationMark.Location = loc.Position.Location; Map.SetView(loc.Position.Location, 17.0); loc.Stop(); } } private void VenueLocation_Click(object sender, EventArgs e) { Map.SetView(Venue, 17.0); } private GeoCoordinate _center; public GeoCoordinate Center { get { return _center; } set { if (_center != value) { _center = value; NotifyPropertyChanged("Center"); } } } private GeoCoordinate Venue; public event PropertyChangedEventHandler PropertyChanged; private void NotifyPropertyChanged(String propertyName) { PropertyChangedEventHandler handler = PropertyChanged; if (null != handler) { handler(this, new PropertyChangedEventArgs(propertyName)); } } public bool HasDirections { get { // TODO : Return true only if has directions. return true; } } #region Tasks private void InitializeDefaults() { // TODO : Initialize default properties. } private void ChangeMapMode() { // TODO : Change map view mode. } private void IncreaseZoomLevel() { // TODO : Increases zoom level. } private void DecreaseZoomLevel() { // TODO : Decreases zoom level. } private void CenterLocation() { // TODO : Center current location. } private void CenterPushpinsPopup(Point touchPoint) { // TODO : Center pushpins popup to the touch point. } private void CreateNewPushpin(object selectedItem, Point point) { // TODO : Create a new pushpin. } private void CalculateRoute() { // TODO : Calculate a route. } #endregion } }