]> www.average.org Git - loctrkd.git/blob - gps303/opencellid.py
typing: annotate opencellid.py
[loctrkd.git] / gps303 / 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 lookup(
19     mcc: int, mnc: int, gsm_cells: List[Tuple[int, int, int]], __: Any
20 ) -> Tuple[float, float]:
21     assert ldb is not None
22     lc = ldb.cursor()
23     lc.execute("""attach database ":memory:" as mem""")
24     lc.execute("create table mem.seen (locac int, cellid int, signal int)")
25     lc.executemany(
26         """insert into mem.seen (locac, cellid, signal)
27                         values (?, ?, ?)""",
28         gsm_cells,
29     )
30     ldb.commit()
31     lc.execute(
32         """select c.lat, c.lon, s.signal
33                   from main.cells c, mem.seen s
34                   where c.mcc = ?
35                   and c.area = s.locac
36                   and c.cell = s.cellid""",
37         (mcc,),
38     )
39     data = list(lc.fetchall())
40     if not data:
41         return 0.0, 0.0
42     sumsig = sum([1 / sig for _, _, sig in data])
43     nsigs = [1 / sig / sumsig for _, _, sig in data]
44     avlat = sum([lat * nsig for (lat, _, _), nsig in zip(data, nsigs)])
45     avlon = sum([lon * nsig for (_, lon, _), nsig in zip(data, nsigs)])
46     # lc.execute("drop table mem.seen")
47     lc.execute("""detach database mem""")
48     lc.close()
49     return avlat, avlon
50
51
52 if __name__.endswith("__main__"):
53     from datetime import datetime, timezone
54     import sys
55     from .gps303proto import *
56
57     db = connect(sys.argv[1])
58     c = db.cursor()
59     c.execute(
60         """select tstamp, packet from events
61             where proto in (?, ?)""",
62         (WIFI_POSITIONING.PROTO, WIFI_OFFLINE_POSITIONING.PROTO),
63     )
64     init({"opencellid": {"dbfn": sys.argv[2]}})
65     for timestamp, packet in c:
66         obj = parse_message(packet)
67         avlat, avlon = lookup(obj.mcc, obj.mnc, obj.gsm_cells, obj.wifi_aps)
68         print(
69             "{} {:+#010.8g},{:+#010.8g}".format(
70                 datetime.fromtimestamp(timestamp), avlat, avlon
71             )
72         )