11 Ocak 2019 Cuma

Konum Hesaplama Formülleri - GPS'i XYZ Kartezyen Koordinate Sistemine Çevirme

GPS'i XYZ Kartezyen Koordinate Sistemine Nasıl Çeviririz?
Bazen GPS enlem/boylamlarını X,Y,Z kartezyen koordinat sistemine çevirmek gerekir. Bu sisteme Earth Centered, Earth Fixed (ECEF) de deniyor. Bu sistemde Z ekseni dünyanın merkezinden kutuplara doğru uzanır.

Küre Kullanarak
Formül şöyle
= r cos(phi) sin(theta) y = r sin(phi) sin(theta) z = r cos(theta)
Bu formülde
theta == latitude phi == longitude
Dolayısıyla tam formül şöyle oluyor.
= radius + altitude x = r cos(long) sin(lat) y = r sin(long) sin(lat) z = r cos(lat)
Çevrim için kullanılan formülde lat (enlem) ve lon (boylam) değerlerinin radyan biriminden olması gerekiyor. Yarıçap ile cos(lat) çarpılarak x-y eksenindeki iz düşümü bulunuyor.

Bu çevrim ile ilgili gördüğüm bir soru burada. Çevrimi anlatan en kolay anlaşılır sayfa burada.

Flattening ile
Eğer flattining kullanılmak istenseydi formül şöyle olurdu. Burada lat ve lon radyan olarak giriliyor.
def LLHtoECEF(lat, lon, alt):
    # see http://www.mathworks.de/help/toolbox/aeroblks/llatoecefposition.html

    rad = np.float64(6378137.0)        # Radius of the Earth (in meters)
    f = np.float64(1.0/298.257223563)  # Flattening factor WGS84 Model
    cosLat = np.cos(lat)
    sinLat = np.sin(lat)
    FF     = (1.0-f)**2
    C      = 1/np.sqrt(cosLat**2 + FF * sinLat**2)
    S      = C * FF

    x = (rad * C + alt)*cosLat * np.cos(lon)
    y = (rad * C + alt)*cosLat * np.sin(lon)
    z = (rad * S + alt)*sinLat

    return (x, y, z)
Bazı hesaplamalarda flattening 0 kabul ediliyor. Bu durumda yukarıdaki küre ile yapılan hesaplamalardan farklı bir sonuç elde edilir.
def llarToWorld(lat, lon, alt, rad):
    # see: http://www.mathworks.de/help/toolbox/aeroblks/llatoecefposition.html
    f  = 0                              # flattening
    ls = atan((1 - f)**2 * tan(lat))    # lambda

    x = rad * cos(ls) * cos(lon) + alt * cos(lat) * cos(lon)
    y = rad * cos(ls) * sin(lon) + alt * cos(lat) * sin(lon)
    z = rad * sin(ls) + alt * sin(lat)

    return c4d.Vector(x, y, z)
C++ kodu şöyle olurdu. Bu kodu hiç anlamadım
struct Point3d {
    float x, y, z;
    Point3d& fromLatLon(float lat_deg, float lon_deg) {
        static const float r = 6371.; // sphere radius
        float lat(lat_deg*M_PI/180.), lon(lon_deg*M_PI/180.);
        x = r * std::cos(lat) * std::cos(lon);
        y = r * std::cos(lat) * std::sin(lon);
        z = r * std::sin(lat);
        return *this;
    }
};

1 yorum: