Add landuse encoded value based on closed-ring ways tagged with landuse=*
I built a quick prototype, which:
-
stores the way tags and OSM node Ids for all OSM ways tagged with
landuse=*in memory during the first pass of OSMReader -
finds all the corresponding node coordinates in the second pass
-
builds an area index for all these (closed-ring) polygons before we read the OSM ways again in the second pass
-
finds the areas each edge is contained in and feeds them to the tag parsers
-
adds a tag parser for the new landuse encoded value, which uses the smallest of these areas to set the landuse value
This way we can, e.g., use custom models that prefer forest areas, or slow down the speed in residential areas etc. We can also just look at the landuse values using path details:

My first quick test resulted in an import time of 117s compared to 80s for a map of Bavaria with the master branch.
The biggest issue I ran into so far was that landuse areas are often mapped as multipolygons ~~many forest areas seem to be mapped as relations with such polygons as members~~. Parsing the relations wouldn't be much harder, but since we only get to see them at the end of the first pass (after the ways) we would have to read the OSM file a third time :(
The biggest issue I ran into so far was that many forest areas seem to be mapped as relations with such polygons as members.
The OSM wiki ~~even~~ says ~~that landuse should not be tagged on relations, but there are currently around 1.8mio such relations in OSM :(~~
"Although multipolygons are technically relations relation, their usage is generally accepted for tags that only list usage on areas area (and for which the wiki states these tags should NOT be used on relations). This is an exception since multipolygons are relations specifically meant to represent areas (polygons). For instance: natural=* is used 2,5 million times on relations; landuse=* 1,8 million times (as per Taginfo, 2023). "
For the Bavaria map I used there were around 634k ways using the landuse tag, and around 23k such multipolygon relations, with a total of around 125k (way) members. So around 16% of the areas were given as members of landuse relations.
I added support for multipolygon landuse relations in my second commit (using a third pass of the OSM file). At least for Bavaria this improves the handling of landuse=forest a lot. Here is a bike route that tries to stay in the forest (indicated by the red color in the path details diagram here) as much as possible:

With #2770 the third (0th) pass only took around 11s for Bavaria:
Finished reading OSM file. pass0: 11s, pass1: 21s, pass2: 79s, total: 111s
So using the landuse relations does slow down the import (because of the area lookups) (~62s total in master), but doing the third run (which only reads the relations) isn't making it so much worse.
This branch looks very promising, although it is quite expensive in terms of RAM and preparation time. I tested the extract for Austria with four bicycle profiles active and had to increase the RAM size from 3GB to 5GB. I just noticed a litte draw-back and this is that in some areas the way does not overlap with the landuse polygon, it is just very very close. In such cases it would be great if it would be possible to utilize the near by landuse polygon. Do you see the possibility for an enhancment to take a lets say a 20 meters margin into account?
I just noticed a litte draw-back and this is that in some areas the way does not overlap with the landuse polygon, it is just very very close. In such cases it would be great if it would be possible to utilize the near by landuse polygon. Do you see the possibility for an enhancement to take a lets say a 20 meters margin into account?
Yes, maybe that is actually quite a good idea. Also because in some cases for example forest areas are separated by roads like here:

even though the road clearly leads 'through' the forest.
Should be doable using jts? https://locationtech.github.io/jts/javadoc/org/locationtech/jts/operation/buffer/BufferOp.html
Should be doable using jts?
I did not look into it yet, but yes this sounds like what we need, thanks! Precision isn't very important for us here I think, we just need to widen the polygons a bit. The tricky part might be dealing with overlapping landuse polygons then.
JTS should be able to properly merge them.
JTS should be able to properly merge them.
I meant landuse polygons with different tag values. For example when a road is located near the border between an forest and a farmland area and we extend both polygons we need to decide which landuse value we like to use for this road.
Btw here is a nice visualization of the landuse tag: https://osmlanduse.org
I thought you meant overlapping parts of multipolygons. Aren't different overlapping landuse polygons already quite common? It would be nice if they weren't and everyone made proper multipolygons with holes in them, but in reality there's going to be quite a lot of overlap.
You'll most likely need to define some kind of sorting behaviour. e.g preferring non-buffered matches and polygons with a smaller area.
It's probably easier to leave the polygons as they are and instead make the search a little less precise.
(Or instead of a point in polygon lookup there is a "circle (or bbox) with polygon" intersection possibility)
I'd love to see a follow up PR that uses the landuse information to augment the urban density EV.
I created PR #2812 which implements the mentioned search buffer from above. @easbar Can you please check?
although it is quite expensive in terms of RAM and preparation time. I tested the extract for Austria with four bicycle profiles active and had to increase the RAM size from 3GB to 5GB.
The RAM requirement should be much lower now, can you please try again? Note that I also removed the relation handling for now, and maybe do this in a follow-up.
Also because in some cases for example forest areas are separated by roads like here
The same problem exists for residential areas where roads might be excluded explicitly from the residential landuse areas, like here (extract from Berlin):

Then again, in these cases the roads are probably often tagged as highway=residential, too.
Querying with a buffer like you proposed should fix this.
Querying with a buffer like you proposed should fix this.
Yes, it does:
