Beakerboy / OSMBuilding

render an individual OSM building
MIT License
40 stars 5 forks source link

Renders sometimes include building parts from nearby buildings #42

Open jmapb opened 2 months ago

jmapb commented 2 months ago

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.

way 278078955

Beakerboy commented 2 months ago

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.

jmapb commented 2 months ago

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.

jmapb commented 2 months ago

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.