-
Notifications
You must be signed in to change notification settings - Fork 819
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Combine road lines and areas to one layer #2046
Comments
@math1985 Right now the layers we have are
Entries in bold are versions of the large 6kb road query. I've successfully brought Would it then be possible to combine them into one layer? |
Great work! Yes, It probably also makes sense then to bring To merge tunnels with the main road query, we have two options:
To merge bridges with the main road query, we need to get rid of the layers I think The layer For the remaining layers
|
Am I right to understand that this would mean that two road sections interconnected but with different layer=x tag, would no longer visually merge their fills, like what you see happening when normal roads connect to tunnels (e.g. here: http://www.openstreetmap.org/#map=18/40.70733/-74.01535)? This would lead to many undesirable artefacts of apparently unconnected roads near bridges and viaducts. I think this would be undesirable in that case. It might actually be solvable by no longer rendering the casing "rounded" at the end point of lines, but instead to cut them straight, and have the rounded fill extend it allowing visual connection. |
No, actually this wouldn't work, good point. For tunnels, this is solved by keeping the fill visible, as in @mboeringa's link. This is good for tunnels, but wouldn't work for regular roads. For bridges, this is solved by having casing straight instead of rounded. This leads to gaps in casing for rounded roads, for example here. It's the same issue as #470. I don't think introducing such gaps would look great. |
I've been working on this in a slightly different context, and ran into an issue I can't seem to get around with I cannot see a way around it. Using The current code does not have this problem because the order is road layer 0 casing, road layer 1 casing, road layer 0 fill, road layer 1 fill. Using one layer would change it to road layer 0 casing, road layer 0 fill, road layer 1 casing, road layer 1 fill. This is the same order that is used in the current code for tunnels and bridges. This means that there is a bug with bridges that have a dead end, but these are very rare. |
True. However, our ordering means that we don't really use the layer tag for non-bridge/tunnel roads. If two non-bridge/tunnel roads with a different layer cross, we don't show which way is on top by the layers. The only way the layer tag has an effect if when two roads with different colour cross: then the intersection gets the colour of the road on top. However, that's a fairly subtle effect compared to using casing to show which road is on top, so I think we can say in practice we ignore the layer tag for non-bridge/tunnel roads. That's in line with the wiki by the way, as it specifies that a layer-tag needs a tunnel or bridge tag, As we basically ignore the layer tag now for non-bridge/tunnel roads, I think a new solution could also ignore the layer tag for these roads. We could for example rewrite the layer tag to 0 in the query if there is no tunnel or bridge tag. That would avoid this problem, wouldn't it? |
Then the wiki is wrong (again, frustratingly). Layer tags are useful for roads that are vertically separated yet parallel, e.g. North Street and the M8 through Glasgow: (North street is on the left of the photo, running parallel to the sunken motorway but neither of them are bridges nor tunnels. Since at many zoom levels the roads are drawn wider than reality, the drawn roads overlap, and which ends up on top can be controlled by the layer tags. Although separate highway tags in this situation, it's easy to see they might have the same highway tag elsewhere in the world). I would like to see the layer information used for the stacking of roads, and use bridge/tunnel tags only for decoration. That makes it most robust, and avoids the potential for people adding fake bridge/tunnel tags to situations where the layer tags are being ignored. |
These streets don't seem to be crossing or overlapping, so I'm not sure if a layer tag makes sense here. |
I added more details under the photo, but you can see in the map extract that they are overlapping. |
sent from a phone
the wiki doesn't say this, it says: |
So
Taking this a bit farther,
|
Sounds good, I think this should work. |
Upon closed thought, I think it actually does not work. Consider the situation where two roads meet under an angle of 90 degrees., one road on layer 1 and the other road on layer 0. The top (normal, butt-end) casing of the road on layer 1 will now be extended too far into the intersection. |
I initially thought you were wrong, so I drew the layers below, except put the bottom casing as a different color. And we currently see this problem with bridges Doing an initial bottom casing would fill in the missing casing on the left, but the casing at the right protruding into the fill is the problem we're talking about. Because we don't have topology, I think this inherently unsolvable while maintaining casings separating roads on different layers. |
And yet another problem with this approach: dead-end, or sharply bent, streets on top of tunnels. Real-life example Your proposed approach would drop the round casing from this dead-end way, making it look like the service road leads to the tunnel. Also inherently unsolvable without topology. |
+ 1, at some point, people should stop pixel peeking and accept this is not a hand-drawn map. In my ArcGIS Renderer, I am facing similar minor issues. But the overall map look, even laser-printed, is OK, so I don't bother. |
A minor technical detail: Even though end points involve less rendering, I've come to prefer rendering the entire road to just the end point because that way everything involves The query I had for road ends was (WITH
bbox_roads AS (SELECT way, z_order, class FROM roads WHERE way && !bbox!),
end_nodes AS (SELECT unnest(ARRAY[ST_PointN(way, 1), ST_PointN(way,ST_NPoints(way))]) AS way, z_order, class FROM bbox_roads)
SELECT DISTINCT ON (way)
way,
class
FROM end_nodes
ORDER BY way, z_order DESC -- take the topmost most important road
) AS road_ends |
I noticed the n-plication of very similar 9and sometimes identical) queries on the layers. All those queries are run independently, (over)loading the database (and its connections). What would actually be needed to solve this is two different things: a) support in the styling/layering code to reference a single query and b) support in mapnik to actually execute it as such. It could also be interesting to be able to reuse a previous query for a certain (meta)tile for rendering the tiles in the next zoom level (thinking of a pyramid rendering scheme). I guess I'm simply calling for another renderer altogether. For the moment, I can only think of creating more |
I did a clean implementation of roads rendering from scratch The road styling is simpler, combining some classifications, but it does handle the way as highway and railway case. It ends up being a lot cleaner than other implementations, and has a few features I'd like to implement in osm-carto. It doesn't yet have road text or shields.
Given the huge reduction in code size and maintenance burden we could, I'm convinced that going forward is a good idea, even if some edge-cases with layering and casing look worse. |
Looks promising. Of course the decrease in code size alone doesn't tell too much, as is for a large part achieved by removing functionality and by moving complexity to the .lua file. I hacked the code a bit to get it to work with a standard rendering database. In my set-up, your code renders all roads on top of bridges. Does it do the same for you or is my set-up to blame? Apart from that I don't immediately see major issues in Luxembourg. |
Just to note that this is probably an issue with the hacking you did on the code, in particular, something related to enum types and sorting. After doing a bit of editing of the SQL queries, I think how I'm going to tackle this is to reimplement the roads code, rather than trying to change it bit by bit. |
I suppose you meant roads below waterway bridges, or did you actually mean roads above waterway bridges? My bet is you won't find the latter, as the entire point of waterway bridges, at least in the Netherlands, is to allow tall ships to pass through unhindered. |
Ok, never say never: here a canal near Birmingham crossing the River Tame, with a motorway bridge passing above: https://www.openstreetmap.org/way/115858978 |
Nope, I meant roads above waterway bridges. I'd expect roads below to be the common case. If we move the waterway bridge layer above the roads layers then we'd be able to merge fill and tunnels, and get the common case right. We'd get the road over waterway bridge case wrong |
Ok, then the Birmingham example will do. |
Looking at it and three bridges I suspect we're currently getting waterway bridges over road bridges wrong. Anyways, the next step is to put my head down and write some MSS |
Correct. |
After work I did a bunch more CartoCSS, and now have the skeleton of something that works: https://github.com/pnorman/openstreetmap-carto/tree/roads_rewrite/master
The general goal is to keep all the code for a road type reasonably close together |
Is it possible to use simply z_order from highway instead this? |
Yep, good catch. Once I do rail styling I'll open a PR so we can do a more detailed review. My main concern at this point is the general approach, which consists of
#transportation {
[class selector] {
::casing {
[geom type] {
styling
}
}
}
} |
I think we should have all areas beneath all roads (in general, area features should render below line features). For example, a tunnel should render on top of an area (oitherwise the tunnel would be invisible). Therefore, having two layers would suffice: one layer for area features, and one layer for road features. There is no need for merging the line and area layers. I agree with the mentioned issues, but the solution proposed in this ticket is not the way forward. |
Re-reading this, I see this ticket is not about merhing lines and areas together, but merging all lines and all areas. That's still useful so I'm re-opening this. |
This PR moves highway areas below all linear road types (resolves gravitystorm#3281). In particular, this change has the following effects: * Render highway areas below tunnels (resolves gravitystorm#529). This prevents the current situation where tunnels are invisible if there happens to be a highway area above them. * Render highway areas below line/area barriers, ferry routes, tourism boundaries, cliffs, landuse-overlay, and turning circles. I think these changes are mainly neutral or positive. * Render highway areas below line/area barriers. This is probably the most controversial aspect (but necessary for the other changes). See screenshot below. * This PR is a necessary condition for merging the roads-casing and roads-fill layers (part of gravitystorm#2046), which would greatly simplify our code. * This PR is a necessary condition for rendering buildings above highway area (gravitystorm#688). * Promoting linear highways over areas makes life easier for other data consumers, that already tend to have poor support for highway areas. For example: * Transport and wikipedia do not render road areas * Humanitarian, bicycle, mapbox, streets, OSM bright renders linear roads on top of areas, like in this proposal
From #1975 (comment)
Doing this will reduce the number of layers and allow future MSS simplifications
The text was updated successfully, but these errors were encountered: