使用 google s2 库 - 查找圆圈内某个级别的所有 s2 单元,给定 lat/lng 和以英里/公里为单位的半径

Posted

技术标签:

【中文标题】使用 google s2 库 - 查找圆圈内某个级别的所有 s2 单元,给定 lat/lng 和以英里/公里为单位的半径【英文标题】:Using google s2 library - find all s2 cells of a certain level within the circle, given lat/lng and radius in miles/km 【发布时间】:2016-07-20 04:18:52 【问题描述】:

我应该使用什么 S2Region 以及如何使用它使用谷歌的 s2 库在给定纬度、经度和以英里/公里为单位的半径的圆圈内获取所有单元格?

S2Region region = ?
S2RegionCoverer coverer = new S2RegionCoverer();
coverer.setMinLevel(17);
coverer.setMaxCells(17);
S2CellUnion covering = coverer.getCovering(region_cap);

谢谢

【问题讨论】:

@tarantula - 关注了您的帖子blog.christianperone.com/2015/08/…,但无法弄清楚如何使用圆形区域进行操作。感谢您的帮助。 【参考方案1】:

这是来自 npm 包 s2geometry-node 的 C++ 示例。代码是从取景器/viewfinder.cc 复制过来的

const double kEarthCircumferenceMeters = 1000 * 40075.017;

double EarthMetersToRadians(double meters) 
  return (2 * M_PI) * (meters / kEarthCircumferenceMeters);


string CellToString(const S2CellId& id) 
  return StringPrintf("%d:%s", id.level(), id.ToToken().c_str());


// Generates a list of cells at the target s2 cell levels which cover
// a cap of radius 'radius_meters' with center at lat & lng.
vector<string> SearchCells(double lat, double lng, double radius_meters,
                           int min_level, int max_level) 
  const double radius_radians = EarthMetersToRadians(radius_meters);
  const S2Cap region = S2Cap::FromAxisHeight(
      S2LatLng::FromDegrees(lat, lng).Normalized().ToPoint(),
      (radius_radians * radius_radians) / 2);
  S2RegionCoverer coverer;
  coverer.set_min_level(min_level);
  coverer.set_max_level(max_level);

  vector<S2CellId> covering;
  coverer.GetCovering(region, &covering);
  vector<string> v(covering.size());
  for (size_t i = 0; i < covering.size(); ++i) 
    v[i] = CellToString(covering[i]);
  
  return v;

【讨论】:

【参考方案2】:

我遇到了同样的任务,并使用S2RegionCoverer.getCovering(S2Region region, ArrayList&lt;S2CellId&gt; covering) 方法解决了它。

S2RegionCoverer.getCovering(S2Region region) 文档中描述了您获得不同级别单元格的问题:

/**
   * Return a normalized cell union that covers the given region and satisfies
   * the restrictions *EXCEPT* for min_level() and level_mod(). These criteria
   * cannot be satisfied using a cell union because cell unions are
   * automatically normalized by replacing four child cells with their parent
   * whenever possible. (Note that the list of cell ids passed to the cell union
   * constructor does in fact satisfy all the given restrictions.)
   */

【讨论】:

以上是关于使用 google s2 库 - 查找圆圈内某个级别的所有 s2 单元,给定 lat/lng 和以英里/公里为单位的半径的主要内容,如果未能解决你的问题,请参考以下文章

【在线等】怎么在百度地图上查找方圆多少公里内的地方

可以使用 S2 库找到 K 个最近点(并且有效)?

MySQL 级联库提升从库 从库降级级联库方法

高效的多维空间点索引算法 — Geohash 和 Google S2

高效的多维空间点索引算法 — Geohash 和 Google S2

怎样用C语言编写程序判断字符串S1是不是包含字符串S2.(不使用库函数)