mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-12-24 15:02:59 +03:00
Generate city picker maps from a bunch of small maps, instead of one huge map. Use for Paris. One giant map covering everything there is going to be too large.
This commit is contained in:
parent
d43bf2c869
commit
b6be9c81d5
@ -408,6 +408,10 @@
|
|||||||
"checksum": "69df8b1a1f93c5d52f872ef18eb5cde2",
|
"checksum": "69df8b1a1f93c5d52f872ef18eb5cde2",
|
||||||
"size_bytes": 8485994
|
"size_bytes": 8485994
|
||||||
},
|
},
|
||||||
|
"data/system/paris/city.bin": {
|
||||||
|
"checksum": "0fd1914ef16ad3797ccfaf14c36c3a17",
|
||||||
|
"size_bytes": 2279409
|
||||||
|
},
|
||||||
"data/system/paris/maps/center.bin": {
|
"data/system/paris/maps/center.bin": {
|
||||||
"checksum": "5ed145aee161a464011fb4bc16d3110a",
|
"checksum": "5ed145aee161a464011fb4bc16d3110a",
|
||||||
"size_bytes": 37829561
|
"size_bytes": 37829561
|
||||||
|
@ -8,6 +8,7 @@ rm -fv data/system/seattle/maps/huge_seattle.bin data/input/raw_maps/huge_seattl
|
|||||||
./import.sh --raw --map --city=berlin
|
./import.sh --raw --map --city=berlin
|
||||||
./import.sh --raw --map --city=krakow
|
./import.sh --raw --map --city=krakow
|
||||||
./import.sh --raw --map --city=london
|
./import.sh --raw --map --city=london
|
||||||
|
./import.sh --raw --map --city_overview --city=paris
|
||||||
./import.sh --raw --map --city=tel_aviv
|
./import.sh --raw --map --city=tel_aviv
|
||||||
./import.sh --raw --map --city=xian
|
./import.sh --raw --map --city=xian
|
||||||
|
|
||||||
|
@ -25,6 +25,7 @@ struct Job {
|
|||||||
raw_to_map: bool,
|
raw_to_map: bool,
|
||||||
scenario: bool,
|
scenario: bool,
|
||||||
scenario_everyone: bool,
|
scenario_everyone: bool,
|
||||||
|
city_overview: bool,
|
||||||
|
|
||||||
skip_ch: bool,
|
skip_ch: bool,
|
||||||
keep_bldg_tags: bool,
|
keep_bldg_tags: bool,
|
||||||
@ -49,6 +50,8 @@ fn main() {
|
|||||||
scenario: args.enabled("--scenario"),
|
scenario: args.enabled("--scenario"),
|
||||||
// Produce a variation of the weekday scenario including off-map trips.
|
// Produce a variation of the weekday scenario including off-map trips.
|
||||||
scenario_everyone: args.enabled("--scenario_everyone"),
|
scenario_everyone: args.enabled("--scenario_everyone"),
|
||||||
|
// Produce a city overview from all of the individual maps in a city.
|
||||||
|
city_overview: args.enabled("--city_overview"),
|
||||||
// Skip the most expensive step of --map, building contraction hierarchies. The simulation
|
// Skip the most expensive step of --map, building contraction hierarchies. The simulation
|
||||||
// will use a slower method to pathfind.
|
// will use a slower method to pathfind.
|
||||||
skip_ch: args.enabled("--skip_ch"),
|
skip_ch: args.enabled("--skip_ch"),
|
||||||
@ -70,11 +73,12 @@ fn main() {
|
|||||||
&& !job.raw_to_map
|
&& !job.raw_to_map
|
||||||
&& !job.scenario
|
&& !job.scenario
|
||||||
&& !job.scenario_everyone
|
&& !job.scenario_everyone
|
||||||
|
&& !job.city_overview
|
||||||
&& job.oneshot.is_none()
|
&& job.oneshot.is_none()
|
||||||
{
|
{
|
||||||
println!(
|
println!(
|
||||||
"Nothing to do! Pass some combination of --raw, --map, --scenario, \
|
"Nothing to do! Pass some combination of --raw, --map, --scenario, \
|
||||||
--scenario_everyone or --oneshot"
|
--scenario_everyone, --city_overview, or --oneshot"
|
||||||
);
|
);
|
||||||
std::process::exit(1);
|
std::process::exit(1);
|
||||||
}
|
}
|
||||||
@ -221,6 +225,15 @@ fn main() {
|
|||||||
timer.stop(format!("scenario_everyone for {}", name.describe()));
|
timer.stop(format!("scenario_everyone for {}", name.describe()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if job.city_overview {
|
||||||
|
timer.start(format!("generate city overview for {}", job.city));
|
||||||
|
abstutil::write_binary(
|
||||||
|
abstutil::path(format!("system/{}/city.bin", job.city)),
|
||||||
|
&map_model::City::from_individual_maps(&job.city, &mut timer),
|
||||||
|
);
|
||||||
|
timer.stop(format!("generate city overview for {}", job.city));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn oneshot(
|
fn oneshot(
|
||||||
|
@ -142,7 +142,7 @@ pub fn raw_to_map(
|
|||||||
timer.start("generating city manifest");
|
timer.start("generating city manifest");
|
||||||
abstutil::write_binary(
|
abstutil::write_binary(
|
||||||
abstutil::path(format!("system/{}/city.bin", map.get_city_name())),
|
abstutil::path(format!("system/{}/city.bin", map.get_city_name())),
|
||||||
&map_model::City::new(&map),
|
&map_model::City::from_huge_map(&map),
|
||||||
);
|
);
|
||||||
timer.stop("generating city manifest");
|
timer.stop("generating city manifest");
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use abstutil::MapName;
|
use abstutil::{MapName, Timer};
|
||||||
use geom::{LonLat, Polygon, Ring};
|
use geom::{GPSBounds, LonLat, Polygon, Ring};
|
||||||
|
|
||||||
use crate::{AreaType, Map};
|
use crate::{AreaType, Map};
|
||||||
|
|
||||||
@ -12,13 +12,14 @@ pub struct City {
|
|||||||
pub name: String,
|
pub name: String,
|
||||||
pub boundary: Polygon,
|
pub boundary: Polygon,
|
||||||
pub areas: Vec<(AreaType, Polygon)>,
|
pub areas: Vec<(AreaType, Polygon)>,
|
||||||
// The individual maps
|
/// The individual maps
|
||||||
pub regions: Vec<(MapName, Polygon)>,
|
pub regions: Vec<(MapName, Polygon)>,
|
||||||
// TODO Move nice_map_name from game into here?
|
// TODO Move nice_map_name from game into here?
|
||||||
}
|
}
|
||||||
|
|
||||||
impl City {
|
impl City {
|
||||||
pub fn new(huge_map: &Map) -> City {
|
/// If there's a single map covering all the smaller maps, use this.
|
||||||
|
pub fn from_huge_map(huge_map: &Map) -> City {
|
||||||
let city_name = huge_map.get_city_name().clone();
|
let city_name = huge_map.get_city_name().clone();
|
||||||
let mut regions = abstutil::list_dir(format!("importer/config/{}", city_name))
|
let mut regions = abstutil::list_dir(format!("importer/config/{}", city_name))
|
||||||
.into_iter()
|
.into_iter()
|
||||||
@ -46,4 +47,53 @@ impl City {
|
|||||||
regions,
|
regions,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Generate a city from a bunch of smaller, individual maps. The boundaries of those maps
|
||||||
|
/// may overlap and may have gaps between them.
|
||||||
|
pub fn from_individual_maps(city_name: &str, timer: &mut Timer) -> City {
|
||||||
|
let boundary_per_region: Vec<(MapName, Vec<LonLat>)> =
|
||||||
|
abstutil::list_dir(format!("importer/config/{}", city_name))
|
||||||
|
.into_iter()
|
||||||
|
.filter(|path| path.ends_with(".poly"))
|
||||||
|
.map(|path| {
|
||||||
|
(
|
||||||
|
MapName::new(&city_name, &abstutil::basename(&path)),
|
||||||
|
LonLat::read_osmosis_polygon(&path).unwrap(),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
// Figure out the total bounds for all the maps
|
||||||
|
let mut gps_bounds = GPSBounds::new();
|
||||||
|
for (_, pts) in &boundary_per_region {
|
||||||
|
for pt in pts {
|
||||||
|
gps_bounds.update(*pt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let boundary = gps_bounds.to_bounds().get_rectangle();
|
||||||
|
|
||||||
|
let mut regions = Vec::new();
|
||||||
|
for (name, pts) in boundary_per_region {
|
||||||
|
regions.push((name, Ring::must_new(gps_bounds.convert(&pts)).to_polygon()));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add areas from every map. It's fine if they partly overlap.
|
||||||
|
let mut areas = Vec::new();
|
||||||
|
for path in abstutil::list_dir(abstutil::path(format!("system/{}/maps", city_name))) {
|
||||||
|
let map = Map::new(path, timer);
|
||||||
|
for area in map.all_areas() {
|
||||||
|
let pts = map.gps_bounds.convert_back(area.polygon.points());
|
||||||
|
// TODO Holes in the polygons get lost
|
||||||
|
if let Ok(ring) = Ring::new(gps_bounds.convert(&pts)) {
|
||||||
|
areas.push((area.area_type, ring.to_polygon()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
City {
|
||||||
|
name: city_name.to_string(),
|
||||||
|
boundary,
|
||||||
|
areas,
|
||||||
|
regions,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user