1

我如何存储一个矩形 - 由 2 个点 NorthEast 和 SouthWest 组成,每个点都是纬度和经度的坐标

并添加一个由中心( lat-lng )和半径(int/float 值)组成的圆

如果 lat-lng 在任何圆形或矩形的范围内,存储和稍后查询的最佳方法是什么?另外,我可以存储一个数组吗?在一条记录中说 10 个矩形和 5 个圆形?我可以使用 Nhibernate 来缓解疼痛吗?

对不起,如果这看起来很无聊,我从来没有对空间数据做过任何事情,我什至不知道从哪里开始。任何示例和指针都有帮助!提前致谢。

4

1 回答 1

2

下面是我如何使用 TSQL 来解决这个问题。

对于矩形,最简单的方法是使用原始点的相关坐标外推额外的 2 个点。例如

东北 (lat1, lon1) 西北* (lat1, lon2)

东南* (lat2, lon1) 西南 (lat2, lon2)

*新点

这并没有给你一个真正的矩形(在数学意义上),但它是 GIS 中的一种常用方法(它是 geohashes 的形成方式)你得到的是一个粗略的矩形,其大小根据与赤道的距离而变化。如果您需要某个高度/宽度的精确矩形,您应该考虑使用 Haversine 公式来计算剩余的 2 个点,这将考虑到方位角和大圆距离。

http://www.movable-type.co.uk/scripts/latlong.html

为了存储矩形,我将创建一个带有 GEOGRAPHY 类型列的 SQL 表,这将允许您分配其他属性(例如名称)以及空间索引,这将使未来的查询更快。

CREATE TABLE dbo.geographies
(
    NAME VARCHAR(50)
    ,GEOG GEOGRAPHY
)

INSERT INTO dbo.geographies (NAME, GEOG)
VALUES ('Rectangle', geography::STPolyFromText('POLYGON((lon1 lat1, lon2 lat1, lon2 lat2, lon1 lat2, lon1 lat1))', 4326))

请注意,第一个点和最后一个点是相同的,这是“关闭”多边形所必需的,最后一个数字表示 SRID 或坐标系,在本例中为 WGS84。你可以参考这个页面:http: //msdn.microsoft.com/en-us/library/bb933971

至于圆,存储一个点然后使用半径在该点周围应用缓冲区很简单:

INSERT INTO dbo.geographies (NAME, GEOG)
VALUES ('Circle with Radius', geography::STPointFromText('POINT(lon lat)', 4326).STBuffer([radius]))

请注意,缓冲区以米为单位输入,因此您可能需要应用转换,此页面上的更多注释:http: //msdn.microsoft.com/en-us/library/bb933979

现在有趣的部分是,使用 STIntersects 方法很容易检查一个点上的交叉点。

http://msdn.microsoft.com/en-us/library/bb933962.aspx

DECLARE @point GEOGRAPHY = geography::STPointFromText('POINT(lon lat)', 4326)

SELECT * FROM dbo.geographies
WHERE @point.STIntersects(GEOG) = 1

代码示例获取一个点并返回该点所在的所有地理位置的列表。重要的是新点的 SRID 和表中的地理匹配,否则您将获得零匹配(并且可能会在您意识到自己的错误之前将您的头撞到墙上一段时间,至少,这就是我所做的) .

至于将它与 C# 集成,我不确定我能提供多少帮助,但返回 SQLGeography 类型应该不是太大的挑战

http://msdn.microsoft.com/en-us/library/microsoft.sqlserver.types.sqlgeography.aspx

希望这至少可以为您指明正确的方向。

于 2012-07-06T13:31:33.140 回答