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