Обчислення нової довготи, широти від старих + n метрів


84

Я хочу створити 2 нові довготи та 2 нові широти на основі координати та відстані в метрах, я хочу створити гарний обмежувальний квадрат навколо певної точки. Це для частини міста та не більше ± 1500 метрів. Тому я не думаю, що кривизна землі повинна враховуватися.

Отже, у мене є 50.0452345(х) та 4.3242234(у), і я хочу знати х + 500 метрів, х - 500 метрів, у - 500 метрів, у + 500 метрів

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


Відповіді:


122

Кількість кілометрів на градус довготи становить приблизно

(2*pi/360) * r_earth * cos(theta)

де thetaширота в градусах і r_earthстановить приблизно 6378 км.

Кількість кілометрів на градус широти приблизно однакова в усіх місцях, приблизно

(2*pi/360) * r_earth = 111 km / degree 

Отже, ви можете зробити:

new_latitude  = latitude  + (dy / r_earth) * (180 / pi);
new_longitude = longitude + (dx / r_earth) * (180 / pi) / cos(latitude * pi/180);

Поки dxі dyмалі в порівнянні з радіусом землі, і ви не наближаєтесь до полюсів.


2
для перетворення градусів у радіани ви множите на py та ділите на 180. Але ви пишетеcos(latitude*180/pi)
josch

9
@josch: Хороший улов. Спробуйте наступного разу виправити відповідь, а не просто пропонувати виправлення. Багато людей просто копіюють та вставляють код із StackOverflow, вважаючи його правильним і готовим до використання.
Alex Essilfie,

4
гаразд, яким буде напрямок? Я маю на увазі, якщо я хочу додати 50 метрів, де він буде доданий? Вправо, вліво, вгору чи вниз?
Тушар Монірул

3
Земля не є абсолютно сферичною, тому використання одного значення для "радіуса" є наближенням. У Вікіпедії сказано, що "відстань від точок на поверхні до центру коливається від 6353 км до 6384 км". У ньому також сказано: "Кілька різних способів моделювання Землі як кулі, кожен із яких дає середній радіус 6 371 км", що вказує на ваше значення. Дійсно, якщо це виправлення є значним у вашому додатку, ви все одно повинні використовувати кращий алгоритм.
нібот

4
Для тих, хто не впевнений, що змінна r_earth повинна бути в метрах і дорівнювати приблизно 6371000,0
Amit

26

Прийнята відповідь абсолютно правильна і працює. Я зробив кілька налаштувань і перетворився на це:

double meters = 50;

// number of km per degree = ~111km (111.32 in google maps, but range varies
   between 110.567km at the equator and 111.699km at the poles)
// 1km in degree = 1 / 111.32km = 0.0089
// 1m in degree = 0.0089 / 1000 = 0.0000089
double coef = meters * 0.0000089;

double new_lat = my_lat + coef;

// pi / 180 = 0.018
double new_long = my_long + coef / Math.cos(my_lat * 0.018);

Сподіваюся, це теж допомагає.


27
0.0000089? Намагайтеся уникати магічних цифр, ніхто цього не зрозуміє.
scai

2
Це коротка версія діаметра землі та цифр пі в коді. не магія.
Нуман Карааслан,

16
Це все ще магія, якщо ніхто не знає, як відтворити це число. Чому б вам не вкласти повний розрахунок у свій код?
scai

13
1 градус на карті Google дорівнює 111,32 кілометра. 1 градус = 111,32 км. 1 км в градусах = 1 / 111,32 = 0,008983. 1 М в градусах = 0,000008983.
Мухаммед Азім,

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

18

Для широти:

var earth = 6378.137,  //radius of the earth in kilometer
    pi = Math.PI,
    m = (1 / ((2 * pi / 360) * earth)) / 1000;  //1 meter in degree

var new_latitude = latitude + (your_meters * m);

Для довготи робіть:

var earth = 6378.137,  //radius of the earth in kilometer
    pi = Math.PI,
    cos = Math.cos,
    m = (1 / ((2 * pi / 360) * earth)) / 1000;  //1 meter in degree

var new_longitude = longitude + (your_meters * m) / cos(latitude * (pi / 180));

Змінна your_metersможе містити позитивне або негативне значення.


8

Ви перевіряли: Як мені знайти ширину / довжину, яка знаходиться на х км на північ від даної ширини / довжину ?

Ці розрахунки в кращому випадку дратують, я зробив багато з них. Формула гаверсину буде вашим другом.

Деякі посилання: http://www.movable-type.co.uk/scripts/latlong.html


якщо ви працюєте на досить невеликій території, чи дійсно погано просто зробити широту -0,09 і довготу-0,0148, щоб отримати приблизно квадратний км площі?
Benjamin Udink ten Cate

Я б сказав, що це насправді не погано. Квадратний км на цьому рівні не буде спотворений кривизною Землі - поки Lat / Lng, з яким ви маєте справу, є десятковою.
Ryan Ternier

1
@BenjaminUdinktenCate Це спрацює в Амстердамі, але буде неточним в інших частинах світу. Виконання "довготи-0,0148" дасть вам лише 0,16 км до екватора.
нібот

3

Мені довелося витратити близько двох годин на розробку рішення @nibot, мені просто знадобився метод створення межового поля з урахуванням його центральної точки та ширини / висоти (або радіуса) в кілометрах:

Я не розумію рішення математично / географічно. Я змінив рішення (шляхом спроб і помилок), щоб отримати чотири координати:

Північ:

private static Position FromKmToNPosition(Position p, double km)
{
    double r_earth = 6378;
    var pi = Math.PI;
    var new_latitude = p.Lat + (km / r_earth) * (180 / pi);
    return new Position(new_latitude, p.Long);
}

Схід:

private static Position FromKmToEPosition(Position p, double km)
{
    double r_earth = 6378;
    var pi = Math.PI;
    var new_longitude = p.Long + (km / r_earth) * (180 / pi) / Math.Cos(p.Lat * pi / 180);
    return new Position(p.Lat, new_longitude);
}

Південь:

private static Position FromKmToSPosition(Position p, double km)
{
    double r_earth = 6378;
    var pi = Math.PI;
    var new_latitude = p.Lat - (km / r_earth) * (180 / pi);
    return new Position(new_latitude, p.Long);
}

Захід:

private static Position FromKmToWPosition(Position p, double km)
{
    double r_earth = 6378;
    var pi = Math.PI;
    var new_longitude = p.Long - (km / r_earth) * (180 / pi) / Math.Cos(p.Lat * pi / 180);
    return new Position(p.Lat, new_longitude);
}

1

якщо вам не потрібно бути дуже точним тоді: кожні 10000 метрів - це приблизно 0,1 для широти та довготи. наприклад, я хочу завантажити місця розташування 3000 метрів навколо point_A зі своєї бази даних:

double newMeter =  3000 * 0.1 / 10000;
double lat1 = point_A.latitude - newMeter;
double lat2 = point_A.latitude + newMeter;
double lon1 = point_A.longitude - newMeter;
double lon1 = point_A.longitude + newMeter;
Cursor c = mDb.rawQuery("select * from TABLE1  where lat >= " + lat1 + " and lat <= " + lat2 + " and lon >= " + lon1 + " and lon <= " + lon2 + " order by id", null);

0
public double MeterToDegree(double meters, double latitude)
{
    return meters / (111.32 * 1000 * Math.Cos(latitude * (Math.PI / 180)));
}

-1
var meters = 50;
var coef = meters * 0.0000089;
var new_lat = map.getCenter().lat.apply() + coef;
var new_long = map.getCenter().lng.apply() + coef / Math.cos(new_lat * 0.018);
map.setCenter({lat:new_lat, lng:new_long});

2
Будь ласка, додайте пояснення до своєї відповіді.
Анна

якщо ви хочете перемістити об'єкт карти приблизно на 50 метрів поблизу центру поточної карти, тоді ви можете використовувати цей код з +, - цифрами як заміною +50
Ейні Каве
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.