在SQL Server中查找地理空间数据的前K个最常见位置

时间:2018-08-29 07:34:08

标签: sql sql-server geometry geospatial

我们拥有的用户数据本质上是地理空间(纬度,经度)。我们使用SQL Server来存储此数据(几何数据类型)。是否有任何实现方式可以让用户了解用户访问过的最热门的k个地理位置(地理位置数据)。假设我们的半径为100m,并考虑其中的所有点到同一位置。这基本上意味着对所有用户位置进行聚类,并找到填充量最大的聚类。

就像标量值一样,我们在表上进行分组以找出哪个条目出现得最多。如何为地理数据实现这一目标?

1 个答案:

答案 0 :(得分:0)

Geohashing可用于解决此问题,这是一种用哈希表述地球区域的方法。有效的实现是Google的S2库。

使用S2,您将执行以下操作:

  1. 将每个点分配给代表区域的给定S2 CellId(您可以将其调整为a face of the Earth to something smaller than your fingertip的不同区域级别)

  2. 在检索时,对于给定点,将其转换为S2 CellId并将其分解为处于索引级别的S2 CellId。然后使用简单的SELECT * FROM points WHERE point.s2_cell_id IN $RETRIEVAL_IDS

  3. 获取所有“集群”

下面是使用Node S2 library建立索引的简单示例:

const s2 = require('@radarlabs/s2');

const user1LongLat = [-73.95772933959961, 40.71623280185081];
const user2LongLat = [-73.95927429199219, 40.71629785715124];
const user3LongLat = [-73.99206161499023, 40.688708709249646];

const user1S2 = ["user1", new s2.CellId(new s2.LatLng(user1LongLat[1], user1LongLat[0])).parent(13)];
const user2S2 = ["user2", new s2.CellId(new s2.LatLng(user2LongLat[1], user2LongLat[0])).parent(13)];
const user3S2 = ["user3", new s2.CellId(new s2.LatLng(user3LongLat[1], user3LongLat[0])).parent(13)];

const groups = {};
[user1S2, user2S2, user3S2].forEach(([userId, cellId]) => {
  const group = groups[cellId.token()] || [];
  group.push(userId);
  groups[cellId.token()] = group;
});

console.log(groups); // { '89c2595c': [ 'user1', 'user2' ], '89c25a4c': [ 'user3' ] }

现在,这只是一个简单的查找。 S2具有将给定区域转换为S2单元格的方法,因此您可以按单个点或区域进行查询。

您可以可视化this on the map here

相关问题