Перетворення від довготи \ широти до декартових координат


103

У мене є деякі точки, орієнтовані на землю, координати, задані як широта і довгота ( WGS-84 ).

Як я можу перетворити їх на декартові координати (x, y, z) з початком у центрі землі?


1
Чи вдалося вам перетворити довготу та широту WGS-84 в декартові координати ?. У мене також піднесення. Я спробував прийняту відповідь тут, але це не дає мені правильної відповіді. Я порівняв свої результати з цим веб-сайтом: apsalin.com/convert-geodetic-to-cartesian.aspx .
Ясмін

Відповіді:


47

Нещодавно я зробив щось подібне до цього, використовуючи "Формулу Гаверсина" за даними WGS-84, яка є похідною від "Закону Геверсина" з дуже задоволеними результатами.

Так, WGS-84 припускає, що Земля є еліпсоїдом, але я вважаю, що ви отримуєте лише приблизно 0,5% середньої помилки, використовуючи такий підхід, як "Формула Гаверсіна", що може бути прийнятною кількістю помилок у вашому випадку. Ви завжди будете мати деяку кількість помилок, якщо не будете говорити про відстань у кілька футів, і навіть тоді теоретично буде кривизна Землі ... Якщо вам потрібна більш жорстка перевірка сумісного підходу WGS-84 до "Формули Вінсенті".

Я розумію, звідки береться Starblue , але хороша інженерія програмного забезпечення часто стосується компромісів, тому все залежить від точності, яка вам потрібна для того, що ви робите. Наприклад, результат, розрахований за формулою "Відстань на Манхеттені" проти результату від "Формули відстані", може бути кращим для певних ситуацій, оскільки він обчислювально дешевший. Подумайте, "яка точка найближча?" сценарії, де не потрібно точне вимірювання відстані.

Щодо "Формули Гаверсина", то її легко реалізувати і приємно, оскільки вона використовує "сферичну тригонометрію" замість підходу, заснованого на "законі косинусів", який базується на двовимірній тригонометрії, тому ви отримуєте хороший баланс точності над складністю.

Джентльмени на ім'я Кріса Венеса мають чудовий веб-сайт за адресою http://www.movable-type.co.uk/scripts/latlong.html, який пояснює деякі цікаві вам концепції та демонструє різні програмні реалізації; це також має відповісти на ваше питання перетворення x / y.


1
0,5% помилка - 0,5% від чого? У контексті цього питання це може бути радіус землі, тому 0,5% може бути 30 км :)
MarkJ

2
Перевірили своє посилання. Цитата 0,5% - це помилка у великій відстані між двома точками, тому це питання не суворо відповідає. Я б подумав, що при перетворенні давньої довжини на декартові координати з початком у центрі Землі помилки від припущення сферичної землі можуть бути істотними. Не ясно, що запитувач хоче зробити з декартовими координатами. Чи просто зручніше працювати в них з якихось химерних причин, чи, можливо, це якась вимога щодо експорту даних? Якщо останнє, точність була б важливою.
MarkJ

130

Ось відповідь, яку я знайшов:

Просто для того, щоб визначення було завершеним, в декартовій системі координат:

  • вісь x проходить через довгу, lat (0,0), тому довгота 0 відповідає екватору;
  • вісь y проходить через (0,90);
  • і вісь z проходить через полюси.

Конверсія:

x = R * cos(lat) * cos(lon)

y = R * cos(lat) * sin(lon)

z = R *sin(lat)

Де R - приблизний радіус землі (наприклад, 6371 км).

Якщо ваші тригонометричні функції очікують радіани (які, ймовірно, роблять), вам потрібно спочатку перетворити свою довготу і широту в радіани. Вам, очевидно, потрібне десяткове представлення, а не градуси \ хвилини \ секунди (див., Наприклад, тут про конверсію).

Формула зворотного перетворення:

   lat = asin(z / R)
   lon = atan2(y, x)

asin - це, звичайно, дуга. читати про atan2 у Вікіпедії . Не забудьте перетворити назад з радіанів у градуси.

Ця сторінка містить c # код для цього (зауважте, що він сильно відрізняється від формул), а також деякі пояснення та приємну діаграму, чому це правильно,


17
-1 Це неправильно. Ви припускаєте, що земля - ​​це сфера, тоді як WGS-84 передбачає еліпсоїд.
starblue

42
@starblue: Я не впевнений, що ти можеш позначити дану відповідь "правильною" чи "неправильною". Сферичне наближення (для отримання координат x, y, z у стилі ECEF) з використанням наявних lat / lngs (на які посилається WGS-84) або "адекватне" для потреб оригінального афіші, або "не адекватне". Що стосується відстані та оцінок несучості, то я б ставлюся за те, що це просто перетворення добре. Якщо він запускає супутники, можливо, ні. Зрештою, сам WGS-84 «помиляється» ... в тому, що це не досконала модель земної поверхні; всі еліпсоїдальні моделі є наближеннями. Шкода, що ОП не сказала нам, що він намагається зробити.
Dan H

11
@Dan H Питання задає WGS-84, і якщо ви відповісте на щось інше, вам слід принаймні обговорити відмінності / помилки, на які ця відповідь не відповідає.
starblue

@ daphna-shezaf не може зробити зворотну конверсію ... Я також зробив задню частину від радіанів до градусів, але результат не той самий ...

дякую, витратьте годину, з’ясовуючи, чому це не працює, виявляється, я поміняв трохи cos (lat) та sin (lat)
aeroson

6

Теорія перетворення GPS(WGS84)на декартові координати https://en.wikipedia.org/wiki/Geographic_coordinate_conversion#From_geodetic_to_ECEF_coordinate

Далі - це те, що я використовую:

  • Довгота в GPS (WGS84) і декартових координатах однакова.
  • Широту потрібно перетворити на WGS 84 параметри еліпсоїда напівмагістральної осі 6378137 м, і
  • Зворотний вирівнювання становить 298,257223563.

Я додав код VB, який я написав:

Imports System.Math

'Input GPSLatitude is WGS84 Latitude,h is altitude above the WGS 84 ellipsoid

Public Function GetSphericalLatitude(ByVal GPSLatitude As Double, ByVal h As Double) As Double

        Dim A As Double = 6378137 'semi-major axis 
        Dim f As Double = 1 / 298.257223563  '1/f Reciprocal of flattening
        Dim e2 As Double = f * (2 - f)
        Dim Rc As Double = A / (Sqrt(1 - e2 * (Sin(GPSLatitude * PI / 180) ^ 2)))
        Dim p As Double = (Rc + h) * Cos(GPSLatitude * PI / 180)
        Dim z As Double = (Rc * (1 - e2) + h) * Sin(GPSLatitude * PI / 180)
        Dim r As Double = Sqrt(p ^ 2 + z ^ 2)
        Dim SphericalLatitude As Double =  Asin(z / r) * 180 / PI
        Return SphericalLatitude
End Function

Будь ласка, зауважте, що hце висота над WGS 84 ellipsoid.

Зазвичай GPSдасть нам Hвище MSLвисоти. MSLВисота повинна бути перетворена в висоту hвище WGS 84 ellipsoidза допомогою геопотенціальною моделі EGM96( Lemoine і співавт, 1998. ).
Це робиться шляхом інтерполяції сітки з файлу висоти геоїдів з просторовим дозволом 15 дугових хвилин.

Або якщо у вас є професіонал рівня, який GPSмає висоту H( мсл, висота вище середнього рівня моря ), а UNDULATIONтакож співвідношення між вибраним даним geoidі вихіднимellipsoid (m) даним з внутрішньої таблиці. ти можеш отриматиh = H(msl) + undulation

До XYZ за декартовими координатами:

x = R * cos(lat) * cos(lon)

y = R * cos(lat) * sin(lon)

z = R *sin(lat)

Яке значення R?
eych

4
Я думаю, що це радіус сфери, який становить 6371 км для землі.
Маттіас

5

Програмне забезпечення proj.4 забезпечує програму командного рядка, яка може здійснити перетворення, наприклад

LAT=40
LON=-110
echo $LON $LAT | cs2cs +proj=latlong +datum=WGS84 +to +proj=geocent +datum=WGS84

Він також надає API C . Зокрема, функція pj_geodetic_to_geocentricздійснюватиме перетворення без попереднього встановлення об'єкта проекції.


5

У python3.x це можна зробити за допомогою:

# Converting lat/long to cartesian
import numpy as np

def get_cartesian(lat=None,lon=None):
    lat, lon = np.deg2rad(lat), np.deg2rad(lon)
    R = 6371 # radius of the earth
    x = R * np.cos(lat) * np.cos(lon)
    y = R * np.cos(lat) * np.sin(lon)
    z = R *np.sin(lat)
    return x,y,z

3

Якщо ви хочете отримати координати на основі еліпсоїда, а не сфери, погляньте на сторінку http://en.wikipedia.org/wiki/Geodetic_system#From_geodetic_to_ECEF - це дає формули, а також константи WGS84, необхідні для перетворення. .

Формули там також враховують висоту відносно еталонної поверхні еліпсоїда (корисно, якщо ви отримуєте дані про висоту від пристрою GPS).


Оновлення, навіть якщо ви не опублікували тут вміст посилання.
Божевільний фізик

2

Навіщо реалізовувати те, що вже було впроваджено та перевірено?

У C #, наприклад, є NetTopologySuite, який є портом .NET пакету JT Topology.

Зокрема, у вас є сильний недолік у вашому розрахунку. Земля не є досконалою сферою, і наближення радіусу Землі може не вирішити її для точних вимірювань.

Якщо в деяких випадках прийнятно використовувати функції домашнього перекладу, ГІС є хорошим прикладом поля, в якому набагато переважніше використовувати надійну, перевірену тестом бібліотеку.


1
+1. Використання надійної бібліотеки точніше, ніж функція домашнього перекладу, а також простіше .
MarkJ

5
Яким чином NetTopologySuite перетворюється з тривалого / пізнього в декартоване?
vinayan

1
NTS не включає можливості перетворення координат, можливо, вам потрібен Proj.NET projnet.codeplex.com
D_Guidi

6
Смішна відповідь навіть не забезпечує можливість конверсії.
Мотес

1
Coordinate[] coordinates = new Coordinate[3];
coordinates[0] = new Coordinate(102, 26);
coordinates[1] = new Coordinate(103, 25.12);
coordinates[2] = new Coordinate(104, 16.11);
CoordinateSequence coordinateSequence = new CoordinateArraySequence(coordinates);

Geometry geo = new LineString(coordinateSequence, geometryFactory);

CoordinateReferenceSystem wgs84 = DefaultGeographicCRS.WGS84;
CoordinateReferenceSystem cartesinaCrs = DefaultGeocentricCRS.CARTESIAN;

MathTransform mathTransform = CRS.findMathTransform(wgs84, cartesinaCrs, true);

Geometry geo1 = JTS.transform(geo, mathTransform);

Чи змогли б ви допрацювати? Я створив просту програму, яка дозволяє перетворити єдину координату за допомогою вашого підходу. Він завжди виходить з ладу, хоча розміри джерела (2) і розміри цілі (3) відрізняються, внаслідок чого винятокjava.lang.IllegalArgumentException: dimension must be <= 3
oschrenk

Гммм ... я трохи подивився на JTS. Лінії вгору і включаючи новий LineString () виглядають як JTS. Але я не бачу речей CRS і Transform в JTS. Отже: вони там і я їх пропускаю? Були там і вилучені в 1.12? Або: це інша бібліотека?
День Н

0

Це можна зробити так на Java.

public List<Double> convertGpsToECEF(double lat, double longi, float alt) {

    double a=6378.1;
    double b=6356.8;
    double N;
    double e= 1-(Math.pow(b, 2)/Math.pow(a, 2));
    N= a/(Math.sqrt(1.0-(e*Math.pow(Math.sin(Math.toRadians(lat)), 2))));
    double cosLatRad=Math.cos(Math.toRadians(lat));
    double cosLongiRad=Math.cos(Math.toRadians(longi));
    double sinLatRad=Math.sin(Math.toRadians(lat));
    double sinLongiRad=Math.sin(Math.toRadians(longi));
    double x =(N+0.001*alt)*cosLatRad*cosLongiRad;
    double y =(N+0.001*alt)*cosLatRad*sinLongiRad;
    double z =((Math.pow(b, 2)/Math.pow(a, 2))*N+0.001*alt)*sinLatRad;

    List<Double> ecef= new ArrayList<>();
    ecef.add(x);
    ecef.add(y);
    ecef.add(z);

    return ecef;


}

що таке параметр alt?
баліман

висоту, що ти тут навіть робиш, якщо не знаєш, як працює GPS;)
MushyPeas
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.