Take two at a water layer - #39
Conversation
jake-low
left a comment
There was a problem hiding this comment.
Sorry it took me a couple of weeks to reply to this. I've left a few comments.
I tend to be conservative about which tags to include in each layer, because it's easier to add a column than to remove it. OSM tags wax and wane over time, which works because of its fluid schema. But Layercake attempts to squish OSM into something rigid and typed, so removing a column later (e.g. if the community decides to change how something is tagged) is a breaking change for downstream users who reference that column in their SQL queries or similar. Most of my comments are from that perspective.
| -- Reason: dimensions. | ||
| tags['width'] AS width, | ||
| tags['depth'] AS depth, | ||
| tags['depth:'] AS 'depth:', |
There was a problem hiding this comment.
Or at the very least should be a prefix_map, I'll try and figure out whether I was looking at a depth prefix, before just removing it.
There was a problem hiding this comment.
I didn't see any of these in the data i've downloaded, but I believe that these were for the prefix_map mentioned in
https://wiki.openstreetmap.org/wiki/Key:depth
They prefix map seems used for things like how the depth tag was obtained/measured it's accuracy, etc.
depth:source_quality, depth:technique, depth:accuracy depth:exposition.
It may just be used more for water bodies than rivers?
| tags['height'] AS height, -- For waterfalls? | ||
|
|
||
| -- Reason: navigation direction and obstruction bypass, | ||
| prefix_map('oneway:', tags) AS 'oneway:', |
There was a problem hiding this comment.
I'd avoid using a trailing : in a column name; it's confusing. I also don't think we need to include oneway:* tags at all (yet) since there are only a handful of uses on waterways worldwide currently.
There was a problem hiding this comment.
I suppose it doesn't matter if we're just removing the prefix_map, but is there any suggestion/convention for
tags that act as both a prefix_map and a tag? That's why I was using : here in column names.
There was a problem hiding this comment.
The convention used in other layers is to pluralize the tag key. E.g. prefix_map('name:', tags) AS names. As a user you can then do SELECT name AS default_name, names['en'] AS english_name or similar which reads pretty well.
This is somewhat awkward for some tag keys though.
There was a problem hiding this comment.
Ahh, yeah I think if I recall I might have started doing the : thing after some awkwardness.
tags['rapids'] as rapids,
tags['rapids'] as rapidss,
seems the most likely culprit
There was a problem hiding this comment.
One thought: prefix_map exists because name:* is an unbounded set of keys (every present and possible future language code, and more), so we can't enumerate it at build time. But rapids:* has a small, known set of keys. The best structure then is probably just to have the following fixed set of columns:
rapidsrapids:namerapids:classrapids:intermittent- (others can be added too but that's probably a good start)
This is how Layercake currently handles similar cases. For example building, building:material, and building:levels are each a top level column in the buildings layer.
An additional advantage of this is that top-level columns can be efficiently filtered or projected in a query; map columns cannot.
There was a problem hiding this comment.
I couldn't find anything tagged with rapids:intermittent only two with rapids:class
mostly just rapids:name, plus 62 with rapids:description.
| -- Reason: navigation direction and obstruction bypass, | ||
| prefix_map('oneway:', tags) AS 'oneway:', | ||
| tags['oneway'] AS oneway, | ||
| tags['canoe_pass'] AS canoe_pass, |
There was a problem hiding this comment.
canoe_pass doesn't look like an established tag (only 21 uses)
| tags['lock'] AS lock, | ||
|
|
||
| -- Boat access | ||
| map_from_tag_list(tags, ['motorboat', 'ship', 'sailboat', 'boat', 'canoe']) as vessel_access, |
There was a problem hiding this comment.
I think it's clearer to make each of these its own column (this is what the highways layer does).
| tags['hazard'] AS hazard, | ||
|
|
||
| -- Reason: Fish navigation? | ||
| tags['fish_pass'] AS fish_pass, |
There was a problem hiding this comment.
fish_pass also doesn't look like an established tag (only 76 uses)
| -- Reason: Fish navigation? | ||
| tags['fish_pass'] AS fish_pass, | ||
| -- Reason: hydrology | ||
| tags['order:strahler'] AS 'order:strahler', |
There was a problem hiding this comment.
I don't think this info belongs in OSM; Strahler number can easily be computed and is just one of several methods of analyzing stream topography. So I would not include it in Layercake.
| prefix_map('oneway:', tags) AS 'oneway:', | ||
| tags['oneway'] AS oneway, | ||
| tags['canoe_pass'] AS canoe_pass, | ||
| tags['lock'] AS lock, |
There was a problem hiding this comment.
Might also want lock_name and lock_ref if we're including this.
| -- waterway-relevant tags i've added or changed... | ||
| -- Reason: general | ||
| tags['usage'] AS usage, | ||
| tags['natural'] AS natural, |
There was a problem hiding this comment.
I'm unsure whether to include natural; I think most of the values come from a small set (valley, canyon, etc) and it's much more common for those features to be mapped as a separate element, so SELECT * FROM waterways WHERE natural = 'canyon' wouldn't actually be a reliable way to identify waterways that flow through canyons.
There was a problem hiding this comment.
I think the exact reason I included is was because of https://wiki.openstreetmap.org/wiki/Waterways
If a stream starts as as spring, the node can be tagged with natural=spring.
But now that I look at that it, it's limited to nodes and areas, and this script has a where clause WHERE kind = 'line'
I'll just remove it for now.
| type, | ||
| id, | ||
| tags['waterway'] AS waterway, | ||
| tags['name'] AS name, |
There was a problem hiding this comment.
Probably want to split_mutli on name, and include prefix_map_split('names:') too, since major rivers that pass through or form the border between different countries will usually have multiple names.
| WHERE kind = 'line' | ||
| AND tags['waterway'] IN ('river', 'stream', 'canal', 'ditch', 'drain', 'flowline', 'fairway', 'link', | ||
| -- Reason: Routing obstructions. | ||
| 'dam', 'weir', 'waterfall' |
There was a problem hiding this comment.
I'm mixed about whether including dams, weirs, and waterfalls is useful. We do not include barrier elements in the highways layer, which would be necessary for correct highway routing. And it seems like it might surprise data consumers that dams, weirs, and waterfalls are included in the "waterways" layer (IMO this is one of the many confusing things about OSM's taxonomy; natural=waterfall and man_made=dam would be clearer, but alas).
There was a problem hiding this comment.
I'll just drop damns, weirs, and waterfalls for now, it can always be added later.
On man_made=dam it isn't really common but there are also natural=beaver_dam it's wiki page is actually hilarious.
https://wiki.openstreetmap.org/wiki/Tag:natural%3Dbeaver_dam
While similar to the man_made=, beaver_made='s use count was too low to be kept as good practice.
There was a problem hiding this comment.
Since we removed that I also got rid of height which is probably only useful for waterfalls.
|
Thank you for the review, I'll try and work on your suggestions tomorrow |
|
I went ahead and pushed some changes, plus some reformatting in a separate commit to make everything look nicer. One question that I had, is this uses the general Is there a goal of optimizing the geometry for specific types in layercake? |
|
I guess one thing I wonder is if you want to just wait for another person who can use the layer in their program |
DuckDB actually does this automatically when writing parquet files. It observes what types get written into the column and then sets the appropriate type annotation at the end. I checked and the I'm not aware of any software that actually uses this info to optimize how it handles the data though, so it's mainly just advisory info that might appear when someone inspects the file.
I think it's okay to ship this even if we don't know exactly who will use it. There's lots of reasons someone might want to grab all of the waterways in OSM, and this layer makes that easy. The set of attributes we've arrived at feels like a reasonable starting point; we can always tweak it later. If you mark this PR as "ready for review" I am happy to rebase it, review it, and test it. |
|
Okay I marked it as ready for review, |
I went ahead and added comments to each of the tags I added.
I couldn't really understand how to do navigation without obstructions like dams/weir/waterfalls,
so I did end up including those, let me know if you really want those omitted.
Looking through the keys, they are pretty sparse for most of the regions I tried.
It seemed like one key would appear on a few items in one area. Ditto for a different key on a different region.
(Like open_water in the regions I tried only appeared in finland)
I'm not sure if you'll actually want
map_from_tag_listfor building a map from related tags.It seemed weird to have separate columns for each vessel kind, for restricting access by kind of boat,
however the majority of these appear to have
cardinality(vessel_access) == 1. So I'm not entirely sure it's the right thing to do.