11#!/usr/bin/python3
22"""Roads."""
33import os
4- from enum import auto
5- from enum import Enum
4+ from enum import IntEnum
65
76from tqdm import tqdm
87
1110from pretty_gpx .common .request .gpx_data_cache_handler import GpxDataCacheHandler
1211from pretty_gpx .common .request .overpass_processing import get_ways_coordinates_from_results
1312from pretty_gpx .common .request .overpass_request import OverpassQuery
13+ from pretty_gpx .common .utils .asserts import assert_same_keys
1414from pretty_gpx .common .utils .logger import logger
1515from pretty_gpx .common .utils .pickle_io import read_pickle
1616from pretty_gpx .common .utils .pickle_io import write_pickle
2020ROADS_CACHE = GpxDataCacheHandler (name = 'roads' , extension = '.pkl' )
2121
2222
23- class CityRoadType ( Enum ):
24- """City Road Type ."""
25- HIGHWAY = auto ()
26- SECONDARY_ROAD = auto ()
27- STREET = auto ()
28- ACCESS_ROAD = auto ()
23+ class CityRoadPrecision ( IntEnum ):
24+ """Enum defining different road precision levels ."""
25+ VERY_HIGH = 3 # Access roads
26+ HIGH = 2 # Streets
27+ MEDIUM = 1 # Secondary roads
28+ LOW = 0 # Highways
2929
30+ @property
31+ def pretty_name (self ) -> str :
32+ """Human-friendly name, e.g. 'Very-High'."""
33+ return self .name .replace ("_" , "-" ).title ()
3034
31- HIGHWAY_TAGS_PER_CITY_ROAD_TYPE = {
32- CityRoadType .HIGHWAY : ["motorway" , "trunk" , "primary" ],
33- CityRoadType .SECONDARY_ROAD : ["tertiary" , "secondary" ],
34- CityRoadType .STREET : ["residential" , "living_street" ],
35- CityRoadType .ACCESS_ROAD : ["unclassified" , "service" ]
36- }
35+ @staticmethod
36+ def coarse_to_fine () -> list ["CityRoadPrecision" ]:
37+ """Return the list of road precision from coarse to fine."""
38+ return sorted (CityRoadPrecision , key = lambda p : p .value )
3739
38- QUERY_NAME_PER_CITY_ROAD_TYPE = {
39- CityRoadType .HIGHWAY : "highway" ,
40- CityRoadType .SECONDARY_ROAD : "secondary_roads" ,
41- CityRoadType .STREET : "street" ,
42- CityRoadType .ACCESS_ROAD : "access_roads"
43- }
4440
45- assert HIGHWAY_TAGS_PER_CITY_ROAD_TYPE .keys () == QUERY_NAME_PER_CITY_ROAD_TYPE .keys ()
41+ ROAD_HIGHWAY_TAGS : dict [CityRoadPrecision , list [str ]] = {
42+ CityRoadPrecision .LOW : ["motorway" , "trunk" , "primary" ],
43+ CityRoadPrecision .MEDIUM : ["tertiary" , "secondary" ],
44+ CityRoadPrecision .HIGH : ["residential" , "living_street" ],
45+ CityRoadPrecision .VERY_HIGH : ["unclassified" , "service" ]
46+ }
4647
47- CityRoads = dict [ CityRoadType , list [ ListLonLat ]]
48+ assert_same_keys ( ROAD_HIGHWAY_TAGS , CityRoadPrecision )
4849
4950
5051@profile
@@ -65,9 +66,9 @@ def prepare_download_city_roads(query: OverpassQuery,
6566 query .add_cached_result (ROADS_CACHE .name , cache_file = cache_pkl )
6667 return
6768
68- for city_road_type in tqdm (CityRoadType ):
69- highway_tags_str = "|" .join (HIGHWAY_TAGS_PER_CITY_ROAD_TYPE [ city_road_type ])
70- query .add_overpass_query (QUERY_NAME_PER_CITY_ROAD_TYPE [ city_road_type ] ,
69+ for city_road_precision in tqdm (CityRoadPrecision ):
70+ highway_tags_str = "|" .join (ROAD_HIGHWAY_TAGS [ city_road_precision ])
71+ query .add_overpass_query (city_road_precision . name ,
7172 [f"way['highway'~'({ highway_tags_str } )']" ],
7273 bounds ,
7374 include_way_nodes = True ,
@@ -76,18 +77,18 @@ def prepare_download_city_roads(query: OverpassQuery,
7677
7778@profile
7879def process_city_roads (query : OverpassQuery ,
79- bounds : GpxBounds ) -> dict [CityRoadType , list [ListLonLat ]]:
80+ bounds : GpxBounds ) -> dict [CityRoadPrecision , list [ListLonLat ]]:
8081 """Query the overpass API to get the roads of a city."""
8182 if query .is_cached (ROADS_CACHE .name ):
8283 cache_file = query .get_cache_file (ROADS_CACHE .name )
8384 return read_pickle (cache_file )
8485
8586 with Profiling .Scope ("Process City Roads" ):
8687 roads = dict ()
87- for city_road_type , query_name in QUERY_NAME_PER_CITY_ROAD_TYPE . items () :
88- logger .debug (f"Query name : { query_name } " )
89- result = query .get_query_result (query_name )
90- roads [city_road_type ] = get_ways_coordinates_from_results (result )
88+ for city_road_precision in CityRoadPrecision :
89+ logger .debug (f"Query precision : { city_road_precision . name } " )
90+ result = query .get_query_result (city_road_precision . name )
91+ roads [city_road_precision ] = get_ways_coordinates_from_results (result )
9192
9293 cache_pkl = ROADS_CACHE .get_path (bounds )
9394 write_pickle (cache_pkl , roads )
0 commit comments