Files
sunnypilot/selfdrive/mapd/lib/osm.py
T
Jason Wen c726a82eaf mapd: offline/local OpenStreetMap database, Feature Speed Limits (#55)
* mapd: offline/local database

* link overpy before manager

* add path to deps

* down here

* this too

* don't force redownload/reinstall unless db not current

* make things neater in json

* small fix

* Revert "small fix"

This reverts commit dbc70ee6d40b51e4d7c4a4af4523d23737350905.

* Revert "make things neater in json"

This reverts commit 1b244c552c1bf877e8b6bf879ca73ebf72617025.

* neater attempt 2 (no reboot for now)

* neater attempt 2 (no reboot for now)

* "selected" not working

* make it stick

* already QString

* check when menu is up

* check when menu is up

* interactive buttons

* add label to inform users about car off

* update texts

* set all params properly

* clean up ui logic

* test

* revert

* ui logic again

* interactive button

* after confirmation updates

* only check when selected

* stop signs?

* bruh

* missed

* small cleanup

* query for real from local db

* Revert "query for real from local db"

This reverts commit d7eb664da2949b073c7d7eb00e0098aa01c83ad3.

* don't hold in same object

* remote server as fallback if local server fails

* use different waypoint

* use function

* declare missing vars

* skip SSL/TLS verification

* fallback to online query if local query fails

* don't prompt to reboot if none is selected

* update ui on press

* Revert "skip SSL/TLS verification"

This reverts commit 2eb5c0972a08227edbfc4f50c38d22d2ced62423.

* simplier

* handle ConnectionError

* point to sunnypilot-osm S3 bucket

* revert freq of road name

* small cleanup

* small cleanup

* revert

* cleanup

* TEMP: test online/offline switchover

* Revert "TEMP: test online/offline switchover"

This reverts commit 4641b8e6f26f4015559a9aff2271f1850708ab09.

* set user-agent

* more databases!

* new urls

* TEST: remove check here

* parse timestamp from file content instead of HEAD Last Modified

* not correct

* wrong var

* don't need this

* have list in cpp

* don't read from json

* provide expectation

* add var to gate feature speed limits

* remove unused
2023-03-24 14:46:14 -04:00

72 lines
2.8 KiB
Python

import overpy
import subprocess
import numpy as np
from cereal import log
from common.params import Params
from selfdrive.mapd.lib.geo import R
from selfdrive.mapd.lib.helpers import is_local_osm_installed, OSM_QUERY
DataType = log.LiveMapData.DataType
def create_way(way_id, node_ids, from_way):
"""
Creates and OSM Way with the given `way_id` and list of `node_ids`, copying attributes and tags from `from_way`
"""
return overpy.Way(way_id, node_ids=node_ids, attributes={}, result=from_way._result,
tags=from_way.tags)
class OSM:
def __init__(self):
self.api = overpy.Overpass()
self.param_s = Params()
self._osm_local_db_enabled = self.param_s.get_bool("OsmLocalDb")
self._local_osm_installed = is_local_osm_installed(self.param_s)
# self.api = overpy.Overpass(url='http://3.65.170.21/api/interpreter')
def _online_query(self, q, area_q):
print("Query OSM from remote server")
query = self.api.query(q + area_q)
areas, ways = query.areas, query.ways
data_type = DataType.online
return areas, ways, data_type
def fetch_road_ways_around_location(self, lat, lon, radius):
# Calculate the bounding box coordinates for the bbox containing the circle around location.
bbox_angle = np.degrees(radius / R)
# fetch all ways and nodes on this ways in bbox
bbox_str = f'{str(lat - bbox_angle)},{str(lon - bbox_angle)},{str(lat + bbox_angle)},{str(lon + bbox_angle)}'
lat_lon = "(%f,%f)" % (lat, lon)
q = """
way(""" + bbox_str + """)
[highway]
[highway!~"^(footway|path|corridor|bridleway|steps|cycleway|construction|bus_guideway|escape|service|track)$"];
(._;>;);
out;"""
area_q = """is_in""" + lat_lon + """;area._[admin_level~"[24]"];
convert area ::id = id(), admin_level = t['admin_level'],
name = t['name'], "ISO3166-1:alpha2" = t['ISO3166-1:alpha2'];out;
"""
try:
if self._osm_local_db_enabled and self._local_osm_installed:
print("Query OSM from local server")
completion = subprocess.run(OSM_QUERY + [f"--request={q}"], check=True, capture_output=True)
ways = self.api.parse_xml(completion.stdout).ways
if completion.returncode == 0 and len(ways) != 0:
try:
areas = self.api.query(area_q).areas
except Exception as e:
print(f'Exception while querying "AREAS" OSM from local server:\n{e}')
areas = None
data_type = DataType.offline
else:
areas, ways, data_type = self._online_query(q, area_q)
else:
areas, ways, data_type = self._online_query(q, area_q)
except Exception as e:
print(f'Exception while querying OSM:\n{e}')
areas, ways, data_type = [], [], DataType.default
return areas, ways, data_type