Doble o decimal para valores de latitud / longitud en C #

97

¿Cuál es el mejor tipo de datos para usar al almacenar datos geoposicionales en C #? Usaría decimal por su exactitud, pero las operaciones con números de coma flotante decimal son más lentas que los números de coma flotante binaria (doble).

Leí que la mayoría de las veces no necesitará más de 6 o 7 dígitos de precisión para latitud o longitud. ¿Importa entonces la inexactitud de los dobles o puede ignorarse?

KRTac
fuente
6
Yo haría la pregunta opuesta: ¿importa la diferencia de rendimiento o se puede ignorar?
Heinzi
1
En la base de datos, debe usar "tipo de datos espaciales sql" para almacenar la longitud y la latitud
azhar_SE_nextbridge
8
Tenga en cuenta que .NET BCL en sí mismo usa dobles en su clase GeoCoordinate , lo cual es una fuerte indicación de que la precisión podría ser suficiente.
Heinzi
1
TzdbZoneLocation de NodaTime también usa double.
Rick Davin
4
1) Consideraría un punto fijo. 2) Dado que a menudo necesita realizar operaciones trigonométricas en coordenadas geográficas, y esas solo se implementan para double, doublepodría ser la mejor opción.
CodesInChaos

Respuestas:

120

Adelante double, hay varias razones.

  • Las funciones trigonométricas están disponibles solo para doble
  • La precisión del doble (rango de 100 nanómetros) supera con creces cualquier cosa que pueda necesitar para los valores Lat / Lon
  • La clase GeoCoordinate y los módulos de terceros (por ejemplo, DotSpatial ) también usan doble para las coordenadas
Wernfried Domscheit
fuente
75

Un doble tiene hasta 15 dígitos decimales de precisión. Entonces, supongamos que tres de esos dígitos estarán a la izquierda del punto decimal para los valores lat / long (máximo de 180 grados). Esto deja 12 dígitos de precisión a la derecha. Dado que un grado de latitud / longitud es ~ 111 km, 5 de esos 12 dígitos nos darían precisión al metro. 3 dígitos más nos darían precisión al milímetro. Los 4 dígitos restantes nos llevarían a una precisión de alrededor de 100 nanómetros. Dado que el doble ganará desde la perspectiva del rendimiento y la memoria, no veo ninguna razón para considerar siquiera usar decimal.

MarkPflug
fuente
2
Más uno para una explicación detallada y precisa.
Najeeb
4

Me enfrenté a esta pregunta hace bastante tiempo cuando comencé con la programación espacial. Leí un libro hace un tiempo que me llevó a esto.

//sql server has a really cool dll that deals with spacial data such like
//geography points and so on. 
//add this namespace
Using Microsoft.SqlServer.Types;

//SqlGeography.Point(dblLat, dblLon, srid)

var lat_lon_point = Microsoft.SqlServer.Types.SqlGeography.Point(lat, lon, 4326);

Esta es la mejor forma de trabajar en su aplicación con datos espaciales. luego, para guardar los datos, use esto en sql

CREATE TABLE myGeoTable
{
LatLonPoint GEOMETRY 
}

de lo contrario, si está usando otra cosa que no sea SQL, simplemente convierta el punto a hexadecimal y guárdelo. Después de mucho tiempo usando spacial, sé que este es el más seguro.

Jonny
fuente
Tengo problemas para encontrar LatLonPoint, ¿qué referencias o paquetes tuvo que incluir o qué 'usos' en su proyecto de c #? (asumiendo que la tabla de creación fue para el modelo de identidad / código c #, porque ese tipo tampoco se evalúa en SSMS). ¡gracias de antemano!
Chris
1

Doble

Combinando las respuestas, es como Microsoft lo representa en la biblioteca SqlGeography.

[get: Microsoft.SqlServer.Server.SqlMethod (IsDeterministic = true, IsPrecise = true)] public System.Data.SqlTypes.SqlDouble Lat {get; } Valor de propiedad SqlDouble Un valor de SqlDouble que especifica la latitud.

alex.peter
fuente