StrandedKitty / streets-gl

đź—ş OpenStreetMap 3D renderer powered by WebGL2
http://streets.gl
MIT License
632 stars 48 forks source link

Non-building:part parts of buildings are not rendered #3

Open VladimirMorozov opened 1 year ago

VladimirMorozov commented 1 year ago

When a building has building:parts only those are rendered, but the outline which doesn't have a part is not included. Compare churches here.

https://demo.f4map.com/#lat=59.4362195&lon=24.7407079&zoom=18&camera.theta=54.454&camera.phi=6.302 https://streets.gl/#59.43631,24.74125,35.75,356.25,713.98

Even if the building's height's is set, it's still not rendered if there are any parts https://www.openstreetmap.org/way/301781529

ivanbranco commented 1 year ago

It's because of this Simple 3D Buildings rule (I found a more precise rule than the one I mentioned in #3):

When a building has any building:part=* areas, the building outline is not considered for 3D rendering.

StrandedKitty commented 1 year ago

This is a really deep problem.

AFAIK, F4 Map has a unique way of handling building=* areas that have building:part=yes areas intersecting them. F4Map's approach is to subtract all building parts from buildings and then render what's left. And if a building is fully covered with parts then it doesn't get rendered at all.

On the other hand, other renderers such as OSMBuildings, OSM2World, OSM go don't do this. They certainly don't follow this subtraction approach. I think all three of them have no distinction between buildings and building parts and always render everything, though I might be wrong.

When I initially did my research on how Simple 3D Buildings are supposed to work I haven't found that much information on F4 Maps approach of handling it. It seems like they've made it up and it doesn't follow the schema which is described on wiki.

As @ivanbranco pointed out, on Simple 3D Buildings wikipage it's clearly stated that buildings intersecting building parts should not be rendered. I've implemented exactly this, and it seems to work, building outlines do get discarded correctly. Funnily enough, the same wikipage states that F4 Map has full schema support, which it clearly does not (if we consider what's described on that page the schema).

But it seems like F4 Map's approach to handling outlines has had a strong impact on how people map 3D buildings, as it's the most popular renderer with such a wide Simple 3D Buildings schema support. So I wonder if the schema should be reviewed to reflect the way the most people actually map.

Beakerboy commented 1 year ago

As a second opinion, here’s how it is rendered in my project:

https://beakerboy.github.io/OSMBuilding/index.html?id=26889368&info

Matthias84 commented 1 year ago

Yes I know the rule, but to be honest, most mappers and renderers handle it differently. They use building:parts to modify smaller blocks of the buildings on dedicated features, as this is the easiest way for little modifications and individualisation on buildings...

Here are some of many broken buildings in Rostock: https://streets.gl/#54.07926,12.14431,51.00,343.50,391.47

_P.S: Anyway a pretty astonishing visual imprettation of S3DB and micrommapped areas :explodinghead: Thats what I hoped that renderings would look like, when we started the united tagging schema!

Beakerboy commented 1 year ago

There is also the following errors with the building data:

Way 713297322 is taller than building. (79.28>3)
Way 713297323 is taller than building. (79.28>3)
Way 713297324 is taller than building. (79.28>3)
Way 713297325 is taller than building. (79.28>3)
Way 713297326 is taller than building. (123.8>3)
Way 842822342 is taller than building. (34>3) 
c-h-r-i-s-t-i-a-n commented 1 year ago

I also do not like the subtraction approach. The mapper should be able to decide if the outline is rendered or not by adding building:part=yes to the outline. Unfortunately JOSM gives a warning in this case.

ivanbranco commented 1 year ago

Unfortunately JOSM gives a warning in this case.

Luckily I would say! As the Wiki says: "Note that building:part= are optional areas used in addition to a building= area." It also makes sense logically, an element is either a building or part of a building, can't be both at the same time (that's why someone tags buildings with building:part=no, which is counter intuitive because adding it makes that element a building part...)

sekerob commented 1 year ago

This building renders complete to almost complete in StreetComplete, OSM Building and F4Map. It uses the type=building relation, has an outline and building parts with layering https://www.openstreetmap.org/relation/12485899. This was mapped > 2 years ago, well prior to knowing of existence of OSM Buildings and F4Map, only having removed the height=0 tag recently on the outline that suppressed it causing rendering max height for the whole building after which it turned it into a whole 1 height blob in SC, where OSMB and F4Map were correctly discarding the outline height tag / building outline already.

image

how it shows in StreetsGL, just the commercial ground floor.

image

JOSM gave no warnings at all when I removed the height from the relation outline. https://www.openstreetmap.org/changeset/133405707

Hope this helps

ivanbranco commented 1 year ago

how it shows in StreetsGL, just the commercial ground floor.

because is the only building:part=yes, the other parts are mapped as building=yes with layers

Beakerboy commented 1 year ago

@sekerob

one problem is the members of the relation have the role “buildingpart” instead of just “part”. https://wiki.openstreetmap.org/w/index.php?title=Relation:building&mobileaction=toggle_view_desktop

I suggest you look at the Burj Khalifa as a “gold standard” way to map building relations.

StrandedKitty commented 1 year ago

@sekerob

This building renders complete to almost complete in StreetComplete, OSM Building and F4Map. It uses the type=building relation, has an outline and building parts with layering https://www.openstreetmap.org/relation/12485899.

Parts in this relation have roles buildingpart, not part. I don't think this is valid tagging.

ivanbranco commented 1 year ago

@sekerob Note also that the building name goes on the building=* outline, not on the type=building relation

This outline must be tagged with building=*. The outline also holds any other tags (e.g. address, name, overall height, operator, ...) which apply to the building as a whole.

sekerob commented 1 year ago

As simple as role/part tags standardizing, did some adjacent buildings while there that had no heights or levels and added some windows=no and colours, albeit the windows on the elevator shafts did not go away in this screen refresh. Looks much better now though. đź‘Ť

image

sekerob commented 1 year ago

@sekerob Note also that the building name goes on the building=* outline, not on the type=building relation

This outline must be tagged with building=*. The outline also holds any other tags (e.g. address, name, overall height, operator, ...) which apply to the building as a whole.

Actually it's not the name, just an easy reference placeholder for recognition in ID Editor while working with relations, for building at corner Avezzano-Bologna. It shows up in the relations list of the area. Renderers ignore these as intended.

zyphlar commented 1 year ago

It makes relatively little sense to discard a whole building if there's any bit of a building:part within it, because that means for the vast majority of buildings with parts (say, a rectangle with a box or tower on top like every elevator shaft and roof access on the planet) you'd have to draw two overlapping rectangles to properly represent a simple building outline. That's simply not going to happen, even if it makes complex buildings that much harder. It violates the OSM principle of one element per feature (the vast majority of buildings have footprints that align with their facades, because most walls are straight) and turns any building that's not a box into a mess.

The only alternative in my mind is to move heaven and earth and dictate that building:part is only to be used when making truly complex buildings and in all other cases (say, a clocktower or water tank or antenna tower or elevator shaft or roof access on top of a building) should just be buildings on top of / inside of other buildings (additive to each other instead of throwing away the footprint.) Or make it very very very clear that if you use building:part you have to do a bunch more work.

This isn't your fault, of course, I just don't think the schema was thought out very well. The wiki page itself features the most contrived example of a building ever, of which maybe a dozen examples exist on the planet, while ignoring the much more ambiguous and important case of millions of buildings that are essentially rectangular with a flat or pitched roof and a box on top.

Two examples: https://www.openstreetmap.org/way/544929861 https://www.openstreetmap.org/way/544937123

Screenshot 2023-05-04 124247 Screenshot 2023-05-04 124258

tordanik commented 1 year ago

Originally, OSM2World actually supported subtraction of building parts from a building outline. But I quickly discovered that this only causes a different class of mapping errors to surface in the rendering. For example, when a mapper adds an entrance node and forgets to insert it into both the building:part and the building, rather than just one of them, you get a small triangle left over in the subtraction. There are also issues with indoor rendering (the subtraction approach implies a hole below the "box on the roof" which just happens to be invisible in an outdoor-only rendering) or ambiguity whether tags refer to the building as a whole or the building part.

So I eventually dropped that from OSM2World, both because of the constant bugs related to it and to encourage clean mapping. And while I do still grudgingly support the "building:part tag on the building outline" hack, I'd be happy to get rid of that as well – it's inherently contradictory and an example of mapping for the renderer (probably F4, given its prominence).

(By the way: Duplicating the outline can be quick with the right tools. For example, JOSM Shrinkwrap makes it a single key press. And the "follow" command often makes it quite easy in iD as well, at least for free-standing buildings.)

It violates the OSM principle of one element per feature

To the contrary, using the same element for the building and its largest part violates "one element per feature". This is apparent when you consider what the height tag on that feature should be: For the building, the height should include, say, a tower. For the building part with the same footprint, the height should not include that tower.

zyphlar commented 1 year ago

@tordanik

using the same element for the building and its largest part violates "one element per feature". This is apparent when you consider what the height tag on that feature should be: For the building, the height should include, say, a tower. For the building part with the same footprint, the height should not include that tower.

I will begrudgingly accept this logic but I will protest it until my dying days, and regardless the wiki needs to be made much more clear about these things. Honestly I think the real answer here is that building:part should only be used for people who want to throw away the building as a fully rendered object and are ready to do a ton of work achieving their "simple" 3D Building dreams, and for the rest of us who just want to plop a clock tower on top of a building we should probably just put a building inside of / on top of another building, like 90% of the planet already does when a main building has a shed or garage or awning attached. It's just too complex for too many objects for too little benefit. Made more sense back when the only buildings that got mapped were notable, and is absolutely bonkers for the millions of buildings out there with 10x10x10-foot rectangles on their roofs.

And yeah how to deal with things attached to that building outline like entrances is just one of the many issues. I don't like it, not one bit.

Anyway this isn't StrandedKitty's problem they just have to deal with the fallout, so don't mind me.

StrandedKitty commented 1 year ago

I'm thinking that it might be better to discard building outlines less agressively. Maybe only hide such building outlines that are mostly covered by building parts. Some sort of a threshold will have to be introduced -- lets say 90%, so that only outlines covered by 90%+ will not be rendered.

This is a bit hacky, but I think this should fix the way a lot of buildings with parts are rendered.

sekerob commented 1 year ago

Here's an example I was looking at to see how spires are mapped, seemingly many stepped layers, noticed the main building is missing.

image

mnalis commented 1 year ago

Maybe only hide such building outlines that are mostly covered by building parts. Some sort of a threshold will have to be introduced -- lets say 90%, so that only outlines covered by 90%+ will not be rendered.

Makes sense to me @StrandedKitty. Afterall, the building:part is intended to add extra details to existing building.

So if those building:part elements are faulty and are not meeting their own specification (i.e. all of them combined do not represent [very close to] 100% of the building), then it is those faulty building:part elements that should be discarded, not the main building.

ivanbranco commented 1 year ago

image

Now the building=* outline overrides the building parts tho, creating levels that are not there, such as here, where a building:part with min_level=1 was set.

zyphlar commented 1 year ago

Things are looking amazing now thanks! Sorry to be all ranty about standards. If you want to highlight the noncompliance, maybe outline the building in red with a popup or something to help people either adhere to the standard or make the standard usable

kayD commented 1 year ago

I'm not sure how it could be other than the building not being rendered at all in case there are any building:parts present.

The height of a building is the overall height including all (excluding antennas). How about this building: https://streets.gl/#49.79488,9.94128,45.00,270.61,426.18 image Image of the Johanniskirche in WĂĽrzburg, by some dubbed Batman Church, don't know why, looking at its shadow :)

The overall building height therefore would have to be 60m (i.e. the height of the towers = overall height of building). If the building would be rendered, it would overshadow all the building parts. https://www.openstreetmap.org/way/89260175 https://www.openstreetmap.org/changeset/136305197#map=19/49.79492/9.94184&layers=D

I do not fully go with this definition, because a renderer unaware of building:parts that would render only the building, most building with bell-towers would look way too high. Therefore I decided (without a consistent reason) to set the height of the church building to the height of the main part, i.e. 30m.

zyphlar commented 1 year ago

Someone in a chat room suggested that you could tag the outer building as building=yes as well as building:part=yes to achieve a similar effect of the outer perimeter being drawn, however you're correct that then the height would encompass every other part according to the standard. Ultimately I think the standard is just poorly thought out and optimizes for edge cases (complex iconic buildings that tend to get mapped first) instead of common cases (millions of apartment buildings with elevator/roof access "boxes" on top.)

For now the best solution I can think of for renderers is to do the best it can while calling slight attention to the nonstandard schema.

kayD commented 1 year ago

@mnalis wrote:

Afterall, the building:part is intended to add extra details to existing building.

I think this is exactly summing up the root of the mix-up. To my understanding, the building:parts define the whole building, as a finer replacement of the coarse building. (So they would have to define 100%.) Otherwise you could not have holes in buildings (like a drivethrough-passage to a courtyard).

An example of this is this building: https://www.openstreetmap.org/way/189668869#map=19/49.78869/9.93279 image There should be a gap in the ground floor where the service way passes through to the parking lot "behind" the building. kendzi3d gets it wrong and renders the ground floor of the building outline (with the "?" texture), but it should not, as it filles the drive-through, and is in conflict with the two other building:part specs of the ground floor.

Where do you read the definition of building:part is a mere addition to an existing building?

(It seems hard to believe this is a new discussion.)

mnalis commented 1 year ago

@kayD see building:part wiki, especially part with:

Note that building:part= are optional areas used in addition to a building= area

as well as simple 3D buildings wiki I linked to previously.

(So they would have to define 100%.)

They should, yes. The issue is exactly what to do when then they don't define 100% of the building.

mnalis commented 1 year ago

I think the standard is just poorly thought out and optimizes for edge cases (complex iconic buildings that tend to get mapped first) instead of common cases (millions of apartment buildings with elevator/roof access "boxes" on top.)

The main issue is legacy. There were building first, when building:part was invented it was naturally not said "ok lets delete all what is mapped so far, and start from scratch" but instead it was though of as addition with more details, but thus *it had to preserve all existing semantic of `building=`** for all data consumers that (wish to) use that.

Also, what is best height depends what is your use case. For 3D rendering, yeah, perhaps most common (median) height is most visually pleasing. But if you are doing drone collision-avoidance programming, you don't really care that it is just a bell tower part of the church that is 100m high, and majority of the building is only 20m high. Because, if you fly at 50m you will still crash.

kayD commented 1 year ago

@mnalis good and concise summary.

I think the first 3 items are completely valid, and the fourth is the one we are discussing.

pro: If data "is like it is" and would not change, a heuristic to interpret erroneous data is best. It enables users to easily (sloppily) improve building geometry a bit.

con: This behavior masks problems and causes people to become accustomed to viewing erroneous data as acceptable. This is bad for data quality in the future.

Would it be a good idea to have two rendering modes:

  1. End user mode: show me a beautiful 3d map
  2. Author mode: show me problematic data

or is even one of those not a use case at all? (Also: is there even a decent 3D building validator?)

natrius commented 5 months ago

I'm completely with https://wiki.openstreetmap.org/wiki/Simple_3D_Buildings definition:

The building outline provides backward compatibility for 2D rendering software, such as Mapnik, and other data consumers not interested in 3D modeling. When a building has any building:part=* areas, the building outline is not considered for 3D rendering

And it seems https://wiki.openstreetmap.org/wiki/Key:building:part the explaining paragraph should get edited to make it fit the "Simple 3D Building" so avoid the confusion. That way if someone edits something in 3d and checks afterwards and looks at the two sites it should be consistent. "Ah, i used building:part=* so everything should be. Funny enough, the "How to use" section actually goes into it with the third paragraph.

This may at times result in 2 ways sharing the same building nodes if the ground building:part is identical in circumference as the total building outline. A 2 part building is thus mapped with 3 objects regardless if with or without a type=building relation.

I think i will edit the wiki now.

What would be nice?

To encourage a correct tagging.

dreua commented 5 months ago

Could this be added as another check in osmose?