Расчет новой долготы, широты из старых + n метров

86

Я хочу создать 2 новые долготы и 2 новые широты на основе координаты и расстояния в метрах, я хочу создать красивую ограничивающую рамку вокруг определенной точки. Это для части города и максимум ± 1500 метров. Поэтому я не думаю, что нужно принимать во внимание кривизну Земли.

Итак, у меня есть 50.0452345(x) и 4.3242234(y), и я хочу знать x + 500 метров, x - 500 метров, y - 500 метров, y + 500 метров.

Я нашел много алгоритмов, но почти все, похоже, имеют дело с расстоянием между точками.

Бенджамин Удинк тен Кейт
источник

Ответы:

125

Количество километров на градус долготы составляет примерно

(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 и cos(latitude*180/pi)
делите
9
@josch: Хороший улов. Попытайтесь исправить ответ в следующий раз вместо того, чтобы просто предлагать исправление. Многие люди просто копируют и вставляют код из StackOverflow, считая его правильным и готовым к использованию.
Alex Essilfie 04
4
хорошо, в каком направлении будет? Я имею ввиду, если я хочу добавить 50 метров, где это будет добавлено? Вправо, влево, вверх или вниз?
Тушар Монирул
3
Земля не является идеально сферической, поэтому использование одного значения для «радиуса» является приблизительным. Википедия говорит, что «расстояние от точек на поверхности до центра колеблется от 6 353 км до 6 384 км». В нем также говорится: «Каждый из нескольких способов моделирования Земли как сферы дает средний радиус 6 371 км», что указывает на вашу ценность. На самом деле, если это исправление значимо для вашего приложения, вам все равно следует использовать лучший алгоритм.
nibot
5
Для тех, кто не уверен, что переменная r_earth должна быть в метрах и равняться примерно 6371000.0
Амит
30

Принятый ответ совершенно правильный и работает. Я сделал некоторые настройки и превратился в это:

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
Это сокращенная версия диаметра земли и числа Пи в коде. не волшебство.
Нуман Карааслан
17
Это все еще волшебство, если никто не знает, как воспроизвести это число. Почему бы вам не включить полный расчет в свой код?
scai
13
1 градус на карте Google равен 111,32 километру. 1 градус = 111,32 км. 1 км в градусах = 1 / 111,32 = 0,008983. 1M в градусах = 0,000008983.
Мухаммад Азим
7
Вы должны были оставить комментарий в своем ответе, добавление его в комментарии бесполезно.
chutsu
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может содержать положительное или отрицательное значение.

ssten
источник
9

Вы проверили: как мне найти широту / долготу, которая находится на x км к северу от заданной широты / долготы ?

Эти расчеты в лучшем случае раздражают, я их много проделал. Формула гаверсина станет вашим другом.

Некоторая ссылка: http://www.movable-type.co.uk/scripts/latlong.html

Райан Тернье
источник
Если вы работаете на довольно небольшой площади, действительно ли плохо просто задать широту 0,09 и долготу 0,0148, чтобы получить площадь примерно квадратного километра?
Benjamin Udink ten Cate
Я бы сказал, что это не так уж и плохо. Квадратные километры на этом уровне не будут искажены кривизной Земли - пока широта и долгота, с которыми вы имеете дело, являются десятичными.
Райан Тернье
1
@BenjaminUdinktenCate Это будет работать в Амстердаме, но будет неточным в других частях мира. Выполнение «долготы-0,0148» даст вам всего около 0,16 км на экваторе.
nibot
4

Мне пришлось потратить около двух часов, чтобы разработать решение с помощью @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);
}
mshwf
источник
1

если нет необходимости быть очень точным: каждые 10000 метров составляют примерно 0,1 для широты и долготы. например, я хочу загрузить местоположения на 3000 метров вокруг точки_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);
farhad.kargaran
источник
0
public double MeterToDegree(double meters, double latitude)
{
    return meters / (111.32 * 1000 * Math.Cos(latitude * (Math.PI / 180)));
}
M Komaei
источник
-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
Eyni Kave