Skip to content

Commit d27519e

Browse files
authored
Do not include any part for which no points are within the main building (#138)
1 parent 84b619d commit d27519e

File tree

4 files changed

+56
-6
lines changed

4 files changed

+56
-6
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,13 @@ Roof Types:
3333
* Dome
3434
* Pyramidal
3535
* Gabled
36+
* Hipped
3637

3738
Examples:
3839
* Simple building with no parts - [Washington Monument](https://beakerboy.github.io/OSMBuilding/index.html?id=766761337)
3940
* Glass - [Petronas Towers](https://beakerboy.github.io/OSMBuilding/index.html?id=279944536)
4041
* Dome roof, Gabled roof, and Skillion ramp - [Jefferson Memorial](https://beakerboy.github.io/OSMBuilding/index.html?type=relation&id=3461570)
41-
* Dome, Gabled, and Pyramidal Roof - [US Capitol](https://beakerboy.github.io/OSMBuilding/index.html?type=relation&id=12286916)
42+
* Dome, Gabled, Hipped, and Pyramidal Roof - [US Capitol](https://beakerboy.github.io/OSMBuilding/index.html?type=relation&id=12286916)
4243
* [Chrysler Building](https://beakerboy.github.io/OSMBuilding/index.html?id=42500770)
4344
* Building Relation [Burj Khalifa](https://beakerboy.github.io/OSMBuilding/index.html?type=relation&id=7584462)
4445
* Multipolygon with no parts - [Freer Art Gallery](https://beakerboy.github.io/OSMBuilding/index.html?type=relation&id=1029355)

src/building.js

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -206,10 +206,13 @@ class Building {
206206
} else {
207207
// Filter to all ways
208208
var parts = this.fullXmlData.getElementsByTagName('way');
209-
for (let j = 0; j < parts.length; j++) {
210-
if (parts[j].querySelector('[k="building:part"]')) {
211-
const id = parts[j].getAttribute('id');
212-
this.parts.push(new BuildingPart(id, this.fullXmlData, this.nodelist, this.outerElement.options));
209+
for (const xmlPart of parts) {
210+
if (xmlPart.querySelector('[k="building:part"]')) {
211+
const id = xmlPart.getAttribute('id');
212+
const part = new BuildingPart(id, this.fullXmlData, this.nodelist, this.outerElement.options);
213+
if (this.partIsInside(part)) {
214+
this.parts.push(part);
215+
}
213216
}
214217
}
215218
// Filter all relations
@@ -408,5 +411,22 @@ class Building {
408411
}
409412
}
410413
}
414+
415+
/**
416+
* Check if any point in a part is within this building's outline.
417+
* It only checknof points are inside, not if crossing events occur, or
418+
* if the part completly surrounds the building.
419+
* @param {BuildingPart} part - the part to be tested
420+
* @returns {bool} is it?
421+
*/
422+
partIsInside(part) {
423+
const shape = part.shape;
424+
for (const vector of shape.extractPoints().shape) {
425+
if (BuildingShapeUtils.surrounds(this.outerElement.shape, [vector.x, vector.y])) {
426+
return true;
427+
}
428+
}
429+
return false;
430+
}
411431
}
412432
export {Building};

src/extras/BuildingShapeUtils.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ class BuildingShapeUtils extends ShapeUtils {
2424
const elements = way.getElementsByTagName('nd');
2525

2626
// Get the coordinates of all the nodes and add them to the shape outline.
27-
2827
for (const element of elements) {
2928
ref = element.getAttribute('ref');
3029
nodes.push(nodelist[ref]);

test/building.test.js

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,36 @@ test('Test downloading type=building with multipolygon outline and multiple inne
315315
expect(global.fetch.mock.calls[2][0]).toBe(urlBase + 'map?bbox=30.4980057,59.9380365,30.4993839,59.9385087');
316316
});
317317

318+
test('Part must be within outline', () => {
319+
const data = `<?xml version="1.0" encoding="UTF-8"?>
320+
<osm>
321+
<node id="1" lat="0.001" lon="0.001"/>
322+
<node id="2" lat="0.001" lon="0"/>
323+
<node id="3" lat="0" lon="0"/>
324+
<node id="4" lat="0" lon=".0005"/>
325+
<node id="5" lat="0" lon=".001"/>
326+
<node id="6" lat=".0001" lon=".001"/>
327+
<node id="7" lat=".0001" lon="0.005"/>
328+
<way id="11">
329+
<nd ref="1"/>
330+
<nd ref="2"/>
331+
<nd ref="3"/>
332+
<nd ref="1"/>
333+
<tag k="building" v="apartments"/>
334+
</way>
335+
<way id="22">
336+
<nd ref="4"/>
337+
<nd ref="5"/>
338+
<nd ref="6"/>
339+
<nd ref="7"/>
340+
<nd ref="4"/>
341+
<tag k="building:part" v="yes"/>
342+
</way>
343+
</osm>
344+
`;
345+
expect(new Building('11', data).parts.length).toBe(0);
346+
});
347+
318348
window.printError = printError;
319349

320350
var errors = [];

0 commit comments

Comments
 (0)