X-Git-Url: http://average.org/gitweb/?a=blobdiff_plain;f=gps303%2Fopencellid.py;h=1d60bfee1671defc9f8ed6fe9e994e787408ac0f;hb=b84a40a485b0563d572d14e748ad324185584344;hp=5527a1912bf38f69013210b19d824e452ea72463;hpb=4aaa5cd899d6b2bb9fd5e90dfac3d43461394e9b;p=loctrkd.git diff --git a/gps303/opencellid.py b/gps303/opencellid.py index 5527a19..1d60bfe 100644 --- a/gps303/opencellid.py +++ b/gps303/opencellid.py @@ -1,56 +1,72 @@ """ -Download csv for your carrier and your area from https://opencellid.org/ -$ sqlite3 -sqlite> create table if not exists cells ( - "radio" text, - "mcc" int, - "net" int, - "area" int, - "cell" int, - "unit" int, - "lon" int, - "lat" int, - "range" int, - "samples" int, - "changeable" int, - "created" int, - "updated" int, - "averageSignal" int -); -sqlite> .mode csv -sqlite> .import cells -sqlite> create index if not exists cell_idx on cells (mcc, area, cell); +Lookaside backend to query local opencellid database """ -from datetime import datetime, timezone -from pprint import pprint from sqlite3 import connect -import sys - -from .GT06mod import * - -db = connect(sys.argv[1]) -ldb = connect(sys.argv[2]) -lc = ldb.cursor() -c = db.cursor() -c.execute( - """select timestamp, imei, clntaddr, length, proto, payload from events - where proto in (?, ?)""", - (WIFI_POSITIONING.PROTO, WIFI_OFFLINE_POSITIONING.PROTO), -) -for timestamp, imei, clntaddr, length, proto, payload in c: - obj = make_object(length, proto, payload) - qry = """select lat, lon from cells - where mcc = {} and (area, cell) in ({})""".format( - obj.mcc, - ", ".join( - [ - "({}, {})".format(locac, cellid) - for locac, cellid, _ in obj.gsm_cells - ] - ), +from typing import Any, Dict, List, Tuple + +__all__ = "init", "lookup" + +ldb = None + + +def init(conf: Dict[str, Any]) -> None: + global ldb + ldb = connect(conf["opencellid"]["dbfn"]) + + +def lookup( + mcc: int, mnc: int, gsm_cells: List[Tuple[int, int, int]], __: Any +) -> Tuple[float, float]: + assert ldb is not None + lc = ldb.cursor() + lc.execute("""attach database ":memory:" as mem""") + lc.execute("create table mem.seen (locac int, cellid int, signal int)") + lc.executemany( + """insert into mem.seen (locac, cellid, signal) + values (?, ?, ?)""", + gsm_cells, + ) + ldb.commit() + lc.execute( + """select c.lat, c.lon, s.signal + from main.cells c, mem.seen s + where c.mcc = ? + and c.area = s.locac + and c.cell = s.cellid""", + (mcc,), + ) + data = list(lc.fetchall()) + if not data: + return 0.0, 0.0 + sumsig = sum([1 / sig for _, _, sig in data]) + nsigs = [1 / sig / sumsig for _, _, sig in data] + avlat = sum([lat * nsig for (lat, _, _), nsig in zip(data, nsigs)]) + avlon = sum([lon * nsig for (_, lon, _), nsig in zip(data, nsigs)]) + # lc.execute("drop table mem.seen") + lc.execute("""detach database mem""") + lc.close() + return avlat, avlon + + +if __name__.endswith("__main__"): + from datetime import datetime, timezone + import sys + from .gps303proto import * + + db = connect(sys.argv[1]) + c = db.cursor() + c.execute( + """select tstamp, packet from events + where proto in (?, ?)""", + (WIFI_POSITIONING.PROTO, WIFI_OFFLINE_POSITIONING.PROTO), ) - print(qry) - lc.execute(qry) - for lat, lon in lc: - print(lat, lon) + init({"opencellid": {"dbfn": sys.argv[2]}}) + for timestamp, packet in c: + obj = parse_message(packet) + avlat, avlon = lookup(obj.mcc, obj.mnc, obj.gsm_cells, obj.wifi_aps) + print( + "{} {:+#010.8g},{:+#010.8g}".format( + datetime.fromtimestamp(timestamp), avlat, avlon + ) + )