Розрахунок відстані між двома географічними місцями


77

просимо пролити світло на цю ситуацію

Зараз у мене є два масиви, що мають широту та довготу найближчих місць, а також мають широту та довжину розташування користувача, тепер я хочу розрахувати відстань між місцезнаходженням користувача та найближчими місцями та хочу показати їх у списку.

Я знаю, що існує метод розрахунку відстані як

public static void distanceBetween (double startLatitude, double startLongitude, double endLatitude, double endLongitude, float[] results);

Зараз проблема полягає в тому, як передавати ці два масиви, що мають сусідні широту та довготу, у цьому методі та отримати масив відстаней.


перевірте це посилання: stackoverflow.com/questions/5739734/… Сподіваюся, це допоможе вам.
Дінеш Шарма

дякую за відповідь, але я хочу розрахувати відстань, використовуючи вищезазначений метод.
Сонячно

поясніть, технічно ви надали нам лише підпис методу, якого недостатньо для того, щоб знати, де можна знайти документацію до методу. Спробуйте додати інформацію про вміщуючий клас
Marmoy

Припинити використання distanceTo , тому що retourns неправильних значень: stackoverflow.com/questions/30664031 / ...
Karamsa

@Karamsa, але у вашому посиланні описано, що він працює правильно.
CoolMind

Відповіді:


190

http://developer.android.com/reference/android/location/Location.html

Подивіться вдалину

Повертає приблизну відстань у метрах між цим місцем і даним місцем. Відстань визначається за допомогою еліпсоїда WGS84.

або відстань Між

Обчислює приблизну відстань у метрах між двома місцями, а також за бажанням початковий і кінцевий підшипники найкоротшого шляху між ними. Відстань і підшипники визначаються за допомогою еліпсоїда WGS84.

Ви можете створити об'єкт Location з широти та довготи:

Location locationA = new Location("point A");

locationA.setLatitude(latA);
locationA.setLongitude(lngA);

Location locationB = new Location("point B");

locationB.setLatitude(latB);
locationB.setLongitude(lngB);

float distance = locationA.distanceTo(locationB);

або

private double meterDistanceBetweenPoints(float lat_a, float lng_a, float lat_b, float lng_b) {
    float pk = (float) (180.f/Math.PI);

    float a1 = lat_a / pk;
    float a2 = lng_a / pk;
    float b1 = lat_b / pk;
    float b2 = lng_b / pk;

    double t1 = Math.cos(a1) * Math.cos(a2) * Math.cos(b1) * Math.cos(b2);
    double t2 = Math.cos(a1) * Math.sin(a2) * Math.cos(b1) * Math.sin(b2);
    double t3 = Math.sin(a1) * Math.sin(b1);
    double tt = Math.acos(t1 + t2 + t3);
   
    return 6366000 * tt;
}

Чи дає це відстань між двома місцями дорогою?
Харша М.В.

2
ні, це повертає переміщення (найкоротша відстань між двома точками)
Зеешан Чаудхрі,

2
float pk = (float) (180/3.14169);- невелика орфографічна помилка, це не Pi ... вона повинна бути 3.141 5 9 або Math.PIвикористана (також Mathзамість класу застаріла FloatMath). 57 голосів проти і ніхто не помітив? : D
snachmsm

Хтось підтверджує, чи locationA.distanceTo(locationB)бере до уваги висоту над рівнем моря?
Secret Squirrel

2
Для чого призначений другий блок коду? Чому б вам просто не використовувати Location. distanceBetween()?
spaaarky21,

16

Спробуйте цей код. тут ми маємо два значення довготи та широти, а функція selected_location.distanceTo (near_locations) повертає відстань між цими місцями в метрах.

Location selected_location=new Location("locationA");
            selected_location.setLatitude(17.372102);
            selected_location.setLongitude(78.484196);
Location near_locations=new Location("locationB");
            near_locations.setLatitude(17.375775);
            near_locations.setLongitude(78.469218);
double distance=selected_location.distanceTo(near_locations);

тут "відстань" - це відстань між місцем розташування А і місцем розташування В (у метрах)


3

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

distanceBetween()Наскільки я розумію, це для далеких місць, його вихід - еліпсоїд WGS84.


Чи можете ви підказати, яка з них надає точну відстань?
Пареш Маяні

3
    private static Double _MilesToKilometers = 1.609344;
    private static Double _MilesToNautical = 0.8684;


    /// <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="coordinate1">First coordinate.</param>
    /// <param name="coordinate2">Second coordinate.</param>
    /// <param name="unitsOfLength">Sets the return value unit of length.</param>
    public static Double Distance(Coordinate coordinate1, Coordinate coordinate2, UnitsOfLength unitsOfLength)
    {

        double theta = coordinate1.getLongitude() - coordinate2.getLongitude();
        double distance = Math.sin(ToRadian(coordinate1.getLatitude())) * Math.sin(ToRadian(coordinate2.getLatitude())) +
                       Math.cos(ToRadian(coordinate1.getLatitude())) * Math.cos(ToRadian(coordinate2.getLatitude())) *
                       Math.cos(ToRadian(theta));

        distance = Math.acos(distance);
        distance = ToDegree(distance);
        distance = distance * 60 * 1.1515;

        if (unitsOfLength == UnitsOfLength.Kilometer)
            distance = distance * _MilesToKilometers;
        else if (unitsOfLength == UnitsOfLength.NauticalMiles)
            distance = distance * _MilesToNautical;

        return (distance);

    }

1

distanceTo дасть вам відстань у метрах між двома даними розташуванням ej target.distanceTo (пункт призначення).

distanceBetween також дасть вам відстань, але вона буде зберігати відстань у масиві з плаваючою точкою (результати [0]). у документі сказано, що якщо результати мають довжину 2 або більше, початковий підшипник зберігається в результатах [1]. Якщо результати мають довжину 3 або більше, кінцевий підшипник зберігається в результатах [2]

сподіваюся, що це допомагає

я використав distanceTo, щоб отримати відстань від точки A до B, я думаю, що це шлях.


0
public double distance(Double latitude, Double longitude, double e, double f) {
        double d2r = Math.PI / 180;

        double dlong = (longitude - f) * d2r;
        double dlat = (latitude - e) * d2r;
        double a = Math.pow(Math.sin(dlat / 2.0), 2) + Math.cos(e * d2r)
                * Math.cos(latitude * d2r) * Math.pow(Math.sin(dlong / 2.0), 2)
        double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
        double d = 6367 * c;
                return d;

    }

0

Я хотів реалізувати це, я закінчив читати сторінку Вікіпедії за формулою відстані Великого кола , оскільки жоден код був недостатньо читабельним, щоб я міг використовувати його як основу.

Приклад C #

    /// <summary>
    /// Calculates the distance between two locations using the Great Circle Distance algorithm
    /// <see cref="https://en.wikipedia.org/wiki/Great-circle_distance"/>
    /// </summary>
    /// <param name="first"></param>
    /// <param name="second"></param>
    /// <returns></returns>
    private static double DistanceBetween(GeoLocation first, GeoLocation second)
    {
        double longitudeDifferenceInRadians = Math.Abs(ToRadians(first.Longitude) - ToRadians(second.Longitude));

        double centralAngleBetweenLocationsInRadians = Math.Acos(
            Math.Sin(ToRadians(first.Latitude)) * Math.Sin(ToRadians(second.Latitude)) +
            Math.Cos(ToRadians(first.Latitude)) * Math.Cos(ToRadians(second.Latitude)) *
            Math.Cos(longitudeDifferenceInRadians));

        const double earthRadiusInMeters = 6357 * 1000;

        return earthRadiusInMeters * centralAngleBetweenLocationsInRadians;
    }

    private static double ToRadians(double degrees)
    {
        return degrees * Math.PI / 180;
    }
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.