Skip to content

Commit 460afb5

Browse files
authored
check count members with role=outline (#148)
1 parent bbeba91 commit 460afb5

File tree

2 files changed

+150
-1
lines changed

2 files changed

+150
-1
lines changed

src/building.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,14 @@ class Building {
107107
} else if (this.type === 'multipolygon') {
108108
this.outerElement = new MultiBuildingPart(id, this.fullXmlData, this.nodelist);
109109
} else {
110-
const outlineRef = outerElementXml.querySelector('member[role="outline"]').getAttribute('ref');
110+
const outlines = outerElementXml.querySelectorAll('member[role="outline"]');
111+
if (outlines.length > 1) {
112+
throw new Error(`Found multiple outline members in relation ${this.id}`);
113+
}
114+
if (outlines.length === 0) {
115+
throw new Error(`The relation ${this.id} does not contain a member with the outline role`);
116+
}
117+
const outlineRef = outlines[0].getAttribute('ref');
111118
const outline = this.fullXmlData.getElementById(outlineRef);
112119
const outlineType = outline.tagName.toLowerCase();
113120
if (outlineType === 'way') {

test/building.test.js

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,148 @@ 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+
const typeBuildingWithoutOutlineMember = `<?xml version='1.0' encoding='UTF-8'?>
319+
<osm version="0.6">
320+
<node id="1" lat="59.938127" lon="30.4980057"/>
321+
<node id="2" lat="59.9380365" lon="30.4992843"/>
322+
<node id="3" lat="59.9384134" lon="30.4993839"/>
323+
<node id="4" lat="59.9385087" lon="30.4981066"/>
324+
<node id="5" lat="59.9381203" lon="30.4989364"/>
325+
<node id="6" lat="59.93838" lon="30.499005"/>
326+
<node id="7" lat="59.9384221" lon="30.498439"/>
327+
<node id="8" lat="59.9381551" lon="30.4983684"/>
328+
<way id="20">
329+
<nd ref="4"/>
330+
<nd ref="3"/>
331+
<nd ref="2"/>
332+
<nd ref="1"/>
333+
</way>
334+
<way id="21">
335+
<nd ref="1"/>
336+
<nd ref="4"/>
337+
</way>
338+
<way id="22">
339+
<nd ref="6"/>
340+
<nd ref="7"/>
341+
</way>
342+
<way id="23">
343+
<nd ref="5"/>
344+
<nd ref="6"/>
345+
</way>
346+
<way id="24">
347+
<nd ref="8"/>
348+
<nd ref="5"/>
349+
</way>
350+
<way id="25">
351+
<nd ref="7"/>
352+
<nd ref="8"/>
353+
</way>
354+
<relation id="40">
355+
<member type="way" ref="20" role="outer"/>
356+
<member type="way" ref="21" role="outer"/>
357+
<member type="way" ref="22" role="inner"/>
358+
<member type="way" ref="23" role="inner"/>
359+
<member type="way" ref="24" role="inner"/>
360+
<member type="way" ref="25" role="inner"/>
361+
<tag k="building" v="school"/>
362+
<tag k="building:levels" v="3"/>
363+
<tag k="roof:shape" v="flat"/>
364+
<tag k="type" v="multipolygon"/>
365+
</relation>
366+
<relation id="42">
367+
<member type="relation" ref="40" role="part"/>
368+
<tag k="type" v="building"/>
369+
</relation>
370+
</osm>
371+
`;
372+
373+
test('Test outline member exist', async() => {
374+
fetch.mockResponses(
375+
[typeBuildingRelationFullResponse], // /relation/42/full
376+
[outlineRelationFullResponse], // /relation/40/full
377+
[typeBuildingWithoutOutlineMember], // /map call
378+
);
379+
const innerData = await Building.downloadDataAroundBuilding('relation', '42');
380+
expect(() => new Building('42', innerData))
381+
.toThrow(new Error('The relation 42 does not contain a member with the outline role'));
382+
const urlBase = 'https://api.openstreetmap.org/api/0.6/';
383+
expect(global.fetch.mock.calls[0][0]).toBe(urlBase + 'relation/42/full');
384+
expect(global.fetch.mock.calls[1][0]).toBe(urlBase + 'relation/40/full');
385+
expect(global.fetch.mock.calls[2][0]).toBe(urlBase + 'map?bbox=30.4980057,59.9380365,30.4993839,59.9385087');
386+
});
387+
388+
const typeBuildingWithMultipleOutlineMembers = `<?xml version='1.0' encoding='UTF-8'?>
389+
<osm version="0.6">
390+
<node id="1" lat="59.938127" lon="30.4980057"/>
391+
<node id="2" lat="59.9380365" lon="30.4992843"/>
392+
<node id="3" lat="59.9384134" lon="30.4993839"/>
393+
<node id="4" lat="59.9385087" lon="30.4981066"/>
394+
<node id="5" lat="59.9381203" lon="30.4989364"/>
395+
<node id="6" lat="59.93838" lon="30.499005"/>
396+
<node id="7" lat="59.9384221" lon="30.498439"/>
397+
<node id="8" lat="59.9381551" lon="30.4983684"/>
398+
<way id="20">
399+
<nd ref="4"/>
400+
<nd ref="3"/>
401+
<nd ref="2"/>
402+
<nd ref="1"/>
403+
</way>
404+
<way id="21">
405+
<nd ref="1"/>
406+
<nd ref="4"/>
407+
</way>
408+
<way id="22">
409+
<nd ref="6"/>
410+
<nd ref="7"/>
411+
</way>
412+
<way id="23">
413+
<nd ref="5"/>
414+
<nd ref="6"/>
415+
</way>
416+
<way id="24">
417+
<nd ref="8"/>
418+
<nd ref="5"/>
419+
</way>
420+
<way id="25">
421+
<nd ref="7"/>
422+
<nd ref="8"/>
423+
</way>
424+
<relation id="40">
425+
<member type="way" ref="20" role="outer"/>
426+
<member type="way" ref="21" role="outer"/>
427+
<member type="way" ref="22" role="inner"/>
428+
<member type="way" ref="23" role="inner"/>
429+
<member type="way" ref="24" role="inner"/>
430+
<member type="way" ref="25" role="inner"/>
431+
<tag k="building" v="school"/>
432+
<tag k="building:levels" v="3"/>
433+
<tag k="roof:shape" v="flat"/>
434+
<tag k="type" v="multipolygon"/>
435+
</relation>
436+
<relation id="42">
437+
<member type="relation" ref="40" role="outline"/>
438+
<member type="relation" ref="50" role="outline"/>
439+
<tag k="type" v="building"/>
440+
</relation>
441+
</osm>
442+
`;
443+
444+
test('Test that it is checked that there is only one member with outline role', async() => {
445+
fetch.mockResponses(
446+
[typeBuildingRelationFullResponse], // /relation/42/full
447+
[outlineRelationFullResponse], // /relation/40/full
448+
[typeBuildingWithMultipleOutlineMembers], // /map call
449+
);
450+
const innerData = await Building.downloadDataAroundBuilding('relation', '42');
451+
expect(() => new Building('42', innerData))
452+
.toThrow(new Error('Found multiple outline members in relation 42'));
453+
const urlBase = 'https://api.openstreetmap.org/api/0.6/';
454+
expect(global.fetch.mock.calls[0][0]).toBe(urlBase + 'relation/42/full');
455+
expect(global.fetch.mock.calls[1][0]).toBe(urlBase + 'relation/40/full');
456+
expect(global.fetch.mock.calls[2][0]).toBe(urlBase + 'map?bbox=30.4980057,59.9380365,30.4993839,59.9385087');
457+
});
458+
459+
318460
test('Part must be within outline', () => {
319461
const data = `<?xml version="1.0" encoding="UTF-8"?>
320462
<osm>

0 commit comments

Comments
 (0)