mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-12-25 15:33:44 +03:00
infer clipping polygon from entire .osm if no polygon is specified
This commit is contained in:
parent
3fd59ebdb5
commit
1910d06bc7
@ -5,11 +5,9 @@ mod remove_disconnected;
|
||||
mod split_ways;
|
||||
|
||||
use abstutil::Timer;
|
||||
use geom::{Distance, FindClosest, GPSBounds, Line, LonLat, PolyLine, Polygon, Pt2D};
|
||||
use geom::{Distance, FindClosest, Line, PolyLine, Pt2D};
|
||||
use kml::ExtraShapes;
|
||||
use map_model::{raw_data, LaneID, OffstreetParking, Position, LANE_THICKNESS};
|
||||
use std::fs::File;
|
||||
use std::io::{BufRead, BufReader};
|
||||
use structopt::StructOpt;
|
||||
|
||||
#[derive(StructOpt, Debug)]
|
||||
@ -49,13 +47,8 @@ pub struct Flags {
|
||||
}
|
||||
|
||||
pub fn convert(flags: &Flags, timer: &mut abstutil::Timer) -> raw_data::Map {
|
||||
if flags.clip.is_empty() {
|
||||
panic!("You must specify an Osmosis boundary polygon with --clip");
|
||||
}
|
||||
let mut map = split_ways::split_up_roads(
|
||||
osm::extract_osm(&flags.osm, read_osmosis_polygon(&flags.clip), timer),
|
||||
timer,
|
||||
);
|
||||
let mut map =
|
||||
split_ways::split_up_roads(osm::extract_osm(&flags.osm, &flags.clip, timer), timer);
|
||||
clip::clip_map(&mut map, timer);
|
||||
remove_disconnected::remove_disconnected_roads(&mut map, timer);
|
||||
|
||||
@ -136,36 +129,6 @@ fn use_parking_hints(map: &mut raw_data::Map, path: &str, timer: &mut Timer) {
|
||||
timer.stop("apply parking hints");
|
||||
}
|
||||
|
||||
fn read_osmosis_polygon(path: &str) -> raw_data::Map {
|
||||
let mut pts: Vec<LonLat> = Vec::new();
|
||||
let mut gps_bounds = GPSBounds::new();
|
||||
for (idx, maybe_line) in BufReader::new(File::open(path).unwrap())
|
||||
.lines()
|
||||
.enumerate()
|
||||
{
|
||||
if idx == 0 || idx == 1 {
|
||||
continue;
|
||||
}
|
||||
let line = maybe_line.unwrap();
|
||||
if line == "END" {
|
||||
break;
|
||||
}
|
||||
let parts: Vec<&str> = line.trim_start().split(" ").collect();
|
||||
assert!(parts.len() == 2);
|
||||
let pt = LonLat::new(
|
||||
parts[0].parse::<f64>().unwrap(),
|
||||
parts[1].parse::<f64>().unwrap(),
|
||||
);
|
||||
pts.push(pt);
|
||||
gps_bounds.update(pt);
|
||||
}
|
||||
|
||||
let mut map = raw_data::Map::blank();
|
||||
map.boundary_polygon = Polygon::new(&gps_bounds.must_convert(&pts));
|
||||
map.gps_bounds = gps_bounds;
|
||||
map
|
||||
}
|
||||
|
||||
fn use_offstreet_parking(map: &mut raw_data::Map, path: &str, timer: &mut Timer) {
|
||||
timer.start("match offstreet parking points");
|
||||
let shapes = kml::load(path, &map.gps_bounds, timer).expect("loading offstreet_parking failed");
|
||||
|
@ -1,12 +1,14 @@
|
||||
use abstutil::{FileWithProgress, Timer};
|
||||
use geom::{HashablePt2D, LonLat, Polygon, Pt2D};
|
||||
use geom::{GPSBounds, HashablePt2D, LonLat, Polygon, Pt2D};
|
||||
use map_model::{raw_data, AreaType};
|
||||
use osm_xml;
|
||||
use std::collections::{BTreeMap, HashMap, HashSet};
|
||||
use std::fs::File;
|
||||
use std::io::{BufRead, BufReader};
|
||||
|
||||
pub fn extract_osm(
|
||||
osm_path: &str,
|
||||
mut map: raw_data::Map,
|
||||
maybe_clip_path: &str,
|
||||
timer: &mut Timer,
|
||||
) -> (
|
||||
raw_data::Map,
|
||||
@ -25,6 +27,17 @@ pub fn extract_osm(
|
||||
);
|
||||
done(timer);
|
||||
|
||||
let mut map = if maybe_clip_path.is_empty() {
|
||||
let mut m = raw_data::Map::blank();
|
||||
for node in doc.nodes.values() {
|
||||
m.gps_bounds.update(LonLat::new(node.lon, node.lat));
|
||||
}
|
||||
m.boundary_polygon = m.gps_bounds.to_bounds().get_rectangle();
|
||||
m
|
||||
} else {
|
||||
read_osmosis_polygon(maybe_clip_path)
|
||||
};
|
||||
|
||||
let mut id_to_way: HashMap<i64, Vec<Pt2D>> = HashMap::new();
|
||||
let mut roads: Vec<raw_data::Road> = Vec::new();
|
||||
let mut traffic_signals: HashSet<HashablePt2D> = HashSet::new();
|
||||
@ -79,13 +92,20 @@ pub fn extract_osm(
|
||||
parking_lane_back: false,
|
||||
});
|
||||
} else if is_bldg(&tags) {
|
||||
let deduped = Pt2D::approx_dedupe(pts, geom::EPSILON_DIST);
|
||||
if deduped.len() < 3 {
|
||||
continue;
|
||||
}
|
||||
map.buildings.push(raw_data::Building {
|
||||
osm_way_id: way.id,
|
||||
polygon: Polygon::new(&Pt2D::approx_dedupe(pts, geom::EPSILON_DIST)),
|
||||
polygon: Polygon::new(&deduped),
|
||||
osm_tags: tags,
|
||||
parking: None,
|
||||
});
|
||||
} else if let Some(at) = get_area_type(&tags) {
|
||||
if pts.len() < 3 {
|
||||
continue;
|
||||
}
|
||||
map.areas.push(raw_data::Area {
|
||||
area_type: at,
|
||||
osm_id: way.id,
|
||||
@ -291,3 +311,33 @@ fn glue_multipolygon(mut pts_per_way: Vec<Vec<Pt2D>>) -> Vec<Polygon> {
|
||||
polygons.push(Polygon::new(&result));
|
||||
polygons
|
||||
}
|
||||
|
||||
fn read_osmosis_polygon(path: &str) -> raw_data::Map {
|
||||
let mut pts: Vec<LonLat> = Vec::new();
|
||||
let mut gps_bounds = GPSBounds::new();
|
||||
for (idx, maybe_line) in BufReader::new(File::open(path).unwrap())
|
||||
.lines()
|
||||
.enumerate()
|
||||
{
|
||||
if idx == 0 || idx == 1 {
|
||||
continue;
|
||||
}
|
||||
let line = maybe_line.unwrap();
|
||||
if line == "END" {
|
||||
break;
|
||||
}
|
||||
let parts: Vec<&str> = line.trim_start().split(" ").collect();
|
||||
assert!(parts.len() == 2);
|
||||
let pt = LonLat::new(
|
||||
parts[0].parse::<f64>().unwrap(),
|
||||
parts[1].parse::<f64>().unwrap(),
|
||||
);
|
||||
pts.push(pt);
|
||||
gps_bounds.update(pt);
|
||||
}
|
||||
|
||||
let mut map = raw_data::Map::blank();
|
||||
map.boundary_polygon = Polygon::new(&gps_bounds.must_convert(&pts));
|
||||
map.gps_bounds = gps_bounds;
|
||||
map
|
||||
}
|
||||
|
@ -4,26 +4,16 @@ My current priority is to make Seattle work very well, but if you want to try
|
||||
out A/B Street in another place, you can follow this guide. Please file a Github
|
||||
issue or email <dabreegster@gmail.com> if you hit any problems.
|
||||
|
||||
First you need to prepare input. Obtain a `.osm` file and create an
|
||||
[Osmosis polygon filter file](https://wiki.openstreetmap.org/wiki/Osmosis/Polygon_Filter_File_Format)
|
||||
for the area you want to import. You can clip a `.osm` like this:
|
||||
|
||||
```
|
||||
osmosis \
|
||||
--read-xml enableDateParsing=no file=large_area.osm \
|
||||
--bounding-polygon file=clip.poly completeWays=true \
|
||||
--write-xml data/input/your_city.osm
|
||||
```
|
||||
First obtain a `.osm` with your desired area. You can use a tool like Osmosis to
|
||||
clip a specific area from a large file. Put the `.osm` in `data/input/`.
|
||||
|
||||
Then you'll run some tools to import the map. Make sure you can compile
|
||||
everything [from source](INSTRUCTIONS.md). Keep `clip.poly` around for the next
|
||||
command.
|
||||
everything [from source](INSTRUCTIONS.md).
|
||||
|
||||
```
|
||||
cd convert_osm
|
||||
cargo run --release -- \
|
||||
--osm=../data/input/your_city.osm \
|
||||
--clip=../data/input/clip.poly \
|
||||
--output=../data/raw_maps/your_city.bin
|
||||
cd ../precompute
|
||||
cargo run --release -- ../data/raw_maps/your_city.bin
|
||||
|
@ -1,4 +1,4 @@
|
||||
use crate::{LonLat, Pt2D};
|
||||
use crate::{LonLat, Polygon, Pt2D};
|
||||
use aabb_quadtree::geom::{Point, Rect};
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use std::f64;
|
||||
@ -58,13 +58,14 @@ impl Bounds {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_corners(&self) -> Vec<Pt2D> {
|
||||
vec![
|
||||
pub fn get_rectangle(&self) -> Polygon {
|
||||
Polygon::new(&vec![
|
||||
Pt2D::new(self.min_x, self.min_y),
|
||||
Pt2D::new(self.max_x, self.min_y),
|
||||
Pt2D::new(self.max_x, self.max_y),
|
||||
Pt2D::new(self.min_x, self.max_y),
|
||||
]
|
||||
Pt2D::new(self.min_x, self.min_y),
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -81,12 +81,10 @@ impl Neighborhood {
|
||||
}
|
||||
|
||||
fn make_everywhere(map: &Map) -> Neighborhood {
|
||||
let mut pts = map.get_bounds().get_corners();
|
||||
pts.push(pts[0]);
|
||||
Neighborhood {
|
||||
map_name: map.get_name().to_string(),
|
||||
name: "_everywhere_".to_string(),
|
||||
polygon: Polygon::new(&pts),
|
||||
polygon: map.get_bounds().get_rectangle(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user