Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,13 @@ Roof Types:
* Dome
* Pyramidal
* Gabled
* Hipped

Examples:
* Simple building with no parts - [Washington Monument](https://beakerboy.github.io/OSMBuilding/index.html?id=766761337)
* Glass - [Petronas Towers](https://beakerboy.github.io/OSMBuilding/index.html?id=279944536)
* Dome roof, Gabled roof, and Skillion ramp - [Jefferson Memorial](https://beakerboy.github.io/OSMBuilding/index.html?type=relation&id=3461570)
* Dome, Gabled, and Pyramidal Roof - [US Capitol](https://beakerboy.github.io/OSMBuilding/index.html?type=relation&id=12286916)
* Dome, Gabled, Hipped, and Pyramidal Roof - [US Capitol](https://beakerboy.github.io/OSMBuilding/index.html?type=relation&id=12286916)
* [Chrysler Building](https://beakerboy.github.io/OSMBuilding/index.html?id=42500770)
* Building Relation [Burj Khalifa](https://beakerboy.github.io/OSMBuilding/index.html?type=relation&id=7584462)
* Multipolygon with no parts - [Freer Art Gallery](https://beakerboy.github.io/OSMBuilding/index.html?type=relation&id=1029355)
Expand Down
28 changes: 24 additions & 4 deletions src/building.js
Original file line number Diff line number Diff line change
Expand Up @@ -206,10 +206,13 @@ class Building {
} else {
// Filter to all ways
var parts = this.fullXmlData.getElementsByTagName('way');
for (let j = 0; j < parts.length; j++) {
if (parts[j].querySelector('[k="building:part"]')) {
const id = parts[j].getAttribute('id');
this.parts.push(new BuildingPart(id, this.fullXmlData, this.nodelist, this.outerElement.options));
for (const xmlPart of parts) {
if (xmlPart.querySelector('[k="building:part"]')) {
const id = xmlPart.getAttribute('id');
const part = new BuildingPart(id, this.fullXmlData, this.nodelist, this.outerElement.options);
if (this.partIsInside(part)) {
this.parts.push(part);
}
}
}
// Filter all relations
Expand Down Expand Up @@ -408,5 +411,22 @@ class Building {
}
}
}

/**
* Check if any point in a part is within this building's outline.
* It only checknof points are inside, not if crossing events occur, or
* if the part completly surrounds the building.
* @param {BuildingPart} part - the part to be tested
* @returns {bool} is it?
*/
partIsInside(part) {
const shape = part.shape;
for (const vector of shape.extractPoints().shape) {
if (BuildingShapeUtils.surrounds(this.outerElement.shape, [vector.x, vector.y])) {
return true;
}
}
return false;
}
}
export {Building};
1 change: 0 additions & 1 deletion src/extras/BuildingShapeUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ class BuildingShapeUtils extends ShapeUtils {
const elements = way.getElementsByTagName('nd');

// Get the coordinates of all the nodes and add them to the shape outline.

for (const element of elements) {
ref = element.getAttribute('ref');
nodes.push(nodelist[ref]);
Expand Down
30 changes: 30 additions & 0 deletions test/building.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,36 @@ test('Test downloading type=building with multipolygon outline and multiple inne
expect(global.fetch.mock.calls[2][0]).toBe(urlBase + 'map?bbox=30.4980057,59.9380365,30.4993839,59.9385087');
});

test('Part must be within outline', () => {
const data = `<?xml version="1.0" encoding="UTF-8"?>
<osm>
<node id="1" lat="0.001" lon="0.001"/>
<node id="2" lat="0.001" lon="0"/>
<node id="3" lat="0" lon="0"/>
<node id="4" lat="0" lon=".0005"/>
<node id="5" lat="0" lon=".001"/>
<node id="6" lat=".0001" lon=".001"/>
<node id="7" lat=".0001" lon="0.005"/>
<way id="11">
<nd ref="1"/>
<nd ref="2"/>
<nd ref="3"/>
<nd ref="1"/>
<tag k="building" v="apartments"/>
</way>
<way id="22">
<nd ref="4"/>
<nd ref="5"/>
<nd ref="6"/>
<nd ref="7"/>
<nd ref="4"/>
<tag k="building:part" v="yes"/>
</way>
</osm>
`;
expect(new Building('11', data).parts.length).toBe(0);
});

window.printError = printError;

var errors = [];
Expand Down