Мне нужна функция, которая отображает положения 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 зависит в Долготе. кто-либо знает, как эта проблема может быть решена?
Для начала, я думаю, у вас поменяны местами ваши широта и долгота . Долгота измеряет X, а широта - Y.
Широту легко превратить в расстояние с севера на юг. Мы знаем, что 360 градусов - это полный круг вокруг Земли через полюса, и это расстояние составляет 40008000 метров . Если вам не нужно учитывать ошибки из-за того, что Земля не является идеально сферической, формула будет deltaLatitude * 40008000/360
.
Как вы и подозревали, самая сложная часть - это преобразование долготы в X. Поскольку это зависит от широты, вам нужно решить, какую широту вы собираетесь использовать - вы можете выбрать широту своего происхождения, широту пункта назначения или какую-то произвольную точку между ними. Окружность на экваторе (0 широты) составляет 40075160 метров. Длина окружности на заданной широте будет пропорциональна косинусу, поэтому формула будет deltaLongitude * 40075160 * cos (широта) / 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 потребует некоторых компромиссов. Формула, которую я вывел выше, работает лучше всего, когда область, которую вы конвертируете, достаточно мала, чтобы считать ее плоской, и где небольшую кривизну и непараллельность линий север-юг можно игнорировать. Есть целая наука, чтобы составить карту проекций; Если вы хотите увидеть какие-то возможности, то лучше всего начать с Википедии . Эта конкретная проекция известна как Равнопрямоугольная проекция с некоторым добавленным масштабированием.
Функция Harvesine - это то, что вам нужно. Проверьте ее на moveable-types Там есть Distance, Bearing, Midpoint и другие вещи, реализация Javascript работает очень хорошо.
UPDATE
Я нашел Java-реализацию функции Harvesineв другом вопросе на stackoverflow
На 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");