Подтвердить что ты не робот

Рассчитать фактическое расстояние, пройденное мобильным

Я хочу рассчитать фактическое расстояние, пройденное мобильным телефоном (iOS и Android). Я знаю через API карты google, мы можем найти оптимальное расстояние между двумя координатами. Но я хочу рассчитать расстояние, фактический путь мобильного (в транспортном средстве) покрыт.

Один из Algo, с которым я познакомился, сохраняет координаты через х секунд, скажем, через 5 или 10 секунд, а затем вычисляет расстояние между последовательными координатами, и сумма даст общее расстояние.

Я хочу обсудить лучший подход к его решению, есть ли лучшее решение?

Изменить: как работают приложения, такие как приложение Nike и Uber?

4b9b3361

Ответ 1

------------------ UPDATE --------------------- -

В вашем вопросе есть два основных момента.

1) получить координаты телефона (которые были обработаны в первой части этого ответа)

2) Рассчитайте реальное расстояние между этими двумя координатами

ИМХО, исчисление может быть выполнено веб-службой: только на основе расчета на расстоянии между двумя координатами может привести к действительно неправильному результату.

Вот пример такой веб-службы https://graphhopper.com/#directions-api

Демо-приложение: https://graphhopper.com/api/1/examples/

Он основан на потоке трафика (как и многие из этих инструментов) Поэтому вы должны быть осторожны с порядком координат потому что это может привести к неправильному результату.

Например, с двумя точками в правильном порядке: введите описание изображения здесь

Это дает хороший результат

Но если вы дадите неправильный порядок (с теми же координатами) введите описание изображения здесь

Для тех же координат это может привести к совершенно другому результату.

Итак, для координат ABCD (в хронологическом порядке) вам нужно сделать:

A- > B B- > C C- > D

Graphhopper кажется способным выполнять автономное вычисление расстояния

Вот lib на iOS и Android

https://github.com/graphhopper/graphhopper-ios/

https://github.com/graphhopper/graphhopper/tree/master/android

-------------------------------------------- -------

Вы должны определить, как работает ваше приложение. Передний план или фон?

Как сказано в других ответах, вам нужно получить позицию пользователя каждые X секунд. Затем вычислите расстояние.

Для iOS:

  • Вы можете использовать информацию на этом веб-сайте: http://mobileoop.com/

В нем говорится о отслеживании местоположения пользователя на iOS, когда приложение находится в фоновом режиме.

  1. Вот github: https://github.com/voyage11/Location

Затем вам нужно преобразовать точку благодаря

CLLocationDistance distance = [aCLLocationA distanceFromLocation:aCLLocationB];

Вы также можете проверить это (из apple doc) https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/LocationAwarenessPG/CoreLocation/CoreLocation.html:

Убедитесь, что у менеджеров местоположений pausesLocationUpdatesAutomatically установлено значение YES. Если для этого свойства установлено значение YES, Core Location приостанавливает обновление местоположения (и отключает аппаратное обеспечение местоположения) всякий раз, когда имеет смысл это делать, например, когда пользователь вряд ли будет двигаться в любом случае. (Core Location также приостанавливает обновления, когда он не может получить исправление местоположения.)

Назначьте соответствующее значение свойству activityType для менеджеров местоположений. Значение этого свойства помогает диспетчеру местоположения определить, когда безопасно приостанавливать обновления местоположения. Для приложения, которое предоставляет пошаговую автомобильную навигацию, установка свойства CLActivityTypeAutomotiveNavigation заставляет диспетчер местоположений приостанавливать события только тогда, когда пользователь не перемещает значительное расстояние в течение определенного периода времени.

CLActivityTypeAutomotiveNavigation застраховать вас, чтобы получить позицию, которая находится на дороге.

Для Android:

Это может легко помочь вам получить позицию пользователя через время Благодаря объекту TrackerSettings

TrackerSettings settings =
        new TrackerSettings()
            .setUseGPS(true)
            .setUseNetwork(true)
            .setUsePassive(true)
            .setTimeBetweenUpdates(30 * 60 * 1000)
            .setMetersBetweenUpdates(100);
  1. Чтобы найти расстояние между двумя точками на Android, вы можете проверить это: Получите расстояние между двумя точками геометрии

Обе ОС

В зависимости от позиции, выбранной каждые X секунд, вам необходимо сократить время между выбором данных местоположения для повышения точности.

Как вы хотите рассчитать расстояние в контексте дороги, настройте диспетчер местоположения в режиме навигации, этот режим дает координаты, которые находятся на дороге.

Наконец

Если вы хотите улучшить точность своего исчисления расстояния, вы можете использовать API Google: https://developers.google.com/maps/documentation/distance-matrix/intro

Установив правильный режим:

Дополнительные параметры

режим (по умолчанию для вождения) - указывает режим транспорта, который следует использовать при расчете расстояния. Допустимые значения и другие данные запроса указаны в разделе "Режимы перемещения" этого документа.

Ответ 2

Я работаю над чем-то похожим на Andoriod, но принципы для iOS одинаковы:

  • Для каждого образца GPS проверьте его точность. Если он превысит некоторый порог (скажем, 20 метров) - проигнорируйте его.
  • Помните, что даже если мобильное устройство является статическим, различные образцы GPS будут давать вам разные места в зависимости от точности. Автомобиль, долго стоящий на светофоре, покажет, что вы продвинулись на несколько десятков метров, поэтому добавьте метод, который определяет, является ли мобильный статичным или нет. Я реализовал это, читая акселерометр - если дельта между двумя показаниями, если больше некоторого порога - устройство движется. Если он слишком мал - игнорируйте GPS.
  • Если вы намерены использовать его в автомобиле, вы можете читать GPS каждый раз, когда у него новое чтение (в Android используется метод onLocationChanged). Если вы используете его для работы/ходьбы, учтите, что ваша скорость медленная - два последовательных чтения будут относительно близки, но из-за точности GPS вы можете получить довольно большое расстояние между ними. Его можно устранить, увеличив время между двумя последовательными показаниями или игнорируя некоторые из них (т.е. Учитывайте только каждое 10-е чтение).
  • Используйте формулу Haversine, чтобы рассчитать расстояние между двумя последовательными показаниями. В Android это можно сделать с помощью метода Location.distanceTo().

Вам придется протестировать его против одометра в вашем автомобиле и настроить пороговые значения для акселерометра.

Ответ 3

Вы можете достичь большей точности с помощью комбинации следующих стратегий.

  • Как уже упоминалось в других ответах, вы можете сохранить позицию мобильного телефона каждые X секунд (скажем, 10 секунд) с использованием GPS и измерения последовательное время между точками.

  • Также, когда пользователь совершает быстрые повороты, убедитесь, что используя значения магнитного датчика, поэтому в таком случае уменьшить "время между хранением позиции", чтобы сказать 1-2 секунды (потребуется для точности)

  • В качестве последнего шага используйте данные Карты (например, Карты Google и т.д.), чтобы убедиться вы правильно отслеживаетесь (если на дороге).

И затем суммируйте все значения, чтобы получить точное расстояние.

P.S. Я дал информацию об этих стратегиях, поскольку я не уверен в ее реализации в Android (или iOS).

Надеюсь, что это поможет:)

Ответ 4

4 года назад я только что сделал приложение под названием Landsurvayor, которое вычисляет фактическое расстояние двух географических точек, нарисованных на Карте Google. Я не знаю, что могло бы вам помочь или нет, но есть формула Формула Хаверсина, которая вычисляет фактическое расстояние между двумя географическими точками. Вы можете попробовать и посмотреть, полезно ли это для вас или нет. Ниже приведен пример кода формулы Хаверсина:

public double CalculationByDistance(double initialLat, double initialLong,
                            double finalLat, double finalLong){
int R = 6371; // km
double dLat = toRadians(finalLat-initialLat);
double dLon = toRadians(finalLong-initialLong);
lat1 = toRadians(lat1);
lat2 = toRadians(lat2);

double a = Math.sin(dLat/2) * Math.sin(dLat/2) +
        Math.sin(dLon/2) * Math.sin(dLon/2) * Math.cos(lat1) * Math.cos(lat2); 
double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); 
return R * c;
}

public double toRadians(deg) {
  return deg * (Math.PI/180)
}

Подробнее о формуле Хаверсина: https://en.wikipedia.org/wiki/Haversine_formula

Существует еще один простой встроенный подход Android SDK для вычисления расстояния между двумя латами, lng:

Location locationA = new Location("point A");     
locationA.setLatitude(latA); 
locationA.setLongitude(lngA);
Location locationB = new Location("point B");
locationB.setLatitude(latB); 
LocationB.setLongitude(lngB);
distance = locationA.distanceTo(locationB) ;

Надеюсь, это поможет вам.

Ответ 5

Если вы ищете точную (или почти точную) информацию о расстоянии, вам необходимо отслеживать пройденный путь, что означает проверку координат каждые несколько секунд (в зависимости от ожидаемой скорости движения). Вы можете сэкономить место, отбросив старые координаты после вычисления каждого сегмента и просто сохранить текущее пройденное расстояние.

Ответ 6

Android:: как рассчитать расстояние во время ходьбы в андроиде?

Существуют разные способы сделать это:

1.GPS: продолжайте добавлять расстояние GPS между двумя точками каждые X секунд (скажем, 10 секунд). Проверьте Android Location.distanceTo или distanceBetween. Проверьте My Tracks, это с открытым исходным кодом. GPS недоступен в помещении и будет иметь ошибку, если пользователь меняет направление очень часто (читайте каждые 1-2 секунды) 2.Аккелерометр: найдите код/​​библиотеку для определения шага с помощью акселерометра. Расстояние происходит от двойной интеграции ускорения, ошибки могут быть очень быстрыми. 3. Статический детектор: встроенный в Nexus 5. Google, возможно, позаботился об ошибках акселерометра. Это аппаратно вычислений, потребляет меньше батареи, но недоступно в большинстве трубки с даты.

Второй вариант кажется очень похожим на то, что вы предложили, и я думаю, что это лучший способ его достичь, поскольку iOS и Android откладываются в коде и в функциональности, поэтому лучший способ его достижения заключается в сохранении currentLocation и previousLocation в цикле while, который будет .sleep() и просто суммирует весь цикл как пройденное расстояние. больший вопрос - это, предположительно, приложение - приложение для летнего времени? это всего лишь небольшая функция внутри? как вы решаете, когда прекратить вычисление расстояния?

Ответ 7

Одной из проблем с использованием GPS-координат является то, что они (очевидно) не точны. Если вы путешествуете по прямой линии, координаты GPS могут показать вам движение по зигзагообразному пути, следовательно, возвращение на большее расстояние, чем истинное расстояние. Даже с хорошей точностью GPS эта ошибка может быть значительной. Использование меньших координат может привести к более точному вычислению или нет.

Что вам нужно - это способ сгладить траекторию GPS с учетом вашей требуемой точности (опять-таки компромисс).

Моя первая мысль состоит в том, чтобы разбить точки на группы и подстроить сегменты линии каждой группе (искать "линейную регрессию" ). Затем найдите, где каждая последовательная линейная пара перекрывается для определения каждого сегмента линии. Затем просто суммируйте длины сегментов линии.

Вы могли бы сгибать сегменты, но гораздо более интенсивно математически, и не могли бы дать лучший результат (и какую формулу кривой использовать?). Могут быть лучшие математические способы, о которых я не знаю.

Надеюсь, это поможет.

Ответ 8

Используйте GPS, чтобы получить лат-лон обоих мест и после того, как оба прошли его ниже метода. Он вернет расстояние в км

public static double getDistanceFromLatLonInKm(double lat1, double lon1,
        double lat2, double lon2) {



    double R = 6371; // Radius of the earth in km
    double dLat = deg2rad(lat2 - lat1); // deg2rad below
    double dLon = deg2rad(lon2 - lon1);
    double a = Math.sin(dLat / 2) * Math.sin(dLat / 2)
            + Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2))
            * Math.sin(dLon / 2) * Math.sin(dLon / 2);
    double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
    double d = R * c; // Distance in km


    return d;

}

public static double deg2rad(double deg) {
    return deg * (Math.PI / 180);
}

}

Ответ 9

Если точность критическая, вы можете использовать данные с акселерометра и гироскопа. Вы можете найти очень простую формулу для решения простой кинематической задачи, чтобы получить acc в глобальной оси. Чем вам просто нужно использовать интеграл дважды (сначала получить скорость, чем получить позицию). Просто чтобы показать другую перспективу.

Ответ 10

Регистрирует точки каждые x секунд (возможно, 2-3?) и использует формулу расстояния ниже для каждой зарегистрированной точки.

Distance = sqrt((x2−x1)^2+(y2−y1)^2)

Суммируйте их все, и вы получите расстояние