Renders sometimes include building parts from nearby buildings
When rendering a building way, all elements that intersect the way's bounding box are fetched from the OSM API. This can include elements outside of the building perimeter -- including building parts of nearby buildings, which are added to the parts list and rendered.
Example: 278078955 as currently rendered at https://beakerboy.github.io/OSMBuilding/index.html?info&id=278078955 also shows building parts 369862691 and 369862692 from building 369862694 to the north. Note that it doesn't add the entire extra building -- the northernmost part 369862690 is entirely outside of building 278078955's bounding box, so is not fetched.
Yeah, this is a known issue, and can be seen in one of my examples, the Chrysler Building (I think). And it’s actually worse than you state. For a “building way” versus a “building relationship”, the code will grab the building way, calculate its extents, and query to grab all ways within the area. So if a building is exactly aligned with north-south, it will only grab ways which either share the border or are within. If the building is rotated, it can grab ways which do not intersect the “outer” building.
Add to this, the standard says that “building-parts must fill in the entire building” but parts actually CAN extend outside the “outline”.
I think what I need to do is, inspect each way and if no node falls inside the building, discard it. If a node falls on the border, a calculation would have to be done to see if the border of this way crosses through some part of the outer building.
also, appending “&info” to the url will bring up some extra controls (looks like you already know this :-) . You may be able to make the other building parts invisible by expanding the controls for the offending ways and clicking the checkbox labeled “visible” for that part.
all in all, this is kind of complicated due to the loose rules defined for simple buildings. Building relations are easier to work with, and I encourage you to use them instead when possible.
Yeah, I swapped the order of the id & info url params for easier pasting of way ids! 😉
...For good or bad, OSM doesn't have a lot of top-down tagging rules. Most of the documentation simply describes how mappers tend to map things, with a lot of refinement & commentary over the years. I find the 3D building docs ambiguous sometimes, and I do my best.
That said, my understanding is: Mapping building parts that extend outside of a building's perimeter is only possible by using a type=building relation. So when rendering a simple polygon building (with a building tag on a closed way) it'd be reasonable to discard a building part unless all the part's nodes are either 1) inside the building or 2) attached to the perimeter. Multipolygon buildings (with a building tag on a type=multipolygon relation) would be similar, with slight complications regarding "inside" and "perimeter."
For my own purposes. btw, this is a feature-style bug -- seeing how a 3D building interacts with its neighbors can be quite helpful. I might even hack it to show more neighbor details. In the mean time, toggling off the extra building parts using the info controls works just fine.
Thinking again, the all-nodes-in-or-on check could still give false negatives when complex buildings abut. What would probably do best is some kind of polygonInPolygon function that would return the percentage of the part that was inside the main building way. Discard anything that scores < .99, leaving a little slack for floating point vagaries. Would nearly always be overkill, but would catch the (literal) edge cases.
#138
The code now discards any building part that is a way, and has no points “within” the main building. It still will include Multipolygon, and way parts which are outside, but share an edge. The next step is to perform the same exclusion on multipolygons. Then, I feel a good compromise to calculating “shared percent area” is to exclude parts which only share edge points, and the center of the part is not inside the main building.
I should also write to the log when these exclusions occur in case there are any false positives.