2012-04-26 3 views
1

Я использую структуру MvvmCross для создания приложения с кросс-платформой (iOS, Android, WP7). Я использую MvxGeoLocationWatcher, который создает для меня объекты MvxGeoLocation с требуемыми длинными, латскими, скоростными, заголовками и т. Д.Поиск расстояния между двумя географическими местоположениями при использовании рамки 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

+0

На самом деле, я думаю, что неправильно прочитал 1 ... что бы я сделал, это написать который использует два местоположения. Я лично попытаюсь сохранить это внешнее по отношению к mvvmcross - например. в дополнительной библиотеке дополнений или даже в виде фрагмента кода. Я думаю о попытке сохранить mvvmcross как можно более легким - особенно, чтобы избежать ненужного линкера, раздутого от monotouch. – Stuart

ответ

3

В настоящее время mvvmcross намеренно не включены расчеты лат/LNG.

Мотивации для этого была:

  • , чтобы сохранить размер коды вниз - не каждое приложение нуждается в этих расчетах
  • дальше у меня в виде, что некоторые вычисления лучше сделаны собственными библиотеками, а не общих C# - например некоторые вычисления полигонов выиграют от встроенного аппаратного ускорения. Этот тип мысли существует не только для геоиндуцирования, но и для других областей - например, любые вещи, такие как манипуляция изображения, требуются, то использование собственного ускорения имеет смысл.

Возможно, что mvvmcross предоставляет «официальный» вспомогательный плагин IOC для размещения (или набор методов расширения) в какой-то момент в будущем ... например. возможно, что мы построим плагин IoC вокруг http://xamarin.com/mobileapi ... и я также очень рад за то, что другие тоже строят и публикуют их.

Итак ....

На очень простом уровне, вы можете легко выбрать расстояние между двумя точками lat/lng на C# - есть кучи довольно простого кода, доступные как отличные javascript, на http://www.movable-type.co.uk/scripts/latlong.html - и есть кучи библиотек на 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. Можете ли вы рассказать мне, является ли приведенный вами фрагмент более точным «относиться к Земле как к эллипсоиду», а не «относиться к Земле как к сфере»? (т. е. он учитывает, что Земля выпучивается на экваторе). Большое спасибо. –

+1

смотрит на http://www.movable-type.co.uk/scripts/latlong.html, как это метод Haversine/большой круг ... он хорошо работает для моих поездок на велосипеде и работает - но тогда локально земля довольно квартира ;) – Stuart

Смежные вопросы