Duplo ou decimal para valores de latitude / longitude em C #

96

Qual é o melhor tipo de dados a ser usado ao armazenar dados geográficos em C #? Eu usaria decimal para sua exatidão, mas as operações em números de ponto flutuante decimal são mais lentas do que os números de ponto flutuante binário (duplo).

Eu li que na maioria das vezes você não precisará de mais de 6 ou 7 dígitos de precisão para latitude ou longitude. A inexatidão dos duplos importa então ou pode ser ignorada?

KRTac
fonte
6
Eu faria a pergunta oposta: a diferença de desempenho é importante ou pode ser ignorada?
Heinzi
1
No banco de dados, você deve usar "tipo de dados espaciais sql" para armazenar longitude e latitude
azhar_SE_nextbridge
8
Observe que o próprio .NET BCL usa double em sua classe GeoCoordinate , o que é uma forte indicação de que a precisão pode ser suficiente.
Heinzi
1
O TzdbZoneLocation do NodaTime também usa o dobro.
Rick Davin
4
1) Eu consideraria um ponto fixo. 2) Uma vez que você frequentemente precisa fazer operações trigonométricas em coordenadas geográficas, e essas são implementadas apenas para double, doublepode ser o melhor ajuste.
CodesInChaos

Respostas:

120

Vá em frente double, há vários motivos.

  • As funções trigonométricas estão disponíveis apenas para dupla
  • A precisão do dobro (faixa de 100 nanômetros) está muito além de qualquer coisa que você possa precisar para valores de Lat / Lon
  • Classe GeoCoordinate e módulos de terceiros (por exemplo, DotSpatial ) também usam double para coordenadas
Wernfried Domscheit
fonte
74

Um duplo tem até 15 dígitos decimais de precisão. Então, vamos supor que três desses dígitos estarão à esquerda da vírgula decimal para os valores de latitude / longitude (máximo de 180 graus). Isso deixa 12 dígitos de precisão à direita. Como um grau de latitude / longitude é ~ 111km, 5 desses 12 dígitos nos dariam a precisão do metro. Mais 3 dígitos nos dariam a precisão milimétrica. Os 4 dígitos restantes nos forneceriam uma precisão de cerca de 100 nanômetros. Já que o dobro vai ganhar do ponto de vista de desempenho e memória, não vejo razão para sequer considerar o uso de decimal.

MarkPflug
fonte
2
Mais um para uma explicação detalhada e precisa.
Najeeb
4

Enfrentei essa questão há algum tempo, quando comecei com a programação espacial. Eu li um livro há algum tempo que me levou a isso.

//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 é a melhor maneira de trabalhar em sua aplicação com dados espaciais. então para salvar os dados use isto em sql

CREATE TABLE myGeoTable
{
LatLonPoint GEOMETRY 
}

senão, se você estiver usando algo que não seja sql, apenas converta o ponto em hexadecimal e armazene-o. Sei depois de muito tempo usando o espaço que esse é o mais seguro.

Jonny
fonte
Estou tendo problemas para encontrar o LatLonPoint, quais referências ou pacotes você precisou incluir ou quais 'usos' em seu projeto c #? (assumindo que a tabela de criação foi para o modelo de identidade / código c #, porque esse tipo também não avalia no SSMS). Agradeço antecipadamente!
Chris
0

Duplo

Combinando as respostas, é como a Microsoft se representa na biblioteca SqlGeography

[obter: Microsoft.SqlServer.Server.SqlMethod (IsDeterministic = true, IsPrecise = true)] public System.Data.SqlTypes.SqlDouble Lat {get; } Valor da propriedade SqlDouble Um valor SqlDouble que especifica a latitude.

alex.peter
fonte