¿Cómo calculo el acimut (ángulo hacia el norte) entre dos coordenadas WGS84 en una sola consulta T-SQL?

StackOverflow https://stackoverflow.com/questions/1050950

Pregunta

Encontré la solución para esta pregunta en C # , pero no puedo traducirla a una sola consulta T-SQL, ya que mi implementación de C # requiere ramificación (si es así).

También encontré la siguiente solución de C #, que podría traducirse a una sola consulta T-SQL pero no produce los resultados correctos

public static double GetAzimuth(WGSCoord c1, WGSCoord c2) { 
     var lat1 = DegToRad(c1.Latitude); 
     var lon1 = DegToRad(c1.Longitude); 
     var lat2 = DegToRad(c2.Latitude); 
     var lon2 = DegToRad(c2.Longitude);

     return RadToDeg(Math.Asin(Math.Sin(lon1 – lon2) * Math.Cos(lat2) / Math.Sin(Math.Acos(Math.Sin(lat2) * Math.Sin(lat1) + Math.Cos(lat1) * Math.Cos(lat2) * Math.Cos(lon2 – lon1))))); 
}

Código de Tamir Khason & # 8211; Solo codifique

¿Alguien podría corregir el código anterior o proporcionar una solución alternativa?

¿Fue útil?

Solución

Reemplazar ifs con expresiones CASE:

   if (latitudinalDifference == 0)
            {
                if (longitudinalDifference != 0)
                {
                    azimuth = Math.PI / 2d;
                }
            }

reemplazar con:

SELECT CASE WHEN @latitudinalDifference = 0 AND @longitudinalDifference <> 0 THEN ...
 ELSE ... END AS azimuth

reemplazar ifs consecutivos con selecciones anidadas:

if(some condition)
{
  i=1; 
}
else
{
 i=2;
}
if(some other condition)
{
  i++; 
}

reemplazar con

SELECT i + CASE WHEN (some other condition) THEN 1 ELSE 0 END
FROM(
SELECT CASE WHEN (some condition) THEN 1 ELSE 2 END AS i
) AS t

Otros consejos

¿Ha considerado crear un ensamblado con un SP en C # para el servidor SQL? Esa es la ruta que probablemente seguiría.

Hay bastante trigonometría esférica necesaria en la respuesta a SO 389211 . Copiando y modificando lo que escribí allí:

Considere un triángulo esférico con ángulos A , B , C en los vértices y lados a , < em> b , c opuesto a esos vértices (es decir, el lado a es de B a C , etc.). Aplicando esto al problema, podemos llamar a los dos puntos dados B y C , y creamos un triángulo esférico recto con un ángulo recto en A .

Considere este diagrama:

                  + C
                 /|
                / |
            a  /  | b
           |  /   |
           |X/    |
           |/     |
         B +------+ A
              c

Se le otorgan dos puntos B y C , y desea determinar el ángulo X = 90 & # 186; - B. El lado c es igual a la diferencia en longitud, & # 916; & # 955 ;; el lado b es igual a la diferencia de latitud, & # 916; & # 966 ;; el ángulo A es 90 & # 186 ;, entonces sin A = 1 y cos A = 0. Para determinar X, queremos el valor de B dado b , c y A .

Mirando el problema desde los primeros principios, necesitamos las dos ecuaciones principales de trigonometría esférica:

  1. La fórmula sinusoidal:

    sin A   sin B   sin C
    ----- = ----- = -----
    sin a   sin b   sin c
    
  2. La fórmula del coseno:

    cos a = cos b . cos c + sin b . sin c . cos A
    

Por lo tanto, creo que una ecuación para a es:

cos a = cos Δλ . cos Δφ + sin Δλ . sin Δφ . cos 90º

a = arccos (cos Δλ . cos Δφ)

Dados a , b y A , podemos usar la fórmula sinusoidal para determinar B :

sin a   sin b
----- = ----
sin A   sin B

O

        sin b . sin A
sin B = -------------
            sin a

O, ya que A = 90 & # 186 ;, sin A = 1, y sin B = sin (90 & # 186; - X) = cos X:

        sin b
cos X = -----
        sin a

Prefiero sospechar que si me inclino (o lo haces), podrías encontrar una respuesta que no implique el uso de arcos seguidos de pecado.

En T-SQL, puede usar la expresión CASE

por ejemplo

SELECT ...
CASE 
    WHEN latD = 0 AND longD < 0 THEN ....
    WHEN latD < 0 AND longD = 0 THEN ....

etc.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top