Mengonversi dari bujur \ lintang ke koordinat Kartesius


103

Saya memiliki beberapa titik koordinat pusat bumi yang diberikan sebagai garis lintang dan garis bujur ( WGS-84 ).

Bagaimana cara mengubahnya menjadi koordinat Kartesius (x, y, z) dengan titik asal di pusat bumi?


1
Sudahkah Anda berhasil mengubah WGS-84 bujur dan lintang menjadi koordinat Cartesian?. Saya juga memiliki ketinggian. Saya telah mencoba jawaban yang diterima di sini, tetapi tidak memberi saya jawaban yang benar. Saya membandingkan hasil saya dengan situs web ini: apsalin.com/convert-geodetic-to-cartesian.aspx .
Yasmin

Jawaban:


47

Saya baru-baru ini melakukan sesuatu yang mirip dengan ini menggunakan "Haversine Formula" pada data WGS-84, yang merupakan turunan dari "Law of Haversines" dengan hasil yang sangat memuaskan.

Ya, WGS-84 mengasumsikan Bumi adalah elipsoid, tetapi saya yakin Anda hanya mendapatkan kesalahan rata-rata 0,5% menggunakan pendekatan seperti "Formula Haversine", yang mungkin merupakan jumlah kesalahan yang dapat diterima dalam kasus Anda. Anda akan selalu mendapatkan sejumlah kesalahan kecuali jika Anda berbicara tentang jarak beberapa kaki dan bahkan kemudian ada kelengkungan secara teoritis dari Bumi ... Jika Anda memerlukan pendekatan yang lebih kompatibel dengan WGS-84, periksa "Formula Vincenty".

Saya mengerti dari mana starblue berasal, tetapi rekayasa perangkat lunak yang baik sering kali tentang kompromi, jadi semuanya tergantung pada keakuratan yang Anda perlukan untuk apa yang Anda lakukan. Misalnya, hasil yang dihitung dari "Rumus Jarak Manhattan" versus hasil dari "Rumus Jarak" bisa lebih baik untuk situasi tertentu karena secara komputasi lebih murah. Pikirkan "titik mana yang paling dekat?" skenario di mana Anda tidak memerlukan pengukuran jarak yang tepat.

Mengenai, "Formula Haversine" mudah diterapkan dan bagus karena menggunakan "Trigonometri Bulat" bukan pendekatan berbasis "Hukum Kosinus" yang didasarkan pada trigonometri dua dimensi, oleh karena itu Anda mendapatkan keseimbangan akurasi yang bagus lebih dari kompleksitas.

Seorang pria bernama Chris Veness memiliki situs web yang bagus di http://www.movable-type.co.uk/scripts/latlong.html yang menjelaskan beberapa konsep yang Anda minati dan mendemonstrasikan berbagai implementasi programatik; ini harus menjawab pertanyaan konversi x / y Anda juga.


1
Kesalahan 0,5% - 0,5% dari apa? Dalam konteks pertanyaan ini bisa jadi jari-jari bumi, jadi 0,5% bisa jadi 30 km :)
MarkJ

2
Memeriksa tautan Anda. Kutipan 0,5% adalah untuk kesalahan dalam jarak lingkaran besar antara dua titik jadi tidak sepenuhnya relevan dengan pertanyaan ini. Saya akan berpikir ketika mengubah koordinat lintang-bujur ke Cartesian dengan asal di pusat bumi, kesalahan dari asumsi bumi bulat bisa menjadi signifikan. Tidak jelas apa yang ingin dilakukan penanya dengan koordinat Cartesian. Entah lebih nyaman untuk bekerja di dalamnya karena alasan yang aneh, atau mungkin itu beberapa persyaratan untuk ekspor data? Jika yang terakhir, akurasi akan menjadi penting.
MarkJ

130

Inilah jawaban yang saya temukan:

Hanya untuk membuat definisi lengkap, dalam sistem koordinat Kartesius:

  • sumbu x melewati bujur, lintang (0,0), sehingga bujur 0 bertemu dengan ekuator;
  • sumbu y melewati (0,90);
  • dan sumbu z melewati kutub.

Konversinya adalah:

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

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

z = R *sin(lat)

Dimana R adalah radius perkiraan bumi (misalnya 6371 km).

Jika fungsi trigonometri Anda mengharapkan radian (yang mungkin bisa terjadi), Anda perlu mengonversi bujur dan lintang ke radian terlebih dahulu. Anda jelas membutuhkan representasi desimal, bukan derajat \ menit \ detik (lihat misalnya di sini tentang konversi).

Rumus konversi balik:

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

asin tentu saja arc sinus. baca tentang atan2 di wikipedia . Jangan lupa untuk mengubah kembali dari radian ke derajat.

Halaman ini memberikan kode c # untuk ini (perhatikan bahwa ini sangat berbeda dari rumus), dan juga beberapa penjelasan dan diagram yang bagus mengapa ini benar,


18
-1 Ini salah. Anda mengasumsikan bumi adalah bola, sedangkan WGS-84 mengasumsikan ellipsoid.
starblue

42
@starblue: Saya tidak yakin Anda berada dalam posisi untuk memberi label jawaban yang diberikan "benar" atau "salah". Pendekatan bola (untuk mendapatkan koord x, y, z bergaya ECEF) menggunakan lat / lng yang tersedia (yang dirujuk ke WGS-84) adalah "memadai" untuk kebutuhan poster asli, atau "tidak memadai". Untuk perkiraan jarak dan arah, saya yakin konversi sederhana ini baik-baik saja. Jika dia meluncurkan satelit, mungkin tidak. Bagaimanapun, WGS-84 sendiri "salah" ... karena ini bukanlah model yang sempurna dari permukaan bumi; semua model ellipsoidal adalah perkiraan. Sayang sekali OP tidak memberi tahu kami apa yang dia coba lakukan.
Dan H

11
@Dan H Pertanyaan menanyakan WGS-84, dan jika Anda menjawab sesuatu yang lain, Anda setidaknya harus mendiskusikan perbedaan / kesalahan, yang jawaban ini tidak.
starblue

@ daphna-shezaf tidak dapat melakukan konversi mundur ... Saya juga telah melakukan konversi balik dari radian ke derajat, tetapi hasilnya tidak sama ...

terima kasih, habiskan waktu berjam-jam untuk mencari tahu mengapa itu tidak berhasil, ternyata saya menukar beberapa cos (lat) dan sin (lat)
aeroson

6

Teori untuk mengonversi GPS(WGS84)ke koordinat Cartesian https://en.wikipedia.org/wiki/Geographic_coordinate_conversion#From_geodetic_to_ECEF_coordinates

Berikut ini yang saya gunakan:

  • Bujur di GPS (WGS84) dan koordinat Cartesian adalah sama.
  • Lintang perlu diubah oleh WGS 84 parameter ellipsoid sumbu semi mayor adalah 6378137 m, dan
  • Kebalikan dari perataan adalah 298.257223563.

Saya melampirkan kode VB yang saya tulis:

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

Harap perhatikan bahwa hadalah ketinggian di atas WGS 84 ellipsoid.

Biasanya GPSakan memberi kita ketinggian di Hatas MSL. The MSLtinggi harus dikonversi ke ketinggian hdi atas WGS 84 ellipsoiddengan menggunakan geopotential Model EGM96( Lemoine et al, 1998 ).
Ini dilakukan dengan menginterpolasi grid file ketinggian geoid dengan resolusi spasial 15 arc-menit.

Atau jika Anda memiliki beberapa level profesional GPS memiliki Ketinggian H( msl, tinggi di atas permukaan laut rata-rata ) dan UNDULATION, hubungan antara geoiddan ellipsoid (m)dari keluaran datum yang dipilih dari tabel internal. Anda bisa mendapatkanh = H(msl) + undulation

Ke XYZ dengan koordinat Cartesian:

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

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

z = R *sin(lat)

Berapakah nilai R?
eych

4
Saya kira radius bulatannya, yaitu 6371km untuk bumi.
Matthias

5

Perangkat lunak proj.4 menyediakan program baris perintah yang dapat melakukan konversi, misalnya

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

Ini juga menyediakan C API . Secara khusus, fungsi tersebut pj_geodetic_to_geocentricakan melakukan konversi tanpa harus menyiapkan objek proyeksi terlebih dahulu.


5

Di python3.x itu bisa dilakukan dengan menggunakan:

# 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


2

Mengapa menerapkan sesuatu yang telah diterapkan dan diuji-terbukti?

C #, misalnya, memiliki NetTopologySuite yang merupakan port .NET dari JTS Topology Suite.

Secara khusus, Anda memiliki kesalahan yang parah dalam perhitungan Anda. Bumi bukanlah bola yang sempurna, dan perkiraan jari-jari bumi mungkin tidak tepat untuk pengukuran yang tepat.

Jika dalam beberapa kasus dapat diterima untuk menggunakan fungsi homebrew, GIS adalah contoh yang baik dari bidang yang lebih disukai untuk menggunakan pustaka yang andal dan terbukti uji.


1
+1. Menggunakan perpustakaan yang andal lebih akurat daripada fungsi homebrew dan juga lebih mudah .
MarkJ

5
Bagaimana NetTopologySuite mengonversi dari long / late to cartesion?
vinayan

1
NTS tidak menyertakan kemampuan konversi koordinat, mungkin Anda memerlukan Proj.NET projnet.codeplex.com
D_Guidi

6
Konyol, jawaban bahkan tidak memberikan kemampuan konversi.
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);

Bisakah Anda menjelaskan lebih lanjut? Saya membuat aplikasi sederhana yang bertingkat untuk mengubah satu koordinat menggunakan pendekatan Anda. Itu selalu gagal karena dimensi sumber (2) dan dimensi target (3) berbeda, menghasilkan pengecualianjava.lang.IllegalArgumentException: dimension must be <= 3
oschrenk

Hmmm ... Saya sudah melihat JTS sebentar. Garis upto dan termasuk LineString () baru terlihat seperti JTS. Tapi saya tidak melihat CRS dan Transformasi di JTS. Jadi: apakah mereka ada di sana dan saya merindukan mereka? Apakah ada, dan dihapus di 1,12? Atau: apakah itu perpustakaan yang berbeda?
Dan H

0

Anda dapat melakukannya dengan cara ini di 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;


}

apa parameter alt?
baliman

ketinggian, apa yang Anda lakukan di sini jika Anda tidak tahu cara kerja GPS;)
MushyPeas
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.