Podwójne lub dziesiętne dla wartości szerokości / długości geograficznej w języku C #

97

Jaki jest najlepszy typ danych do użycia podczas przechowywania danych geopozycyjnych w C #? Użyłbym dziesiętnego dla jego dokładności, ale operacje na dziesiętnych liczbach zmiennoprzecinkowych są wolniejsze niż binarne liczby zmiennoprzecinkowe (podwójne).

Czytałem, że przez większość czasu nie potrzebujesz więcej niż 6 lub 7 cyfr precyzji dla szerokości lub długości geograficznej. Czy niedokładność podwójnych w ogóle ma wtedy znaczenie, czy można ją zignorować?

KRTac
źródło
6
Zadałbym przeciwne pytanie: czy różnica w wydajności ma w ogóle znaczenie, czy można ją zignorować?
Heinzi,
1
W bazie danych do przechowywania długości i szerokości geograficznej należy użyć „sql spatial data type”
azhar_SE_nextbridge
8
Należy zauważyć, że sam .NET BCL używa podwójnych wartości w swojej klasie GeoCoordinate , co jest mocną wskazówką, że precyzja może być wystarczająca.
Heinzi
1
TzdbZoneLocation NodaTime również używa double.
Rick Davin,
4
1) Rozważałbym stały punkt. 2) Ponieważ często trzeba wykonywać operacje trygonometryczne na współrzędnych geograficznych, a te są realizowane tylko dla double, doublemoże być najlepszym rozwiązaniem.
CodesInChaos

Odpowiedzi:

120

Idź double, jest kilka powodów.

  • Funkcje trygonometryczne są dostępne tylko dla double
  • Precyzja podwójna (zakres 100 nanometrów) jest znacznie większa niż wszystko, czego kiedykolwiek będziesz potrzebować dla wartości Lat / Lon
  • Klasa GeoCoordinate i moduły innych firm (np. DotSpatial ) również używają podwójnego dla współrzędnych
Wernfried Domscheit
źródło
75

Podwójna ma dokładność do 15 cyfr dziesiętnych. Zatem załóżmy, że trzy z tych cyfr będą znajdować się po lewej stronie przecinka dziesiętnego dla wartości szerokości / długości (maksymalnie 180 stopni). Pozostawia to 12 cyfr precyzji po prawej stronie. Ponieważ stopień szerokości / długości wynosi ~ 111 km, 5 z tych 12 cyfr dałoby nam dokładność do metra. 3 dodatkowe cyfry dałyby nam dokładność do milimetra. Pozostałe 4 cyfry dałyby nam precyzję do około 100 nanometrów. Ponieważ podwójna wygra z punktu widzenia wydajności i pamięci, nie widzę powodu, by nawet rozważać użycie dziesiętnych.

MarkPflug
źródło
2
Plus jeden za szczegółowe i precyzyjne wyjaśnienie.
Najeeb
4

Spotkałem się z tym pytaniem już jakiś czas temu, kiedy zacząłem od programowania przestrzennego. Niedawno przeczytałem książkę, która doprowadziła mnie do tego.

//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);

To najlepszy sposób podczas pracy w aplikacji z danymi przestrzennymi. następnie, aby zapisać dane, użyj tego w sql

CREATE TABLE myGeoTable
{
LatLonPoint GEOMETRY 
}

w przeciwnym razie, jeśli używasz czegoś innego, co nie jest sql, po prostu przekonwertuj punkt na szesnastkowy i zapisz go. Wiem po długim czasie używania spacerów, że to jest najbezpieczniejsze.

Jonny
źródło
Mam problem ze znalezieniem LatLonPoint, jakie odniesienia lub pakiety musieliście uwzględnić lub jakie „zastosowania” w projekcie C #? (zakładając, że tabela tworzenia była dla modelu tożsamości / kodu C #, ponieważ ten typ również nie jest oceniany w SSMS). z góry dziękuję!
Chris
1

Podwójnie

Łącząc odpowiedzi, Microsoft przedstawia siebie w bibliotece SqlGeography

[get: Microsoft.SqlServer.Server.SqlMethod (IsDeterministic = true, IsPrecise = true)] public System.Data.SqlTypes.SqlDouble Lat {get; } Wartość właściwości SqlDouble Wartość SqlDouble określająca szerokość geograficzną.

alex.peter
źródło