欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Windows Phone中Map控件由浅及深

程序员文章站 2022-09-19 15:41:02
  Map控件,是基于Microsoft的Bing map的地图控件,在WP7能很好的使用bing map实现地图的呈现,缩放,标注和定位等功能。...

 

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="https://schemas.microsoft.com/winfx/2006/xaml/presentation"

    xmlns:x="https://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="https://schemas.microsoft.com/expression/blend/2008"

    xmlns:mc="https://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

 

    }

}

 

 

MSRA-USTC Class

OMG team

 

摘自 OMG!日志