# -*- coding: utf-8 -*-
"""补齐 OSRM table 没返回的网点：逐对用 /route 单独算，仍失败则用球面距离×1.35 估算（标 est）。"""
import io, json, time, math, urllib.request

GEO = r"D:\workbbbbbb\build\geodb.json"
BASE = 'https://router.project-osrm.org/route/v1/driving/'
OPENER = urllib.request.build_opener(urllib.request.ProxyHandler({}))
MISS = ['T710290000', 'T788020000', 'T7O50141000']


def hav(la1, lo1, la2, lo2):
    R = 6371.0
    p1, p2 = math.radians(la1), math.radians(la2)
    dp = p2 - p1
    dl = math.radians(lo2 - lo1)
    a = math.sin(dp / 2) ** 2 + math.cos(p1) * math.cos(p2) * math.sin(dl / 2) ** 2
    return 2 * R * math.asin(math.sqrt(a))


def route(lng1, lat1, lng2, lat2):
    url = ('%s%.6f,%.6f;%.6f,%.6f?overview=false' % (BASE, lng1, lat1, lng2, lat2))
    req = urllib.request.Request(url, headers={'User-Agent': 'paiban-tool/1.0'})
    with OPENER.open(req, timeout=40) as r:
        js = json.loads(r.read().decode('utf-8'))
    if js.get('code') != 'Ok':
        return None, None
    rt = (js.get('routes') or [None])[0]
    if not rt:
        return None, None
    return rt['distance'] / 1000.0, rt['duration'] / 60.0


def main():
    db = json.load(io.open(GEO, encoding='utf-8'))
    homes = db['homes']
    orgs = {o['c']: o for o in db['orgs']}
    drive, driveMin = db['drive'], db['driveMin']
    fixed = 0
    est = 0
    for h in homes:
        for code in MISS:
            o = orgs[code]
            try:
                d, t = route(h['lng'], h['lat'], o['lng'], o['lat'])
            except Exception as e:
                d, t = None, None
            if d is None:
                d = round(hav(h['lat'], h['lng'], o['lat'], o['lng']) * 1.35, 1)
                t = int(round(d / 0.4))  # 约 24 km/h 城市均速
                est += 1
            else:
                d = round(d, 1)
                t = int(round(t))
                fixed += 1
            drive.setdefault(h['n'], {})[code] = d
            driveMin.setdefault(h['n'], {})[code] = t
            time.sleep(1.1)
        print('  home %s done' % h['n'])
    db['drive'] = drive
    db['driveMin'] = driveMin
    db['driveMeta']['pairs'] = sum(len(v) for v in drive.values())
    db['driveMeta']['routeFixed'] = fixed
    db['driveMeta']['est'] = est
    io.open(GEO, 'w', encoding='utf-8').write(
        json.dumps(db, ensure_ascii=False, separators=(',', ':')))
    print('DONE fixed=%d est=%d total=%d' % (fixed, est, db['driveMeta']['pairs']))


main()
