Conversion de longitude latitude en coordonnées cartésiennes

j'ai quelques coordonnées terrestres données comme latitude et longitude ( WGS-84 ).

comment les convertir en coordonnées cartésiennes (x, y, z) avec l'origine au centre de la terre?

82
demandé sur SuperElectric 2009-07-27 00:00:50

8 réponses

j'ai récemment fait quelque chose de similaire à ceci en utilisant le "Formule Haversine" sur Données WGS-84, qui est un dérivé de la "Loi de Haversines" avec des résultats très satisfaisants.

Oui, WGS-84 suppose que la Terre est un ellipsoïde, mais je crois qu'on obtient seulement une erreur moyenne d'environ 0.5% en utilisant une approche comme la "formule Haversine", qui peut être un montant acceptable d'erreur dans votre cas. Vous aurez toujours une certaine quantité d'erreur, sauf si vous parlez d'un distance de quelques pieds et même alors il y a théoriquement une courbure de la Terre... Si vous avez besoin d'une approche compatible WGS-84 plus rigide, consultez la formule "Vincenty"."

je comprends d'où starblue , mais bon génie logiciel est souvent question de compromis, donc tout dépend de la précision dont vous avez besoin pour ce que vous faites. Par exemple, le résultat calculé à partir de la "formule de la Distance de Manhattan" par rapport au résultat de la La "formule de la Distance" peut être meilleure dans certaines situations, car elle est moins coûteuse sur le plan informatique. Pensez " quel point est le plus proche?"scénarios où vous n'avez pas besoin d'une mesure précise de la distance.

en ce qui concerne, la" formule Haversine "il est facile à mettre en œuvre et est agréable parce qu'il utilise" trigonométrie sphérique "au lieu d'une" loi des cosinus " approche basée qui est basée sur la trigonométrie bidimensionnelle, donc vous obtenez un bel équilibre de la précision sur la complexité.

a gentlemen by the name of Chris Veness has a great website at http://www.movable-type.co.uk/scripts/latlong.html qui explique certains des concepts qui vous intéressent et montre diverses implémentations programmatiques; cela devrait répondre à votre question de conversion x/Y.

38
répondu bn. 2009-07-26 21:04:59

Voici la réponse que j'ai trouvée:

Juste pour faire de la définition complète, dans le système de coordonnées Cartésiennes:

  • l'axe des x passe par long, lat (0,0), donc la longitude 0 rencontre l'Équateur;
  • l'axe des y passe par (0,90);
  • et l'axe z passe à travers les pôles.

la conversion est:

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

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

z = R *sin(lat)

où R est rayon approximatif de la terre (par exemple 6371KM).

si vos fonctions trigonométriques attendent des radians (ce qui est probablement le cas), vous devrez d'abord convertir votre longitude et votre latitude en radians. Vous avez évidemment besoin d'une représentation décimale, pas degrés\minutes\secondes (voir par exemple ici à propos de la conversion).

la formule pour la conversion en arrière:

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

asin est de cours arc sinus. lire à propos de atan2 dans wikipédia . N'oubliez pas de convertir en degrés le retour de radians.

Cette page donne le code c# (à noter qu'il est très différent de la formule), et aussi une explication et une belle diagramme de pourquoi c'est correct,

103
répondu daphshez 2017-05-23 12:10:46

théorie pour convertir GPS(WGS84) en coordonnées cartésiennes https://en.wikipedia.org/wiki/Geographic_coordinate_conversion#From_geodetic_to_ECEF_coordinates

ce qui suit est ce que j'utilise:

  • la Longitude dans le GPS WGS84 le WGS84 le WGS84 le WGS84 le WGS84 et les coordonnées cartésiennes sont les mêmes.
  • Latitude doivent être convertis par WGS 84 paramètres ellipsoïdes demi-grand axe est 6378137 m, et
  • réciproque d'aplatissement est 298.257223563.

j'ai joint un code VB j'ai écrit:

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

veuillez noter que le h est une altitude au-dessus du WGS 84 ellipsoid .

habituellement GPS nous donnera H de plus de MSL hauteur. La hauteur MSL doit être converti en hauteur h au-dessus du WGS 84 ellipsoid en utilisant le géopotentiel modèle EGM96 ( Lemoine et al, 1998 ).

Ceci est fait en interpolant une grille du fichier de hauteur géoïde avec une résolution spatiale de 15 arc-minutes.

ou si vous avez un certain niveau professionnel GPS a de L'Altitude H ( msl,heigh au-dessus de la mer moyenne niveau ) et UNDULATION , la relation entre le geoid et le ellipsoid (m) de la sortie choisie sortie de référence de la table interne. vous pouvez obtenir h = H(msl) + undulation

À XYZ par coordonnées cartésiennes:

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

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

z = R *sin(lat)
6
répondu Howie 2015-12-21 15:27:53

Pourquoi mettre en œuvre quelque chose qui a déjà été mis en œuvre et testé?

C#, pour un, a la NetTopologySuite qui est le .NET port de la STC de la Topologie de Suite.

en particulier, vous avez un défaut grave dans votre calcul. La terre n'est pas une sphère parfaite, et le approximation du rayon de la Terre pourrait ne pas le couper pour des mesures précises.

si dans dans certains cas, il est acceptable d'utiliser des fonctions maison, GIS est un bon exemple d'un domaine dans lequel il est préférable d'utiliser une bibliothèque fiable, testée.

5
répondu Yuval Adam 2016-06-02 14:01:58

si vous vous souciez d'obtenir des coordonnées basées sur un ellipsoïde plutôt qu'une sphère, jetez un oeil à http://en.wikipedia.org/wiki/Geodetic_system#From_geodetic_to_ECEF - il donne les formules ainsi que les constantes WGS84 dont vous avez besoin pour la conversion.

les formules prennent également en compte l'altitude relative à la surface ellipsoïde de référence (utile si vous obtenez des données d'altitude à partir d'un GPS).

3
répondu Stjepan Rajko 2011-08-05 00:41:23

Le proj.4 logiciel fournit un programme de ligne de commande qui peut faire la conversion, par exemple

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

il fournit également un C API . En particulier, la fonction pj_geodetic_to_geocentric effectuera la conversion sans avoir à configurer d'abord un objet de projection.

3
répondu Brian Hawkins 2017-01-21 08:15:53
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);
1
répondu yang jun 2011-08-18 01:48:42

vous pouvez le faire de cette façon sur 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;


}
0
répondu Ashutosh Chapagain 2018-08-09 06:12:31