Doppel- oder Dezimalzahl für Breiten- / Längengrade in C #

96

Was ist der beste Datentyp für die Speicherung von Geopositionsdaten in C #? Ich würde Dezimalstellen für die Genauigkeit verwenden, aber Operationen mit dezimalen Gleitkommazahlen sind langsamer als binäre Gleitkommazahlen (doppelt).

Ich habe gelesen, dass Sie die meiste Zeit nicht mehr als 6 oder 7 Stellen Genauigkeit für Breiten- oder Längengrade benötigen. Ist die Ungenauigkeit von Doppel dann überhaupt von Bedeutung oder kann sie ignoriert werden?

KRTac
quelle
6
Ich würde die gegenteilige Frage stellen: Ist der Leistungsunterschied überhaupt wichtig oder kann er ignoriert werden?
Heinzi
1
In der Datenbank sollten Sie "SQL-Geodatentyp" verwenden, um Längen- und Breitengrade zu speichern
azhar_SE_nextbridge
8
Beachten Sie, dass die .NET BCL selbst in ihrer GeoCoordinate-Klasse Doubles verwendet. Dies ist ein starker Hinweis darauf, dass die Genauigkeit möglicherweise ausreichend ist.
Heinzi
1
Die TzdbZoneLocation von NodaTime verwendet ebenfalls double.
Rick Davin
4
1) Ich würde Fixpunkt in Betracht ziehen. 2) Da Sie häufig trigonometrische Operationen an Geokoordinaten durchführen müssen und diese nur für implementiert sind double, ist dies doublemöglicherweise die beste Lösung.
CodesInChaos

Antworten:

119

Gehen Sie für double, gibt es mehrere Gründe.

  • Trigonometrische Funktionen sind nur für Double verfügbar
  • Die Doppelgenauigkeit (Bereich von 100 Nanometern) geht weit über alles hinaus, was Sie jemals für Lat / Lon-Werte benötigen
  • GeoCoordinate Class- und Drittanbieter-Module (z. B. DotSpatial ) verwenden ebenfalls double für Koordinaten
Wernfried Domscheit
quelle
74

Ein Double hat eine Genauigkeit von bis zu 15 Dezimalstellen. Nehmen wir also an, drei dieser Ziffern befinden sich für Lat / Long-Werte (max. 180 Grad) links vom Dezimalpunkt. Dadurch bleiben rechts 12 Stellen Genauigkeit. Da ein Lat / Long-Grad ~ 111 km beträgt, würden 5 dieser 12 Ziffern uns Präzision für das Messgerät geben. 3 weitere Ziffern würden uns millimetergenau machen. Die verbleibenden 4 Stellen würden uns eine Genauigkeit von etwa 100 Nanometern bringen. Da Double aus Sicht von Leistung und Gedächtnis gewinnen wird, sehe ich keinen Grund, überhaupt die Verwendung von Dezimalzahlen in Betracht zu ziehen.

MarkPflug
quelle
2
Plus eins für eine detaillierte und präzise Erklärung.
Najeeb
4

Ich habe mich vor einiger Zeit mit dieser Frage befasst, als ich mit der räumlichen Programmierung begann. Ich habe vor einiger Zeit ein Buch gelesen, das mich dazu geführt hat.

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

Dies ist der beste Weg, wenn Sie in Ihrer Anwendung mit räumlichen Daten arbeiten. Um die Daten zu speichern, verwenden Sie diese in SQL

CREATE TABLE myGeoTable
{
LatLonPoint GEOMETRY 
}

Andernfalls, wenn Sie etwas anderes verwenden, das nicht SQL ist, konvertieren Sie den Punkt einfach in hexadezimal und speichern Sie ihn. Ich weiß nach langer Zeit mit Spacial, dass dies am sichersten ist.

Jonny
quelle
Ich habe Probleme, LatLonPoint zu finden. Welche Referenzen oder Pakete mussten Sie aufnehmen oder welche "Verwendungen" haben Sie in Ihrem c # -Projekt? (Angenommen, die Erstelltabelle war für Identitätsmodell / c # -Code, da dieser Typ auch in SSMS nicht ausgewertet wird.) Vielen Dank im Voraus!
Chris
0

Doppelt

Durch die Kombination der Antworten wird es von Microsoft selbst in der SqlGeography-Bibliothek dargestellt

[get: Microsoft.SqlServer.Server.SqlMethod (IsDeterministic = true, IsPrecise = true)] public System.Data.SqlTypes.SqlDouble Lat {get; } Eigenschaftswert SqlDouble Ein SqlDouble-Wert, der den Breitengrad angibt.

alex.peter
quelle