mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-12-29 01:13:53 +03:00
Change language of roads via settings, for #271
This commit is contained in:
parent
2e93fdbf54
commit
6749edb2b6
@ -133,7 +133,7 @@ impl CommonState {
|
||||
let r = map.get_parent(l);
|
||||
osd.append_all(vec![
|
||||
Line(format!("{} of ", map.get_l(l).lane_type.describe())),
|
||||
Line(r.get_name()).fg(name_color),
|
||||
Line(r.get_name(app.opts.language.as_ref())).fg(name_color),
|
||||
]);
|
||||
if app.opts.dev {
|
||||
osd.append(Line(" ("));
|
||||
@ -166,7 +166,7 @@ impl CommonState {
|
||||
|
||||
let mut road_names = BTreeSet::new();
|
||||
for r in &map.get_i(i).roads {
|
||||
road_names.insert(map.get_r(*r).get_name());
|
||||
road_names.insert(map.get_r(*r).get_name(app.opts.language.as_ref()));
|
||||
}
|
||||
list_names(&mut osd, |l| l.fg(name_color), road_names);
|
||||
}
|
||||
@ -218,7 +218,7 @@ impl CommonState {
|
||||
osd.append(Line(r.to_string()).fg(id_color));
|
||||
osd.append(Line(" is "));
|
||||
}
|
||||
osd.append(Line(map.get_r(r).get_name()).fg(name_color));
|
||||
osd.append(Line(map.get_r(r).get_name(app.opts.language.as_ref())).fg(name_color));
|
||||
}
|
||||
}
|
||||
osd
|
||||
|
@ -30,7 +30,7 @@ impl Navigator {
|
||||
.map
|
||||
.all_roads()
|
||||
.iter()
|
||||
.map(|r| (r.get_name(), r.id))
|
||||
.map(|r| (r.get_name(app.opts.language.as_ref()), r.id))
|
||||
.collect(),
|
||||
)
|
||||
.named("street"),
|
||||
@ -108,7 +108,7 @@ impl CrossStreet {
|
||||
// TODO This isn't so clear...
|
||||
txt.add(Line(format!(
|
||||
"(Or just quit to go to {})",
|
||||
map.get_r(first[0]).get_name(),
|
||||
map.get_r(first[0]).get_name(app.opts.language.as_ref()),
|
||||
)));
|
||||
txt.draw(ctx)
|
||||
},
|
||||
@ -120,7 +120,7 @@ impl CrossStreet {
|
||||
ctx,
|
||||
cross_streets
|
||||
.into_iter()
|
||||
.map(|r| (map.get_r(r).get_name(), r))
|
||||
.map(|r| (map.get_r(r).get_name(app.opts.language.as_ref()), r))
|
||||
.collect(),
|
||||
)
|
||||
.named("street"),
|
||||
|
@ -640,7 +640,8 @@ fn find_divided_highways(app: &App) -> HashSet<RoadID> {
|
||||
])
|
||||
.intersection(&map.get_r(r2).center_pts)
|
||||
.is_some()
|
||||
&& r1.get_name() == map.get_r(r2).get_name()
|
||||
&& r1.get_name(app.opts.language.as_ref())
|
||||
== map.get_r(r2).get_name(app.opts.language.as_ref())
|
||||
{
|
||||
found.insert(r1.id);
|
||||
found.insert(r2);
|
||||
|
@ -75,9 +75,12 @@ impl LaneEditor {
|
||||
|
||||
let parent = app.primary.map.get_parent(l);
|
||||
let col = vec![
|
||||
format!("Convert this lane of {} to what type?", parent.get_name())
|
||||
.draw_text(ctx)
|
||||
.centered_horiz(),
|
||||
format!(
|
||||
"Convert this lane of {} to what type?",
|
||||
parent.get_name(app.opts.language.as_ref())
|
||||
)
|
||||
.draw_text(ctx)
|
||||
.centered_horiz(),
|
||||
Widget::custom_row(row).centered(),
|
||||
change_speed_limit(ctx, parent.speed_limit),
|
||||
Btn::text_fg("Change access restrictions").build_def(ctx, hotkey(Key::A)),
|
||||
|
@ -210,7 +210,13 @@ impl State for StopSignEditor {
|
||||
let mut osd = Text::new();
|
||||
osd.add_appended(vec![
|
||||
Line("Stop sign for "),
|
||||
Line(app.primary.map.get_r(r).get_name()).fg(app.cs.bottom_bar_name),
|
||||
Line(
|
||||
app.primary
|
||||
.map
|
||||
.get_r(r)
|
||||
.get_name(app.opts.language.as_ref()),
|
||||
)
|
||||
.fg(app.cs.bottom_bar_name),
|
||||
]);
|
||||
CommonState::draw_custom_osd(g, app, osd);
|
||||
} else {
|
||||
|
@ -478,13 +478,22 @@ impl State for TrafficSignalEditor {
|
||||
let osd = if id.crosswalk {
|
||||
Text::from(Line(format!(
|
||||
"Crosswalk across {}",
|
||||
app.primary.map.get_r(id.from.id).get_name()
|
||||
app.primary
|
||||
.map
|
||||
.get_r(id.from.id)
|
||||
.get_name(app.opts.language.as_ref())
|
||||
)))
|
||||
} else {
|
||||
Text::from(Line(format!(
|
||||
"Turn from {} to {}",
|
||||
app.primary.map.get_r(id.from.id).get_name(),
|
||||
app.primary.map.get_r(id.to.id).get_name()
|
||||
app.primary
|
||||
.map
|
||||
.get_r(id.from.id)
|
||||
.get_name(app.opts.language.as_ref()),
|
||||
app.primary
|
||||
.map
|
||||
.get_r(id.to.id)
|
||||
.get_name(app.opts.language.as_ref())
|
||||
)))
|
||||
};
|
||||
CommonState::draw_custom_osd(g, app, osd);
|
||||
@ -564,7 +573,12 @@ fn make_side_panel(
|
||||
|
||||
let mut road_names = BTreeSet::new();
|
||||
for r in &app.primary.map.get_i(i).roads {
|
||||
road_names.insert(app.primary.map.get_r(*r).get_name());
|
||||
road_names.insert(
|
||||
app.primary
|
||||
.map
|
||||
.get_r(*r)
|
||||
.get_name(app.opts.language.as_ref()),
|
||||
);
|
||||
}
|
||||
for r in road_names {
|
||||
txt.add(Line(format!("- {}", r)));
|
||||
|
@ -237,7 +237,7 @@ pub fn route(ctx: &mut EventCtx, app: &App, details: &mut Details, id: BusRouteI
|
||||
rows.push(format!("{} stops", route.stops.len()).draw_text(ctx));
|
||||
{
|
||||
let i = map.get_i(map.get_l(route.start).src_i);
|
||||
let name = format!("Starts at {}", i.name(map));
|
||||
let name = format!("Starts at {}", i.name(app.opts.language.as_ref(), map));
|
||||
rows.push(Widget::row(vec![
|
||||
Btn::svg(
|
||||
"system/assets/timeline/goal_pos.svg",
|
||||
@ -273,7 +273,7 @@ pub fn route(ctx: &mut EventCtx, app: &App, details: &mut Details, id: BusRouteI
|
||||
}
|
||||
if let Some(l) = route.end_border {
|
||||
let i = map.get_i(map.get_l(l).dst_i);
|
||||
let name = format!("Ends at {}", i.name(map));
|
||||
let name = format!("Ends at {}", i.name(app.opts.language.as_ref(), map));
|
||||
rows.push(Widget::row(vec![
|
||||
Btn::svg(
|
||||
"system/assets/timeline/goal_pos.svg",
|
||||
|
@ -20,7 +20,12 @@ pub fn info(ctx: &EventCtx, app: &App, details: &mut Details, id: IntersectionID
|
||||
let mut txt = Text::from(Line("Connecting"));
|
||||
let mut road_names = BTreeSet::new();
|
||||
for r in &i.roads {
|
||||
road_names.insert(app.primary.map.get_r(*r).get_name());
|
||||
road_names.insert(
|
||||
app.primary
|
||||
.map
|
||||
.get_r(*r)
|
||||
.get_name(app.opts.language.as_ref()),
|
||||
);
|
||||
}
|
||||
for r in road_names {
|
||||
// TODO The spacing is ignored, so use -
|
||||
|
@ -222,7 +222,7 @@ fn header(ctx: &EventCtx, app: &App, details: &mut Details, id: LaneID, tab: Tab
|
||||
.draw(ctx),
|
||||
header_btns(ctx),
|
||||
]));
|
||||
rows.push(format!("@ {}", r.get_name()).draw_text(ctx));
|
||||
rows.push(format!("@ {}", r.get_name(app.opts.language.as_ref())).draw_text(ctx));
|
||||
|
||||
let mut tabs = vec![("Info", Tab::LaneInfo(id))];
|
||||
if !l.is_parking() {
|
||||
|
@ -160,8 +160,8 @@ pub fn future(
|
||||
));
|
||||
} else {
|
||||
// TODO Warp buttons. make_table is showing its age.
|
||||
let (id1, _, name1) = endpoint(&trip.start, &app.primary.map);
|
||||
let (id2, _, name2) = endpoint(&trip.end, &app.primary.map);
|
||||
let (id1, _, name1) = endpoint(&trip.start, app);
|
||||
let (id2, _, name2) = endpoint(&trip.end, app);
|
||||
details
|
||||
.warpers
|
||||
.insert(format!("jump to start of {}", id), id1);
|
||||
@ -323,8 +323,8 @@ pub fn aborted(ctx: &mut EventCtx, app: &App, id: TripID) -> Widget {
|
||||
.draw(ctx)];
|
||||
|
||||
// TODO Warp buttons. make_table is showing its age.
|
||||
let (_, _, name1) = endpoint(&trip.start, &app.primary.map);
|
||||
let (_, _, name2) = endpoint(&trip.end, &app.primary.map);
|
||||
let (_, _, name1) = endpoint(&trip.start, app);
|
||||
let (_, _, name2) = endpoint(&trip.end, app);
|
||||
col.extend(make_table(
|
||||
ctx,
|
||||
vec![
|
||||
@ -344,8 +344,8 @@ pub fn cancelled(ctx: &mut EventCtx, app: &App, id: TripID) -> Widget {
|
||||
let mut col = vec!["Trip cancelled due to traffic pattern modifications".draw_text(ctx)];
|
||||
|
||||
// TODO Warp buttons. make_table is showing its age.
|
||||
let (_, _, name1) = endpoint(&trip.start, &app.primary.map);
|
||||
let (_, _, name2) = endpoint(&trip.end, &app.primary.map);
|
||||
let (_, _, name1) = endpoint(&trip.start, app);
|
||||
let (_, _, name2) = endpoint(&trip.end, app);
|
||||
col.extend(make_table(
|
||||
ctx,
|
||||
vec![
|
||||
@ -374,7 +374,7 @@ fn make_timeline(
|
||||
let end_time = phases.last().as_ref().and_then(|p| p.end_time);
|
||||
|
||||
let start_btn = {
|
||||
let (id, center, name) = endpoint(&trip.start, map);
|
||||
let (id, center, name) = endpoint(&trip.start, app);
|
||||
details
|
||||
.warpers
|
||||
.insert(format!("jump to start of {}", trip_id), id);
|
||||
@ -419,7 +419,7 @@ fn make_timeline(
|
||||
};
|
||||
|
||||
let goal_btn = {
|
||||
let (id, center, name) = endpoint(&trip.end, map);
|
||||
let (id, center, name) = endpoint(&trip.end, app);
|
||||
details
|
||||
.warpers
|
||||
.insert(format!("jump to goal of {}", trip_id), id);
|
||||
@ -699,18 +699,21 @@ fn make_elevation(ctx: &EventCtx, color: Color, walking: bool, path: &Path, map:
|
||||
}
|
||||
|
||||
// (ID, center, name)
|
||||
fn endpoint(endpt: &TripEndpoint, map: &Map) -> (ID, Pt2D, String) {
|
||||
fn endpoint(endpt: &TripEndpoint, app: &App) -> (ID, Pt2D, String) {
|
||||
match endpt {
|
||||
TripEndpoint::Bldg(b) => {
|
||||
let bldg = map.get_b(*b);
|
||||
let bldg = app.primary.map.get_b(*b);
|
||||
(ID::Building(*b), bldg.label_center, bldg.address.clone())
|
||||
}
|
||||
TripEndpoint::Border(i, _) => {
|
||||
let i = map.get_i(*i);
|
||||
let i = app.primary.map.get_i(*i);
|
||||
(
|
||||
ID::Intersection(i.id),
|
||||
i.polygon.center(),
|
||||
format!("off map, via {}", i.name(map)),
|
||||
format!(
|
||||
"off map, via {}",
|
||||
i.name(app.opts.language.as_ref(), &app.primary.map)
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -22,6 +22,8 @@ pub struct Options {
|
||||
pub time_increment: Duration,
|
||||
pub resume_after_edit: bool,
|
||||
pub dont_draw_time_warp: bool,
|
||||
|
||||
pub language: Option<String>,
|
||||
}
|
||||
|
||||
impl Options {
|
||||
@ -39,6 +41,8 @@ impl Options {
|
||||
time_increment: Duration::minutes(10),
|
||||
resume_after_edit: true,
|
||||
dont_draw_time_warp: false,
|
||||
|
||||
language: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -167,6 +171,17 @@ impl OptionsPanel {
|
||||
None,
|
||||
app.opts.large_unzoomed_agents,
|
||||
),
|
||||
Widget::row(vec![
|
||||
"Language".draw_text(ctx),
|
||||
Widget::dropdown(ctx, "language", app.opts.language.clone(), {
|
||||
let mut choices = Vec::new();
|
||||
choices.push(Choice::new("Map native language", None));
|
||||
for lang in app.primary.map.get_languages() {
|
||||
choices.push(Choice::new(lang, Some(lang.to_string())));
|
||||
}
|
||||
choices
|
||||
}),
|
||||
]),
|
||||
])
|
||||
.bg(app.cs.section_bg)
|
||||
.padding(8),
|
||||
@ -222,7 +237,7 @@ impl State for OptionsPanel {
|
||||
if app.opts.traffic_signal_style != style {
|
||||
app.opts.traffic_signal_style = style;
|
||||
println!("Rerendering traffic signals...");
|
||||
for i in app.primary.draw_map.intersections.iter_mut() {
|
||||
for i in &mut app.primary.draw_map.intersections {
|
||||
*i.draw_traffic_signal.borrow_mut() = None;
|
||||
}
|
||||
}
|
||||
@ -237,6 +252,14 @@ impl State for OptionsPanel {
|
||||
app.opts.large_unzoomed_agents =
|
||||
self.composite.is_checked("Draw enlarged unzoomed agents");
|
||||
|
||||
let language = self.composite.dropdown_value("language");
|
||||
if language != app.opts.language {
|
||||
app.opts.language = language;
|
||||
for r in &mut app.primary.draw_map.roads {
|
||||
r.clear_rendering();
|
||||
}
|
||||
}
|
||||
|
||||
return Transition::Pop;
|
||||
}
|
||||
_ => unreachable!(),
|
||||
|
@ -26,6 +26,7 @@ impl DrawRoad {
|
||||
|
||||
pub fn clear_rendering(&mut self) {
|
||||
*self.draw_center_line.borrow_mut() = None;
|
||||
*self.label.borrow_mut() = None;
|
||||
}
|
||||
}
|
||||
|
||||
@ -73,7 +74,7 @@ impl Renderable for DrawRoad {
|
||||
let mut batch = GeomBatch::new();
|
||||
let r = app.primary.map.get_r(self.id);
|
||||
if !r.is_light_rail() {
|
||||
let name = r.get_name();
|
||||
let name = r.get_name(app.opts.language.as_ref());
|
||||
if r.center_pts.length() >= Distance::meters(30.0) && name != "???" {
|
||||
// TODO If it's definitely straddling bus/bike lanes, change the color? Or
|
||||
// even easier, just skip the center lines?
|
||||
|
@ -163,7 +163,10 @@ impl TurnExplorer {
|
||||
Text::from(
|
||||
Line(format!(
|
||||
"Turns from {}",
|
||||
app.primary.map.get_parent(l).get_name()
|
||||
app.primary
|
||||
.map
|
||||
.get_parent(l)
|
||||
.get_name(app.opts.language.as_ref())
|
||||
))
|
||||
.small_heading(),
|
||||
)
|
||||
|
@ -105,7 +105,7 @@ fn get_address(tags: &Tags, sidewalk: LaneID, map: &Map) -> String {
|
||||
match (tags.get("addr:housenumber"), tags.get("addr:street")) {
|
||||
(Some(num), Some(st)) => format!("{} {}", num, st),
|
||||
(None, Some(st)) => format!("??? {}", st),
|
||||
_ => format!("??? {}", map.get_parent(sidewalk).get_name()),
|
||||
_ => format!("??? {}", map.get_parent(sidewalk).get_name(None)),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -197,7 +197,7 @@ impl Map {
|
||||
biking_blackhole: false,
|
||||
});
|
||||
}
|
||||
if road.get_name() == "???" {
|
||||
if road.get_name(None) == "???" {
|
||||
// Suppress the warning in some cases.
|
||||
if !(road.osm_tags.is("noname", "yes")
|
||||
|| road
|
||||
|
@ -26,7 +26,7 @@ pub fn get_possible_policies(
|
||||
timer.error(format!(
|
||||
"seattle_traffic_signals data for {} ({}) out of date, go update it",
|
||||
i.orig_id,
|
||||
i.name(map)
|
||||
i.name(None, map)
|
||||
));
|
||||
}
|
||||
}
|
||||
|
@ -633,4 +633,16 @@ impl Map {
|
||||
self.bus_routes[br.0].orig_spawn_times = times.clone();
|
||||
self.bus_routes[br.0].spawn_times = times;
|
||||
}
|
||||
|
||||
pub fn get_languages(&self) -> BTreeSet<&str> {
|
||||
let mut languages = BTreeSet::new();
|
||||
for r in self.all_roads() {
|
||||
for key in r.osm_tags.inner().keys() {
|
||||
if let Some(x) = key.strip_prefix("name:") {
|
||||
languages.insert(x);
|
||||
}
|
||||
}
|
||||
}
|
||||
languages
|
||||
}
|
||||
}
|
||||
|
@ -142,11 +142,11 @@ impl Intersection {
|
||||
.map(|l| map.get_l(*l).get_directed_parent(map))
|
||||
}
|
||||
|
||||
pub fn name(&self, map: &Map) -> String {
|
||||
pub fn name(&self, lang: Option<&String>, map: &Map) -> String {
|
||||
let road_names = self
|
||||
.roads
|
||||
.iter()
|
||||
.map(|r| map.get_r(*r).get_name())
|
||||
.map(|r| map.get_r(*r).get_name(lang))
|
||||
.collect::<BTreeSet<_>>();
|
||||
abstutil::plain_list_names(road_names)
|
||||
}
|
||||
|
@ -293,7 +293,13 @@ impl Road {
|
||||
.make_polygons(self.get_half_width(map) * 2.0)
|
||||
}
|
||||
|
||||
pub fn get_name(&self) -> String {
|
||||
pub fn get_name(&self, lang: Option<&String>) -> String {
|
||||
if let Some(lang) = lang {
|
||||
if let Some(name) = self.osm_tags.get(&format!("name:{}", lang)) {
|
||||
return name.to_string();
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(name) = self.osm_tags.get(osm::NAME) {
|
||||
if name == "" {
|
||||
return "???".to_string();
|
||||
|
Loading…
Reference in New Issue
Block a user