]> www.average.org Git - loctrkd.git/blob - gps303/opencellid.py
cleanup of gps303proto
[loctrkd.git] / gps303 / opencellid.py
1 """
2 Download csv for your carrier and your area from https://opencellid.org/
3 $ sqlite3 <cell-database-file>
4 sqlite> create table if not exists cells (
5   "radio" text,
6   "mcc" int,
7   "net" int,
8   "area" int,
9   "cell" int,
10   "unit" int,
11   "lon" int,
12   "lat" int,
13   "range" int,
14   "samples" int,
15   "changeable" int,
16   "created" int,
17   "updated" int,
18   "averageSignal" int
19 );
20 sqlite> .mode csv
21 sqlite> .import <downloaded-file.csv> cells
22 sqlite> create index if not exists cell_idx on cells (mcc, area, cell);
23 """
24
25 from sqlite3 import connect
26
27
28 def qry_cell(dbname, mcc, gsm_cells):
29     with connect(dbname) as ldb:
30         lc = ldb.cursor()
31         lc.execute("""attach database ":memory:" as mem""")
32         lc.execute("create table mem.seen (locac int, cellid int, signal int)")
33         lc.executemany(
34             """insert into mem.seen (locac, cellid, signal)
35                             values (?, ?, ?)""",
36             gsm_cells,
37         )
38         lc.execute(
39             """select c.lat, c.lon, s.signal
40                       from main.cells c, mem.seen s
41                       where c.mcc = ?
42                       and c.area = s.locac
43                       and c.cell = s.cellid""",
44             (mcc,),
45         )
46         data = list(lc.fetchall())
47         if not data:
48             return None, None
49         sumsig = sum([1 / sig for _, _, sig in data])
50         nsigs = [1 / sig / sumsig for _, _, sig in data]
51         avlat = sum([lat * nsig for (lat, _, _), nsig in zip(data, nsigs)])
52         avlon = sum([lon * nsig for (_, lon, _), nsig in zip(data, nsigs)])
53         # lc.execute("drop table mem.seen")
54         lc.close()
55         return avlat, avlon
56
57
58 if __name__.endswith("__main__"):
59     from datetime import datetime, timezone
60     import sys
61     from .gps303proto import *
62
63     db = connect(sys.argv[1])
64     c = db.cursor()
65     c.execute(
66         """select select tstamp, packet from events
67             where proto in (?, ?)""",
68         (WIFI_POSITIONING.PROTO, WIFI_OFFLINE_POSITIONING.PROTO),
69     )
70     for timestamp, imei, clntaddr, proto, payload in c:
71         obj = parse_message(packet)
72         avlat, avlon = qry_cell(sys.argv[2], obj.mcc, obj.gsm_cells)
73         print(
74             "{} {:+#010.8g},{:+#010.8g}".format(
75                 datetime.fromtimestamp(timestamp), avlat, avlon
76             )
77         )