Can opening time of toilets within a library change automatically with the opening times of the library?

That assumption might somehow work on such secondary features like toilets. But will most likely fail on something like a shopping mall.

Or shops in airport.

Would it be reasonable to introduce a new opening hours value that explicitly states the hours are the same as for the containing feature? Something like opening_hours=same_as_containing_feature or just opening_hours=inherit.

The idea being to leverage the spatial relationship and avoid the complexity of relations.

(Unsure if adding a new value is a massive no-no, or if existing consumers are expected to gracefully handle unrecognised values.)

Opening hours field is a rare case of field with defined complex formal syntax with own grammar

This idea can only be considered in the form of eg opening_hours:inherited_from:amenity=library separately and explicitly. Besides the opening_hours= syntax, it can be unclear what the parent feature is when there are multiple enclosing polygons. It’s not always the largest vs smallest polygon, or most vs least prominent feature class.
From my understanding: Finding parent of a child efficiently requires indexing, and operations using the index properly. Depends on whether apps have it offline on each device. Editing software may not do it. An explicit database link might also be more responsive for caching and updating.
The above is assuming all the parents are polygons. When there are parent points, there’s no direct spatial/topological relationship. Search by proximity is inefficient, and unreliable.

Can you give an example of a situation where it wouldn’t be the smallest enclosing polygon with a defined opening_hours? I like the simplicity of opening_hours:inherited=yes, but I think if you have to try to specify which feature to inherit from, a relation would be the better approach since it allows you to pick the exact feature with no ambiguity.

multilevel shopping malls with POI structures

multilevel government buildings

multilevel train stations

So you’d just need to refine that to “the smallest enclosing polygon on the same level with a defined opening_hours”? Or is there something else I’m missing? Admittedly this does seem a lot more error prone when multi-level buildings come into play (the wrong level tag could result in inheriting from the wrong feature).

It seems that it should solve it in basically all cases?

I can imagine two features, each at multiple levels with footprint partially overlapping but I have not seen one.

Amusement parks may be the most likely candidate?

Or something built by Lol We Hate Mappers GMbH spółka z.o.o.

What’s been suggested are all possible solutions too (and may or may not be better), but aren’t actually what I was thinking of at all.

I was suggesting: (a) that you would actually copy the opening_hours=* value onto the target object, and (b) rather than using a relation you’d just tag the target object with one or more tags that encoded the fact that it’s opening_hours value should match that in a specified source object.

The rational for (a) is that most data consumers won’t support any fancy tagging /relation system for inferring values from other objects, and certainly won’t do the geospatial query to work out a smallest enclosing polygon around a POI. Some users may only be downloading the target objects, so would have access to the source object anyway.

The idea is that someone in OSM then runs an integrity checker to periodically check that the relevent tags on each target object match that on each source object, and update them (automatically or manually) when needed.

For (b), a relation seems like overkill, when we can just reference the other OSM object in a tag. Rather than requiring any geospatial queries, we could just use the OSM object ID to refer to the source object.

So I was thinking of something like inherits_from:w1234567=opening_hours on the target object. You could include multiple key names on the right-hand side if more than one key was inherited from the same OSM object.

Suffixing id is as bad as numbers or dates. key= is supposed to be finite.
It can only be vals, or similar to *:conditional= split into parts.
A1. inherits:opening_hours=w1234567 + inherits:access=w1234567
A2. opening_hours:inherits_from=w1234567 + access:inherits_from=w1234567
B1. inherits_from=w1234567 @ (opening_hours;access)
B2. inherits=(opening_hours;access) @ w1234567
However, using id is still flawed for the same reasons as for a PoI’s persistent identifiers. Deleting the parent feature results in a “dangling pointer”, although not critical, and can be used as a flag to fix. Other uses of this method haven’t been widely adopted. Key:previously - OpenStreetMap Wiki

the same can happen with relation…

It cannot (unless something in the toolchain is broken). Unlike raw tags, relations are highly structured, each association having a member id and its role. When you delete an element, those associations in all its relations must also be deleted. Normally, it’s the editor (iD/JOSM) that will automatically generate those deletion operations in the changeset; but even if you access the API manually, I expect that the transaction would be rejected if the resulting model is inconsistent.

(That’s the general theory, I’m not exactly familiar with OSM implementation.)

you definitely can break relations in OSM and remove only some of members - leaving for example turn restrictions with only and solely via member

nope, they ideally would be but it is NOT enforced on any layer

nope, API will happily accept relations utterly mismatching any definition on wiki

there is no content validation at all, none whatsoever (except some limits on member count)

your claim completely and utterly mismatches how relation validation works or does not in OSM

I don’t mind being proved wrong, but you really could adopt a more collegial tone.

I can’t really be sure what is validated or not on the API level (unless I delve into code or documentation), since any extant editor will do the right thing for me: either remove the member automatically, or prevent deleting an element until I remove it from relations manually. So my original point is still valid: something in the toolchain can (and does) validate relations, either partially (referential integrity only) or fully (all required roles and limitations valid). Nothing in the existence validates ids encoded in raw tags.

At least when you delete a member object directly (when everything is downloaded), JOSM can warn you of what’s affected immediately, and iD could even disallow it before removing all its memberships first. Tags don’t have this treatment, yet.
Besides, for using the feature tag opening_hours:inherited_from:amenity=library , there’s the added benefit of being human-readable and more informative. Both users and applications can directly understand and use it.

OK, deleting element remove it from relation

but it does not change at all that you may end with the same problem as

as referencing relation may miss parent element as it got deleted

sorry, I will try be more careful in future

The way I was proposing implementing this was to store the inherited opening times in the opening_hours=* tag on the target object, and then have a tool/bot periodically check the stored value is consistent with the tagged parent.

Any dangling pointers would also be detected by the tool/bot and would be flagged fir manual fixing. So I don’t think the fact that these could arise is a significant issue.

Relations do have slightly more protection against this in editors, but I’m not convinced using relations would be worth the added complication.