преобразовать долготу и широту в метры

Мне нужна функция, которая отображает позиции GPS в значения x / y, например:

getXYpos(GeoPoint relativeNullPoint, GeoPoint p){
   deltaLatitude=p.latitude-relativeNullPoint.latitude;
   deltaLongitude=p.longitude-relativeNullPoint.longitude;
   ...
   resultX=latitude (or west to east) distance in meters from p to relativeNullPoint
   resultY=longitude (or south to north) distance in meters from p to relativeNullPoint
}

Я видел некоторые реализации «расстояния двух гео-точек», но все они просто рассчитывают расстояние по воздуху. Я думаю, что deltaLongitude можно напрямую преобразовать в метры, но deltaLatitude зависит от долготы. кто-нибудь знает, как можно решить эту проблему?


person Simon    schedule 11.06.2010    source источник


Ответы (3)


Для начала, я думаю, у вас есть широта и долгота в обратном порядке. Долгота измеряет X, а широта - Y.

Широту легко превратить в расстояние с севера на юг. Мы знаем, что 360 градусов - это полный круг вокруг Земли через полюса, и это расстояние составляет 40008000 метров. Если вам не нужно учитывать ошибки из-за того, что Земля не является идеально сферической, формула будет deltaLatitude * 40008000 / 360.

Как вы и подозревали, самая сложная часть - это преобразование долготы в X. Поскольку это зависит от широты, вам нужно решить, какую широту вы собираетесь использовать - вы можете выбрать широту своего происхождения, широту вашего пункта назначения или какую-то произвольную точку между ними. Окружность на экваторе (0 широты) составляет 40075160 метров. Длина окружности на заданной широте будет пропорциональна косинусу, поэтому формула будет deltaLongitude * 40075160 * cos(latitude) / 360.

Изменить: ваш комментарий указывает на то, что у вас возникли проблемы с формулой долготы; Вы могли использовать градусы вместо радианов при вызове cos, это частая ошибка новичков. Чтобы убедиться в отсутствии двусмысленности, вот рабочий код на Python.

def asRadians(degrees):
    return degrees * pi / 180

def getXYpos(relativeNullPoint, p):
    """ Calculates X and Y distances in meters.
    """
    deltaLatitude = p.latitude - relativeNullPoint.latitude
    deltaLongitude = p.longitude - relativeNullPoint.longitude
    latitudeCircumference = 40075160 * cos(asRadians(relativeNullPoint.latitude))
    resultX = deltaLongitude * latitudeCircumference / 360
    resultY = deltaLatitude * 40008000 / 360
    return resultX, resultY

Я решил использовать широту relativeNullPoint для вычисления X. Это имеет то преимущество, что если вы конвертируете несколько точек с одинаковой долготой, они будут иметь одинаковый X; линии север-юг будут вертикальными.

Еще раз отредактируйте: Я должен был указать, что это очень простая формула, и вы должны знать ее ограничения. Очевидно, что Земля не плоская, поэтому любая попытка сопоставить ее с координатами XY потребует некоторых компромиссов. Формула, которую я вывел выше, работает лучше всего, когда область, которую вы конвертируете, достаточно мала, чтобы считать ее плоской, и где небольшую кривизну и непараллельность линий север-юг можно игнорировать. Есть целая наука, чтобы составить карту проекций; если вы хотите увидеть какие-то возможности, лучше всего начать с Википедии. Эта конкретная проекция известна как равнопрямоугольная проекция с некоторым добавленным масштабированием.

person Mark Ransom    schedule 11.06.2010
comment
хорошо, я попробовал это, и расчет широты очень точен :) но значения долготомера всегда имеют коэффициент от 1,3 до большого для тестирования широты im. Я думаю, что просто делить на этот коэффициент - не лучшая идея, потому что он, вероятно, будет отличаться для разных широт, может, окружность Земли должна быть рассчитана относительно текущей широты? - person Simon; 12.06.2010
comment
Я только что проверил некоторые из моих источников (например, ссылку, которую вы мне отправили geography.about.com/ library / faq / blqzcircumference.htm) и сам пытался рассчитать окружность земли: c = 2 * PI * r = 2 * PI * 6.378.137m = 40.075.017m, поэтому я думаю, что значение 40075160m, используемое везде, неверно .. я получил r от en.wikipedia.org/wiki/, так что наверное правильно. та же проблема для окружности полюсов: получается 39.940.653, что сильно отличается от значения 40.008.000 .. - person Simon; 08.09.2010
comment
хорошо, земля не является идеальной сферой;) я думаю, это объяснит отклоняющиеся значения, особенно значение для окружности полюса. а как рассчитывается окружность геоида? - person Simon; 08.09.2010
comment
@Sponge, я не знаю, как рассчитывались окружности - я просто доверяю своим источникам. Вы можете использовать другие значения, если они подходят для вашего приложения. Вы никогда не указывали требования к точности для вашего приложения - разница между двумя значениями окружности через полюса составляет менее 0,2%. - person Mark Ransom; 08.09.2010
comment
Что значит Земля не плоская? - person kubante; 27.04.2021

На jstott.me.uk есть библиотеки для PHP, Java и Javascript, которые делают это, например

var lld1 = new LatLng(40.718119, -73.995667); // New York
document.write("New York Lat/Long: " + lld1.toString() + "<br />");
var lld2 = new LatLng(51.499981, -0.125313);  // London
document.write("London Lat/Long: " + lld2.toString() + "<br />");
var d = lld1.distance(lld2);
document.write("Surface Distance between New York and London: " + d + "km");
person skaffman    schedule 11.06.2010

Функция уборки урожая - это то, что вам нужно. Проверьте это на подвижных типах. Есть Расстояние, Пеленг, Средняя точка. и другие вещи. Реализация Javascript работает очень хорошо.

ОБНОВЛЕНИЕ

Я нашел Java-реализацию функции Harvesine в другом вопросе stackoverflow

person user347594    schedule 11.06.2010