2009-07-10 6 views
9

Je travaille actuellement sur des données GPS combinées à des mesures d'altitude précises. Je veux calculer la distance entre deux points de consécution. Il y a beaucoup d'informations sur le calcul de la distance entre deux points en utilisant l'ellipsoïde WGS84 et ainsi de suite.Prise en compte de l'altitude lors du calcul de la distance géodésique

Cependant, je n'ai trouvé aucune information qui prend Altitude changements en compte pour ce calcul de distance .

Est-ce que quelqu'un sait sur certains sites Web, papiers, livres, etc., qui décrit une telle méthode? merci

éditer: Les extensions géographiques Sql Server 2008 négligent également les informations d'altitude lors du calcul de la distance.

+0

Je ne l'ai pas regardé les équations WGS84, donc je ne pas écrire cela comme une réponse. Cela dit, il me semble que vous devriez pouvoir ajuster un rayon ou deux pour que vos points de mesure soient la "nouvelle" surface. Cela fonctionnerait probablement mieux si vos mesures d'altitude sont basées sur le GPS; s'il est basé sur des moyens mécaniques (p. ex. la pression de l'air), alors le «niveau de la mer» peut avoir très peu de rapport avec le géoïde du modèle. – kdgregory

+0

Avez-vous déjà trouvé une bonne solution pour cela? – lnafziger

Répondre

0

Je suggère que sur toute distance où l'utilisation du WGS84 vous donnerait une précision nettement meilleure que la différence d'altitude n'aura pas d'importance. Et sur toute distance où la différence d'altitude est importante, vous devriez probablement utiliser une approximation en ligne droite.

0

Pour ce faire, le premier problème que vous devez résoudre est de savoir comment définir le changement d'altitude. Les équations normales fonctionnent parce qu'elles sont sur une surface bidimensionnelle, cependant ajouter la troisième dimension signifie que la définition simple de la distance la plus courte n'est plus applicable, par exemple maintenant la dimension de thrid est en jeu votre plus courte distance pourrait couper l'original ellipsoïde. C'est un peu rapide et sale, mais votre meilleure solution pourrait être de supposer que le taux de changement d'alltitude est constant le long du chemin 2D original sur l'ellipsoïde. Vous pouvez ensuite calculer la distance 2D comme une longueur, calculer le taux de changement d'altitude et ensuite utiliser simplement Pythagoras pour calculer l'augmentation de longueur avec un côté du triangle étant la distance 2D, et l'altitude étant la deuxième longueur.

6

J'ai implémenté une fonction de distance WGS84 en utilisant la moyenne de l'altitude de début et de fin comme altitude constante. Si vous êtes certain qu'il y aura relativement peu de variation d'altitude le long de votre chemin, cela fonctionnera bien (l'erreur est relative à la différence d'altitude de vos deux points LLA).

Voici mon code (C#):

/// <summary> 
    /// Gets the geodesic distance between two pathpoints in the current mode's coordinate system 
    /// </summary> 
    /// <param name="point1">First point</param> 
    /// <param name="point2">Second point</param> 
    /// <param name="mode">Coordinate mode that both points are in</param> 
    /// <returns>Distance between the two points in the current coordinate mode</returns> 
    public static double GetGeodesicDistance(PathPoint point1, PathPoint point2, CoordMode mode) { 
     // calculate proper geodesics for LLA paths 
     if (mode == CoordMode.LLA) { 
      // meeus approximation 
      double f = (point1.Y + point2.Y)/2 * LatLonAltTransformer.DEGTORAD; 
      double g = (point1.Y - point2.Y)/2 * LatLonAltTransformer.DEGTORAD; 
      double l = (point1.X - point2.X)/2 * LatLonAltTransformer.DEGTORAD; 

      double sinG = Math.Sin(g); 
      double sinL = Math.Sin(l); 
      double sinF = Math.Sin(f); 

      double s, c, w, r, d, h1, h2; 
      // not perfect but use the average altitude 
      double a = (LatLonAltTransformer.A + point1.Z + LatLonAltTransformer.A + point2.Z)/2.0; 

      sinG *= sinG; 
      sinL *= sinL; 
      sinF *= sinF; 

      s = sinG * (1 - sinL) + (1 - sinF) * sinL; 
      c = (1 - sinG) * (1 - sinL) + sinF * sinL; 

      w = Math.Atan(Math.Sqrt(s/c)); 
      r = Math.Sqrt(s * c)/w; 
      d = 2 * w * a; 
      h1 = (3 * r - 1)/2/c; 
      h2 = (3 * r + 1)/2/s; 

      return d * (1 + (1/LatLonAltTransformer.RF) * (h1 * sinF * (1 - sinG) - h2 * (1 - sinF) * sinG)); 
     } 

     PathPoint diff = new PathPoint(point2.X - point1.X, point2.Y - point1.Y, point2.Z - point1.Z, 0); 
     return Math.Sqrt(diff.X * diff.X + diff.Y * diff.Y + diff.Z * diff.Z); 
    } 

En pratique, nous avons constaté que la différence d'altitude fait rarement une grande différence, nos chemins sont généralement 1-2km longue avec l'altitude variant de l'ordre de 100m et nous voyons environ ~ 5m de changement en moyenne par rapport à l'utilisation de l'ellipsoïde WGS84 non modifié.

Edit:

Pour ajouter à cela, si vous ne vous attendez grands changements d'altitude, vous pouvez convertir vos coordonnées WGS84 à ECEF (terre centré sur la Terre fixe) et évaluer les chemins en ligne droite comme indiqué au bas de mon fonction. Conversion d'un point à ECEF est simple:

/// <summary> 
    /// Converts a point in the format (Lon, Lat, Alt) to ECEF 
    /// </summary> 
    /// <param name="point">Point as (Lon, Lat, Alt)</param> 
    /// <returns>Point in ECEF</returns> 
    public static PathPoint WGS84ToECEF(PathPoint point) { 
     PathPoint outPoint = new PathPoint(0); 

     double lat = point.Y * DEGTORAD; 
     double lon = point.X * DEGTORAD; 
     double e2 = 1.0/RF * (2.0 - 1.0/RF); 
     double sinLat = Math.Sin(lat), cosLat = Math.Cos(lat); 

     double chi = A/Math.Sqrt(1 - e2 * sinLat * sinLat); 
     outPoint.X = (chi + point.Z) * cosLat * Math.Cos(lon); 
     outPoint.Y = (chi + point.Z) * cosLat * Math.Sin(lon); 
     outPoint.Z = (chi * (1 - e2) + point.Z) * sinLat; 

     return outPoint; 
    } 

Edit 2:

On m'a demandé quelques-unes des autres variables dans mon code:

// RF is the eccentricity of the WGS84 ellipsoid 
public const double RF = 298.257223563; 

// A is the radius of the earth in meters 
public const double A = 6378137.0; 

LatLonAltTransformer est une classe je convertir les coordonnées LatLonAlt en coordonnées ECEF et définir les constantes ci-dessus.

+0

Je ne pense pas que le questionneur posait des questions sur des situations où l'altitude est effectivement constante. Je pense que le but était de trouver la distance de style grand cercle entre deux points où les altitudes diffèrent significativement entre les deux points. – jprete

+0

Peut-être que je n'ai pas clarifié, mais ma solution fait la moyenne des altitudes des deux points et appelle cette constante. L'évaluation de la distance géodésique en utilisant deux altitudes distinctes prend du temps et est difficile, en particulier lorsqu'une approximation obtient de très bons résultats. –

+0

Je crois que le questionneur d'origine veut capturer le léger changement de distance résultant des changements d'altitude; c'est pourquoi l'utilisation de la moyenne, ou max alt, ou min alt, n'est pas une solution. Les distances en ligne droite ne sont pas non plus une solution au problème de différence d'altitude, parce que ces lignes droites n'ont pas le profil de montée/descente approprié: «J'ai parcouru 60 milles et changé d'altitude de 20000 pieds. temps". Par exemple. Si le point final de votre a est en dessous de l'horizon, alors la première chose que fait le chemin est de creuser un tunnel sous la terre. – jprete

0

Pour les débutants, vous avez besoin d'un modèle qui vous indique comment l'altitude change sur la ligne entre les deux points. Sans un tel modèle, vous n'avez aucune définition cohérente de la distance entre deux points. Si vous aviez un modèle linéaire (parcourir 50% de la distance entre les points signifie également que vous avez augmenté de 50% de l'altitude), alors vous pouvez probablement prétendre que le tout était un triangle rectangle; c'est-à-dire que vous agissez comme si le monde était plat pour déterminer comment le décalage d'altitude affecte la distance. La distance le long du sol est la base, le changement d'altitude est la hauteur du triangle, et l'hypoténuse est votre vraie distance de déplacement estimée d'un point à un autre. Si vous voulez affiner cela plus loin, vous pouvez noter que le modèle ci-dessus est parfaitement adapté aux distances infinitésimales, ce qui signifie que vous pouvez parcourir les deltas individuels de la distance, en utilisant l'altitude actuelle calculer la distance au sol et ensuite utiliser le même rapport trigonométrique pour calculer la contribution de changement altitudinal à la distance parcourue. Je ferais probablement cela dans une boucle for() avec 10 à 100 morceaux du segment, et peut-être par essai et erreur déterminer le nombre de pièces nécessaires pour entrer dans epsilon de la vraie valeur. Il serait également possible de travailler sur l'intégrale de la ligne pour déterminer la distance réelle entre les deux points sous ce modèle.

0

Vous ne vous souciez probablement pas de l'altitude pour les grandes séparations de distance 2D. Donc, si le dist vous obtenez est plus de dire 20 (ou peut-être 50) km, alors qui se soucie de l'altitude diff (dépend de vos besoins). Par exemple, 20 km, nourrir dans la simple addition pythagorienne à la différence d'altitude. Nourrissez-le en douceur.

Distance between two geo-points?

Questions connexes