如何使用 Google S2 几何执行搜索操作
How to perform the Search operation using Google S2 geometry
我有车辆的地理位置和我在城市中的地点,我需要找到在我的地点 5 公里半径范围内的那些车辆。
我可以用 S2 单元 ID 表示车辆位置和我的点。但是怎么查询呢?
我可以将所有用户的数据存储在数据库中并查询 S2 单元 ID。
由于 S2 cell id 使用的是希尔伯特曲线,我们能否知道那些具有更接近 S2 cell id 的车辆彼此之间的距离更近。
或者我必须在这里使用任何其他方法来执行搜索操作?
我会将这个问题分解成几个步骤:
为您的申请选择合适的 S2 级别。在您的情况下,由于您要按 5 公里半径查询,我会选择 级别 13 单元格 ,它们具有 average size of 1.27 km^2.
生成一个覆盖人周围5公里半径的13级单元格。
从汽车的 lat/lng 获得一个 13 级电池。
对汽车 S2 Cell 进行包含检查,以覆盖 5 KM 半径的 S2 Cell。
这里有一个例子 Node.js JavaScript S2 Library:
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 地图工具可视化它的外观:
我有车辆的地理位置和我在城市中的地点,我需要找到在我的地点 5 公里半径范围内的那些车辆。 我可以用 S2 单元 ID 表示车辆位置和我的点。但是怎么查询呢?
我可以将所有用户的数据存储在数据库中并查询 S2 单元 ID。 由于 S2 cell id 使用的是希尔伯特曲线,我们能否知道那些具有更接近 S2 cell id 的车辆彼此之间的距离更近。 或者我必须在这里使用任何其他方法来执行搜索操作?
我会将这个问题分解成几个步骤:
为您的申请选择合适的 S2 级别。在您的情况下,由于您要按 5 公里半径查询,我会选择 级别 13 单元格 ,它们具有 average size of 1.27 km^2.
生成一个覆盖人周围5公里半径的13级单元格。
从汽车的 lat/lng 获得一个 13 级电池。
对汽车 S2 Cell 进行包含检查,以覆盖 5 KM 半径的 S2 Cell。
这里有一个例子 Node.js JavaScript S2 Library:
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 地图工具可视化它的外观: