使用 Python S2/S2sphere 库 - 在一个圆中找到特定级别的所有 s2 单元格(给出纬度、经度和半径)
Using Python S2/S2sphere library - find all s2 cells of a particular level with in a circle(lat, long and radius is given)
什么 S2Region 以及我应该如何使用从给定的纬度、经度和半径绘制的圆覆盖特定父级别(假设 9)的所有 s2 单元格。下面是一个使用 python s2 库获取矩形下所有单元格的示例。
region_rect = S2LatLngRect(
S2LatLng.FromDegrees(-51.264871, -30.241701),
S2LatLng.FromDegrees(-51.04618, -30.000003))
coverer = S2RegionCoverer()
coverer.set_min_level(8)
coverer.set_max_level(15)
coverer.set_max_cells(500)
covering = coverer.GetCovering(region_rect)
示例来源http://blog.christianperone.com/2015/08/googles-s2-geometry-on-the-sphere-cells-and-hilbert-curve/
我正在寻找类似
的东西
region_circle = S2latLangCircle(lat,lang,radius)
我在 google s2 library implemented in c++ Using google s2 library - find all s2 cells of a certain level within the circle, given lat/lng and radius in miles/km 中找到了这个问题的答案,但我在 python.
中需要这个
谢谢
在 link 的帮助下,我制定了 python 解决方案。
我正在使用 python s2sphere 库。
earthCircumferenceMeters = 1000 * 40075.017
def earthMetersToRadians(meters):
return (2 * math.pi) * (float(meters) /
const.earthCircumferenceMeters)
def getCoveringRect(lat, lng, radius, parent_level):
radius_radians = earthMetersToRadians(radius)
latlng = LatLng.from_degrees(float(lat),
float(lng)).normalized().to_point()
region = Cap.from_axis_height(latlng,
(radius_radians*radius_radians)/2)
coverer = RegionCoverer()
coverer.min_level = int(parent_level)
coverer.max_level = int(parent_level)
coverer.max_cells = const.MAX_S2_CELLS
covering = coverer.get_covering(region)
s2_rect = []
for cell_id in covering:
new_cell = Cell(cell_id)
vertices = []
for i in range(4):
vertex = new_cell.get_vertex(i)
latlng = LatLng.from_point(vertex)
vertices.append((math.degrees(latlng.lat().radians),
math.degrees(latlng.lng().radians)))
s2_rect.append(vertices)
return s2_rect
getCoveringRect 方法returns 给定父级别的所有 s2 单元格(矩形边界)被从给定纬度绘制的圆覆盖,长为中心和给定半径
我不确定Guarav使用的公式是否正确。
首先,函数 earthMetersToRadians
不计算 return 弧度,它只是计算 (2*pi*r) / (2*pi*R) = r/R
,其中 R 表示地球的半径。
据此,它计算 height = (r/R)^2/2
,我不确定这个公式来自哪里。
根据球冠的公式,我们有 height = 1 - cos(theta)
,其中 theta = arcsin(r/R)
在我们的例子中。
一起有 height = 1 - cos(arcsin(r/R))
可以计算为 height = 1 - sqrt(1 - (r/R)^2)
.
但是请注意,这两个公式非常接近,因此在实际情况下它们几乎相同,特别是如果您 运行 之后在您的上限上使用 S2Coverer。
什么 S2Region 以及我应该如何使用从给定的纬度、经度和半径绘制的圆覆盖特定父级别(假设 9)的所有 s2 单元格。下面是一个使用 python s2 库获取矩形下所有单元格的示例。
region_rect = S2LatLngRect(
S2LatLng.FromDegrees(-51.264871, -30.241701),
S2LatLng.FromDegrees(-51.04618, -30.000003))
coverer = S2RegionCoverer()
coverer.set_min_level(8)
coverer.set_max_level(15)
coverer.set_max_cells(500)
covering = coverer.GetCovering(region_rect)
示例来源http://blog.christianperone.com/2015/08/googles-s2-geometry-on-the-sphere-cells-and-hilbert-curve/
我正在寻找类似
的东西region_circle = S2latLangCircle(lat,lang,radius)
我在 google s2 library implemented in c++ Using google s2 library - find all s2 cells of a certain level within the circle, given lat/lng and radius in miles/km 中找到了这个问题的答案,但我在 python.
中需要这个谢谢
在 link 的帮助下,我制定了 python 解决方案。
我正在使用 python s2sphere 库。
earthCircumferenceMeters = 1000 * 40075.017
def earthMetersToRadians(meters):
return (2 * math.pi) * (float(meters) /
const.earthCircumferenceMeters)
def getCoveringRect(lat, lng, radius, parent_level):
radius_radians = earthMetersToRadians(radius)
latlng = LatLng.from_degrees(float(lat),
float(lng)).normalized().to_point()
region = Cap.from_axis_height(latlng,
(radius_radians*radius_radians)/2)
coverer = RegionCoverer()
coverer.min_level = int(parent_level)
coverer.max_level = int(parent_level)
coverer.max_cells = const.MAX_S2_CELLS
covering = coverer.get_covering(region)
s2_rect = []
for cell_id in covering:
new_cell = Cell(cell_id)
vertices = []
for i in range(4):
vertex = new_cell.get_vertex(i)
latlng = LatLng.from_point(vertex)
vertices.append((math.degrees(latlng.lat().radians),
math.degrees(latlng.lng().radians)))
s2_rect.append(vertices)
return s2_rect
getCoveringRect 方法returns 给定父级别的所有 s2 单元格(矩形边界)被从给定纬度绘制的圆覆盖,长为中心和给定半径
我不确定Guarav使用的公式是否正确。
首先,函数 earthMetersToRadians
不计算 return 弧度,它只是计算 (2*pi*r) / (2*pi*R) = r/R
,其中 R 表示地球的半径。
据此,它计算 height = (r/R)^2/2
,我不确定这个公式来自哪里。
根据球冠的公式,我们有 height = 1 - cos(theta)
,其中 theta = arcsin(r/R)
在我们的例子中。
一起有 height = 1 - cos(arcsin(r/R))
可以计算为 height = 1 - sqrt(1 - (r/R)^2)
.
但是请注意,这两个公式非常接近,因此在实际情况下它们几乎相同,特别是如果您 运行 之后在您的上限上使用 S2Coverer。