a-b-street / osm2lanes

A common library and set of test cases for transforming OSM tags to lane specifications
https://a-b-street.github.io/osm2lanes/
Apache License 2.0
33 stars 2 forks source link

Web app to edit lanes and upstream changes in OSM #240

Open dabreegster opened 1 year ago

dabreegster commented 1 year ago

I have now started a very minimal prototype in https://github.com/a-b-street/osm2lanes/tree/web_editor to make a new web app that lets people select an OSM way, see the rendered lanes in a cross-section view, edit those lanes (adding, deleting, reordering, modifying width, etc), generate the OSM tags for the changes, and upload to OSM. This is a step towards making it easier to edit lane data in OSM.

@BudgieInWA and I discussed some of the complications that'll come up. Two of the big ones:

1) When a road is split into multiple parallel ways, what do we do? The lane editor as I'm building it operates on a single way. We could maybe ask the user to draw a line and select all of the ways they want to edit, then present a unified cross section across all of them, and make it very clear which way is getting edited. Of course it won't be that simple, so to start, my goal is just to handle simple cases where one way corresponds to the "entire" road.

2) The left-to-right order of the draggable lane cards of course depends how the way in OSM is oriented. We need to display the way on the map and make it clear what's happening. Even better, leverage osm2streets + some rendering to draw the lanes on the 2D map at the same time.

I'm building using vanilla JS, which is new to me (this is a learning project!).

When I get something minimally decent open, I'll open a PR -- hopefully a few days if I can keep dodging other responsibilities. :)

dabreegster commented 1 year ago

@BudgieInWA had asked by email:

In the course of implementing the editing capabilities, it seems like you will be writing reorder_lanes(...), but also add_lane_at_position and remove_lane_at_position etc., even add_sidewalk, add_bus_lanes, etc. It occurs to me that those logical modifications to an existing road are the same sorts of modifications that osm2lanes wants to make during the "building" stage of the process. I wonder if one of the goals of osm2lanes should be a mutable Road type with an API designed for editor applications s to use interactively. That way, the current state (list of lanes) can be returned from wasm to JS, the current state can be rendered based on it, then the editor can capture the intent to make some change that is supported -- such as reorder, remove_lane, add_sidewalk -- which can be sent back to wasm, to let osm2lanes figure out the nuances of that change, before returning the new state to update the UI accordingly.

100% agree. I've already hit this problem with the prototype -- if you drag a "new driving lane" card somewhere, we need to auto-set the direction based on its position, and preferably use the locale's default width. Some of this code already exists actually, but in perhaps the "wrong" layer: https://github.com/a-b-street/osm2streets/tree/main/street_network/src/edit.

I'm thinking through some options for moving it. The main friction is that A/B Street and osm2streets use a LaneSpec definition unrelated to osm2lanes. I've had trouble pushing through #71. One possible smaller step is to make the osm2streets StreetNetwork layer directly use osm2lanes definitions of lanes, and then transform to A/B Street's LaneSpec later on in that codebase. This would be a slightly easier migration maybe.

dabreegster commented 1 year ago

@BudgieInWA and in response to your other question about using trunk, currently I'm just leveraging it to trigger the osm2lanes wasm build. But even that is pretty broken with trunk -- https://github.com/a-b-street/osm2lanes/blob/b6f8c0f4792225e267f3a631fa669d1e469a3a57/web_editor/index.html#L44. Trunk is meant for full web apps, not to just bring in a few Rust functions to JS. So that's an argument for finishing the work to publish osm2lanes to NPM and pull it in from a CDN.

BudgieInWA commented 1 year ago

The main friction is that A/B Street and osm2streets use a LaneSpec definition unrelated to osm2lanes. I've had trouble pushing through https://github.com/a-b-street/osm2lanes/issues/71. One possible smaller step is to make the osm2streets StreetNetwork layer directly use osm2lanes definitions of lanes, and then transform to A/B Street's LaneSpec later on in that codebase.

Cutting osm2streets StreetNetwork over to osm2lanes lanes would be a valuable step to achieve, I think.

...your other question about using trunk, currently I'm just leveraging it to trigger the osm2lanes wasm build. ... So that's an argument for finishing the work to publish osm2lanes to NPM and pull it in from a CDN.

Setting up NPM builds of the rust libs (osm2lanes and osm2streets) that get used (from a CDN or bundled directly) is desired I think, but for this goal, I think it should be considered an "internal impl detail" and not be prioritised. If the trunk commands manage to build the app, then there is no immediate need to change anything :)

dabreegster commented 1 year ago

Just a stray thought: the drag-and-drop UI isn't the only choice here, or even the easiest. Most streets follow a template. An example user flow that could make more sense:

1) Specify there are 4 main travel lanes 2) Click a bus tab, pick left/right/both 3) Click a cycle tab, pick the side, specify the type of separation

Drag and drop could be good for fine-tuning

BudgieInWA commented 1 year ago

I think "click a lane, then pick type (and other properties)" is the most important paradigm for generic editing, such as authoring and correcting OSM data. Treating each lane as an independent entity is a natural and powerful mental model that is not well supported by the raw tags.

Shortcuts like "move lane left/right" (aka drag-n-drop) or "add bike lanes left/right/both" seem like awesome conveniences on top, to me.

dabreegster commented 1 year ago

Shortcuts like "move lane left/right" (aka drag-n-drop) or "add bike lanes left/right/both" seem like awesome conveniences on top, to me.

What if the lanes you start editing don't even have the right number of lanes? If there's just a button to add a new lane at the end, then you need to be able to drag it to the right position. Or maybe we start simpler and just have a (+add) button in between every existing pair of lanes, to avoid needing drag-and-drop entirely.

dabreegster commented 1 year ago

https://www.dflex.dev/ as another possible drag-n-drop JS library

BudgieInWA commented 1 year ago

What if the lanes you start editing don't even have the right number of lanes? If there's just a button to add a new lane at the end, then you need to be able to drag it to the right position. Or maybe we start simpler and just have a (+add) button in between every existing pair of lanes, to avoid needing drag-and-drop entirely.

Adjusting the number of lanes in essential, yes.

My instinct would be to first implement