]> www.average.org Git - loctrkd.git/blob - loctrkd/opencellid.py
opencellid: raise exception on the lack of data
[loctrkd.git] / loctrkd / opencellid.py
1 """
2 Lookaside backend to query local opencellid database
3 """
4
5 from sqlite3 import connect
6 from typing import Any, Dict, List, Tuple
7
8 __all__ = "init", "lookup"
9
10 ldb = None
11
12
13 def init(conf: Dict[str, Any]) -> None:
14     global ldb
15     ldb = connect(conf["opencellid"]["dbfn"])
16
17
18 def shut() -> None:
19     if ldb is not None:
20         ldb.close()
21
22
23 def lookup(
24     mcc: int, mnc: int, gsm_cells: List[Tuple[int, int, int]], __: Any
25 ) -> Tuple[float, float]:
26     assert ldb is not None
27     lc = ldb.cursor()
28     lc.execute("""attach database ":memory:" as mem""")
29     lc.execute("create table mem.seen (locac int, cellid int, signal int)")
30     lc.executemany(
31         """insert into mem.seen (locac, cellid, signal)
32                         values (?, ?, ?)""",
33         gsm_cells,
34     )
35     ldb.commit()
36     lc.execute(
37         """select c.lat, c.lon, s.signal
38                   from main.cells c, mem.seen s
39                   where c.mcc = ?
40                   and c.area = s.locac
41                   and c.cell = s.cellid""",
42         (mcc,),
43     )
44     data = list(lc.fetchall())
45     # lc.execute("drop table mem.seen")
46     lc.execute("""detach database mem""")
47     lc.close()
48     if not data:
49         raise ValueError("No location data found in opencellid")
50     sumsig = sum([1 / sig for _, _, sig in data])
51     nsigs = [1 / sig / sumsig for _, _, sig in data]
52     avlat = sum([lat * nsig for (lat, _, _), nsig in zip(data, nsigs)])
53     avlon = sum([lon * nsig for (_, lon, _), nsig in zip(data, nsigs)])
54     return avlat, avlon