преобразовать широту долготы в метры - PullRequest
8 голосов
/ 11 июня 2010

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

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 зависит от долготы.Кто-нибудь знает, как можно решить эту проблему?

Ответы [ 3 ]

18 голосов
/ 11 июня 2010

Для начала, я думаю, у вас есть широта и долгота в обратном направлении. Меры долготы 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

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

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

2 голосов
/ 11 июня 2010

Функция Harvesine - это то, что вам нужно.Проверьте это на moveable-types Есть реализация Javascript с расстоянием, азимутом, средней точкой и другими вещами.

ОБНОВЛЕНИЕ

Я обнаружил реализацию Java функции Харвесина в другом вопросе стекопотока

1 голос
/ 11 июня 2010

На 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");
...