mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-12-24 15:02:59 +03:00
Add craft and office to import and add/reorg AmenityType (#638)
* Add craft and office to import and add/reorg AmenityType * Remove bike rental/parking and rename BikeShop to Bike * add in leisure and tourism tags, add more categories to AmenityType and remove lesser used tags * add dependency on strum and strum_macros and removed some manual code for text display of Enum and Enum into string * include lock file, fix color of buildings for amenity layer, fix formatting and use orders
This commit is contained in:
parent
c6e4b6147f
commit
4080d0d130
24
Cargo.lock
generated
24
Cargo.lock
generated
@ -2331,6 +2331,8 @@ dependencies = [
|
||||
"rand_xorshift",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"strum 0.20.0",
|
||||
"strum_macros 0.20.1",
|
||||
"thread_local",
|
||||
"traffic_signal_data",
|
||||
]
|
||||
@ -3836,6 +3838,12 @@ version = "0.18.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "57bd81eb48f4c437cadc685403cad539345bf703d78e63707418431cecd4522b"
|
||||
|
||||
[[package]]
|
||||
name = "strum"
|
||||
version = "0.20.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7318c509b5ba57f18533982607f24070a55d353e90d4cae30c467cdb2ad5ac5c"
|
||||
|
||||
[[package]]
|
||||
name = "strum_macros"
|
||||
version = "0.18.0"
|
||||
@ -3848,6 +3856,18 @@ dependencies = [
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "strum_macros"
|
||||
version = "0.20.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ee8bc6b87a5112aeeab1f4a9f7ab634fe6cbefc4850006df31267f4cfb9e3149"
|
||||
dependencies = [
|
||||
"heck",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "subprocess"
|
||||
version = "0.2.6"
|
||||
@ -3909,8 +3929,8 @@ checksum = "0f3ecc17269a19353b3558b313bba738b25d82993e30d62a18406a24aba4649b"
|
||||
dependencies = [
|
||||
"heck",
|
||||
"pkg-config",
|
||||
"strum",
|
||||
"strum_macros",
|
||||
"strum 0.18.0",
|
||||
"strum_macros 0.18.0",
|
||||
"thiserror",
|
||||
"toml",
|
||||
"version-compare",
|
||||
|
@ -539,7 +539,7 @@ fn is_bldg(tags: &Tags) -> bool {
|
||||
|
||||
fn get_bldg_amenities(tags: &Tags) -> Vec<Amenity> {
|
||||
let mut amenities = Vec::new();
|
||||
for key in vec!["amenity", "shop"] {
|
||||
for key in vec!["amenity", "shop", "craft", "office", "tourism", "leisure"] {
|
||||
if let Some(amenity) = tags.get(key) {
|
||||
amenities.push(Amenity {
|
||||
names: NamePerLanguage::new(tags).unwrap_or_else(NamePerLanguage::unnamed),
|
||||
|
@ -12,6 +12,7 @@ use map_gui::tools::{
|
||||
use map_gui::ID;
|
||||
use map_model::connectivity::WalkingOptions;
|
||||
use map_model::{AmenityType, Building, BuildingID, LaneType};
|
||||
use std::str::FromStr;
|
||||
use widgetry::table::{Col, Filter, Table};
|
||||
use widgetry::{
|
||||
lctrl, Cached, Choice, Color, Drawable, EventCtx, GeomBatch, GfxCtx, HorizontalAlignment, Key,
|
||||
@ -97,7 +98,7 @@ impl State<App> for Viewer {
|
||||
.currently_hovering()
|
||||
.and_then(|x| x.strip_prefix("businesses: "));
|
||||
if let Some(category) = key {
|
||||
let category = AmenityType::parse(category).unwrap();
|
||||
let category = AmenityType::from_str(category).unwrap();
|
||||
if self
|
||||
.hovering_on_category
|
||||
.as_ref()
|
||||
@ -177,7 +178,7 @@ impl State<App> for Viewer {
|
||||
ctx,
|
||||
app,
|
||||
&self.isochrone,
|
||||
AmenityType::parse(category).unwrap(),
|
||||
AmenityType::from_str(category).unwrap(),
|
||||
));
|
||||
} else {
|
||||
unreachable!()
|
||||
|
@ -6,7 +6,7 @@ use map_gui::tools::{ColorDiscrete, ColorLegend, ColorNetwork};
|
||||
use map_gui::ID;
|
||||
use map_model::{AmenityType, LaneType};
|
||||
use sim::AgentType;
|
||||
use widgetry::{Color, Drawable, EventCtx, GfxCtx, Line, Panel, Text, TextExt, Widget};
|
||||
use widgetry::{Color, Drawable, EventCtx, GeomBatch, GfxCtx, Line, Panel, Text, TextExt, Widget};
|
||||
|
||||
use crate::app::App;
|
||||
use crate::layer::{header, Layer, LayerOutcome, PANEL_PLACEMENT};
|
||||
@ -251,45 +251,50 @@ impl Static {
|
||||
}
|
||||
|
||||
pub fn amenities(ctx: &mut EventCtx, app: &App) -> Static {
|
||||
let mut colorer = ColorDiscrete::new(
|
||||
app,
|
||||
vec![
|
||||
(AmenityType::Groceries.to_string(), Color::BLACK),
|
||||
(AmenityType::Food.to_string(), Color::RED),
|
||||
(AmenityType::Bar.to_string(), Color::BLUE),
|
||||
(AmenityType::Medical.to_string(), Color::PURPLE),
|
||||
(AmenityType::Religious.to_string(), Color::GREEN),
|
||||
(AmenityType::Education.to_string(), Color::CYAN),
|
||||
(AmenityType::Financial.to_string(), Color::YELLOW),
|
||||
(AmenityType::PostOffice.to_string(), Color::YELLOW),
|
||||
(AmenityType::Culture.to_string(), Color::PINK),
|
||||
(AmenityType::Childcare.to_string(), Color::ORANGE),
|
||||
(AmenityType::Shopping.to_string(), Color::WHITE),
|
||||
("other".to_string(), Color::hex("#96322F")),
|
||||
],
|
||||
);
|
||||
let food = Color::RED;
|
||||
let school = Color::CYAN;
|
||||
let shopping = Color::PURPLE;
|
||||
let other = Color::GREEN;
|
||||
|
||||
let mut unzoomed = GeomBatch::new();
|
||||
let mut zoomed = GeomBatch::new();
|
||||
for b in app.primary.map.all_buildings() {
|
||||
let mut other = false;
|
||||
if b.amenities.is_empty() {
|
||||
continue;
|
||||
}
|
||||
let mut color = None;
|
||||
for a in &b.amenities {
|
||||
if let Some(t) = AmenityType::categorize(&a.amenity_type) {
|
||||
colorer.add_b(b.id, t.to_string());
|
||||
} else {
|
||||
other = true;
|
||||
color = Some(match t {
|
||||
AmenityType::Food => food,
|
||||
AmenityType::School => school,
|
||||
AmenityType::Shopping => shopping,
|
||||
_ => other,
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
if other {
|
||||
colorer.add_b(b.id, "other");
|
||||
}
|
||||
let color = color.unwrap_or(other);
|
||||
unzoomed.push(color, b.polygon.clone());
|
||||
zoomed.push(color.alpha(0.4), b.polygon.clone());
|
||||
}
|
||||
|
||||
Static::new(
|
||||
ctx,
|
||||
colorer,
|
||||
"amenities",
|
||||
"Amenities".to_string(),
|
||||
Widget::nothing(),
|
||||
)
|
||||
let panel = Panel::new(Widget::col(vec![
|
||||
header(ctx, "Amenities"),
|
||||
ColorLegend::row(ctx, food, AmenityType::Food.to_string()),
|
||||
ColorLegend::row(ctx, school, AmenityType::School.to_string()),
|
||||
ColorLegend::row(ctx, shopping, AmenityType::Shopping.to_string()),
|
||||
ColorLegend::row(ctx, other, "other".to_string()),
|
||||
]))
|
||||
.aligned_pair(PANEL_PLACEMENT)
|
||||
.build(ctx);
|
||||
|
||||
Static {
|
||||
panel,
|
||||
unzoomed: ctx.upload(unzoomed),
|
||||
zoomed: ctx.upload(zoomed),
|
||||
name: "amenities",
|
||||
}
|
||||
}
|
||||
|
||||
pub fn no_sidewalks(ctx: &mut EventCtx, app: &App) -> Static {
|
||||
|
@ -18,5 +18,7 @@ rand = "0.8.3"
|
||||
rand_xorshift = "0.3.0"
|
||||
serde = "1.0.123"
|
||||
serde_json = "1.0.61"
|
||||
strum = "0.20"
|
||||
strum_macros = "0.20"
|
||||
thread_local = "1.1.2"
|
||||
traffic_signal_data = { path = "../traffic_signal_data" }
|
||||
|
@ -2,6 +2,8 @@ use std::collections::{BTreeMap, HashSet, VecDeque};
|
||||
use std::fmt;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use strum_macros::Display;
|
||||
use strum_macros::EnumString;
|
||||
|
||||
use abstutil::{
|
||||
deserialize_btreemap, deserialize_usize, serialize_btreemap, serialize_usize, Tags,
|
||||
@ -225,112 +227,185 @@ fn sidewalk_to_bike(sidewalk_pos: Position, map: &Map) -> Option<(Position, Posi
|
||||
}
|
||||
|
||||
/// Businesses are categorized into one of these types.
|
||||
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
|
||||
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, EnumString, Display)]
|
||||
pub enum AmenityType {
|
||||
Groceries,
|
||||
Food,
|
||||
Bank,
|
||||
Bar,
|
||||
Medical,
|
||||
Religious,
|
||||
Education,
|
||||
Financial,
|
||||
PostOffice,
|
||||
Culture,
|
||||
Beauty,
|
||||
Bike,
|
||||
Cafe,
|
||||
CarRepair,
|
||||
CarShare,
|
||||
Childcare,
|
||||
ConvenienceStore,
|
||||
Culture,
|
||||
Exercise,
|
||||
FastFood,
|
||||
Food,
|
||||
GreenSpace,
|
||||
Hotel,
|
||||
Laundry,
|
||||
Library,
|
||||
Medical,
|
||||
Pet,
|
||||
Playground,
|
||||
Pool,
|
||||
PostOffice,
|
||||
Religious,
|
||||
School,
|
||||
Shopping,
|
||||
Supermarket,
|
||||
Tourism,
|
||||
University,
|
||||
}
|
||||
|
||||
impl AmenityType {
|
||||
fn types(self) -> Vec<&'static str> {
|
||||
// TODO: create categories for:
|
||||
// hairdresser beauty chemist
|
||||
// car_repair
|
||||
// laundry
|
||||
|
||||
match self {
|
||||
AmenityType::Groceries => vec!["convenience", "supermarket"],
|
||||
// TODO Sort
|
||||
AmenityType::Bank => vec!["bank"],
|
||||
AmenityType::Bar => vec!["bar", "pub", "nightclub", "biergarten"],
|
||||
AmenityType::Beauty => vec!["hairdresser", "beauty", "chemist", "cosmetics"],
|
||||
AmenityType::Bike => vec!["bicycle"],
|
||||
AmenityType::Cafe => vec!["cafe", "pastry", "coffee", "tea", "bakery"],
|
||||
AmenityType::CarRepair => vec!["car_repair"],
|
||||
AmenityType::CarShare => vec!["car_sharing"],
|
||||
AmenityType::Childcare => vec!["childcare", "kindergarten"],
|
||||
AmenityType::ConvenienceStore => vec!["convenience"],
|
||||
AmenityType::Culture => vec!["arts_centre", "art", "cinema", "theatre"],
|
||||
AmenityType::Exercise => vec!["fitness_centre", "sports_centre", "track", "pitch"],
|
||||
AmenityType::FastFood => vec!["fast_food", "food_court"],
|
||||
AmenityType::Food => vec![
|
||||
"restaurant",
|
||||
"cafe",
|
||||
"fast_food",
|
||||
"food_court",
|
||||
"farm",
|
||||
"ice_cream",
|
||||
"pastry",
|
||||
"seafood",
|
||||
"cheese",
|
||||
"chocolate",
|
||||
"deli",
|
||||
"greengrocer",
|
||||
"bakery",
|
||||
"butcher",
|
||||
"confectionery",
|
||||
"beverages",
|
||||
"alcohol",
|
||||
],
|
||||
AmenityType::Bar => vec!["bar", "lounge", "pub", "nightclub"],
|
||||
AmenityType::GreenSpace => vec!["park", "garden", "nature_reserve"],
|
||||
AmenityType::Hotel => vec!["hotel", "hostel", "guest_house", "motel"],
|
||||
AmenityType::Laundry => vec!["dry_cleaning", "laundry", "tailor"],
|
||||
AmenityType::Library => vec!["library"],
|
||||
AmenityType::Medical => vec![
|
||||
"chiropractor",
|
||||
"clinic",
|
||||
"dentist",
|
||||
"hospital",
|
||||
"pharmacy",
|
||||
"optician",
|
||||
"clinic", "dentist", "hospital", "pharmacy", "doctors", "optician",
|
||||
],
|
||||
AmenityType::Religious => vec!["place_of_worship"],
|
||||
AmenityType::Education => vec!["college", "school", "university"],
|
||||
AmenityType::Financial => vec!["bank"],
|
||||
AmenityType::Pet => vec!["veterinary", "pet", "animal_boarding", "pet_grooming"],
|
||||
AmenityType::Playground => vec!["playground"],
|
||||
AmenityType::Pool => vec!["swimming_pool"],
|
||||
AmenityType::PostOffice => vec!["post_office"],
|
||||
AmenityType::Culture => vec![
|
||||
"arts_centre",
|
||||
"art_gallery",
|
||||
"cinema",
|
||||
"library",
|
||||
"museum",
|
||||
"theatre",
|
||||
],
|
||||
AmenityType::Childcare => vec!["childcare", "kindergarten"],
|
||||
AmenityType::Religious => vec!["place_of_worship", "religion"],
|
||||
AmenityType::School => vec!["school"],
|
||||
AmenityType::Shopping => vec![
|
||||
"wholesale",
|
||||
"bag",
|
||||
"marketplace",
|
||||
"second_hand",
|
||||
"charity",
|
||||
"clothes",
|
||||
"furniture",
|
||||
"lottery",
|
||||
"shoes",
|
||||
"mall",
|
||||
"department_store",
|
||||
"car",
|
||||
"tailor",
|
||||
"nutrition_supplements",
|
||||
"watches",
|
||||
"craft",
|
||||
"fabric",
|
||||
"kiosk",
|
||||
"antiques",
|
||||
"shoemaker",
|
||||
"hardware",
|
||||
"houseware",
|
||||
"mobile_phone",
|
||||
"photo",
|
||||
"toys",
|
||||
"bed",
|
||||
"florist",
|
||||
"electronics",
|
||||
"fishing",
|
||||
"garden_centre",
|
||||
"frame",
|
||||
"watchmaker",
|
||||
"boutique",
|
||||
"mobile_phone",
|
||||
"party",
|
||||
"car_parts",
|
||||
"video",
|
||||
"video_games",
|
||||
"musical_instrument",
|
||||
"music",
|
||||
"baby_goods",
|
||||
"doityourself",
|
||||
"jewelry",
|
||||
"variety_store",
|
||||
"gift",
|
||||
"bicycle",
|
||||
"carpet",
|
||||
"perfumery",
|
||||
"curtain",
|
||||
"appliance",
|
||||
"furniture",
|
||||
"lighting",
|
||||
"sewing",
|
||||
"books",
|
||||
"sports",
|
||||
"travel_agency",
|
||||
"interior_decoration",
|
||||
"stationery",
|
||||
"pet",
|
||||
"computer",
|
||||
"tyres",
|
||||
"newsagent",
|
||||
"general",
|
||||
],
|
||||
AmenityType::Supermarket => vec!["supermarket", "greengrocer"],
|
||||
AmenityType::Tourism => vec![
|
||||
"gallery",
|
||||
"museum",
|
||||
"zoo",
|
||||
"attraction",
|
||||
"theme_park",
|
||||
"aquarium",
|
||||
],
|
||||
AmenityType::University => vec!["college", "university"],
|
||||
}
|
||||
}
|
||||
|
||||
/// All types of amenities, in an arbitrary order.
|
||||
pub fn all() -> Vec<AmenityType> {
|
||||
vec![
|
||||
AmenityType::Groceries,
|
||||
AmenityType::Food,
|
||||
AmenityType::Bank,
|
||||
AmenityType::Bar,
|
||||
AmenityType::Medical,
|
||||
AmenityType::Religious,
|
||||
AmenityType::Education,
|
||||
AmenityType::Financial,
|
||||
AmenityType::PostOffice,
|
||||
AmenityType::Culture,
|
||||
AmenityType::Beauty,
|
||||
AmenityType::Bike,
|
||||
AmenityType::Cafe,
|
||||
AmenityType::CarRepair,
|
||||
AmenityType::CarShare,
|
||||
AmenityType::Childcare,
|
||||
AmenityType::ConvenienceStore,
|
||||
AmenityType::Culture,
|
||||
AmenityType::FastFood,
|
||||
AmenityType::Food,
|
||||
AmenityType::Exercise,
|
||||
AmenityType::GreenSpace,
|
||||
AmenityType::Hotel,
|
||||
AmenityType::Laundry,
|
||||
AmenityType::Library,
|
||||
AmenityType::Medical,
|
||||
AmenityType::Pet,
|
||||
AmenityType::Playground,
|
||||
AmenityType::Pool,
|
||||
AmenityType::PostOffice,
|
||||
AmenityType::Religious,
|
||||
AmenityType::School,
|
||||
AmenityType::Shopping,
|
||||
AmenityType::Supermarket,
|
||||
AmenityType::Tourism,
|
||||
AmenityType::University,
|
||||
]
|
||||
}
|
||||
|
||||
@ -343,43 +418,4 @@ impl AmenityType {
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
pub fn parse(x: &str) -> Option<AmenityType> {
|
||||
match x {
|
||||
"groceries" => Some(AmenityType::Groceries),
|
||||
"food" => Some(AmenityType::Food),
|
||||
"bar" => Some(AmenityType::Bar),
|
||||
"medical" => Some(AmenityType::Medical),
|
||||
"religious" => Some(AmenityType::Religious),
|
||||
"education" => Some(AmenityType::Education),
|
||||
"financial" => Some(AmenityType::Financial),
|
||||
"post office" => Some(AmenityType::PostOffice),
|
||||
"culture" => Some(AmenityType::Culture),
|
||||
"childcare" => Some(AmenityType::Childcare),
|
||||
"shopping" => Some(AmenityType::Shopping),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for AmenityType {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"{}",
|
||||
match self {
|
||||
AmenityType::Groceries => "groceries",
|
||||
AmenityType::Food => "food",
|
||||
AmenityType::Bar => "bar",
|
||||
AmenityType::Medical => "medical",
|
||||
AmenityType::Religious => "religious",
|
||||
AmenityType::Education => "education",
|
||||
AmenityType::Financial => "financial",
|
||||
AmenityType::PostOffice => "post office",
|
||||
AmenityType::Culture => "culture",
|
||||
AmenityType::Childcare => "childcare",
|
||||
AmenityType::Shopping => "shopping",
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user