Windows 8 地理位置定位 4.根据经纬度计算地面两点间的距离

关于根据经纬度计算地面两点间距离的公式及推导可以参考我的另一篇博客http://www.cnblogs.com/chengyujia/archive/2013/01/13/2858484.html

本例依然只有一个页面

先上运行截图:

前台XAML代码:

复制代码
XAML
 1 <Page
 2     x:Class="Win8Location.DistanceAndSpeed"
 3     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 4     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 5     xmlns:local="using:Win8Location"
 6     xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
 7     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
 8     mc:Ignorable="d">
 9     <Page.Resources>
10         <x:Double x:Key="MyFontSize">25</x:Double>
11         <Style TargetType="TextBlock">
12             <Setter Property="FontSize" Value="{StaticResource MyFontSize}"/>
13             <Setter Property="IsTextSelectionEnabled" Value="True"/>
14         </Style>
15         <Style TargetType="Button">
16             <Setter Property="FontSize" Value="{StaticResource MyFontSize}"></Setter>
17             <Setter Property="FontWeight" Value="Light"></Setter>
18         </Style>
19     </Page.Resources>
20 
21     <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
22         <Grid.RowDefinitions>
23             <RowDefinition Height="auto"/>
24             <RowDefinition Height="*"/>
25         </Grid.RowDefinitions>
26         <StackPanel Orientation="Horizontal">
27             <Button x:Name="btnStartTracking" Content="开始定位并跟踪" Click="btnStartTracking_Click"/>
28             <Button x:Name="btnStopTracking" Content="停止位置跟踪" Click="btnStopTracking_Click" IsEnabled="False"/>
29             <Button x:Name="btnClear" Content="清屏" Click="btnClear_Click"/>
30         </StackPanel>
31         <ScrollViewer Grid.Row="1">
32             <TextBlock x:Name="txtMsg" TextWrapping="Wrap"/>
33         </ScrollViewer>
34     </Grid>
35 </Page>
复制代码

后台C#代码:

复制代码
C#
  1 using System;
  2 using System.Collections.Generic;
  3 using System.IO;
  4 using System.Linq;
  5 using System.Text;
  6 using Windows.Devices.Geolocation;
  7 using Windows.Foundation;
  8 using Windows.Foundation.Collections;
  9 using Windows.UI.Core;
 10 using Windows.UI.Xaml;
 11 using Windows.UI.Xaml.Controls;
 12 using Windows.UI.Xaml.Controls.Primitives;
 13 using Windows.UI.Xaml.Data;
 14 using Windows.UI.Xaml.Input;
 15 using Windows.UI.Xaml.Media;
 16 using Windows.UI.Xaml.Navigation;
 17 
 18 namespace Win8Location
 19 {
 20     public sealed partial class DistanceAndSpeed : Page
 21     {
 22         Geolocator geo = null;
 23         private double prevLongitude;
 24         private double prevLatitude;
 25         private double totalDistance;//(米)
 26         private DateTimeOffset prevTime;
 27         private TimeSpan totalTime = TimeSpan.Zero;
 28 
 29         public DistanceAndSpeed()
 30         {
 31             this.InitializeComponent();
 32         }
 33 
 34         async private void btnStartTracking_Click(object sender, RoutedEventArgs e)
 35         {
 36             btnStartTracking.IsEnabled = false;
 37             btnStopTracking.IsEnabled = true;
 38             if (geo == null)
 39             {
 40                 geo = new Geolocator();
 41             }
 42             if (geo != null)
 43             {
 44                 geo.StatusChanged += geo_StatusChanged;
 45                 try
 46                 {
 47                     Geoposition position = await geo.GetGeopositionAsync();
 48                     string msg = position.Coordinate.Timestamp + ">开始定位并跟踪\n";
 49                     msg += "当前经度:" + position.Coordinate.Longitude + "\n";
 50                     msg += "当前纬度:" + position.Coordinate.Latitude + "\n\n";
 51                     txtMsg.Text += msg;
 52                     prevLongitude = position.Coordinate.Longitude;
 53                     prevLatitude = position.Coordinate.Latitude;
 54                     prevTime = position.Coordinate.Timestamp;
 55                 }
 56                 catch (Exception ex)
 57                 {
 58                     txtMsg.Text += DateTime.Now + ">出错了:" + ex.Message + "\n\n";
 59                 }
 60                 geo.PositionChanged += geo_PositionChanged;
 61             }
 62         }
 63 
 64         async void geo_PositionChanged(Geolocator sender, PositionChangedEventArgs args)
 65         {
 66             Geoposition pos = args.Position;
 67             double currLong = pos.Coordinate.Longitude;
 68             double currLat = pos.Coordinate.Latitude;
 69             DateTimeOffset currTime = pos.Coordinate.Timestamp;
 70 
 71             double updateDistance = GetDistance(prevLongitude, prevLatitude, currLong, currLat);
 72             totalDistance += updateDistance;
 73             TimeSpan updateTime = currTime - prevTime;
 74             totalTime += updateTime;
 75 
 76             StringBuilder msg = new StringBuilder();
 77             msg.Append(currTime + "\n");
 78             msg.Append("当前经度:" + args.Position.Coordinate.Longitude + "\n");
 79             msg.Append("当前纬度:" + args.Position.Coordinate.Latitude + "\n");
 80             msg.Append("距上一个位置的距离(米):" + updateDistance.ToString("0") + "\n");
 81             msg.Append("距上一个位置经历的时间:" + updateTime.ToString(@"hh\:mm\:ss") + "\n");
 82             msg.Append("距上一个位置间的平均速度(米/秒):" + GetSpeed(updateDistance, updateTime).ToString("0") + "\n");
 83             msg.Append("已经历的总路程(米):" + totalDistance.ToString("0") + "\n");
 84             msg.Append("已经历的总时间:" + totalTime.ToString(@"hh\:mm\:ss") + "\n");
 85             msg.Append("已经历的总平均速度(米/秒):" + GetSpeed(totalDistance, totalTime).ToString("0") + "\n\n");
 86 
 87             await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
 88            {
 89                txtMsg.Text += msg;
 90            });
 91 
 92             prevLongitude = currLong;
 93             prevLatitude = currLat;
 94             prevTime = currTime;
 95         }
 96 
 97         async void geo_StatusChanged(Geolocator sender, StatusChangedEventArgs args)
 98         {
 99             string msg = DateTime.Now + ">定位器状态:" + args.Status + "\n\n";
100             await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
101             {
102                 txtMsg.Text += msg;
103             });
104         }
105 
106         private void btnStopTracking_Click(object sender, RoutedEventArgs e)
107         {
108             btnStartTracking.IsEnabled = true;
109             btnStopTracking.IsEnabled = false;
110             if (geo != null)
111             {
112                 txtMsg.Text += DateTime.Now + ">停止位置跟踪\n\n";
113                 geo.StatusChanged -= geo_StatusChanged;
114                 geo.PositionChanged -= geo_PositionChanged;
115             }
116         }
117 
118         /// <summary>
119         /// 根据经纬度计算地面两点间的距离
120         /// </summary>
121         /// <param name="prevLong">前一个点的经度</param>
122         /// <param name="prevLat">前一个点的纬度</param>
123         /// <param name="currLong">当前点的经度</param>
124         /// <param name="currLat">当前点的纬度</param>
125         /// <returns>两点间的距离(米)</returns>
126         private double GetDistance(double prevLong, double prevLat, double currLong, double currLat)
127         {
128             const double degreesToRadians = (Math.PI / 180.0);
129             const double earthRadius = 6371; // 地球半径平均值为6371千米
130 
131             var prevRadLong = prevLong * degreesToRadians;
132             var prevRadLat = prevLat * degreesToRadians;
133             var currRadLong = currLong * degreesToRadians;
134             var currRadLat = currLat * degreesToRadians;
135 
136             double cosX = Math.Cos(prevRadLat) * Math.Cos(currRadLat) * Math.Cos(prevRadLong - currRadLong) + Math.Sin(prevRadLat) * Math.Sin(currRadLat);
137             double X = Math.Acos(cosX);//两点与球心连线的夹角
138             double d = earthRadius * X * 1000;//单位转换为米
139             return d;
140         }
141 
142         private double GetSpeed(double distance, TimeSpan timeSpan)
143         {
144             double speed = distance / timeSpan.TotalSeconds;
145             return speed;
146         }
147 
148         private void btnClear_Click(object sender, RoutedEventArgs e)
149         {
150             txtMsg.Text = string.Empty;
151         }
152     }
153 }
复制代码

 

posted @   成宇佳  阅读(1986)  评论(1编辑  收藏  举报
编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?
点击右上角即可分享
微信分享提示