Giter Site home page Giter Site logo

a-b-street / osm2lanes Goto Github PK

View Code? Open in Web Editor NEW
33.0 33.0 2.0 37.35 MB

A common library and set of test cases for transforming OSM tags to lane specifications

Home Page: https://a-b-street.github.io/osm2lanes/

License: Apache License 2.0

Python 0.46% Rust 89.19% Shell 0.23% CSS 5.19% HTML 1.77% JavaScript 3.17%

osm2lanes's People

Contributors

dabreegster avatar droogmic avatar enzet avatar michaelkirk avatar tordans avatar wxinix avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

osm2lanes's Issues

Support Way 246047719

An interesting road with bus lanes, cycle lanes, and electric vehicle lanes.

It breaks today without warning: the bus lane is sandwiched between 2 car lanes, and the roundtrip has bus:lanes=|||designated||||

As of writing, the input is:

bicycle:lanes=||designated
bus:lanes=|designated|
cycleway:right=lane
cycleway:right:width=2
electric_vehicle:lanes=|no|
highway=trunk
lanes=3
maxspeed=40
motor_vehicle:lanes=|no|no
name=Dronning Eufemias gate
oneway=yes
placement=right_of:1
ref=E 18
surface=asphalt
surface:colour:lanes=||red
width:lanes=3|3|2
wikidata=Q11966089

The roundtrip is:

bus:lanes=|||designated||||
cycleway:right=lane
cycleway:right:oneway=yes
highway=trunk
lanes=3
maxspeed=40
oneway=yes
shoulder=no
sidewalk=no

`busway=opposite_lane` not interpreted correctly

It looks like some busway=opposite_lane tagging is not interpreted correctly.

The table below assumes a country with right-hand traffic. Note that the sides flip if oneway=-1 and if it is in a country with left-hand traffic.

inputcurrent outputexpected output
oneway=yes
busway=opposite_lane
oneway=yes
lanes=1
busway:both=lane
oneway=yes
- lanes=1
- busway:both=lane
+ busway:left=lane
oneway=-1
busway=opposite_lane
lanes=2
- lanes=2
+ oneway=-1
+ busway:right=lane

Way fetch loading animation

When fetching ways by way ID in the website, there is a small delay waiting on overpass. It would be a better interface if this active wait was communicated to the user.

A loading animation would be nice, but the simple solution would be to change the button text to "Loading...".

Website cannot differentiate nearby ways

If ways are close together, e.g. a road and an adjacent cyclepath, one may not be selectable.

This is because overpass returns the ways within 10m in no particular order:
https://github.com/a-b-street/osm2lanes/blob/main/osm2lanes/src/overpass.rs#L146

As far as I know, there is no overpass API to do what we want (find the nearest), so we may need to do a linear search of all line segments in the geometries of all returned ways to find which one is the closest to the queried point.

Tags Data Structure

https://wiki.openstreetmap.org/wiki/Tags

Requirements

Key

A key type, at its simplest it could be a &'static str or String. See also: https://lib.rs/crates/kstring.

  • No heap usage when using &'static strs.
  • Add trait implemented to support : joined keys (i.e. A + B + C == "a:b:c")

Value

A value type, at its simplest it could be a &'static str or String.
Trait implemented to support ; joined keys.
The result should also resemble an iterable.
Example: [A, B, C].into() == "a;b;c".

Mapping

Support interaction mimicking a HashMap or BTreeMap <K, V>, for example:

  • fn get<Q>(&self, key: &Q) -> Option<V>
  • fn is<Q, U>(&self, key: &Q, value: &U) -> bool
  • fn is_any<Q, W>(&self, key: &Q, values: &W) -> bool

Arguments of type Q should be possible directly from a &'static str, .e.g. tags.get("highway").

Tree

Support access as a tree structure, for : separated keys.
Example:

// foo:bar:baz=toto
tags.tree().get("foo").unwrap().get("bar").unwrap().is("baz", "toto")

Performance Constraints

In addition to the constraints on the key (see kstring):

  • The data must be stored once (not both as a tree and as a map, as is currently done)
  • The data may not be stored as a naive map, as retrieving a key of foo:bar using foo will be O(N).
  • Retrieving a multi-part key must not incur a runtime : split cost when not needed, i.e. get("foo" + "bar") must not allocate a String("foo:bar") which is then .split_once(':').

Deployment

For now, this should replace https://github.com/a-b-street/osm2lanes/tree/main/rust/osm2lanes/src/tag.
Once proven, a separate crate should be made.

most `cycleway=opposite*` not understood

It looks like some cycleway=opposite* tagging is not understood. This is the "old" method how to tag cycleways that have cyclist contraflow in oneway streets, but it is (still) used a lot and will likely never completely go away.

The table below assumes a country with right-hand traffic. Note that the sides flip if oneway=-1 and if it is in a country with left-hand traffic.

inputcurrent outputexpected outputcomment
oneway=yes
cycleway=opposite_lane
oneway=yes
cycleway:left=lane
cycleway:left:oneway=-1
oneway=yes
cycleway:left=lane
cycleway:left:oneway=-1
+ oneway:bicycle=no

The tag can be inferred from cycleway=opposite*

oneway=yes
cycleway=opposite

Conversion Error: unsupported: 'cycleway=opposite without oneway=yes oneway:bicycle=no'

oneway=yes
+ cycleway:left=no
+ oneway:bicycle=no

It is not an error if they are not tagged explicitly as these can be unambiguously be inferred from cycleway=opposite*

oneway=yes
cycleway=opposite_track

(nothing?)

+ oneway=yes
+ cycleway:left=track
+ cycleway:left:oneway=-1
+ oneway:bicycle=no
oneway=yes
cycleway=opposite_share_busway

(nothing?)

+ oneway=yes
+ cycleway:left=share_busway
+ cycleway:left:oneway=-1
+ oneway:bicycle=no
That cycleway tagging refers to a busway that is itself not tagged can be considered incomplete / erronous tagging, however, that's not the point

Note: Follow-up of this ticket would be to consider it invalid/ambiguos tagging if the cycleway=opposite* tagging contradicts with other tagging, e.g. cycleway=opposite + oneway=no or cycleway=opposite + oneway=yes + oneway:bicycle=yes or cycleway=opposite_lane + oneway=yes + cycleway:left=track etc.

Mitigation for more than one bus lanes scheme used

By far the most common problem I'm seeing with real data is more than one bus lanes scheme used. One example is https://www.openstreetmap.org/way/679636490. Glancing at this, I can't help feeling like though it uses two schemes, they both agree -- there's exactly 1 backwards lane and it's bus-only.

For #71, I'll probably be tactical in the short-term, detect these cases, and just arbitrarilyish rip out keys for one of the schemes. But I had another idea -- if we could parse each bus scheme independently, clone the road builder, and "try out" both schemes, then we could check if the results match. If so, just a warning about redundant tags could suffice -- no need to totally give up?

README typo?

It says:

  • osm2lanes-cli - CLI tool

But the actual is named:
osm2lanes-bin

Generate more test cases to cover the current Rust implementation

The current test case suite lacks bus lanes, cycleway separators, and probably other cases. I can generate a JSON test case for every single OSM way in a region using the Rust implementation. Then run the Python/Kotlin implementation against them, look for discrepancies, and boil down to the simplest test cases.

Living streets

cargo run way 1005922755 yields "error": "unimplemented: highway=living_street" (https://www.openstreetmap.org/way/1005922755)

Few thoughts:

  1. With all the indirections around error transformations, it's not easy to spot the place in the source that's actually deciding this tag isn't implemented. I searched for unimplemented_tag, and the 3 places don't seem relevant. Should we consider one of the error handling crates that adds a bit of context of file + line number of the "thrown" error?

  2. I'd add a test case, except I don't know what we want to infer about highway=living_street (the access=destination doesn't seem relevant). Standard 1 travel lane and sidewalk each side?

unsupported: 'cycleway=* with any cycleway:* values

https://www.openstreetmap.org/way/485926026

{"cycleway": "track", "cycleway:left": "track", "cycleway:left:width": "1.25", "cycleway:right": "lane", "cycleway:right:width": "1.25", "highway": "trunk", "lcn": "yes", "maxspeed": "30 mph", "name": "Wilmslow Road", "parking:lane:both": "no_parking", "ref": "A6010", "surface": "asphalt"})

unsupported: 'cycleway=* with any cycleway:* values

Just noting an error I keep spotting. Will add a test and dig into the problem

Add Web Worker

See the discussion in #185.

Note: I don't actually notice this on my desktop, but I do on my laptop...

I would like the examples and particularly syntax highlighting to be loaded lazily.

Add Website to OSM Wiki

A large part of contributing to OSM goes through the wiki.
This tool should be mentioned there somehow.

Unexpected number of traffic lanes

The last test in A/B Street has the following specification:

            (
                "https://www.openstreetmap.org/way/335668924",
                vec!["lanes=1", "sidewalk=none"],
                DrivingSide::Right,
                "SddS",
                "vv^^",
            ),

Why do we assume two traffic lanes here?

unexpected speed 3025 mph

This one's interesting, because someone has fixed the upstream data since then. It causes a panic now, so I'll definitely add a test case.
https://www.openstreetmap.org/way/102917976 is now fixed, but in my old copy:

        <way id="102917976" version="15" timestamp="2021-07-08T22:56:38Z" changeset="0">
                <nd ref="1487927529"/>
                <nd ref="7085519171"/>
                <nd ref="8523528017"/>
                <nd ref="3629413438"/>
                <nd ref="4273741094"/>
                <tag k="bicycle" v="designated"/>
                <tag k="cycleway" v="lane"/>
                <tag k="highway" v="secondary"/>
                <tag k="lanes" v="5"/>
                <tag k="lanes:backward" v="1"/>
                <tag k="lanes:both_ways" v="1"/>
                <tag k="lanes:forward" v="3"/>
                <tag k="maxspeed" v="3025 mph"/>
                <tag k="name" v="South Royal Brougham Way"/>
                <tag k="name_1" v="State Route 519"/>
                <tag k="surface" v="asphalt"/>
                <tag k="tiger:cfcc" v="A31"/>
                <tag k="tiger:county" v="King, WA"/>
                <tag k="tiger:name_base" v="Royal Brougham"/>
                <tag k="tiger:name_base_1" v="State Route 519"/>
                <tag k="tiger:name_direction_prefix" v="S"/>
                <tag k="tiger:name_type" v="Way"/>
                <tag k="turn:lanes:backward" v="right"/>
                <tag k="turn:lanes:both_ways" v="left"/>
        </way>

/home/dabreegster/.cargo/git/checkouts/osm2lanes-0a9401f46878d04a/df0e7bb/osm2lanes/src/transform/tags_to_lanes/separator/semantic.rs:27:18

Cutover A/B Street to using osm2lanes

osm2lanes is nearly at a point where I'd like to make A/B Street take a dependency on it and remove the original copy of the osm2lanes logic. Just writing down some notes about how to transition, not sure when I'll have time to tackle this.

The steps are probably:

  1. Replace is_road, which initially decides which OSM ways to treat as roads in A/B Street
  2. Replace get_lane_specs_ltr
  3. Import a few maps and manually look for diffs -- I expect to find a few obvious ones, and iterate on osm2lanes or the way A/B Street calls it accordingly
  4. After most issues seem fixed, import all maps and do the usual screenshot diff-based validation procedure
  • Because the osm2lanes API is still in flux, I'm going to add the git dependency and explicitly pin to a version. It'll be moderate effort to keep A/B Street up-to-date with changes here, so I expect to upgrade osm2lanes in occasional batches
  • The biggest missing thing in osm2lanes is width per lane. In the short term, I'll probably just keep https://github.com/a-b-street/abstreet/blob/7fdfdd5e1042a55a7d788ff8470656be9580291b/map_model/src/objects/lane.rs#L495 and do the mapping on the A/B Street side. We'll eventually move this into osm2lanes and handle it properly (reading width tagging from OSM when it's present, using region-specific config)
  • A/B Street currently doesn't import footways, or it mangles them into weird cycleways with walkable shoulders: a-b-street/osm2streets#81. Unless I fix that first (unlikely), I'll probably keep transforming things on the A/B Street side to match the current weird behavior.
  • For the initial cutover, I'll ignore separator lanes with markings (unless they're barriers), to match A/B Street's current lane types. Things like dashed or solid lines are currently just a rendering concept. Not sure how to properly model those yet.
  • Likewise, osm2lanes handles direction for bidirectional and untraversable lanes in a proper way. Some weird corners of A/B Street, like the low-traffic neighborhood "trace around the block" logic, currently depend on sidewalks having a forwards and backwards direction a certain way. I'll post-process the output of osm2lanes in the short-term, and clean up the hack eventually.

Web interface to convert tags to lanes

We could have a simple webpage hosted on github pages where you copy in an OSM way's key/values, press a button, and get the JSON lanes output. Internally it can use Javascript and call the Rust implementation, compiled to WASM.

Next steps after that could be a Leaflet or Mapbox map, where you click on a way, we query Overpass for the nearest way and its tags, and do the same thing.

And then from there, maybe consider some kind of rendering/visualization, just for a single road.

Country Metadata

I think it would be good to share country-related metadata with other tools.
For example, we could fork https://github.com/streetcomplete/StreetComplete/blob/master/res/country_metadata into a different repo, and then include it both here and in streetcomplete as a compile time dependency to determine locale specific data.

Complication: https://github.com/streetcomplete/StreetComplete/blob/master/COPYING this license is incompatible with ours as far as I know.
Either we need to rewrite this from scratch, or discuss licensing with the StreetComplete maintainer.

Support `lanes:psv`/`lanes:bus`

Multiple Language Bindings and Implementations

At the time of writing, there is a python, kotlin, and rust implementation intending to cover the same functionality.

This issue tracks the development of a strategy on what language bindings and implementations to support, how to support them, and how to track their capabilities. (There were other discussions, but this is to regroup them).

Lane Width, `width`, and Locale

Each (non-separator) lane on an OSM way must have a width.

See: https://wiki.openstreetmap.org/wiki/Key:width#Width_of_streets

In the unlikely event that all of the relevant width:carriageway, cycleway:<side>:width, parking:lane:<side>:width, shoulder:width, lanes:width are specified, we could have a trivial implementation. This is rarely the case, so we must assume incomplete information.

Locale

Locale (the region specific encoding of highway construction conventions) will be used to infer the width of each lane.
As this is constant for a given road, we will treat this and the resulting widths as constant in our requirements and algorithms.

No Width

When no width is given, the locale is used to determine typical widths of the lanes in the road.
If tags for certain lanes are provided (e.g. cycleway:<side>:width), the defaults can be replaced.

Total Width: width=* or width:carriageway=*

When a total width is given, we have the strict requirement to fill that width.
In the simple case, we could use the same method as above, and then scale all the lanes by the same factor to reach this requirement. However (depending on the locale) it is reasonable to imagine situations where this is insufficient. For example, bus lanes are unlikely to expand beyond a maximum width, shrinking footpaths will take precedence over shrinking travel lanes, there is a minimum size for a parallel parking bay, etc.

One proposal could be to model the following parameters per locale:

Width {
    min_width: Option<Metre>,
    default_width: Option<Metre>,
    max_width: Option<Metre>,
}

The lanes are still scaled together to meed the width, but will staurate at their minimum or maximum.
In situations where the width constraints cannot be met, an error may be thrown.
As more tags are provided (e.g. cycleway:<side>:width), the calculation above can be further constrained.

Config

Consumers may not want osm2lanes to guess what the width should be, so this should be a config option.

Roundtrip

When a lane width has been inferred with no guarantee of correctness, it should be excluded from the proposed/normalized/roundtrip OSM tags.

This may require an internal representation of the data:

enum DataWithConfidence {
    Direct, // Stated in a tag
    Calculated, // Other tags, when combined, can be used to calculate this
    Locale, // Not known for sure, so based on locale
    Default, // Locale has no standard, so defaults are used
    Unknown, // Unknown
}

We ignore situations where the OSM tags are contradictory.

Implementation

The current implementation does a single direct assignment of the lanes (excluding separators) and all their parameters.

Options:

  1. "Simple"
    Assign the default width first, and as a post processing step apply the above algorithm to mutate the widths.
    This has the downside that information from other tags cannot be added on the preceding step

  2. "Builder"
    A LaneBuilder struct is passed around instead of a Lane, upon which properties like maximum and minimum widths may be set.
    At the end, a LaneBuilder.lane(self) is called to return the API Lane.
    This would allow for more future flexibility when building lanes across multiple "passes".
    Downside: this will be a bit of work to rewrite the current implementation.

More Examples

We have a British and Dutch example on the website. I am looking for suggestions for ways in other country that are good examples.

A good example is:

  • idiomatic to the country
  • has a combination of different tags to make for interesting lanes and separators
  • contains tags not found in other examples

Represent dividers semantically

I want to propose that dividers be represented internally by their semantics, instead of their visual/physical manifestation, and be translated into specific markings in a separate step. My initial feeling is that it would shift most or all locale dependent questions about dividers out of the tag parsing step, into its own divider to markings step. Providing the divider semantics in the output would also be useful for users.

Semantic divider types

Dividers would be broadly categorised something like:

  • curb
  • road edge line (inner / outer)
  • lane separating line
  • center line
  • median (see below)

with additional semantic properties such as

  • stopping: default/no_standing/no_stopping/parking?/...
  • can_change: no/only_left/only_right/both (change= and overtaking=

dividers_to_markings

A separate function concerned with just the problem of converting semantic dividers to markings in the context of a given road would be a easier for new contributors to contribute to, which would be valuable for capturing global nuances. (I would be interested to see how static the mappings turn out to be.)

Having the markings be a separate step would also be a useful to allow additional information to be added to the road after examing the semantics. E.g. I have two connected OSM ways: 2 lanes into 3 lanes. I get the semantic lane info, compare them and decide that first lane in the 3 lane way is an added lane. I annotate the appropriate divider as "merging" before getting markings, and receive a beautifully appropriate dotted line (here in Oz).

Exposing the function as part of the API would also be a good way to query the lane marking database, because describing a situation from scratch in the output schema is much easier than describing it in the OSM schema!

Divider widths

Given that different locales might have different width markings for the same semantic divider, semantic dividers would have zero width: their markings fit within the the width(s) of the adjacent lane(s). (I'm not even sure this isn't how it already works). This is how I would prefer to receive osm2lanes output in semantic mode as a user.

Medians

This makes the "median" divider the odd one out, as the only divider with width of its own. Perhaps this suggest that the median itself should be a "lane" like a shoulder or a verge. One benefit is that the markings that divide the road from the median can be described too. In Australia, a median will often have a continuous solid line surrounding it, even as it transitions from a solid colour to a raised median to a diagonal hatching. The following output to describe the median would make sense to me:

A continuous line (divider) surrounds the median (buffer)

    {"type": "travel_lane", "direction": "forward"},
    {"type": "separator", "markings": [{"style": "solid_line"}]},
    {"type": "median", "kind": "raised"}, // or "colored" or "striped" or whatever
    {"type": "separator", "markings": [{"style": "solid_line"}]},
    {"type": "travel_lane", "direction": "backward"},

Medians are not well represented in OSM at the moment (divider= is the best I could find), but that is no reason not to represent then in this schema.

Contradictory cycleway tagging should report an error

Tagging like

  • cycleway=no + cycleway:left=track
  • cycleway=track + cycleway:left=no
  • cycleway:both=lane+ cycleway:right=track

should report an error.
I.e. wherever cycleway:both/ cycleway contradicts with the cycleway:<direction> tag

This tagging is ambiguous and either one of these tags must be a mistake (or both).

Allow configuring how and when osm2lanes guesses

My idea for surfacing the provenance of values in the output to the user, and providing clarity and control for the round-trip problem is this: Let the user configure if and when osm2lanes should guess details, instead of annotating every detail with its provenance.

Provides a straight forward way for the user to get what they want

If osm2lanes always guesses and annotates data, the chance that the user needs to process the output to filter out guesses that they don't want is high. If the level of guessing is customisable, it is likely that one of the options is exactly what they want:

  • Strict Mode for people implementing an editor and round-tripping: describes exactly what the tags describe, warnings for any tag that could not be reconciled, and errors for straight-up conflicts.
  • Consensus Mode for people rendering an "accurate" map (and probably for the visualisation in an editor too): makes assumptions that mappers expect, such as those documented on the wiki.
  • Fanciful Mode for people making something pretty or A/B Street: assumes as much as possible, describing a plausible road that is not proven wrong but the tags, and never fails.
  • Custom Mode could let the user opt into and even configure exactly the guesses they want.

Keeps the schema simple

Tagging every value in every entry in the output will turn the resulting JSON into a wall of text in no time, and I am not looking forward to any part of that experience.

Provides a way to check provenance

The same tags can be converted in different modes, and the user can compare between the two outputs to make more nuanced decisions.

Enables flexibility in implementing guesses

I feel like this will be easier to implement than tracking provenance, especially if we come up with guesses that have nock-on effects in the rest of the parsing process (such as arbitrarily resolving conflicts). There will be no need to keep track of all the values that have been effected by the guess, while the user can still figure out what was assumed.

Process for starting a schema

First there's the question of how we want to iterate on the schema.

  1. We could get test parity with the Rust implementation as it exists currently, then iterate on the schema and keep all 3 implementations in sync.
  2. We could iterate on the schema first with one implementation (Python, unless I get my Kotlin dev environment set up). Then once the dust has settled a bit, make the other 2 implementations match.

I'd vote for the second, since it seems less work.

How to express the schema

Should we use https://json-schema.org or switch to protocol buffers or similar?

Next steps with the schema

First thing is the set of lane types, and how we want to add details to some of them. For instance, we could have parallel_parking and diagonal_parking... or type = parking, parking_type = parallel. If we used protos, we could be more precise and show that the parking_type field is only valid when type = parking by using oneof. Any preferences?

The next major question on my mind is whether to represent a bus/transit-only lane, or instead list access/usage restrictions. We could just say "travel lane" with some subset of [motor vehicle, high-occupancy vehicle, public transit, taxi] allowed.

I also don't want to get too bogged down in deciding things that're pretty quick to switch in the code, but I'm not convinced blindly following A/B Street's current schema is the right choice.

Should we distinguish center turn lanes?

https://www.openstreetmap.org/way/185226351 (an alleyway) and https://www.openstreetmap.org/way/742718564 (a larger road with a center turn lane) both come up as

{
  "type": "travel",
  "direction": "both", 
  "designated": "motor_vehicle",
} 

I'm starting to think center turn lanes are some edge case. They're not really travel lanes; you generally can't just drive through one of them in either directions. (Or they become a regular turn lane close to the intersection and cease to be a shared turn lane.)

I want to distinguish these two cases in A/B Street. In the short-term I can detect the difference based on the total number of lanes, but I'm wondering if we should consider a type = shared_turn or something

Web app to edit lanes and upstream changes in OSM

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. :)

Cycleway lanes on oneway streets

A recent ping reminded me to update my local A/B-Streets install. Browsing around my city in A/B-Street, which is always a pleasure, I got to see some bidirectional cycleways, which in fact are single direction only. Eg. https://www.openstreetmap.org/way/25745877 has a lane for cyclists contra-flow motorists. Its tagging looks like polished with StreetComplete, still I consider the tagging accurate and complete, if not over-complete.

In A/B-Street, the "opposite-lane" (an old-fashioned osm jargon) for cyclists renders as a bidirectional cycle-way, where in reality, it is just a narrow cycle-only-lane contra the one-way. Cyclists going the motorist-one-way direction are to use the carriageway just as usual.

The OSM-Wiki is silent about directionality in such cases. I asked on the new forum, but only got on response from somebody, sharing the same background that I operate on ;) Is this different in e.g. Seattle? Or, are there just no tiles/presets for that? Or …

Lane surface (and smoothness)

Reading #79, I was wondering what a similar ticket would look like for an easier tagging topic (than width), like surface (and very similarly smoothness).


Goal

Each lane should have a fallback or direct(ly taggeg) surface tag. Including separator-"lanes".

Links

Lanes

What tags to consider…?

Sidewalk

  1. sidewalk:<Side|None>:surface
    11,300 Left https://taginfo.openstreetmap.org/keys/sidewalk%3Aleft%3Asurface
    14,800 Right https://taginfo.openstreetmap.org/keys/sidewalk%3Aright%3Asurface
    6,400 https://taginfo.openstreetmap.org/keys/sidewalk%3Asurface
  2. Local default
  • paving_stones in Germany, I would say

Parking

  1. parking:lane:<Side>:surface
    124 Left https://taginfo.openstreetmap.org/keys/parking%3Alane%3Aleft%3Asurface
    149 Right https://taginfo.openstreetmap.org/keys/parking%3Alane%3Aright%3Asurface
    0 https://taginfo.openstreetmap.org/keys/parking%3Alane%3Asurface
  2. Fallback highway=*.surface

Cycleway Lane

  1. cycleway:<Side|none>:surface
    3,300 Left (all cycleway types) https://taginfo.openstreetmap.org/keys/cycleway%3Aleft%3Asurface
    7,300 Right (all cycleway types) https://taginfo.openstreetmap.org/keys/cycleway%3Aright%3Asurface
    48,200 (all cycleway types) https://taginfo.openstreetmap.org/keys/cycleway%3Asurface
  2. Fallback highway=*.surface

Cycleway Track

This has different fallbacks IMO, that is why I list it separately. Only PBL could fall back to the highway-surface IMO, but those are not mapped explicitly via one tag, so we have no way of identifying them.

  1. cycleway:<Side|none>:surface
  2. Local default
  • paving_stones in Germany, I would say – at least for the existing, old infrastructure we have now. In Berlin the mobility law defines asphalt for new cycleways AFAIK.

Cycleway separately mapped

The combination highway=cycleway + surface=* has 750,000 objects https://taginfo.openstreetmap.org/tags/highway=cycleway#combinations.

Highway lanes

  1. highway=.surface
  2. Local default depending on the highway-type
  • For example track > ground
  • most other asphalt in Germany

For a local analysis, I used this mapping to provide fallback values for missing data: https://github.com/FixMyBerlin/osm-scripts/blob/main/ZESPlus/Highways-SurfaceData/utils/assumedSmoothnessBasedOnHighway.ts#L3-L24. However, this is part of a script that adds smoothness values to all highways using multiple layer of fallbacks, so that is what it is optimized for.

todo: buffers

To complete this list, I should look at the types of buffer and other lanes, that osm2lanes creates …


I will update this based on feedback and what comes to mind later.

`<key>:<opt_side>` schema (`key=val` same as `key:both=val`)

Looking at https://a-b-street.github.io/osm2lanes/ I see

  • sidewalk=both works
  • sidewalk:left=yes works
  • sidewalk:right=yes works
  • sidewalk:both=yes does not work, yet

AFAIK, for all currently accepted tags(*) the the :both tagging is supported whenever there is a :left|right version and the version of the tag without a side is an implicit :both.


*) I know of one exception, which is the WIP separation schema https://wiki.openstreetmap.org/wiki/Proposed_features/cycleway:separation

If no side is given, the side towards the strongest traffic user is meant by default (usually towards a road with motor vehicles – in countries with right-hand traffic usually on the left-hand side of the cycle path).

(PS: I suggest commenting on that proposal in case you find this too complex for data consumers to handle; I tried to raise this issue before, but with little success :-))


Of topic: Are issues like this helpful? Or is it better to wait for a while and test once you are happy with a release?

Explore JVM bindings

@tordanik today expressed interest for OSM2World. I just want to start a place where we can have further discussion and track the process of looking into Rust -> JVM bindings.

`oneway=-1` not understood

oneway=-1 means that the road is a oneway to the opposite direction in which the way is drawn. E.g. if the road is drawn for North to South, it would be a oneway from South to North.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.