2012-04-26 76 views
1

我正在使用MvvmCross框架构建跨平台(iOS,Android,WP7)应用程序。我正在使用MvxGeoLocationWatcher为我创建MvxGeoLocation对象,具有所需的Long,Lat,speed,heading等。使用MvvmCross框架时查找两个地理位置之间的距离

我需要找到两个位置之间的距离(如乌鸦)。在Android上,我致电fromLocation.distanceTo(toLocation)。在iOs上我会使用CLLocationDistance distance = [fromLocation distanceFromLocation:toLocation];

因此,这两个平台都使用该位置上的方法来计算距离,而这在MvxGeoLocation对象上当前不可用。

是否有计划很快添加它?如果不是,我将添加此功能的最佳方法是什么?

  1. 我会改变类本身,并提供平台特定的实现 - 可能是通过使它成为分类并将特定代码放入特定于平台的代码部分类中。或者也许使用扩展方法?
  2. 或者可能是最好的方法,它需要两个点并返回距离。在这种情况下,这个方法应该在MvxGeoLocationWatcher上吗?
  3. Calculate distance of two geo points in km c#添加计算算法在自己也许使用的东西,忘了使用该平台的具体实现
+0

我会去1 - 用一个扩展方法 - 那么我可能会发布这个作为一个Git样本或只是一个Gist – Stuart 2012-04-26 11:05:58

+0

其实我认为我误读了1 ...我会做的是写一个使用两个位置的扩展方法。我会亲自尝试保持mvvmcross的外部 - 例如在可选的附加库中,甚至只是作为代码片段。我正在考虑尽量保持mvvmcross尽可能轻 - 特别是为了避免不必要的连接器从monotouch膨胀。 – Stuart 2012-04-26 11:22:41

回答

3

目前mvvmcross故意不包含纬度/经度计算。

这样做的动机是:

  • 保持代码的大小下来 - 不是每一个应用程序需要这些计算
  • 进一步我在我的脑海里,一些计算更好的机库完成,而不是一般的C# - 例如一些多边形计算将受益于原生硬件加速。这种思想不仅适用于地理计算,也适用于其他地区 - 例如无论像图像处理这样的东西都是必需的,那么使用本地加速是有道理的。

这可能是mvvmcross在未来某个时间点提供了一个“官方”位置助手IoC插件(或一组扩展方法)。也许我们在http://xamarin.com/mobileapi左右建立一个IoC插件......我也很高兴其他人也可以构建和发布它们。

因此....

在一个非常简单的层面上,计算两个经纬度点之间的距离在C#中很容易实现 - 有很多相当简单的代码示例可用,例如http://www.movable-type.co.uk/scripts/latlong.html上的优秀javascript代码示例 - 还有一堆库在GitHub和CodePlex上像http://sharpmap.codeplex.com/

在RunSat(包括iPhone)我使用:

using System; 

namespace Cirrious.NewRunSat.Core.Models.Utils 
{ 
    public class DistanceCalcs 
    { 
     /// <summary> 
     /// Calculates the distance between two points of latitude and longitude. 
     /// Great Link - http://www.movable-type.co.uk/scripts/latlong.html 
     /// </summary> 
     /// <param name="lat1">First coordinate.</param> 
     /// <param name="long1">First coordinate.</param> 
     /// <param name="lat2">Second coordinate.</param> 
     /// <param name="long2">Second coordinate.</param> 
     /// <returns>the distance in metres</returns> 
     public static Double DistanceInMetres(double lat1, double lon1, double lat2, double lon2) 
     { 

      if (lat1 == lat2 && lon1 == lon2) 
       return 0.0; 

      var theta = lon1 - lon2; 

      var distance = Math.Sin(deg2rad(lat1)) * Math.Sin(deg2rad(lat2)) + 
          Math.Cos(deg2rad(lat1)) * Math.Cos(deg2rad(lat2)) * 
          Math.Cos(deg2rad(theta)); 

      distance = Math.Acos(distance); 
      if (double.IsNaN(distance)) 
       return 0.0; 

      distance = rad2deg(distance); 
      distance = distance * 60.0 * 1.1515 * 1609.344; 

      return (distance); 
     } 

     private static double deg2rad(double deg) { 
      return (deg * Math.PI/180.0); 
     } 

     private static double rad2deg(double rad) { 
      return (rad/Math.PI * 180.0); 
     } 
    } 
} 

此外,关于该片段的许可证CC署名 - 因为它从活字衍生 - http://www.movable-type.co.uk/scripts/latlong.html

我提供这些的formulæ&脚本免费使用和适应我从我收到 这么多的开源信息球 贡献。欢迎您在[ 归属许可证下使用这些脚本,没有任何明示或暗示的保证]仅提供 这些脚本,仅保留我的版权声明和对此 页面的引用。

+0

感谢您的答案@Stuart。你能否告诉我,你给出的片段是否更准确“将地球视为椭球体”而不是“将地球视为球体”? (即考虑到地球在赤道隆起)。非常感谢。 – 2012-04-26 13:20:37

+1

看起来像http://www.movable-type.co.uk/scripts/latlong.html就像Haversine /大圆圈方法......它适用于我的骑自行车和跑步 - 但在当地的地球是美丽的平坦;) – Stuart 2012-04-26 14:08:54