Двойное или десятичное значение для значений широты и долготы в C #

97

Какой тип данных лучше всего использовать при хранении геопозиционных данных на C #? Я бы использовал десятичное число для его точности, но операции с десятичными числами с плавающей запятой медленнее, чем с двоичными числами с плавающей запятой (double).

Я читал, что в большинстве случаев вам не понадобится более 6 или 7 цифр точности для широты или долготы. Имеет ли значение тогда неточность двойников или ее можно игнорировать?

KRTac
источник
6
Я бы задал противоположный вопрос: имеет ли значение разница в производительности или ее можно игнорировать?
Heinzi
1
В базе данных вы должны использовать «тип пространственных данных sql» для хранения долготы и широты
azhar_SE_nextbridge
8
Обратите внимание, что сам .NET BCL использует двойники в своем классе GeoCoordinate , что является убедительным признаком того, что точность может быть достаточной.
Heinzi
1
TzdbZoneLocation NodaTime также использует double.
Рик Дэвин
4
1) Я бы рассмотрел фиксированную точку. 2) Поскольку вам часто нужно выполнять тригонометрические операции с географическими координатами, а они реализованы только для double, это doubleможет быть наилучшим вариантом.
CodesInChaos

Ответы:

120

Идите double, есть несколько причин.

  • Тригонометрические функции доступны только для двойных
  • Точность удвоения (диапазон 100 нанометров) намного превосходит все, что вам когда-либо понадобится для значений широты и долготы.
  • Класс GeoCoordinate и сторонние модули (например, DotSpatial ) также используют double для координат
Вернфрид Домшайт
источник
75

Двойное значение имеет точность до 15 десятичных знаков. Итак, давайте предположим, что три из этих цифр будут слева от десятичной точки для значений широты / долготы (максимум 180 градусов). Это оставляет 12 знаков точности справа. Поскольку градус широты / долготы составляет ~ 111 км, 5 из этих 12 цифр дадут нам точность до метра. Еще 3 цифры дадут нам точность до миллиметра. Оставшиеся 4 цифры обеспечат точность порядка 100 нанометров. Поскольку double будет выигрывать с точки зрения производительности и памяти, я не вижу причин даже рассматривать использование decimal.

MarkPflug
источник
2
Плюс один за подробное и точное объяснение.
Najeeb
4

Я столкнулся с этим вопросом довольно давно, когда начинал заниматься пространственным программированием. Некоторое время назад я прочитал книгу, которая привела меня к этому.

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

Это лучший способ работы в вашем приложении с пространственными данными. затем для сохранения данных используйте это в sql

CREATE TABLE myGeoTable
{
LatLonPoint GEOMETRY 
}

иначе, если вы используете что-то еще, кроме sql, просто преобразуйте точку в шестнадцатеричное и сохраните. Я знаю после долгого использования spacial, что это самый безопасный.

Джонни
источник
У меня проблемы с поиском LatLonPoint, какие ссылки или пакеты вы должны были включить или какие «использования» в вашем проекте C #? (предполагая, что таблица создания предназначена для модели Identity / кода C #, поскольку этот тип также не оценивается в SSMS). заранее спасибо!
Крис
1

Двойной

Объединив ответы, это то, как Microsoft представляет себя в библиотеке SqlGeography

[получить: Microsoft.SqlServer.Server.SqlMethod (IsDeterministic = true, IsPrecise = true)] общедоступный System.Data.SqlTypes.SqlDouble Lat {получить; } Значение свойства SqlDouble Значение SqlDouble, определяющее широту.

Алексей Петр
источник