mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-12-25 23:43:25 +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
|
// So we can use retain_btreemap without borrowing issues
|
||||||
let boundary_polygon = map.boundary_polygon.clone();
|
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
|
// This is kind of indirect and slow, but first pass -- just remove roads that start or end
|
||||||
// outside the boundary polygon.
|
// 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 simple_turn_restrictions = Vec::new();
|
||||||
let mut complicated_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/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/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/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/ballard.bin,4d72687ab860144d19ae3f1328f2b61d,https://www.dropbox.com/s/dkxhkir85rtm906/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/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/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_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_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/huge_seattle.bin,95798750903b3a7c35f165aaf3e39c91,https://www.dropbox.com/s/5pumdup46zmhb34/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/lakeslice.bin,28ede305a1e45a4298b8d10503324905,https://www.dropbox.com/s/j707o0ka1k4ixgk/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/montlake.bin,712532a30baa5225aca621fd1f1f7f0a,https://www.dropbox.com/s/evwmldb5872nf0u/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/south_seattle.bin,5eb52175e7fd06da3fc3e93fc2ca88fc,https://www.dropbox.com/s/jfc4ht5ydm05j8y/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/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/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/downtown.zip,bdad536ddb7f0e5aab912433b3c28e69,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/huge_krakow.zip,8edcb39fedadb7991ab2959064c98629,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/lakeslice.zip,73c0ed5add17f8c49218b1c22ee464cc,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/montlake.zip,fbc945c0869c2b85ccfb1fef4340ba2e,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/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/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.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
|
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/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/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/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/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/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/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/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/ballard.bin,d4ab6ceb6905dfa14b2aaac99c495eff,https://www.dropbox.com/s/too29h0nr6s64wm/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/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/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_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_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/huge_seattle.bin,05214611240c878306f351b76d07db3b,https://www.dropbox.com/s/xakfwfqbcyeznuy/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/lakeslice.bin,ecd6b3b127982eb9b42530da2bb0887b,https://www.dropbox.com/s/dkmf2qaa991uxym/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/montlake.bin,cb2246cb15edc0553f5b03af4886471c,https://www.dropbox.com/s/0dnysbp2h7wdaf4/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/south_seattle.bin,174a44c25848f36d82a59644ef56582e,https://www.dropbox.com/s/cu8exdobcdaj6sm/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/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/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/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,d3e42a758ba4e10e6143c8f8370a638f,https://www.dropbox.com/s/jefg0ikjy9dsrdd/car%20vs%20bike%20contention.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,979af6c1db9f5bf31a3cf12301c4c6f9,https://www.dropbox.com/s/0duohjtnbj5y7gc/weekday.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,f6d7dac5af0f35a6ae5589d3943be789,https://www.dropbox.com/s/klvs4wkauh00xud/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,2b4506c9aab41a0a12f8d0ef769db492,https://www.dropbox.com/s/swmss3vyrrjnv6n/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,30cf8491099a33c758aa76c31267bd13,https://www.dropbox.com/s/a20dujaxnwhe2aj/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,19812c16dc90945f5c3659b47c1c55e8,https://www.dropbox.com/s/00cjax1g3bcmwvf/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,ee5359d37d1d9446578d34c3b97b9266,https://www.dropbox.com/s/bx6sv6rogt2alyq/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,9b84537fb47831d6b65f81dcb947600d,https://www.dropbox.com/s/i36o01uv6ud8rj3/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,6c08853e72f8fc65b25b69639cb59464,https://www.dropbox.com/s/3c0tlq9k8niz0pr/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,48a9b04d69948436c8eb89f943e36b5d,https://www.dropbox.com/s/8jq9rs6dom8t0y9/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.
|
experience, so they're hidden for now.
|
||||||
- `cargo run --bin game -- --tutorial=12` starts somewhere in the tutorial
|
- `cargo run --bin game -- --tutorial=12` starts somewhere in the tutorial
|
||||||
- Adding `--edits='name of edits'` starts with edits applied to the map.
|
- 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)
|
- More random notes [here](/docs/misc_dev_tricks.md)
|
||||||
|
|
||||||
## Downloading more cities
|
## Downloading more cities
|
||||||
@ -139,3 +136,24 @@ Common utilities:
|
|||||||
- `abstutil`: a grab-bag of IO helpers, timing and logging utilities, etc
|
- `abstutil`: a grab-bag of IO helpers, timing and logging utilities, etc
|
||||||
- `geom`: types for GPS and map-space points, lines, angles, polylines,
|
- `geom`: types for GPS and map-space points, lines, angles, polylines,
|
||||||
polygons, circles, durations, speeds
|
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(
|
batch.push(
|
||||||
color,
|
color,
|
||||||
Polygon::rounded_rectangle(width, height, self.layout.rounded_radius)
|
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));
|
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 rect = Polygon::rounded_rectangle(width, height, Some(5.0));
|
||||||
let draw_bg = g.upload(GeomBatch::from(vec![
|
let draw_bg = g.upload(GeomBatch::from(vec![
|
||||||
(Color::grey(0.3), rect.clone()),
|
(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(
|
g.fork(
|
||||||
Pt2D::new(0.0, 0.0),
|
Pt2D::new(0.0, 0.0),
|
||||||
|
@ -54,7 +54,7 @@ impl CityPicker {
|
|||||||
if &name == app.primary.map.get_name() {
|
if &name == app.primary.map.get_name() {
|
||||||
batch.push(color.alpha(0.5), polygon.clone());
|
batch.push(color.alpha(0.5), polygon.clone());
|
||||||
} else {
|
} 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)));
|
regions.push((name, color, polygon.scale(zoom_no_scale_factor)));
|
||||||
}
|
}
|
||||||
|
@ -300,7 +300,7 @@ impl Minimap {
|
|||||||
};
|
};
|
||||||
g.draw_polygon(
|
g.draw_polygon(
|
||||||
Color::BLACK,
|
Color::BLACK,
|
||||||
&Ring::new(vec![
|
&Ring::must_new(vec![
|
||||||
Pt2D::new(x1, y1),
|
Pt2D::new(x1, y1),
|
||||||
Pt2D::new(x2, y1),
|
Pt2D::new(x2, y1),
|
||||||
Pt2D::new(x2, y2),
|
Pt2D::new(x2, y2),
|
||||||
|
@ -204,7 +204,7 @@ fn make_object(
|
|||||||
} else if pts[0] == *pts.last().unwrap() {
|
} else if pts[0] == *pts.last().unwrap() {
|
||||||
// TODO Toggle between these better
|
// TODO Toggle between these better
|
||||||
//Polygon::new(&pts)
|
//Polygon::new(&pts)
|
||||||
Ring::new(pts).make_polygons(THICKNESS)
|
Ring::must_new(pts).make_polygons(THICKNESS)
|
||||||
} else {
|
} else {
|
||||||
let backup = pts[0];
|
let backup = pts[0];
|
||||||
match PolyLine::new(pts) {
|
match PolyLine::new(pts) {
|
||||||
|
@ -464,7 +464,7 @@ impl Marker {
|
|||||||
} else {
|
} else {
|
||||||
let poly = Polygon::new(&pts);
|
let poly = Polygon::new(&pts);
|
||||||
batch.push(Color::RED.alpha(0.8), poly.clone());
|
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);
|
batch.push(Color::RED, o);
|
||||||
}
|
}
|
||||||
// TODO Refactor
|
// TODO Refactor
|
||||||
@ -591,9 +591,9 @@ fn simplify(mut raw: Vec<Pt2D>) -> Ring {
|
|||||||
downsampled.push(Pt2D::new(pt.x, pt.y));
|
downsampled.push(Pt2D::new(pt.x, pt.y));
|
||||||
}
|
}
|
||||||
downsampled.push(downsampled[0]);
|
downsampled.push(downsampled[0]);
|
||||||
Ring::new(downsampled)
|
Ring::must_new(downsampled)
|
||||||
} else {
|
} else {
|
||||||
raw.push(raw[0]);
|
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)),
|
app.primary.sim.delayed_intersections(Duration::minutes(5)),
|
||||||
) {
|
) {
|
||||||
cnt += 1;
|
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::RED.alpha(0.5), boundary.clone());
|
||||||
unzoomed.push(Color::WHITE, epicenter.clone());
|
unzoomed.push(Color::WHITE, epicenter.clone());
|
||||||
|
|
||||||
zoomed.push(
|
zoomed.push(
|
||||||
Color::RED.alpha(0.4),
|
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::RED.alpha(0.3), boundary);
|
||||||
zoomed.push(Color::WHITE.alpha(0.4), epicenter);
|
zoomed.push(Color::WHITE.alpha(0.4), epicenter);
|
||||||
|
@ -40,7 +40,7 @@ impl DrawBuilding {
|
|||||||
cs.sidewalk,
|
cs.sidewalk,
|
||||||
front_path_line.make_polygons(NORMAL_LANE_THICKNESS),
|
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);
|
outlines_batch.push(cs.building_outline, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -102,7 +102,7 @@ impl Renderable for DrawBuilding {
|
|||||||
|
|
||||||
fn get_outline(&self, map: &Map) -> Polygon {
|
fn get_outline(&self, map: &Map) -> Polygon {
|
||||||
let b = map.get_b(self.id);
|
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
|
p
|
||||||
} else {
|
} else {
|
||||||
b.polygon.clone()
|
b.polygon.clone()
|
||||||
|
@ -163,7 +163,9 @@ impl Renderable for DrawIntersection {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn get_outline(&self, map: &Map) -> Polygon {
|
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 {
|
fn contains_pt(&self, pt: Pt2D, map: &Map) -> bool {
|
||||||
|
@ -100,7 +100,7 @@ impl Renderable for DrawParkingLot {
|
|||||||
|
|
||||||
fn get_outline(&self, map: &Map) -> Polygon {
|
fn get_outline(&self, map: &Map) -> Polygon {
|
||||||
let pl = map.get_pl(self.id);
|
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
|
p
|
||||||
} else {
|
} else {
|
||||||
pl.polygon.clone()
|
pl.polygon.clone()
|
||||||
|
@ -368,7 +368,7 @@ pub fn make_signal_diagram(
|
|||||||
|
|
||||||
let mut hovered = GeomBatch::new();
|
let mut hovered = GeomBatch::new();
|
||||||
hovered.append(normal.clone());
|
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(
|
Btn::custom(normal, hovered, bbox.clone()).build(
|
||||||
ctx,
|
ctx,
|
||||||
|
@ -266,7 +266,7 @@ fn contingency_table(ctx: &mut EventCtx, app: &App, filter: &Filter) -> Widget {
|
|||||||
if num_savings > 0 {
|
if num_savings > 0 {
|
||||||
let height = (total_savings / max_y) * max_bar_height;
|
let height = (total_savings / max_y) * max_bar_height;
|
||||||
let rect = Polygon::rectangle(bar_width, height).translate(x1, max_bar_height - 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);
|
outlines.push(o);
|
||||||
}
|
}
|
||||||
batch.push(Color::GREEN, rect.clone());
|
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 height = (total_loss / max_y) * max_bar_height;
|
||||||
let rect =
|
let rect =
|
||||||
Polygon::rectangle(bar_width, height).translate(x1, total_height - max_bar_height);
|
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);
|
outlines.push(o);
|
||||||
}
|
}
|
||||||
batch.push(Color::RED, rect.clone());
|
batch.push(Color::RED, rect.clone());
|
||||||
|
@ -74,7 +74,7 @@ impl Circle {
|
|||||||
if false {
|
if false {
|
||||||
let mut pts = Circle::new(center, radius).to_polygon().points().clone();
|
let mut pts = Circle::new(center, radius).to_polygon().points().clone();
|
||||||
pts.push(pts[0]);
|
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.
|
// 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::algorithm::convexhull::ConvexHull;
|
||||||
use geo_booleanop::boolean::BooleanOp;
|
use geo_booleanop::boolean::BooleanOp;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
use std::error::Error;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
#[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
|
// Only works for polygons that're formed from rings. Those made from PolyLines won't work, for
|
||||||
// example.
|
// example.
|
||||||
pub fn to_outline(&self, thickness: Distance) -> Polygon {
|
pub fn to_outline(&self, thickness: Distance) -> Result<Polygon, Box<dyn Error>> {
|
||||||
Ring::new(self.points.clone()).make_polygons(thickness)
|
Ring::new(self.points.clone()).map(|r| r.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))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Usually m^2, unless the polygon is in screen-space
|
// Usually m^2, unless the polygon is in screen-space
|
||||||
@ -301,7 +298,7 @@ impl Polygon {
|
|||||||
|
|
||||||
// Doesn't handle multiple crossings in and out.
|
// Doesn't handle multiple crossings in and out.
|
||||||
pub fn clip_polyline(&self, input: &PolyLine) -> Option<Vec<Pt2D>> {
|
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);
|
let hits = ring.all_intersections(input);
|
||||||
|
|
||||||
if hits.len() == 0 {
|
if hits.len() == 0 {
|
||||||
|
@ -93,7 +93,7 @@ impl PolyLine {
|
|||||||
side1.extend(side2);
|
side1.extend(side2);
|
||||||
side1.push(side1[0]);
|
side1.push(side1[0]);
|
||||||
side1.dedup();
|
side1.dedup();
|
||||||
Some(Ring::new(side1).make_polygons(boundary_width))
|
Some(Ring::must_new(side1).make_polygons(boundary_width))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn reversed(&self) -> PolyLine {
|
pub fn reversed(&self) -> PolyLine {
|
||||||
@ -556,7 +556,7 @@ impl PolyLine {
|
|||||||
let angle = slice.last_pt().angle_to(self.last_pt());
|
let angle = slice.last_pt().angle_to(self.last_pt());
|
||||||
vec![
|
vec![
|
||||||
p,
|
p,
|
||||||
Ring::new(vec![
|
Ring::must_new(vec![
|
||||||
self.last_pt(),
|
self.last_pt(),
|
||||||
self.last_pt()
|
self.last_pt()
|
||||||
.project_away(head_size, angle.rotate_degs(-135.0)),
|
.project_away(head_size, angle.rotate_degs(-135.0)),
|
||||||
|
@ -12,39 +12,16 @@ pub struct Ring {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Ring {
|
impl Ring {
|
||||||
pub fn new(pts: Vec<Pt2D>) -> Ring {
|
pub fn new(pts: Vec<Pt2D>) -> Result<Ring, Box<dyn Error>> {
|
||||||
assert!(pts.len() >= 3);
|
if pts.len() < 3 {
|
||||||
assert_eq!(pts[0], *pts.last().unwrap());
|
return Err(format!("Can't make a ring with < 3 points").into());
|
||||||
|
|
||||||
// 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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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() {
|
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]) {
|
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 };
|
let result = Ring { pts };
|
||||||
@ -54,10 +31,13 @@ impl Ring {
|
|||||||
seen_pts.insert(pt.to_hashable());
|
seen_pts.insert(pt.to_hashable());
|
||||||
}
|
}
|
||||||
if seen_pts.len() != result.pts.len() - 1 {
|
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 {
|
pub fn make_polygons(&self, thickness: Distance) -> Polygon {
|
||||||
@ -137,7 +117,7 @@ impl Ring {
|
|||||||
current.push(pt);
|
current.push(pt);
|
||||||
if intersections.contains(&pt.to_hashable()) && current.len() > 1 {
|
if intersections.contains(&pt.to_hashable()) && current.len() > 1 {
|
||||||
if current[0] == pt {
|
if current[0] == pt {
|
||||||
rings.push(Ring::new(current.drain(..).collect()));
|
rings.push(Ring::must_new(current.drain(..).collect()));
|
||||||
} else {
|
} else {
|
||||||
polylines.push(PolyLine::new(current.drain(..).collect())?);
|
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.
|
// TODO Something like this will be MUCH simpler and avoid going around the long way sometimes.
|
||||||
if false {
|
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
|
// The order of the points here seems backwards, but it's because we scan from corner2
|
||||||
|
Loading…
Reference in New Issue
Block a user