在SQL Server数据库中进行平均纬度/经度值计算

7
我是新手对于SQL Server,我在试图找出如何完成以下操作:
有数千个指向相同位置或非常接近位置的纬度/经度数据。所有这些数据都以LAT和LONG列的形式存储在SQL Server表中。
现在需要对这些纬度/经度数据进行聚类,并从每个聚类中选择一个代表,应该怎么做?
我阅读了一种叫做“STCentroid”的方法: https://msdn.microsoft.com/en-us/library/bb933847.aspx 但让服务器处理包含所有这些数百万行数据的多边形并查找中心点是否值得?这可能意味着所有附近重复项的单个表示。这种方式可能不太高效/正确?
只有距离很近的点才被视为重复项。
我正在考虑如何选择正确的代表。
换句话说:
如果有一组GPS位置G1{}试图指向物理位置L1。& 有一组GPS位置G2{}试图指向物理位置L2。如何从G1{}中推导出中心点CP1。& 从G2{}中推导出CP2,使得CP1非常靠近L1 & CP2非常靠近L2。
事实是,L1和L2可能非常接近,例如10英尺。
我想知道如何解决这个问题。请帮忙?

1
为什么这个问题被负投票了?-1? - user1534863
@Martin。感谢您的回复。如果我只需要一个最终的Lat/long作为结果,那么建议的答案会起作用。但是在这里,我需要从每个段派生出一组最终的Lat/long(S)。因此,对于成千上万条记录,最终输出将是CP1、CP2、CP3、CP4...CPn。 - user1534863
你是想要生成一个聚类并输出其坐标吗? - Jon Bellamy
1
@user1534863 好的,明白了。你需要在数据库层面上完成这个任务吗?还是可以用(例如)c#来实现?另外,如果我们要进行聚类,你是否满意于使用任意点来代表聚类网格的中心,或者你希望聚类是由距离网格中心最近的单一记录的坐标组成的? - Jon Bellamy
确实非常相似:https://dev59.com/-3RC5IYBdhLWcg3wVvfL。请注意,如果您的许可证包括它,[SQL Server Analysis Services会为您完成此操作](https://msdn.microsoft.com/en-us/library/cc280445.aspx) ... - AakashM
显示剩余3条评论
1个回答

3
聚类点可能会有问题。如果两个潜在的聚类很接近,那么你将会遇到问题;如果需要精度或优化,则需要对实现进行一些研究。可以尝试: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。让我试试这个,然后回来。 - user1534863
没问题。嘿,我刚意识到在更新部分我漏掉了一个条件,即AND CluserID IS NULL。抱歉。 - hcaelxxam

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