C#中用double或decimal来表示纬度/经度值?

132

在C#中存储地理位置数据时,最好使用哪种数据类型? 我会使用decimal来获取其精确性,但是与二进制浮点数(double)相比,操作decimal浮点数速度较慢。

我读到大多数情况下,纬度或经度不需要超过6或7位数字的精度。那么double的不准确性是否重要,还是可以忽略不计?


7
我来翻译一下:我会提出相反的问题:性能差异是否重要,还是可以忽略不计? - Heinzi
2
在数据库中,您应该使用“SQL空间数据类型”来存储经度和纬度。 - azhar_SE_nextbridge
10
请注意,.NET基础类库本身在其GeoCoordinate类中使用双精度浮点数,这是一个强烈的暗示,表明精度可能已足够。 - Heinzi
2
NodaTime的TzdbZoneLocation也使用double。 - Rick Davin
5
1)我会考虑固定点。 2)由于在地理坐标上经常需要执行三角函数操作,而这些操作仅适用于“double”类型,因此“double”可能是最合适的选择。 - CodesInChaos
显示剩余3条评论
5个回答

171

选择 double,有几个原因。

  • 只有 double 可以使用三角函数
  • double 的精度(100纳米范围内)远远超出你在Lat/Lon值中所需的任何东西
  • GeoCoordinate Class 和第三方模块(例如DotSpatial)也使用double来表示坐标

107

一个 double 类型可以保留最多15个十进制数字的精度。因此,我们假设在纬度和经度值的小数点左侧有三个数字(最大为180度)。这样就剩下12位数字精度在小数点右侧。由于一度的纬度/经度约为111公里,其中5位数字将给我们提供米级别的精度。再加上3位数字即可得到毫米级别的精度,而剩下的4位数字则可以使我们获得约100纳米的精度。考虑到性能和内存方面,double 类型是更好的选择,因此我认为没有理由考虑使用 decimal 类型。


6
感谢详细准确的解释。 - Najeeb
1
正是我想要看到的解释,谢谢! - e4stwood
你已经说服我从十进制团队转到双精度团队处理坐标。感谢你构建得很好的评论。 - undefined

7

当我开始学习空间编程时,我曾经遇到过这个问题。我之前读过一本书,它引导了我走向这条路。

//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的东西,请将点转换为十六进制并存储。我知道长时间使用空间后,这是最安全的方法。


1
我在寻找LatLonPoint时遇到了麻烦,请问您需要包含哪些引用或软件包,或者在您的C#项目中需要使用哪些“usings”?(假设创建表格是为了Identity模型/C#代码,因为该类型在SSMS中也无法评估)。提前感谢您! - Chris

4

双倍

综合答案,这是微软在SqlGeography库中表示自己的方式。

[get: Microsoft.SqlServer.Server.SqlMethod(IsDeterministic=true, IsPrecise=true)]
public System.Data.SqlTypes.SqlDouble Lat { get; }

属性值

SqlDouble

一个 SqlDouble 值,用于指定纬度。


2

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接