mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-12-24 23:15:24 +03:00
finish up the grand geom stabilization with ring and some docs.
regenerated everything from scratch. one effect is more parking blockface gets matched onto border roads, but that's fine.
This commit is contained in:
parent
07ed1fec95
commit
0c283d0da7
@ -9,7 +9,7 @@ pub fn clip_map(map: &mut RawMap, timer: &mut Timer) {
|
||||
|
||||
// So we can use retain_btreemap without borrowing issues
|
||||
let boundary_polygon = map.boundary_polygon.clone();
|
||||
let boundary_ring = Ring::new(boundary_polygon.points().clone());
|
||||
let boundary_ring = Ring::must_new(boundary_polygon.points().clone());
|
||||
|
||||
// This is kind of indirect and slow, but first pass -- just remove roads that start or end
|
||||
// outside the boundary polygon.
|
||||
|
@ -180,7 +180,7 @@ pub fn extract_osm(
|
||||
}
|
||||
}
|
||||
|
||||
let boundary = Ring::new(map.boundary_polygon.points().clone());
|
||||
let boundary = Ring::must_new(map.boundary_polygon.points().clone());
|
||||
|
||||
let mut simple_turn_restrictions = Vec::new();
|
||||
let mut complicated_turn_restrictions = Vec::new();
|
||||
|
@ -3,22 +3,22 @@ data/input/austin/osm/downtown_atx.osm,a30b0f460a481598e494f16a9d07a822,https://
|
||||
data/input/austin/osm/huge_austin.osm,fb166029fc8006bd20dc959fbbbde3b6,https://www.dropbox.com/s/4x421o9o8px0m6o/huge_austin.osm.zip?dl=0
|
||||
data/input/krakow/osm/huge_krakow.osm,0b098456c8ae844ff240ca9fe3b617d1,https://www.dropbox.com/s/fe2e8qzd4g5tkoy/huge_krakow.osm.zip?dl=0
|
||||
data/input/krakow/osm/malopolskie-latest.osm.pbf,d848a278092001aaab3ced09de4d98ff,https://www.dropbox.com/s/ia2uwy3z52r6hpe/malopolskie-latest.osm.pbf.zip?dl=0
|
||||
data/input/raw_maps/ballard.bin,fea0486d3925c7ffce54d0e21139ab75,https://www.dropbox.com/s/dfbtfu6qq7shj9t/ballard.bin.zip?dl=0
|
||||
data/input/raw_maps/downtown.bin,5da76c12b035bcde09d0735c6673d4ae,https://www.dropbox.com/s/f3jz7qk6xiij5po/downtown.bin.zip?dl=0
|
||||
data/input/raw_maps/ballard.bin,4d72687ab860144d19ae3f1328f2b61d,https://www.dropbox.com/s/dkxhkir85rtm906/ballard.bin.zip?dl=0
|
||||
data/input/raw_maps/downtown.bin,48886494c43fd7b9db12a53f990dcb4f,https://www.dropbox.com/s/87rpndh1yudrlxb/downtown.bin.zip?dl=0
|
||||
data/input/raw_maps/downtown_atx.bin,2995df6f32feb8135fbb1126b52402ba,https://www.dropbox.com/s/csuzjqhhbtw657x/downtown_atx.bin.zip?dl=0
|
||||
data/input/raw_maps/huge_austin.bin,fb671ea39ea254207c334b5662763433,https://www.dropbox.com/s/91i763larrbmx7z/huge_austin.bin.zip?dl=0
|
||||
data/input/raw_maps/huge_krakow.bin,978426f967f122675ba530edc94b43e3,https://www.dropbox.com/s/5l9ojm1lfq32otz/huge_krakow.bin.zip?dl=0
|
||||
data/input/raw_maps/huge_seattle.bin,e7e49c7421e1343371ab06dc9e3dd64b,https://www.dropbox.com/s/dlajjc94bmxf07p/huge_seattle.bin.zip?dl=0
|
||||
data/input/raw_maps/lakeslice.bin,95ed0a848ed098c068ada54db04c9495,https://www.dropbox.com/s/g1y26xudv7rkmko/lakeslice.bin.zip?dl=0
|
||||
data/input/raw_maps/montlake.bin,1840e685f91589cf267f146f43878c47,https://www.dropbox.com/s/p5itfq7zioz2b3r/montlake.bin.zip?dl=0
|
||||
data/input/raw_maps/south_seattle.bin,bb870ffa8bd159a7ce9dca83216ac0b0,https://www.dropbox.com/s/v405rk7wm7luc0o/south_seattle.bin.zip?dl=0
|
||||
data/input/raw_maps/udistrict.bin,ae242a89a2b83b2b9fc115dea0c40256,https://www.dropbox.com/s/vefz3ozb7od9xdf/udistrict.bin.zip?dl=0
|
||||
data/input/raw_maps/huge_seattle.bin,95798750903b3a7c35f165aaf3e39c91,https://www.dropbox.com/s/5pumdup46zmhb34/huge_seattle.bin.zip?dl=0
|
||||
data/input/raw_maps/lakeslice.bin,28ede305a1e45a4298b8d10503324905,https://www.dropbox.com/s/j707o0ka1k4ixgk/lakeslice.bin.zip?dl=0
|
||||
data/input/raw_maps/montlake.bin,712532a30baa5225aca621fd1f1f7f0a,https://www.dropbox.com/s/evwmldb5872nf0u/montlake.bin.zip?dl=0
|
||||
data/input/raw_maps/south_seattle.bin,5eb52175e7fd06da3fc3e93fc2ca88fc,https://www.dropbox.com/s/jfc4ht5ydm05j8y/south_seattle.bin.zip?dl=0
|
||||
data/input/raw_maps/udistrict.bin,a45f45140c03da4abf8d698cda580133,https://www.dropbox.com/s/plspsqay9c77fwz/udistrict.bin.zip?dl=0
|
||||
data/input/raw_maps/west_seattle.bin,4784c2eeebd11c6c180d11eda73cf1e1,https://www.dropbox.com/s/6lp4foo4l7g487n/west_seattle.bin.zip?dl=0
|
||||
data/input/screenshots/downtown.zip,f1cb474323244ef7a31971e3d5b25a12,https://www.dropbox.com/s/qawd35wz62m2acl/downtown.zip.zip?dl=0
|
||||
data/input/screenshots/huge_krakow.zip,cfc8fe595097fed224d369f2c647443c,https://www.dropbox.com/s/dbzon7k5ukndtza/huge_krakow.zip.zip?dl=0
|
||||
data/input/screenshots/lakeslice.zip,37ad352dbe42ce4aea0ba0a67067d451,https://www.dropbox.com/s/z0z96lsn7bunqfy/lakeslice.zip.zip?dl=0
|
||||
data/input/screenshots/montlake.zip,c8b016f00792ef23b9fae44956d2d86c,https://www.dropbox.com/s/r9vkgwesqklfuq2/montlake.zip.zip?dl=0
|
||||
data/input/screenshots/udistrict.zip,584036034b44708da6ae006b2f40fa3b,https://www.dropbox.com/s/ecnt1tyza48y9o2/udistrict.zip.zip?dl=0
|
||||
data/input/screenshots/downtown.zip,bdad536ddb7f0e5aab912433b3c28e69,https://www.dropbox.com/s/qawd35wz62m2acl/downtown.zip.zip?dl=0
|
||||
data/input/screenshots/huge_krakow.zip,8edcb39fedadb7991ab2959064c98629,https://www.dropbox.com/s/dbzon7k5ukndtza/huge_krakow.zip.zip?dl=0
|
||||
data/input/screenshots/lakeslice.zip,73c0ed5add17f8c49218b1c22ee464cc,https://www.dropbox.com/s/z0z96lsn7bunqfy/lakeslice.zip.zip?dl=0
|
||||
data/input/screenshots/montlake.zip,fbc945c0869c2b85ccfb1fef4340ba2e,https://www.dropbox.com/s/r9vkgwesqklfuq2/montlake.zip.zip?dl=0
|
||||
data/input/screenshots/udistrict.zip,c7a7a258e3d0a417ada55f70c897d4d3,https://www.dropbox.com/s/ecnt1tyza48y9o2/udistrict.zip.zip?dl=0
|
||||
data/input/seattle/N47W122.hgt,0db4e23e51f7680538b0bbbc72208e07,https://www.dropbox.com/s/mmb4mgutwotijdw/N47W122.hgt.zip?dl=0
|
||||
data/input/seattle/blockface.bin,add872bab9040ae911366328a230f8b5,https://www.dropbox.com/s/rxd2care60tbe75/blockface.bin.zip?dl=0
|
||||
data/input/seattle/blockface.kml,350bd9e59bf2af4e885a7c0741e6ee6b,https://www.dropbox.com/s/ukknmpjdvilncq9/blockface.kml.zip?dl=0
|
||||
@ -33,30 +33,30 @@ data/input/seattle/osm/south_seattle.osm,2a20b3549004a3d37ef962baf07fbf93,https:
|
||||
data/input/seattle/osm/udistrict.osm,769388ffc0d73c6a149ed79698e2b8f3,https://www.dropbox.com/s/3v6axtyuofqatit/udistrict.osm.zip?dl=0
|
||||
data/input/seattle/osm/washington-latest.osm.pbf,ac31d2a9d3a109f4467e5f64b5922509,https://www.dropbox.com/s/eilk9soyod3war6/washington-latest.osm.pbf.zip?dl=0
|
||||
data/input/seattle/osm/west_seattle.osm,b87c760bd512c4302846519ed052ad5a,https://www.dropbox.com/s/qhtkotrtp7ilmy1/west_seattle.osm.zip?dl=0
|
||||
data/input/seattle/parcels.bin,1cfdc485a35df9edce7b24e5c17b2977,https://www.dropbox.com/s/s977yzbcds355nv/parcels.bin.zip?dl=0
|
||||
data/input/seattle/parcels.bin,fbaa5480e614e7f59a9e958f92a12526,https://www.dropbox.com/s/cy88qmctgya2g76/parcels.bin.zip?dl=0
|
||||
data/input/seattle/parcels_urbansim.txt,db63d7d606e8702d12f9399e87e6a00f,https://www.dropbox.com/s/6g8rbsf200dssj3/parcels_urbansim.txt.zip?dl=0
|
||||
data/input/seattle/popdat.bin,ad38e1f20ce71f488112fe81e32798d2,https://www.dropbox.com/s/ajqii1qpfke8063/popdat.bin.zip?dl=0
|
||||
data/input/seattle/trips_2014.csv,d4a8e733045b28c0385fb81359d6df03,https://www.dropbox.com/s/5ppravwmk6bf20d/trips_2014.csv.zip?dl=0
|
||||
data/system/cities/seattle.bin,9ed9ff25b3f3941fecf530b3815a1b05,https://www.dropbox.com/s/nwb29tt4koqk6um/seattle.bin.zip?dl=0
|
||||
data/system/maps/ballard.bin,b98c9b698d876ebadd34bbcb541630d3,https://www.dropbox.com/s/ocv4p7dzrxcogyq/ballard.bin.zip?dl=0
|
||||
data/system/maps/downtown.bin,f951b7ca011b91f062334a94585b7083,https://www.dropbox.com/s/ww7jzqlbpxur8l6/downtown.bin.zip?dl=0
|
||||
data/system/maps/ballard.bin,d4ab6ceb6905dfa14b2aaac99c495eff,https://www.dropbox.com/s/too29h0nr6s64wm/ballard.bin.zip?dl=0
|
||||
data/system/maps/downtown.bin,6b7735033169acdb4c1429b084632de5,https://www.dropbox.com/s/8s6pjo91spchkfx/downtown.bin.zip?dl=0
|
||||
data/system/maps/downtown_atx.bin,700a4a78af42e37ef1245e4fc63ce0c4,https://www.dropbox.com/s/ixijn46f07zizzi/downtown_atx.bin.zip?dl=0
|
||||
data/system/maps/huge_austin.bin,f7ea14d6b616a6ca9a63ac4460b0a2a0,https://www.dropbox.com/s/5jlbbinjp4132rp/huge_austin.bin.zip?dl=0
|
||||
data/system/maps/huge_krakow.bin,f87b77708170bafa72331cccc6df57b6,https://www.dropbox.com/s/friayproln1gtig/huge_krakow.bin.zip?dl=0
|
||||
data/system/maps/huge_seattle.bin,4086044e523651a631f0745e73238bb8,https://www.dropbox.com/s/aj0h8igtskfths3/huge_seattle.bin.zip?dl=0
|
||||
data/system/maps/lakeslice.bin,ea5e918b7b70db2c8e484f8666c4737b,https://www.dropbox.com/s/p6r64ujz81vx7vd/lakeslice.bin.zip?dl=0
|
||||
data/system/maps/montlake.bin,032f96ae28a2db2d6b4aa848469e9aea,https://www.dropbox.com/s/rjei8n91qil1bhw/montlake.bin.zip?dl=0
|
||||
data/system/maps/south_seattle.bin,c967a5d372ef7298a711fc213244ccd8,https://www.dropbox.com/s/nynh73cxqggeuj3/south_seattle.bin.zip?dl=0
|
||||
data/system/maps/udistrict.bin,a9a320f182af78d235af98a78aa0646c,https://www.dropbox.com/s/92joyhk29cqoipk/udistrict.bin.zip?dl=0
|
||||
data/system/maps/huge_seattle.bin,05214611240c878306f351b76d07db3b,https://www.dropbox.com/s/xakfwfqbcyeznuy/huge_seattle.bin.zip?dl=0
|
||||
data/system/maps/lakeslice.bin,ecd6b3b127982eb9b42530da2bb0887b,https://www.dropbox.com/s/dkmf2qaa991uxym/lakeslice.bin.zip?dl=0
|
||||
data/system/maps/montlake.bin,cb2246cb15edc0553f5b03af4886471c,https://www.dropbox.com/s/0dnysbp2h7wdaf4/montlake.bin.zip?dl=0
|
||||
data/system/maps/south_seattle.bin,174a44c25848f36d82a59644ef56582e,https://www.dropbox.com/s/cu8exdobcdaj6sm/south_seattle.bin.zip?dl=0
|
||||
data/system/maps/udistrict.bin,c0cf3f4758ebd9faef843cf587b32a99,https://www.dropbox.com/s/z38hxojx3x8qpvl/udistrict.bin.zip?dl=0
|
||||
data/system/maps/west_seattle.bin,ccfb1547ffceaa8a635b12252951ce8f,https://www.dropbox.com/s/x9o4lg7fgvy5kr2/west_seattle.bin.zip?dl=0
|
||||
data/system/prebaked_results/lakeslice/weekday.bin,3bcb09e1d6ddeed75e3baf3b6b476e5c,https://www.dropbox.com/s/5odd5kdxn0caodk/weekday.bin.zip?dl=0
|
||||
data/system/prebaked_results/montlake/car vs bike contention.bin,d3e42a758ba4e10e6143c8f8370a638f,https://www.dropbox.com/s/jefg0ikjy9dsrdd/car%20vs%20bike%20contention.bin.zip?dl=0
|
||||
data/system/prebaked_results/montlake/weekday.bin,979af6c1db9f5bf31a3cf12301c4c6f9,https://www.dropbox.com/s/0duohjtnbj5y7gc/weekday.bin.zip?dl=0
|
||||
data/system/scenarios/ballard/weekday.bin,f6d7dac5af0f35a6ae5589d3943be789,https://www.dropbox.com/s/klvs4wkauh00xud/weekday.bin.zip?dl=0
|
||||
data/system/scenarios/downtown/weekday.bin,2b4506c9aab41a0a12f8d0ef769db492,https://www.dropbox.com/s/swmss3vyrrjnv6n/weekday.bin.zip?dl=0
|
||||
data/system/scenarios/huge_seattle/weekday.bin,30cf8491099a33c758aa76c31267bd13,https://www.dropbox.com/s/a20dujaxnwhe2aj/weekday.bin.zip?dl=0
|
||||
data/system/scenarios/lakeslice/weekday.bin,19812c16dc90945f5c3659b47c1c55e8,https://www.dropbox.com/s/00cjax1g3bcmwvf/weekday.bin.zip?dl=0
|
||||
data/system/scenarios/montlake/weekday.bin,ee5359d37d1d9446578d34c3b97b9266,https://www.dropbox.com/s/bx6sv6rogt2alyq/weekday.bin.zip?dl=0
|
||||
data/system/scenarios/south_seattle/weekday.bin,9b84537fb47831d6b65f81dcb947600d,https://www.dropbox.com/s/i36o01uv6ud8rj3/weekday.bin.zip?dl=0
|
||||
data/system/scenarios/udistrict/weekday.bin,6c08853e72f8fc65b25b69639cb59464,https://www.dropbox.com/s/3c0tlq9k8niz0pr/weekday.bin.zip?dl=0
|
||||
data/system/scenarios/west_seattle/weekday.bin,48a9b04d69948436c8eb89f943e36b5d,https://www.dropbox.com/s/8jq9rs6dom8t0y9/weekday.bin.zip?dl=0
|
||||
data/system/prebaked_results/lakeslice/weekday.bin,6cb89d0581ad0d78cd7644a882ab0528,https://www.dropbox.com/s/frg14z9f90qrk8v/weekday.bin.zip?dl=0
|
||||
data/system/prebaked_results/montlake/car vs bike contention.bin,bd7bbdee559245ed5dd85ddd67165cf9,https://www.dropbox.com/s/jefg0ikjy9dsrdd/car%20vs%20bike%20contention.bin.zip?dl=0
|
||||
data/system/prebaked_results/montlake/weekday.bin,be76cdebe55527b2e19e1c09f9540426,https://www.dropbox.com/s/gzxg2orfu8z9s6x/weekday.bin.zip?dl=0
|
||||
data/system/scenarios/ballard/weekday.bin,b1993a9f154cf88c78884eb96ee28a08,https://www.dropbox.com/s/2sf37gu7nur9o37/weekday.bin.zip?dl=0
|
||||
data/system/scenarios/downtown/weekday.bin,67c8345c4340cbd0a69d3c079c1c6b6c,https://www.dropbox.com/s/kasxsyett83oo03/weekday.bin.zip?dl=0
|
||||
data/system/scenarios/huge_seattle/weekday.bin,102b72c09c63042dc7ca3c143bf7508a,https://www.dropbox.com/s/ebvg1zgv2ywnndf/weekday.bin.zip?dl=0
|
||||
data/system/scenarios/lakeslice/weekday.bin,0d86fa1518f5e06942c0b2b8869b9000,https://www.dropbox.com/s/0cuc7urc0fsgqi5/weekday.bin.zip?dl=0
|
||||
data/system/scenarios/montlake/weekday.bin,3c19364da831e3f81fed81b6edc1a844,https://www.dropbox.com/s/8ypid1mus95ivni/weekday.bin.zip?dl=0
|
||||
data/system/scenarios/south_seattle/weekday.bin,16f5512c24bc140b6d333a44819936d2,https://www.dropbox.com/s/rvyypxoc0awubn1/weekday.bin.zip?dl=0
|
||||
data/system/scenarios/udistrict/weekday.bin,25bf5370f905ce57c017028a33612c4e,https://www.dropbox.com/s/msb70poj5dl29q2/weekday.bin.zip?dl=0
|
||||
data/system/scenarios/west_seattle/weekday.bin,089ee9b267bafc860f8c6952a69f3efe,https://www.dropbox.com/s/l3lfj8gk232cyrl/weekday.bin.zip?dl=0
|
||||
|
24
docs/dev.md
24
docs/dev.md
@ -46,9 +46,6 @@ One-time setup:
|
||||
experience, so they're hidden for now.
|
||||
- `cargo run --bin game -- --tutorial=12` starts somewhere in the tutorial
|
||||
- Adding `--edits='name of edits'` starts with edits applied to the map.
|
||||
- All code is automatically formatted using
|
||||
https://github.com/rust-lang/rustfmt; please run `cargo +nightly fmt` before
|
||||
sending a PR. (You have to install the nightly toolchain just for fmt)
|
||||
- More random notes [here](/docs/misc_dev_tricks.md)
|
||||
|
||||
## Downloading more cities
|
||||
@ -139,3 +136,24 @@ Common utilities:
|
||||
- `abstutil`: a grab-bag of IO helpers, timing and logging utilities, etc
|
||||
- `geom`: types for GPS and map-space points, lines, angles, polylines,
|
||||
polygons, circles, durations, speeds
|
||||
|
||||
## Code conventions
|
||||
|
||||
All code is automatically formatted using https://github.com/rust-lang/rustfmt;
|
||||
please run `cargo +nightly fmt` before sending a PR. (You have to install the
|
||||
nightly toolchain just for fmt)
|
||||
|
||||
The error handling is unfortunately inconsistent. The goal is to gracefully
|
||||
degrade instead of crashing the game. If a crash does happen, make sure the logs
|
||||
will have enough context to reproduce and debug. For example, giving up when
|
||||
some geometry problem happens isn't ideal, but at least make sure to print the
|
||||
road / agent IDs or whatever will help find the problem. It's fine to crash
|
||||
during map importing, since the player won't deal with this, and loudly stopping
|
||||
problems is useful. It's also fine to crash when initially constructing all of
|
||||
the renderable map objects, because this crash will consistently happen at
|
||||
startup-time and be noticed by somebody developing before a player gets to it.
|
||||
|
||||
I have lots of thoughts about testing that I haven't written anywhere yet.
|
||||
You'll surely note the lack of unit tests. If it bothers you, let's talk about
|
||||
what tests should exist. In the meantime, note lots of validation does happen
|
||||
via importing maps, running the prebaked scenarios, and screenshot diffing.
|
||||
|
@ -421,7 +421,8 @@ impl Widget {
|
||||
batch.push(
|
||||
color,
|
||||
Polygon::rounded_rectangle(width, height, self.layout.rounded_radius)
|
||||
.to_outline(Distance::meters(thickness)),
|
||||
.to_outline(Distance::meters(thickness))
|
||||
.unwrap(),
|
||||
);
|
||||
}
|
||||
self.bg = Some(ctx.upload(batch));
|
||||
|
@ -130,7 +130,10 @@ impl<T: 'static + Clone> WidgetImpl for Dropdown<T> {
|
||||
let rect = Polygon::rounded_rectangle(width, height, Some(5.0));
|
||||
let draw_bg = g.upload(GeomBatch::from(vec![
|
||||
(Color::grey(0.3), rect.clone()),
|
||||
(Color::WHITE, rect.to_outline(Distance::meters(3.0))),
|
||||
(
|
||||
Color::WHITE,
|
||||
rect.to_outline(Distance::meters(3.0)).unwrap(),
|
||||
),
|
||||
]));
|
||||
g.fork(
|
||||
Pt2D::new(0.0, 0.0),
|
||||
|
@ -54,7 +54,7 @@ impl CityPicker {
|
||||
if &name == app.primary.map.get_name() {
|
||||
batch.push(color.alpha(0.5), polygon.clone());
|
||||
} else {
|
||||
batch.push(color, polygon.to_outline(Distance::meters(200.0)));
|
||||
batch.push(color, polygon.to_outline(Distance::meters(200.0)).unwrap());
|
||||
}
|
||||
regions.push((name, color, polygon.scale(zoom_no_scale_factor)));
|
||||
}
|
||||
|
@ -300,7 +300,7 @@ impl Minimap {
|
||||
};
|
||||
g.draw_polygon(
|
||||
Color::BLACK,
|
||||
&Ring::new(vec![
|
||||
&Ring::must_new(vec![
|
||||
Pt2D::new(x1, y1),
|
||||
Pt2D::new(x2, y1),
|
||||
Pt2D::new(x2, y2),
|
||||
|
@ -204,7 +204,7 @@ fn make_object(
|
||||
} else if pts[0] == *pts.last().unwrap() {
|
||||
// TODO Toggle between these better
|
||||
//Polygon::new(&pts)
|
||||
Ring::new(pts).make_polygons(THICKNESS)
|
||||
Ring::must_new(pts).make_polygons(THICKNESS)
|
||||
} else {
|
||||
let backup = pts[0];
|
||||
match PolyLine::new(pts) {
|
||||
|
@ -464,7 +464,7 @@ impl Marker {
|
||||
} else {
|
||||
let poly = Polygon::new(&pts);
|
||||
batch.push(Color::RED.alpha(0.8), poly.clone());
|
||||
if let Some(o) = poly.maybe_to_outline(Distance::meters(1.0)) {
|
||||
if let Ok(o) = poly.to_outline(Distance::meters(1.0)) {
|
||||
batch.push(Color::RED, o);
|
||||
}
|
||||
// TODO Refactor
|
||||
@ -591,9 +591,9 @@ fn simplify(mut raw: Vec<Pt2D>) -> Ring {
|
||||
downsampled.push(Pt2D::new(pt.x, pt.y));
|
||||
}
|
||||
downsampled.push(downsampled[0]);
|
||||
Ring::new(downsampled)
|
||||
Ring::must_new(downsampled)
|
||||
} else {
|
||||
raw.push(raw[0]);
|
||||
Ring::new(raw)
|
||||
Ring::must_new(raw)
|
||||
}
|
||||
}
|
||||
|
@ -498,13 +498,16 @@ impl TrafficJams {
|
||||
app.primary.sim.delayed_intersections(Duration::minutes(5)),
|
||||
) {
|
||||
cnt += 1;
|
||||
unzoomed.push(Color::RED, boundary.to_outline(Distance::meters(5.0)));
|
||||
unzoomed.push(
|
||||
Color::RED,
|
||||
boundary.to_outline(Distance::meters(5.0)).unwrap(),
|
||||
);
|
||||
unzoomed.push(Color::RED.alpha(0.5), boundary.clone());
|
||||
unzoomed.push(Color::WHITE, epicenter.clone());
|
||||
|
||||
zoomed.push(
|
||||
Color::RED.alpha(0.4),
|
||||
boundary.to_outline(Distance::meters(5.0)),
|
||||
boundary.to_outline(Distance::meters(5.0)).unwrap(),
|
||||
);
|
||||
zoomed.push(Color::RED.alpha(0.3), boundary);
|
||||
zoomed.push(Color::WHITE.alpha(0.4), epicenter);
|
||||
|
@ -40,7 +40,7 @@ impl DrawBuilding {
|
||||
cs.sidewalk,
|
||||
front_path_line.make_polygons(NORMAL_LANE_THICKNESS),
|
||||
);
|
||||
if let Some(p) = bldg.polygon.maybe_to_outline(Distance::meters(0.1)) {
|
||||
if let Ok(p) = bldg.polygon.to_outline(Distance::meters(0.1)) {
|
||||
outlines_batch.push(cs.building_outline, p);
|
||||
}
|
||||
|
||||
@ -102,7 +102,7 @@ impl Renderable for DrawBuilding {
|
||||
|
||||
fn get_outline(&self, map: &Map) -> Polygon {
|
||||
let b = map.get_b(self.id);
|
||||
if let Some(p) = b.polygon.maybe_to_outline(OUTLINE_THICKNESS) {
|
||||
if let Ok(p) = b.polygon.to_outline(OUTLINE_THICKNESS) {
|
||||
p
|
||||
} else {
|
||||
b.polygon.clone()
|
||||
|
@ -163,7 +163,9 @@ impl Renderable for DrawIntersection {
|
||||
}
|
||||
|
||||
fn get_outline(&self, map: &Map) -> Polygon {
|
||||
map.get_i(self.id).polygon.to_outline(OUTLINE_THICKNESS)
|
||||
let poly = &map.get_i(self.id).polygon;
|
||||
poly.to_outline(OUTLINE_THICKNESS)
|
||||
.unwrap_or_else(|_| poly.clone())
|
||||
}
|
||||
|
||||
fn contains_pt(&self, pt: Pt2D, map: &Map) -> bool {
|
||||
|
@ -100,7 +100,7 @@ impl Renderable for DrawParkingLot {
|
||||
|
||||
fn get_outline(&self, map: &Map) -> Polygon {
|
||||
let pl = map.get_pl(self.id);
|
||||
if let Some(p) = pl.polygon.maybe_to_outline(OUTLINE_THICKNESS) {
|
||||
if let Ok(p) = pl.polygon.to_outline(OUTLINE_THICKNESS) {
|
||||
p
|
||||
} else {
|
||||
pl.polygon.clone()
|
||||
|
@ -368,7 +368,7 @@ pub fn make_signal_diagram(
|
||||
|
||||
let mut hovered = GeomBatch::new();
|
||||
hovered.append(normal.clone());
|
||||
hovered.push(Color::RED, bbox.to_outline(Distance::meters(5.0)));
|
||||
hovered.push(Color::RED, bbox.to_outline(Distance::meters(5.0)).unwrap());
|
||||
|
||||
Btn::custom(normal, hovered, bbox.clone()).build(
|
||||
ctx,
|
||||
|
@ -266,7 +266,7 @@ fn contingency_table(ctx: &mut EventCtx, app: &App, filter: &Filter) -> Widget {
|
||||
if num_savings > 0 {
|
||||
let height = (total_savings / max_y) * max_bar_height;
|
||||
let rect = Polygon::rectangle(bar_width, height).translate(x1, max_bar_height - height);
|
||||
if let Some(o) = rect.maybe_to_outline(Distance::meters(1.5)) {
|
||||
if let Ok(o) = rect.to_outline(Distance::meters(1.5)) {
|
||||
outlines.push(o);
|
||||
}
|
||||
batch.push(Color::GREEN, rect.clone());
|
||||
@ -287,7 +287,7 @@ fn contingency_table(ctx: &mut EventCtx, app: &App, filter: &Filter) -> Widget {
|
||||
let height = (total_loss / max_y) * max_bar_height;
|
||||
let rect =
|
||||
Polygon::rectangle(bar_width, height).translate(x1, total_height - max_bar_height);
|
||||
if let Some(o) = rect.maybe_to_outline(Distance::meters(1.5)) {
|
||||
if let Ok(o) = rect.to_outline(Distance::meters(1.5)) {
|
||||
outlines.push(o);
|
||||
}
|
||||
batch.push(Color::RED, rect.clone());
|
||||
|
@ -74,7 +74,7 @@ impl Circle {
|
||||
if false {
|
||||
let mut pts = Circle::new(center, radius).to_polygon().points().clone();
|
||||
pts.push(pts[0]);
|
||||
return Ok(Ring::new(pts).make_polygons(thickness));
|
||||
return Ok(Ring::must_new(pts).make_polygons(thickness));
|
||||
}
|
||||
|
||||
// TODO Argh this one also leaves a little piece missing, but it looks less bad. Fine.
|
||||
|
@ -3,6 +3,7 @@ use geo::algorithm::area::Area;
|
||||
use geo::algorithm::convexhull::ConvexHull;
|
||||
use geo_booleanop::boolean::BooleanOp;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::error::Error;
|
||||
use std::fmt;
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
@ -286,12 +287,8 @@ impl Polygon {
|
||||
|
||||
// Only works for polygons that're formed from rings. Those made from PolyLines won't work, for
|
||||
// example.
|
||||
pub fn to_outline(&self, thickness: Distance) -> Polygon {
|
||||
Ring::new(self.points.clone()).make_polygons(thickness)
|
||||
}
|
||||
|
||||
pub fn maybe_to_outline(&self, thickness: Distance) -> Option<Polygon> {
|
||||
Ring::maybe_new(self.points.clone()).map(|r| r.make_polygons(thickness))
|
||||
pub fn to_outline(&self, thickness: Distance) -> Result<Polygon, Box<dyn Error>> {
|
||||
Ring::new(self.points.clone()).map(|r| r.make_polygons(thickness))
|
||||
}
|
||||
|
||||
// Usually m^2, unless the polygon is in screen-space
|
||||
@ -301,7 +298,7 @@ impl Polygon {
|
||||
|
||||
// Doesn't handle multiple crossings in and out.
|
||||
pub fn clip_polyline(&self, input: &PolyLine) -> Option<Vec<Pt2D>> {
|
||||
let ring = Ring::new(self.points.clone());
|
||||
let ring = Ring::must_new(self.points.clone());
|
||||
let hits = ring.all_intersections(input);
|
||||
|
||||
if hits.len() == 0 {
|
||||
|
@ -93,7 +93,7 @@ impl PolyLine {
|
||||
side1.extend(side2);
|
||||
side1.push(side1[0]);
|
||||
side1.dedup();
|
||||
Some(Ring::new(side1).make_polygons(boundary_width))
|
||||
Some(Ring::must_new(side1).make_polygons(boundary_width))
|
||||
}
|
||||
|
||||
pub fn reversed(&self) -> PolyLine {
|
||||
@ -556,7 +556,7 @@ impl PolyLine {
|
||||
let angle = slice.last_pt().angle_to(self.last_pt());
|
||||
vec![
|
||||
p,
|
||||
Ring::new(vec![
|
||||
Ring::must_new(vec![
|
||||
self.last_pt(),
|
||||
self.last_pt()
|
||||
.project_away(head_size, angle.rotate_degs(-135.0)),
|
||||
|
@ -12,39 +12,16 @@ pub struct Ring {
|
||||
}
|
||||
|
||||
impl Ring {
|
||||
pub fn new(pts: Vec<Pt2D>) -> Ring {
|
||||
assert!(pts.len() >= 3);
|
||||
assert_eq!(pts[0], *pts.last().unwrap());
|
||||
|
||||
// This checks no lines are too small. Could take the other approach and automatically
|
||||
// squish down points here and make sure the final result is at least EPSILON_DIST.
|
||||
// But probably better for the callers to do this -- they have better understanding of what
|
||||
// needs to be squished down, why, and how.
|
||||
if pts.windows(2).any(|pair| pair[0] == pair[1]) {
|
||||
panic!("Ring has ~dupe adjacent pts: {:?}", pts);
|
||||
pub fn new(pts: Vec<Pt2D>) -> Result<Ring, Box<dyn Error>> {
|
||||
if pts.len() < 3 {
|
||||
return Err(format!("Can't make a ring with < 3 points").into());
|
||||
}
|
||||
|
||||
let result = Ring { pts };
|
||||
|
||||
let mut seen_pts = HashSet::new();
|
||||
for pt in result.pts.iter().skip(1) {
|
||||
seen_pts.insert(pt.to_hashable());
|
||||
}
|
||||
if seen_pts.len() != result.pts.len() - 1 {
|
||||
panic!("Ring has repeat points: {}", result);
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
pub fn maybe_new(pts: Vec<Pt2D>) -> Option<Ring> {
|
||||
assert!(pts.len() >= 3);
|
||||
if pts[0] != *pts.last().unwrap() {
|
||||
return None;
|
||||
return Err(format!("Can't make a ring with mismatching first/last points").into());
|
||||
}
|
||||
|
||||
if pts.windows(2).any(|pair| pair[0] == pair[1]) {
|
||||
return None;
|
||||
return Err(format!("Ring has ~dupe adjacent pts").into());
|
||||
}
|
||||
|
||||
let result = Ring { pts };
|
||||
@ -54,10 +31,13 @@ impl Ring {
|
||||
seen_pts.insert(pt.to_hashable());
|
||||
}
|
||||
if seen_pts.len() != result.pts.len() - 1 {
|
||||
return None;
|
||||
return Err(format!("Ring has repeat non-adjacent points").into());
|
||||
}
|
||||
|
||||
Some(result)
|
||||
Ok(result)
|
||||
}
|
||||
pub fn must_new(pts: Vec<Pt2D>) -> Ring {
|
||||
Ring::new(pts).unwrap()
|
||||
}
|
||||
|
||||
pub fn make_polygons(&self, thickness: Distance) -> Polygon {
|
||||
@ -137,7 +117,7 @@ impl Ring {
|
||||
current.push(pt);
|
||||
if intersections.contains(&pt.to_hashable()) && current.len() > 1 {
|
||||
if current[0] == pt {
|
||||
rings.push(Ring::new(current.drain(..).collect()));
|
||||
rings.push(Ring::must_new(current.drain(..).collect()));
|
||||
} else {
|
||||
polylines.push(PolyLine::new(current.drain(..).collect())?);
|
||||
}
|
||||
|
@ -549,7 +549,7 @@ fn make_shared_sidewalk_corner(
|
||||
|
||||
// TODO Something like this will be MUCH simpler and avoid going around the long way sometimes.
|
||||
if false {
|
||||
return Ring::new(i.polygon.points().clone()).get_shorter_slice_btwn(corner1, corner2);
|
||||
return Ring::must_new(i.polygon.points().clone()).get_shorter_slice_btwn(corner1, corner2);
|
||||
}
|
||||
|
||||
// The order of the points here seems backwards, but it's because we scan from corner2
|
||||
|
Loading…
Reference in New Issue
Block a user