Files
homeassistant_config/config/custom_components/blitzortung/geohash_utils.py
2024-05-31 13:07:35 +02:00

59 lines
1.4 KiB
Python

import math
from collections import namedtuple
from . import geohash
Box = namedtuple("Box", ["s", "w", "n", "e"])
def geohash_bbox(gh):
ret = geohash.bbox(gh)
return Box(ret["s"], ret["w"], ret["n"], ret["e"])
def bbox(lat, lon, radius):
lat_delta = radius * 360 / 40000
lon_delta = lat_delta / math.cos(lat * math.pi / 180.0)
return Box(lat - lat_delta, lon - lon_delta, lat + lat_delta, lon + lon_delta)
def overlap(a1, a2, b1, b2):
return a1 < b2 and a2 > b1
def box_overlap(box1: Box, box2: Box):
return overlap(box1.s, box1.n, box2.s, box2.n) and overlap(
box1.w, box1.e, box2.w, box2.e
)
def compute_geohash_tiles(lat, lon, radius, precision):
bounds = bbox(lat, lon, radius)
center = geohash.encode(lat, lon, precision)
stack = set()
checked = set()
stack.add(center)
checked.add(center)
while stack:
current = stack.pop()
for neighbor in geohash.neighbors(current):
if neighbor not in checked and box_overlap(geohash_bbox(neighbor), bounds):
stack.add(neighbor)
checked.add(neighbor)
return checked
def geohash_overlap(lat, lon, radius, max_tiles=9):
result = []
for precision in range(1, 13):
tiles = compute_geohash_tiles(lat, lon, radius, precision)
if len(tiles) <= 9:
result = tiles
precision += 1
else:
break
return result