Boylam \ enlemden Kartezyen koordinatlara dönüştürme


104

Enlem ve boylam olarak verilen bazı dünya merkezli koordinat noktalarım var ( WGS-84 ).

Kökeni dünyanın merkezinde olacak şekilde Kartezyen koordinatlara (x, y, z) nasıl dönüştürebilirim?


1
WGS-84 boylam ve enlemini Kartezyen koordinatlarına dönüştürmeyi başardınız mı? Benim de yüksekliğim var. Kabul edilen cevabı burada denedim ama bana doğru cevabı vermiyor. Sonuçlarımı şu web sitesiyle karşılaştırdım: apsalin.com/convert-geodetic-to-cartesian.aspx .
Yasmin

Yanıtlar:


47

Son zamanlarda WGS-84 verileri üzerinde "Haversine Formülü" nü kullanarak, "Haversines Yasası" nın bir türevi olan ve çok tatmin edici sonuçlarla buna benzer bir şey yaptım.

Evet, WGS-84 Dünya'nın bir elipsoid olduğunu varsayar, ancak "Haversine Formülü" gibi bir yaklaşım kullanarak yalnızca yaklaşık% 0.5 ortalama hata aldığınıza inanıyorum, bu sizin durumunuzda kabul edilebilir bir hata miktarı olabilir. Birkaç fitlik bir mesafeden bahsetmediğiniz ve hatta Dünya'nın teorik olarak eğriliğinden bahsetmediğiniz sürece her zaman bir miktar hata yaşarsınız ... Daha katı bir şekilde WGS-84 uyumlu yaklaşıma ihtiyacınız varsa "Vincenty Formülü" nü kontrol edin.

Starblue'nun nereden geldiğini anlıyorum , ancak iyi bir yazılım mühendisliği genellikle değiş tokuşlarla ilgilidir, bu yüzden her şey yaptığınız şey için ihtiyaç duyduğunuz doğruluğa bağlıdır. Örneğin, "Manhattan Mesafe Formülü" nden hesaplanan sonuçla "Mesafe Formülü" nden hesaplanan sonuç, hesaplama açısından daha ucuz olduğu için belirli durumlar için daha iyi olabilir. "En yakın nokta hangisi?" Diye düşünün. hassas bir mesafe ölçümüne ihtiyaç duymadığınız senaryolar.

"Haversine Formülü" ile ilgili olarak, uygulanması kolaydır ve güzeldir çünkü iki boyutlu trigonometriye dayanan "Kosinüs Yasası" temelli bir yaklaşım yerine "Küresel Trigonometri" kullanır, bu nedenle güzel bir doğruluk dengesi elde edersiniz karmaşıklığın üzerinde.

Chris Veness adında bir beyefendinin http://www.movable-type.co.uk/scripts/latlong.html adresinde , ilgilendiğiniz bazı kavramları açıklayan ve çeşitli programatik uygulamaları gösteren harika bir web sitesi vardır; bu, x / y dönüştürme sorunuzu da yanıtlamalıdır.


1
% 0,5 hata - neyin% 0,5'i? % 0.5 30 km :) olabilir bu yüzden bu soruya bağlamında o, yeryüzünün yarıçapı olabilir
MarkJ

2
Bağlantınıza baktım. % 0,5'lik alıntı, iki nokta arasındaki büyük daire mesafesindeki hata içindir, dolayısıyla bu soruyla tam olarak ilgili değildir. Kökeni dünyanın merkezinde bulunan enlem-boyunu Kartezyen koordinatlarına dönüştürürken, küresel bir dünya varsayımından kaynaklanan hataların önemli olabileceğini düşünürdüm. Soru soranın Kartezyen koordinatlarla ne yapmak istediği açık değil . Tuhaf bir nedenden ötürü bunlarda çalışmak sadece daha uygun mu, yoksa veri aktarımı için bir gereklilik mi? İkincisi ise, doğruluk önemli olacaktır.
MarkJ

132

İşte bulduğum cevap:

Kartezyen koordinat sisteminde tanımı tamamlamak için:

  • x ekseni enlem (0,0) uzunluğundan geçer, bu nedenle 0 boylamı ekvator ile buluşur;
  • y ekseni (0,90) içinden geçer;
  • ve z ekseni kutuplardan geçer.

Dönüşüm şudur:

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

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

z = R *sin(lat)

R, dünyanın yaklaşık yarıçapıdır (örneğin 6371 km).

Trigonometrik fonksiyonlarınız radyan bekliyorsa (ki muhtemelen yaparlar), önce boylamınızı ve enleminizi radyana çevirmeniz gerekecektir. Açıkça ondalık gösterime ihtiyacınız var, derece \ dakika \ saniye değil ( örneğin dönüştürme hakkında buraya bakın ).

Geri dönüşüm formülü:

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

asin tabii ki ark sinüs. wikipedia'da atan2 hakkında okuyun . Radyandan dereceye geri dönüştürmeyi unutmayın.

Bu sayfa bunun için c # kodu verir (formüllerden çok farklı olduğunu unutmayın) ve ayrıca bunun neden doğru olduğuna dair bazı açıklamalar ve güzel şema,


19
-1 Bu yanlış. WGS-84 bir elipsoid varsayarken, dünyanın bir küre olduğunu varsayıyorsunuz.
starblue

43
@starblue: Verilen yanıtı "doğru" veya "yanlış" olarak etiketleyebilecek durumda olup olmadığından emin değilim. Mevcut enlem / lngs (WGS-84'e atıfta bulunulan) kullanan küresel yaklaşım (ECEF tarzı x, y, z koordinatları elde etmek için) orijinal posterin ihtiyaçları için "yeterli" veya "yetersiz" dir. Mesafe ve yön tahminleri için, bu basit dönüşümün iyi olduğuna bahse girerim. Uyduları fırlatıyorsa, belki de değil. Sonuçta, WGS-84'ün kendisi "yanlıştır" ... çünkü dünya yüzeyinin mükemmel bir modeli değildir; tüm elipsoidal modeller yaklaşıktır. Operatörün bize ne yapmaya çalıştığını söylememesi çok kötü.
Dan H

11
@Dan H Soru WGS-84'ü soruyor ve eğer başka bir şeye cevap verirseniz, en azından bu cevabın yapmadığı farklılıkları / hataları tartışmalısınız.
starblue

@ daphna-shezaf geri dönüşüm yapamıyor ... Radyandan dereceye geri dönüşü de yaptım, ancak sonuç aynı değil ...

teşekkür ederim, neden işe yaramadığını anlamak için saatler harcayın, bazı cos (lat) ve sin (lat) değiştirdim
aeroson

6

Dönüştürme için Teorisi GPS(WGS84)için Kartezyen koordinatlar https://en.wikipedia.org/wiki/Geographic_coordinate_conversion#From_geodetic_to_ECEF_coordinates

Aşağıdakiler kullanıyorum:

  • GPS (WGS84) ve Kartezyen koordinatlarındaki boylam aynıdır.
  • Enlemin WGS 84 elipsoid parametreleri tarafından dönüştürülmesi gerekir yarı ana eksen 6378137 m'dir ve
  • Düzleştirmenin tersi 298.257223563'tür.

Yazdığım bir VB kodunu ekledim:

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

Lütfen hrakımın üzerinde olduğuna dikkat edin WGS 84 ellipsoid.

Genellikle GPSbize Hyukarıdaki MSLyüksekliği verir. MSLYükseklik yüksekliğine dönüştürülecek olan h, yukarıda WGS 84 ellipsoidkullanarak izgesindeki modeli EGM96( Lemoine et al, 1998 ).
Bu, jeoid yükseklik dosyasının bir ızgarasının 15 yay-dakikalık uzamsal çözünürlükle enterpolasyonu ile yapılır.

Bazı seviye varsa Veya profesyonel GPS Rakımı sahiptir H( msl, ortalama deniz seviyesinden heigh ) ve UNDULATIONarasındaki ilişkiyi geoidve ellipsoid (m)seçilmiş bir sıfır noktası çıkışı iç tablosundan. alabilirsinizh = H(msl) + undulation

Kartezyen koordinatlara göre XYZ'ye:

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

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

z = R *sin(lat)

R'nin değeri nedir?
eych

4
Sanırım bu, dünyanın 6371 km'lik yarıçapı olan kürenin yarıçapı.
Matthias

6

Python3.x içinde şu şekilde yapılabilir:

# 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

5

Proj.4 yazılım dönüştürme yapabilirsiniz bir komut satırı programı, örneğin sağlar

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

Ayrıca bir C API sağlar . Özellikle, işlev pj_geodetic_to_geocentric, önce bir projeksiyon nesnesi kurmaya gerek kalmadan dönüşümü gerçekleştirecektir.


3

Bir küre yerine bir elipsoide dayalı koordinatlar almayı önemsiyorsanız, http://en.wikipedia.org/wiki/Geodetic_system#From_geodetic_to_ECEF adresine bakın - formülleri ve dönüşüm için ihtiyacınız olan WGS84 sabitlerini verir .

Buradaki formüller ayrıca referans elipsoid yüzeye göre rakımı da hesaba katar (bir GPS cihazından yükseklik verisi alıyorsanız kullanışlıdır).


Bağlantının içeriğini burada yayınlamamış olmanıza rağmen oylama.
Mad Fizikçi

2

Zaten uygulanmış ve test edilmiş bir şeyi neden uygulayasınız?

Birincisi, C #, JTS Topology Suite'in .NET bağlantı noktası olan NetTopologySuite'e sahiptir.

Özellikle, hesaplamanızda ciddi bir kusurunuz var. Dünya mükemmel bir küre değildir ve dünyanın yarıçapının yaklaştırılması , kesin ölçümler için onu kesmeyebilir.

Bazı durumlarda homebrew işlevlerinin kullanılması kabul edilebilirse, CBS, güvenilir, testle kanıtlanmış bir kitaplık kullanmanın daha çok tercih edildiği bir alan için iyi bir örnektir.


1
+1. Güvenilir bir kitaplık kullanmak, homebrew işlevinden daha doğrudur ve ayrıca daha kolaydır .
MarkJ

5
NetTopologySuite, uzun / geç'ten kartezyona nasıl dönüşür?
vinayan

1
NTS koordinat dönüştürme yetenekleri içermez, belki Proj.NET projnet.codeplex.com
D_Guidi

6
Gülünç, cevap dönüştürme yeteneği bile sağlamıyor.
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);

Detaylandırabilir misin? Ben oluşturulan katmanları tek yaklaşımınızı kullanarak koordinat dönüşümü basit bir uygulama. Kaynağın (2) boyutları ve hedefin (3) boyutları farklı olduğundan her zaman başarısız olur, bu da bir istisna ile sonuçlanırjava.lang.IllegalArgumentException: dimension must be <= 3
oschrenk

Hmmm ... JTS'ye biraz baktım. Yeni LineString () dahil olmak üzere satırlar JTS'ye benzer. Ancak JTS'de CRS ve Transform olaylarını göremiyorum. Yani: onlar oradalar ve ben onları özlüyorum? Orada mıydı ve 1.12'de kaldırıldı mı? Veya: bu farklı bir kitaplık mı?
Dan H

0

Java'da bu şekilde yapabilirsiniz.

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 parametre nedir?
baliman

rakım, GPS'in nasıl çalıştığını bilmiyorsan burada ne yapıyorsun;)
MushyPeas
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.