Open dabreegster opened 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 alsoadd_lane_at_position
andremove_lane_at_position
etc., evenadd_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 mutableRoad
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 asreorder
,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.
@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.
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 :)
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
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.
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.
https://www.dflex.dev/ as another possible drag-n-drop JS library
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
then drag-n-drop can be implemented as an alternative way to trigger the "move left/right" functionality. (It's good to have the buttons for accessibility too)
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. :)