在 SQL Server 数据库中平均纬度/经度
Posted
技术标签:
【中文标题】在 SQL Server 数据库中平均纬度/经度【英文标题】:Averaging out Lat/longs in SQL Server database 【发布时间】:2015-08-23 06:46:41 【问题描述】:我是 SQL Server 的新手。我正在尝试弄清楚如何完成以下任务:
我有数千个纬度/经度位置指向同一个或非常接近的位置。它都以 LAT 和 LONG 列的形式存储在 SQL Server 表中。
现在要对纬度/经度进行聚类并为每个聚类选择一种表示形式,我必须做什么?
我通读了一个名为“STCentroid”的方法: https://msdn.microsoft.com/en-us/library/bb933847.aspx
但是让服务器用所有这百万行做一个多边形并找到中心点是否值得?这将隐含地表示所有附近重复项的单一表示。可能是一种有效/错误的方式?
只有几米左右的点必须被视为重复条目。 我正在考虑如何选择正确的表示。
用更好的话来说:
如果有一组点 G1(GPS 位置)试图指向位置 L1。 (物理位置)。 & 有一组点 G2,试图指向位置 L2。如何从 G1 导出中心点 CP1。 & CP2 来自 G2,因此 CP1 非常接近 L1 而 CP2 非常接近 L2。
事实上,L1 和 L2 可能非常接近,例如 10 英尺。
只是在想我该如何解决这个问题。有什么帮助吗?
【问题讨论】:
为什么这个问题被否决了? -1? 为什么不把所有纬度平均得到平均纬度,把所有经度平均得到平均经度?由于这些点都靠近在一起应该给出合理的结果。 @Martin。谢谢回复。如果我必须得到一个最终的 Lat/long 作为结果,建议的答案会起作用。但是在这里,我需要从每个段中派生出最后一组 Lat/long(S)。因此,在数千条记录中,最终输出将是 CP1、CP2、CP3、CP4...CPn。 你想生成一个簇并输出它的坐标吗? @user1534863 好的,明白了。好的 - 你在数据库级别需要这个,还是你可以在(例如)c# 中做到这一点?另外,如果我们要进行聚类,您是否对代表聚类网格中心的任意点感到满意,或者您是否希望聚类是最接近网格中心的奇异记录的坐标? 【参考方案1】:聚类点会有问题。如果你有两个潜在的集群靠得很近,你就会遇到问题,如果你需要精确或优化,那么你需要对你的实现做一些研究。试试看:Wiki-Cluster Analysis
但是,如果点集群相距甚远,那么您可以尝试一个相当简单的集群,然后找到包络。
这样的事情可能会奏效,尽管您会很好地实际创建一个空间列并添加一个空间索引。
ALTER TABLE Recordset ADD (ClusterID INT) -- Add a grouping ID
GO
DECLARE @i INT --Group Counter
DECLARE @g GEOGRAPHY --Point from which the cluster will be made
DECLARE @Limit INT --Distance limitation
SET @Limit = 10
SET @i = 0
WHILE (SELECT COUNT(*) FROM Recordset R WHERE ClusterID IS NULL) > 0 --Loop until all points are clustered
BEGIN
SET @g = (SELECT TOP 1 GEOGRAPHY::STPointFromText('POINT(' + CAST(LAT AS VARCHAR(20)) + ' ' + CAST(LONG AS VARCHAR(20)) + ')', 4326) WHERE ClusterID IS NULL) --Point to cluster on
UPDATE Recordset SET ClusterID = @i WHERE GEOGRAPHY::STPointFromText('POINT(' + CAST(LAT AS VARCHAR(20)) + ' ' + CAST(LONG AS VARCHAR(20)) + ')', 4326).STDistance(@g) < @Limit AND ClusterID IS NULL--update all points within the limit circle
SET @i = @i + 1
END
SELECT --Clustered centers
ClusterID,
GEOGRAPHY::ConvexHullAggregate(GEOGRAPHY::STPointFromText('POINT(' + CAST(LAT AS VARCHAR(20)) + ' ' + CAST(LONG AS VARCHAR(20)) + ')', 4326)).EnvelopeCenter().Lat AS 'LatCenter',
GEOGRAPHY::ConvexHullAggregate(GEOGRAPHY::STPointFromText('POINT(' + CAST(LAT AS VARCHAR(20)) + ' ' + CAST(LONG AS VARCHAR(20)) + ')', 4326)).EnvelopeCenter().Long AS 'LatCenter',
FROM
RecordSet
GROUP BY
ClusterID
【讨论】:
感谢 hcaelxxam 的简洁回复。让我试试这个然后回来。 没问题。嘿,我刚刚意识到我在更新部分遗漏了一个条件,即 AND CluserID 为 NULL。对不起。以上是关于在 SQL Server 数据库中平均纬度/经度的主要内容,如果未能解决你的问题,请参考以下文章
在 SQL Server 中使用纬度和经度查找两点之间的距离