Windows Phone 使用地图服务

1.注册Bing Maps API密匙

在Windows Phone开发中,我们可以通过使用Windows Phone中的Map控件,使用微软提供的Bing Maps服务,在程序中使用Bing Maps服务需要获取一个地图应用API的Key,这要求你注册一个Windows Live的账号,这是免费的,而且步骤非常简单(这里是获取Key的地址),使用Windows Live账号登陆后:

点击“Create or View Keys":

Windows Phone 使用地图服务_第1张图片

填写好相应的表单后就会得到一个属于你自己的Key了。

Windows Phone 使用地图服务_第2张图片

在后面的程序中你将会使用到它。

2.Map的缩放和显示模式

下面我们通过是一个简单的示例来了解Map控件是如何进行缩放以及设置它的显示模式:道路模式航测模式。这是前台页面MainPage.xaml的代码:

 

<!--ContentPanel - 在此处放置其他内容-->
          <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
              <StackPanel>
                  <my:Map  Name="map1" Height="450" CredentialsProvider="你注册的Key值">
                  </my:Map>
                  <StackPanel>
                      <Grid>
                          <Button Content="航测模式" HorizontalAlignment="Left" Width="160" Name="btnAerial" Click="btnAerial_Click"></Button>
                          <Button Content="道路模式" HorizontalAlignment="Right" Width="160" Name="btnRoad" Click="btnRoad_Click"></Button>
                      </Grid>
                  </StackPanel>
                  <StackPanel>
                      <Grid>
                          <Button Content="放大" HorizontalAlignment="Left" Width="160" Name="btnZoomIn" Click="btnZoomIn_Click"></Button>
                          <Button Content="缩小" HorizontalAlignment="Right" Width="160" Name="btnZoomOut" Click="btnZoomOut_Click"></Button>
                      </Grid>
                  </StackPanel>
              </StackPanel>
          </Grid>

这里给出后台程序MainPage.xaml.cs的处理代码:

/// <summary>
        /// 放大
       /// </summary>
       /// <param name="sender"></param>
       /// <param name="e"></param>
          private void btnZoomIn_Click(object sender, RoutedEventArgs e)
          {
              double zoom;
              zoom = map1.ZoomLevel;
              map1.ZoomLevel = ++zoom;
          }
  
          /// <summary>
       /// 缩小
       /// </summary>
       /// <param name="sender"></param>
       /// <param name="e"></param>
          private void btnZoomOut_Click(object sender, RoutedEventArgs e)
          {
              double zoom;
              zoom = map1.ZoomLevel;
              map1.ZoomLevel = --zoom;
          }
  
         /// <summary>
      /// 道路模式
      /// </summary>
      /// <param name="sender"></param>
      /// <param name="e"></param>
          private void btnRoad_Click(object sender, RoutedEventArgs e)
          {
              map1.Mode = new RoadMode();
          }
  
          /// <summary>
       /// 航测模式
       /// </summary>
       /// <param name="sender"></param>
       /// <param name="e"></param>
          private void btnAerial_Click(object sender, RoutedEventArgs e)
          {
              map1.Mode = new AerialMode(true);//参数为true的构造函数表示显示地理信息
          }

3.在Map中使用位置服务(定位)和图钉(pushpin)

MainPage.xaml:

<!--ContentPanel - 在此处放置其他内容-->
          <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
              <my:Map  Name="map1"  Height="500" VerticalAlignment="Top" CredentialsProvider="你注册的Map Key"/>
              <Button Content="定位" VerticalAlignment="Bottom" Name="btn_Location" Click="btn_Location_Click"/>
          </Grid>

后台处理程序,MainPage.xaml.cs:

public partial class MainPage : PhoneApplicationPage
      {
          GeoCoordinateWatcher watcher;
          // 构造函数
          public MainPage()
          {
              InitializeComponent();
          }
  
          /// <summary>
        /// 在地图上定位
       /// </summary>
        /// <param name="sender"></param>
       /// <param name="e"></param>
          private void btn_Location_Click(object sender, RoutedEventArgs e)
          {
              if (watcher == null)
              {
                  watcher = new GeoCoordinateWatcher(GeoPositionAccuracy.High); // 采用高精度
                  watcher.MovementThreshold = 20; // PositionChanged事件之间传送的最小距离
            //绑定事件
                  watcher.PositionChanged += new EventHandler<GeoPositionChangedEventArgs<GeoCoordinate>>(watcher_PositionChanged);
                  //开始从位置服务获取数据
                  watcher.Start();
              }
          }
  
          //检测到位置更改时
       //当定位服务已准备就绪并接收数据时,它将开始引发 PositionChanged 事件
          void watcher_PositionChanged(object sender, GeoPositionChangedEventArgs<GeoCoordinate> e)
          {
              Location location = new Location();//实例化一个位置位置类的实例
         //将当前的经纬度值赋给位置对象
              location.Latitude = e.Position.Location.Latitude;
              location.Longitude = e.Position.Location.Longitude;
  
              Pushpin pushpin = new Pushpin();//实例化一个图钉实例
              pushpin.Content = "当前位置";
              pushpin.Location = location;
  
              this.map1.Children.Add(pushpin);//将图钉显示在地图上
              this.map1.SetView(location, 10);//缩放界别为10(1-16),始终将当前位置位于地图中心
          }
      }

4.使用Bing Maps SOAP Services

Bing Maps提供了一组SOAP Services,通过使用这些服务可以使我们能够使我们的应用实现地理位置计算、路径计算等额外的功能。现在让我们一起来了解如何使用其中的两个服务。

地理编码服务可以通过搜索地名来匹配在地图上对应的位置(经度和纬度),或者通过实际位置的经度和纬度来确定对应在地图上的位置。

路由功能服务可以通过计算地点的坐标来显示线路的功能比如在百度地图中常用的驾车线路功能等。     

  下面让我们通过一个示例来了解如何使用这些服务,在Windows Phone中实现我们在地图应用中常见的出行路径计算的功能。首先添加前面给出地址的两个服务引用,下面让代码来说话:

MainPage.xaml代码:

<!--LayoutRoot 是包含所有页面内容的根网格-->
      <Grid x:Name="LayoutRoot" Background="Transparent">
          <Grid.RowDefinitions>
              <RowDefinition Height="auto"/>
              <RowDefinition Height="*"/>
          </Grid.RowDefinitions>
          <!--ContentPanel - 在此处放置其他内容-->
          <Grid x:Name="ContentPanel" Grid.Row="0">
              <Grid Height="530" VerticalAlignment="Top">
                  <my:Map Name="map1" CredentialsProvider="Map Key" />
              </Grid>
          </Grid>
          <Grid Grid.Row="1" >
              <StackPanel Orientation="Vertical">
                      <Grid>
                      <TextBlock Text="起点:"  HorizontalAlignment="Left" VerticalAlignment="Center" FontSize="28" ></TextBlock>
                      <TextBox Width="400" Height="80" HorizontalAlignment="Right" Name="txtStartPath"></TextBox>
                      </Grid>
                  <Grid>
                      <TextBlock Text="终点:"  HorizontalAlignment="Left" VerticalAlignment="Center" FontSize="28" ></TextBlock>
                      <TextBox Width="400" Height="80" HorizontalAlignment="Right" Name="txtStopPath"></TextBox>
                  </Grid>
                  <Button Height="80" Content="查找路径" FontSize="28"  Name="btnQueryPath" Click="btnQueryPath_Click"></Button>
              </StackPanel>
          </Grid>
      </Grid>

后台处理程序,代码比较长:

  1 View Code 
  2  public partial class MainPage : PhoneApplicationPage
  3        {
  4            // 构造函数
  5            public MainPage()
  6            {
  7                InitializeComponent();
  8            }
  9    
 10           /// <summary>
 11        /// 查询路线
 12        /// </summary>
 13        /// <param name="sender"></param>
 14        /// <param name="e"></param>
 15            private void btnQueryPath_Click(object sender, RoutedEventArgs e)
 16            {
 17                geocodeResults = new GeocodeResult[2];
 18    
 19                GetGeocodeAsync(this.txtStartPath.Text, 0);//起点
 20                GetGeocodeAsync(this.txtStopPath.Text, 1);//终点
 21            }
 22    
 23           /// <summary>
 24        /// 根据地名查询地理坐标
 25        /// </summary>
 26        /// <param name="strGeocodeInfo"></param>
 27            public void GetGeocodeAsync(string strAddress, int waypointIndex)
 28            {
 29                try
 30                {
 31                    //实例化GeocodeService客户端对象
 32                    GeocodeServiceClient client = new GeocodeServiceClient("BasicHttpBinding_IGeocodeService");
 33                    //绑定事件,查询完成后发生
 34                    client.GeocodeCompleted += new EventHandler<GeocodeCompletedEventArgs>(OnGeocodeCompleted);
 35    
 36                    //创建一个Geocode检索请求
 37                    GeocodeRequest request = new GeocodeRequest();
 38                    //设置地图证书
 39                    request.Credentials = new Microsoft.Phone.Controls.Maps.Credentials();
 40                    request.Credentials.ApplicationId = ((ApplicationIdCredentialsProvider)map1.CredentialsProvider).ApplicationId;
 41                    //设置检索条件
 42                    request.Query = strAddress;
 43                    //异步调用Geocode服务方法
 44                    client.GeocodeAsync(request, waypointIndex);
 45                }
 46                catch (Exception ex)
 47                {
 48                    MessageBox.Show("地理信息编码服务解析过程中出现错误.");
 49                }
 50            }
 51    
 52            //使用全局变量来存储起点和终点的位置信息
 53            internal GeocodeResult[] geocodeResults;
 54    
 55           /// <summary>
 56        /// 当检索地理信息完成后的回调函数
 57        /// </summary>
 58        /// <param name="sender"></param>
 59        /// <param name="e"></param>
 60            private void OnGeocodeCompleted(object sender, GeocodeCompletedEventArgs e)
 61            {
 62                if (e.Error == null)
 63                {
 64                    int waypointIndex = System.Convert.ToInt32(e.UserState);
 65                    geocodeResults[waypointIndex] = e.Result.Results[0];
 66    
 67                    bool doneGeocoding = true;
 68    
 69                    foreach (GeocodeService.GeocodeResult gr in geocodeResults)
 70                    {
 71                        if (gr == null)
 72                        {
 73                            doneGeocoding = false;
 74                        }
 75                    }
 76    
 77                    //当起点和终点位置查询都已经完成时,调用Route服务查询路线
 78                    if (doneGeocoding)
 79                    {
 80                        CalculateRoute(geocodeResults);
 81                    }
 82                }
 83            }
 84    
 85            /// <summary>
 86         /// 根据起点终点坐标查询,使用路由服务查询路线
 87         /// </summary>
 88         /// <param name="results"></param>
 89            private void CalculateRoute(GeocodeResult[] results)
 90            {
 91                RouteServiceClient routeService = new RouteServiceClient("BasicHttpBinding_IRouteService");
 92                //绑定事件回调函数
 93                routeService.CalculateRouteCompleted += new EventHandler<RouteService.CalculateRouteCompletedEventArgs>(routeService_CalculateRouteCompleted);
 94    
 95                // 设置地图证书
 96                RouteRequest routeRequest = new RouteRequest();
 97                routeRequest.Credentials = new Credentials();
 98                routeRequest.Credentials.ApplicationId = ((ApplicationIdCredentialsProvider)map1.CredentialsProvider).ApplicationId;
 99    
100                //实例化一个路由节点
101                routeRequest.Options = new RouteOptions();
102                routeRequest.Options.RoutePathType = RoutePathType.Points;
103    
104                //将保存Geocode服务查询结果的变量赋给到Route服务的waypoints属性中
105                routeRequest.Waypoints = new ObservableCollection<RouteService.Waypoint>();
106                foreach (GeocodeResult result in results)
107                {
108                    routeRequest.Waypoints.Add(GeocodeResultToWaypoint(result));
109                }
110    
111                //向路由服务发送异步请求
112                routeService.CalculateRouteAsync(routeRequest);
113    
114            }
115    
116           /// <summary>
117        /// 解析Geocode服务返回的数据
118        /// </summary>
119        /// <param name="result"></param>
120        /// <returns></returns>
121            private Waypoint GeocodeResultToWaypoint(GeocodeResult result)
122            {
123                Waypoint waypoint = new Waypoint();
124                waypoint.Description = result.DisplayName;//显示名称
125                waypoint.Location = new Location();
126                waypoint.Location.Latitude = result.Locations[0].Latitude;//纬度
127                waypoint.Location.Longitude = result.Locations[0].Longitude;//精度
128                return waypoint;
129            }
130    
131           /// <summary>
132        /// 当CalculateRoute方法请求完成后的回调函数
133        /// </summary>
134        /// <param name="sender"></param>
135        /// <param name="e"></param>
136            private void routeService_CalculateRouteCompleted(object sender, RouteService.CalculateRouteCompletedEventArgs e)
137            {
138                try
139                {
140                    //如果路由服务成功返回来路线信息,就把路线绘制到地图上
141                    if ((e.Result.ResponseSummary.StatusCode == RouteService.ResponseStatusCode.Success) & (e.Result.Result.Legs.Count != 0))
142                    {
143                        //设置你想要绘制路线的信息
144                        Color routeColor = Colors.Red;
145                        SolidColorBrush routeBrush = new SolidColorBrush(routeColor);
146                        MapPolyline routeLine = new MapPolyline();
147                        routeLine.Locations = new LocationCollection();
148                        routeLine.Stroke = routeBrush;
149                        routeLine.Opacity = 0.6;
150                        routeLine.StrokeThickness = 5.0;
151    
152                        // 循环读取返回的路线信息
153                        foreach (Location p in e.Result.Result.RoutePath.Points)
154                        {
155                            Location location = new Location()
156                            {
157                                Longitude = p.Longitude,
158                                Latitude = p.Latitude
159                            };
160                            routeLine.Locations.Add(location);
161                        }
162                        // 增加一个地图图层来绘制路线
163                        MapLayer myRouteLayer = new MapLayer();
164                        map1.Children.Add(myRouteLayer);
165    
166                        //把路线添加到图层中来
167                        myRouteLayer.Children.Add(routeLine);
168    
169                        //遍历处理服务调用接口中的路程行程点,将各个行程点上绘制一个红色圆形标记
170                        foreach (GeocodeService.GeocodeResult gr in geocodeResults)
171                        {
172                            Ellipse point = new Ellipse();
173                            point.Width = 10;
174                            point.Height = 10;
175                            point.Fill = new SolidColorBrush(Colors.Red);
176                            point.Opacity = 0.65;
177                            Location location = new Location()
178                            {
179                                Latitude = gr.Locations[0].Latitude,
180                                Longitude = gr.Locations[0].Longitude
181                            };
182                            //将图层添加到地图制定的位置                   
183                            myRouteLayer.AddChild(point, location);
184                        }
185                        //包含整个绘制路线的矩形
186                        var routeModel = new RouteModel(e.Result.Result.RoutePath.Points);
187                        LocationRect rect = LocationRect.CreateLocationRect(routeModel.Locations);
188    
189                        //将路线显示在视图中间
190                        map1.SetView(rect);
191                    }
192                }
193                catch (Exception ex)
194                {
195                    MessageBox.Show("路由服务解析过程中出现错误.");
196                }
197            }
198        }
199      /// <summary>
200      /// 代表路线的数据模型
201      /// </summary>
202        public class RouteModel
203        {
204            private readonly LocationCollection _locations;
205    
206            /// <summary>
207         /// 得到这个路线的位置集合
208           /// </summary>
209            public ICollection<GeoCoordinate> Locations
210            {
211                get { return _locations; }
212            }
213    
214            /// <summary>
215         ///初始化该类型的一个新的实例
216         /// </summary>
217         /// <param name="locations">一个Loaction的集合</param>
218            public RouteModel(ICollection<Location> locations)
219            {
220                _locations = new LocationCollection();
221                foreach (Location location in locations)
222                {
223                    _locations.Add(location);
224                }
225            }
226        }
View Code

编译运行,我们输入出发点和终点,程序会首先调用地理编码服务计算出起点和终点的经纬度,然后把他们放在一个集合中,作为参数向路由功能服务发送请求,计算起点和终点的路线信息,最后显示在地图中,下面是程序运行的效果:

附:源码下载

  《Programming Windows Phone 7 Microsoft Silverlight Edition》

作者:晴天猪

出处:http://www.cnblogs.com/IPrograming

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

 

 

 

 

 

你可能感兴趣的:(windows,phone)