a-b-street/abstreet

Hardcoded IDs in tutorial can get out-of-sync

Antel0pe opened this issue · 5 comments

Hey @dabreegster! Can we discuss the issue you mentioned in #1084 here?

My first instinct is to create a simple config file with all the hardcoded IDs. This would ensure that a particular object's ID is never out of sync, however this wouldn't 100% prevent IDs from being out of sync with each other. In other words it's possible to update one ID but forget to update another related ID. That being said, I'm not sure how we update the OSM data and whether IDs being out of sync with each other is even an issue.

You definitely have more insight into how we update our data and maybe there's a way we don't have to rely on IDs at all perhaps? You also mentioned you had some ideas of your own?

One question that I did have is why exactly we are updating the data for the tutorial. Does it matter if the tutorial references a real place with 100% up to date data vs a made up city that might allow us to explain the features better?

Thank you as always!!

Reiterating the problem: at

map.find_r_by_osm_id(OriginalRoad::new(36952952, (53128049, 53101726)))
we grab a specific road segment between two intersections. This hardcodes OSM node and way IDs. If someone edits that OSM way one day and splits it (maybe because lane attributes change somewhere along it) and we grab the new OSM data, the ID could change. Or in the osm2streets layer that handles complex intersections and short roads, we make an improvement that merges short roads together, IDs could again change.

That being said, I'm not sure how we update the OSM data and whether IDs being out of sync with each other is even an issue.

The problem isn't really consistency within tutorial.rs. It's that the map data gets out of sync with this file for the reasons above.

You definitely have more insight into how we update our data and maybe there's a way we don't have to rely on IDs at all perhaps?

We need some "stable" way to refer to 22nd Ave E between Calhoun and Miller (https://www.openstreetmap.org/#map=18/47.64126/-122.30355). A very simple idea is to make a new method map.find_road_by_name("22nd Ave E", ("E Calhoun St", "Miller")) -> Option<RoadID> that matches based on the main road name, and looks for the cross streets. (There are some things to be slightly careful about the implementation of this; the cross-street might change names at the intersection we're trying to look for.)

A more complicated method would be to write down the GPS coordinates of the linestring representing that road, at some level of detail. And later do map matching to find the road segment. That matching process might not return a single RoadID -- if OSM or osm2streets changes mean it's now split into multiple pieces, maybe we return all the matching pieces. For tutorial mode this is overkill, but for #995 it's necessary.

Does it matter if the tutorial references a real place with 100% up to date data vs a made up city that might allow us to explain the features better?

There's no good reason other than laziness on my part! We can absolutely create our own "synthetic" city, never change it, and have confidence the hardcoded IDs in a tutorial are stable. There's actually an example of doing that right now for tests:

we make an improvement that merges short roads together, IDs could again change.

Another real example of this problem in the past. Service roads and driveways used to be skipped by the importer. When I added them in, all of the saved MapEdits files referred to roads using a pair of intersection IDs. Suddenly some roads got split into more pieces because of the service roads, so all of those saved files broke.

Road name for roads OR GPS coords for intersections seems the way to go to prevent hardcoding ids

Thank you very much for the breakdown! I've looked at the lines you've linked and crawled through #995 with a few of the related issues and commits. I think I'm slowly starting to get the picture.

I'm happy to rely on your guys judgement of which method between road names or gps coords we use.

Whichever method we do end up using, it'd be immensely helpful if we could break the task down into a few high level goals so I have some direction about how to approach this issue.

Thank you as always!

For the tutorial, I'd say start simple and try by road name. The goal is to replace the one use of map.find_r_by_osm_id in the tutorial with map.find_road_by_name.

  1. Create the new method and use it in the tutorial
  2. Consider doing the same for the few uses of map.find_i_by_osm_id in the tutorial -- we could have a Vec<&str> for all the cross streets of an intersection. But I think those IDs don't change as frequently, so it's less urgent.
  3. More broadly, reconsider the tutorial mode. It was written long ago when the traffic simulation was the focus, with the goal of introducing controls. And it was never finished -- we wanted to have something more gradually introducing the lane editor, traffic signal editor, etc. It hasn't been a high-priority for a long time, but if you're particularly interested and have ideas about a synthetic map to introduce things, we could try using map_editor or any OSM editor to create a fake area. And then replace the current tasks in the tutorial with it, never having to worry about OSM IDs changing again, or adjust/rewrite/add parts of the tutorial.