7

我有车辆的地理位置和我在城市中的点,我需要找到那些在我点半径 5 公里内的车辆。我可以用 S2 单元 ID 表示车辆位置和我的观点。但我该如何查询?

我可以将所有用户的数据存储在数据库中并查询 S2 单元格 ID。由于 S2 cell id 使用 Hilbert 曲线,我们可以知道那些具有更接近 S2 cell id 的车辆彼此之间的距离更近。还是我必须在这里使用其他任何方法来执行搜索操作?

4

1 回答 1

10

我会把这个问题分成几个步骤:

  1. 为您的应用程序选择合适的 S2 级别。在您的情况下,由于您以 5 KM 半径进行查询,我会选择13 级单元格,其平均大小为 1.27 km^2

  2. 生成覆盖人周围 5 公里半径的 13 级单元格。

  3. 从汽车的 lat/lng 获取 13 级单元格。

  4. 对汽车 S2 小区进行包含检查,以覆盖 5 公里半径的 S2 小区。

这是Node.js JavaScript S2 库的示例:

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

# s2 cell level of ~1.27 km^2
const level = 13;

# cell covering of enclosure around a person
const enclosureLLs = [
  [40.77933906065449, -73.96983146667479],
  [40.77933906065449, -73.9634370803833],
  [40.78483079505022, -73.9634370803833],
  [40.78483079505022, -73.96983146667479],
].map((latlng) => {
  const [lat, lng] = latlng;
  return new s2.LatLng(lat, lng);
});

const enclosureCells = new Set(s2.RegionCoverer.getCoveringTokens(enclosureLLs, { min: level, max: level }));
# -> Set { '89c25894', '89c2589c' }

// arbitrary vehicle lat longs

const vehicle1 = new s2.CellId(new s2.LatLng(40.78340103809933,  -73.96515369415283)).parent(level);
# -> '89c2589c'

const vehicle2 = new s2.CellId(new s2.LatLng(40.782848623761375, -73.95506858825684)).parent(level);
# -> '89c258a4'


console.log(enclosureCells.has(vehicle1.token()));
# -> true

console.log(enclosureCells.has(vehicle2.token()));
# -> false

您可以使用 Sidewalk Lab 的 S2 地图工具将其可视化:

于 2019-09-04T21:45:42.713 回答