使用MvvmCross框架时查找两个Geo位置之间的距离

时间:2012-04-26 10:45:30

标签: windows-phone-7 xamarin.ios xamarin.android mvvmcross

我正在使用MvvmCross框架来构建跨平台(iOS,Android,WP7)应用程序。我正在使用MvxGeoLocationWatcher,它为我创建了MvxGeoLocation对象,具有所需的Long,Lat,speed,heading等。

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

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

有计划很快添加吗?如果不是,那么添加此功能的最佳方法是什么?

  1. 我是否会更改类本身并提供特定于平台的实现 - 可能是将其作为部分类并将特定代码放在特定于平台的代码分部类中。或者也许通过使用扩展方法?
  2. 或者也许最好的方法是拿两点并返回距离。在哪种情况下,此方法应该在MvxGeoLocationWatcher上?
  3. 在我自己中添加计算算法,或许使用来自Calculate distance of two geo points in km c#的内容并忘记使用特定于平台的实现

1 个答案:

答案 0 :(得分:3)

目前mvvmcross故意不包括lat / lng计算。

这样做的动机是:

  • 保持代码大小 - 不是每个应用都需要这些计算
  • 我还想到,本地库而不是通用C#可以更好地完成一些计算 - 例如一些多边形计算将受益于本机硬件加速。这种思想不仅适用于地理计算,也适用于其他领域 - 例如如果需要图像处理之类的东西,那么使用原生加速是有意义的。

mvvmcross可能会在未来的某个时刻提供“官方”位置助手IoC插件(或一组扩展方法)...也许我们在http://xamarin.com/mobileapi周围构建一个IoC插件......我也非常高兴其他人也可以构建和发布它们。

...所以

在一个非常简单的层面上,在C#中很容易计算出两个lat / lng点之间的距离 - 有很多相当简单的代码示例可用,例如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æ&amp;自由使用和改编的脚本作为我的   对我收到的开源信息领域的贡献   非常。欢迎您重复使用这些脚本[简单   提供归属许可证,不附带任何明示或暗示的保证   仅保留我的版权声明和对此的引用   页。