Chuyển đổi từ kinh độ \ vĩ độ sang tọa độ Descartes


103

Tôi có một số điểm tọa độ trung tâm trái đất được cung cấp dưới dạng vĩ độ và kinh độ ( WGS-84 ).

Làm cách nào để chuyển đổi chúng sang tọa độ Descartes (x, y, z) với điểm gốc là tâm trái đất?


1
Bạn đã quản lý để chuyển đổi kinh độ và vĩ độ WGS-84 thành tọa độ Descartes chưa ?. Tôi cũng có độ cao. Tôi đã thử câu trả lời được chấp nhận ở đây, nhưng nó không cho tôi câu trả lời đúng. Tôi đã so sánh kết quả của mình với trang web này: apsalin.com/convert-geodetic-to-cartesian.aspx .
Yasmin

Câu trả lời:


46

Gần đây tôi đã làm một việc tương tự như vậy bằng cách sử dụng "Công thức Haversine" trên dữ liệu WGS-84, là một dẫn xuất của "Định luật Haversines" với kết quả rất hài lòng.

Có, WGS-84 giả định Trái đất là một ellipsoid, nhưng tôi tin rằng bạn chỉ nhận được sai số trung bình khoảng 0,5% khi sử dụng phương pháp như "Công thức Haversine", đây có thể là mức sai số chấp nhận được trong trường hợp của bạn. Bạn sẽ luôn có một số sai sót trừ khi bạn đang nói về khoảng cách vài feet và thậm chí sau đó về mặt lý thuyết là độ cong của Trái đất ... Nếu bạn yêu cầu cách tiếp cận tương thích với WGS-84 khắt khe hơn, hãy kiểm tra "Công thức Vincenty."

Tôi hiểu starblue đến từ đâu, nhưng kỹ thuật phần mềm tốt thường là đánh đổi, vì vậy tất cả phụ thuộc vào độ chính xác mà bạn yêu cầu cho những gì bạn đang làm. Ví dụ: kết quả được tính từ "Công thức khoảng cách Manhattan" so với kết quả từ "Công thức khoảng cách" có thể tốt hơn trong một số trường hợp nhất định vì nó ít tốn kém hơn về mặt tính toán. Hãy suy nghĩ "điểm nào là gần nhất?" tình huống mà bạn không cần đo khoảng cách chính xác.

Về vấn đề, "Công thức Haversine" rất dễ thực hiện và hay vì nó sử dụng "Lượng giác hình cầu" thay vì cách tiếp cận dựa trên "Định luật Cosin" dựa trên lượng giác hai chiều, do đó bạn sẽ có được sự cân bằng tốt về độ chính xác quá phức tạp.

Một quý ông tên là Chris Veness có một trang web tuyệt vời tại http://www.movable-type.co.uk/scripts/latlong.html giải thích một số khái niệm mà bạn quan tâm và thể hiện các triển khai có lập trình khác nhau; điều này cũng sẽ trả lời câu hỏi chuyển đổi x / y của bạn.


1
Lỗi 0,5% - 0,5% của cái gì? Trong bối cảnh của câu hỏi này nó có thể là bán kính của trái đất, vì vậy 0,5% có thể là 30 km :)
MarkJ

2
Đã kiểm tra liên kết của bạn. Phần trích dẫn 0,5% dành cho sai số trong khoảng cách vòng tròn lớn giữa hai điểm, do đó không hoàn toàn phù hợp với câu hỏi này. Tôi sẽ nghĩ khi chuyển đổi vĩ độ sang tọa độ Descartes với gốc tọa độ tại tâm trái đất, các sai số khi giả định một trái đất hình cầu có thể rất đáng kể. Không rõ người hỏi muốn làm gì với tọa độ Descartes. Hoặc nó chỉ thuận tiện hơn khi làm việc với chúng vì một số lý do kỳ lạ, hoặc có lẽ đó là một số yêu cầu cho việc xuất dữ liệu? Nếu sau này, độ chính xác sẽ rất quan trọng.
MarkJ

130

Đây là câu trả lời tôi đã tìm thấy:

Chỉ để làm cho định nghĩa hoàn chỉnh, trong hệ tọa độ Descartes:

  • trục x đi qua long, vĩ (0,0), do đó kinh độ 0 gặp xích đạo;
  • trục y đi qua (0,90);
  • và trục z đi qua các cực.

Sự chuyển đổi là:

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

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

z = R *sin(lat)

Trong đó R là bán kính gần đúng của trái đất (ví dụ 6371 km).

Nếu các hàm lượng giác của bạn mong đợi radian (mà chúng có thể làm như vậy), trước tiên bạn sẽ cần chuyển đổi kinh độ và vĩ độ của mình sang radian. Rõ ràng bạn cần một biểu diễn thập phân, không phải độ \ phút \ giây (xem ví dụ: ở đây về chuyển đổi).

Công thức cho chuyển đổi ngược:

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

asin tất nhiên là cung sin. đọc về atan2 trong wikipedia . Đừng quên chuyển đổi ngược lại từ radian sang độ.

Trang này cung cấp mã c # cho điều này (lưu ý rằng nó rất khác với các công thức), và cũng có một số giải thích và sơ đồ đẹp về lý do tại sao điều này đúng,


17
-1 Điều này là sai. Bạn đang giả định trái đất là một hình cầu, trong khi WGS-84 giả sử một ellipsoid.
starblue,

42
@starblue: Tôi không chắc bạn có thể gắn nhãn câu trả lời đã cho là "đúng" hay "sai". Phép tính gần đúng hình cầu (để có được các dây x, y, z kiểu ECEF) bằng cách sử dụng các vĩ độ có sẵn (được tham chiếu đến WGS-84) là "đủ" cho nhu cầu của người đăng ban đầu hoặc "không đủ". Đối với các ước tính về khoảng cách và vòng bi, tôi cá rằng chuyển đổi đơn giản này là ổn. Nếu anh ta đang phóng vệ tinh, có lẽ không. Rốt cuộc, bản thân WGS-84 đã "sai" ... ở chỗ nó không phải là một mô hình hoàn hảo của bề mặt trái đất; tất cả các mô hình ellipsoidal đều là gần đúng. Thật tệ là OP đã không cho chúng tôi biết anh ấy đang cố gắng làm gì.
Dan H

11
@Dan H Câu hỏi yêu cầu cho WGS-84 và nếu bạn trả lời câu hỏi khác, ít nhất bạn nên thảo luận về sự khác biệt / lỗi, câu trả lời này không.
starblue

@ Daphna-shezaf không thể thực hiện chuyển đổi trở lại ... Tôi đã làm cũng là trở lại từ radian sang độ, nhưng kết quả là không giống nhau ...

cảm ơn bạn, chi tiêu giờ tìm ra lý do tại sao nó không làm việc, lượt ra tôi hoán đổi một số cos (lat) và sin (lat)
aeroson

6

Lý thuyết chuyển đổi GPS(WGS84)sang tọa độ Descartes https://en.wikipedia.org/wiki/Geographic_coosystem_conversion#From_geodetic_to_ECEF_coosystem

Sau đây là những gì tôi đang sử dụng:

  • Kinh độ trong GPS (WGS84) và tọa độ Descartes là giống nhau.
  • Vĩ độ cần được chuyển đổi bởi WGS 84 tham số ellipsoid bán trục chính là 6378137 m và
  • Đối ứng của dẹt là 298,257223563.

Tôi đã đính kèm mã VB mà tôi đã viết:

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

Xin lưu ý rằng hđộ cao là trên WGS 84 ellipsoid.

Thông thường GPSsẽ cho chúng ta chiều cao Htrên MSL. Các MSLchiều cao phải được chuyển đổi sang chiều cao hphía trên WGS 84 ellipsoidbằng cách sử dụng các geopotential mô hình EGM96( Lemoine et al, 1998 ).
Điều này được thực hiện bằng cách nội suy một lưới của tệp chiều cao geoid với độ phân giải không gian là 15 vòng cung-phút.

Hoặc nếu bạn có một số chuyên gia cấp độ GPScó Độ cao H( msl, độ cao trên mực nước biển trung bình ) và UNDULATION, mối quan hệ giữa geoidđầu ra dữ liệuellipsoid (m) đã chọn từ bảng nội bộ. bạn có thể làm đượch = H(msl) + undulation

Tới XYZ theo tọa độ Descartes:

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

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

z = R *sin(lat)

Giá trị của R là?
eych

4
Tôi đoán đó là bán kính của hình cầu, là 6371km đối với trái đất.
Matthias

5

Phần mềm proj.4 cung cấp một chương trình dòng lệnh có thể thực hiện chuyển đổi, ví dụ:

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

Nó cũng cung cấp một API C . Đặc biệt, hàm pj_geodetic_to_geocentricsẽ thực hiện chuyển đổi mà không cần phải thiết lập đối tượng chiếu trước.


5

Trong python3.x, nó có thể được thực hiện bằng cách sử dụng:

# 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

Nếu bạn quan tâm đến việc lấy tọa độ dựa trên hình elipsoid thay vì hình cầu, hãy xem tại http://en.wikipedia.org/wiki/Geodetic_system#From_geodetic_to_ECEF - nó cung cấp các công thức cũng như hằng số WGS84 mà bạn cần để chuyển đổi .

Các công thức ở đó cũng tính đến độ cao so với bề mặt ellipsoid tham chiếu (hữu ích nếu bạn đang nhận dữ liệu độ cao từ thiết bị GPS).


Ủng hộ mặc dù bạn không đăng nội dung của liên kết ở đây.
Mad Physicist

2

Tại sao phải triển khai một thứ gì đó đã được triển khai và đã được kiểm chứng?

C #, ví dụ, có NetTopologySuite là cổng .NET của JTS Topology Suite.

Cụ thể, bạn có một sai sót nghiêm trọng trong tính toán của mình. Trái đất không phải là một hình cầu hoàn hảo, và tính gần đúng bán kính của trái đất có thể không cắt nó để có các phép đo chính xác.

Nếu trong một số trường hợp, việc sử dụng các hàm homebrew được chấp nhận, thì GIS là một ví dụ điển hình về lĩnh vực mà nó được ưu tiên sử dụng một thư viện đáng tin cậy, đã được kiểm chứng.


1
+1. Sử dụng thư viện đáng tin cậy chính xác hơn hàm homebrew và cũng dễ dàng hơn .
MarkJ

5
Làm thế nào để NetTopologySuite chuyển đổi từ dài / trễ sang cartesion?
vinayan

1
NTS không bao gồm khả năng chuyển đổi tọa độ, có thể bạn cần Proj.NET projnet.codeplex.com
D_Guidi

6
Thật nực cười, câu trả lời thậm chí không cung cấp khả năng chuyển đổi.
motes

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);

Bạn có thể giải thích? Tôi đã tạo một ứng dụng đơn giản phân cấp để biến đổi một tọa độ duy nhất bằng cách sử dụng phương pháp của bạn. Nó luôn không thành công mặc dù kích thước của nguồn (2) và kích thước của mục tiêu (3) khác nhau, dẫn đến một ngoại lệjava.lang.IllegalArgumentException: dimension must be <= 3
oschrenk

Hmmm ... Tôi đã xem xét JTS một chút. Các dòng tối đa và bao gồm cả LineString () mới trông giống như JTS. Nhưng tôi không thấy nội dung CRS và Transform trong JTS. Vậy: họ có ở đó không và tôi đang nhớ họ? Có ở đó không và bị xóa trong 1.12? Hoặc: đó là một thư viện khác?
Dan H

0

Bạn có thể thực hiện theo cách này trên 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;


}

tham số alt là gì?
baliman

độ cao, bạn thậm chí đang làm gì ở đây nếu bạn không biết cách hoạt động của GPS;)
MushyPeas
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.