1

What S2Region should i use and how should i use it to get all cells within a circle given a latitude, longitude and a radius in miles/km using google's s2 library?

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

Thanks

Darshan
  • 39
  • 2
  • 4
  • 1
    @tarantula - followed your post http://blog.christianperone.com/2015/08/googles-s2-geometry-on-the-sphere-cells-and-hilbert-curve/ however was not able to figure out how to do it with circular region. Appreciate your help on the same. – Darshan Jul 20 '16 at 04:20

2 Answers2

1

Here's a C++ example from the npm package s2geometry-node. The code was copied from viewfinder/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;
}
1

I had encountered the same task and solved it with the usage of S2RegionCoverer.getCovering(S2Region region, ArrayList<S2CellId> covering) method.

The problem why you were getting cells of a different levels is described in S2RegionCoverer.getCovering(S2Region region) documentation:

/**
   * 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.)
   */
amukhachov
  • 5,822
  • 1
  • 41
  • 60