Skip to content

Commit 825f89a

Browse files
authored
Coverage (#107)
1 parent 9fc5414 commit 825f89a

File tree

3 files changed

+114
-81
lines changed

3 files changed

+114
-81
lines changed

src/buildingpart.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,7 @@ class BuildingPart {
283283
const center = BuildingShapeUtils.center(this.shape, angle / 180 * Math.PI);
284284
const options = {
285285
center: center,
286-
angle: angle,
286+
angle: angle / 360 * 2 * Math.PI,
287287
depth: this.options.roof.height,
288288
};
289289
const geometry = new WedgeGeometry(this.shape, options);

src/extras/BuildingShapeUtils.js

Lines changed: 28 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,13 @@ class BuildingShapeUtils extends ShapeUtils {
2323
const elements = way.getElementsByTagName('nd');
2424

2525
// Get the coordinates of all the nodes and add them to the shape outline.
26-
for (let i = 0; i < elements.length; i++) {
27-
ref = elements[i].getAttribute('ref');
26+
let first = true;
27+
for (const element of elements) {
28+
ref = element.getAttribute('ref');
2829
node = nodelist[ref];
29-
// The first node requires a differnet function call.
30-
if (i === 0) {
30+
// Th node requires a differnet function call.
31+
if (first) {
32+
first = false;
3133
shape.moveTo(parseFloat(node[0]), parseFloat(node[1]));
3234
} else {
3335
shape.lineTo(parseFloat(node[0]), parseFloat(node[1]));
@@ -199,10 +201,10 @@ class BuildingShapeUtils extends ShapeUtils {
199201
* @return {DOM.Element} way
200202
*/
201203
static joinWays(way1, way2) {
202-
const elements = way2.getElementsByTagName('nd');
204+
const nodes = way2.getElementsByTagName('nd');
203205
const newWay = way1.cloneNode(true);
204-
for (let i = 1; i < elements.length; i++) {
205-
let elem = elements[i].cloneNode();
206+
for (let i = 1; i < nodes.length; i++) {
207+
let elem = nodes[i].cloneNode();
206208
newWay.appendChild(elem);
207209
}
208210
return newWay;
@@ -268,10 +270,15 @@ class BuildingShapeUtils extends ShapeUtils {
268270
}
269271

270272
/**
271-
* can points be an array of shapes?
273+
* Extract point data from a shape.
274+
* Combine all the x values into one array and
275+
* y values into another
276+
*
277+
* @param {THREE.Shape} shape - the shape
278+
*
279+
* @return {[number], [number]} array of xs and ys.
272280
*/
273281
static combineCoordinates(shape) {
274-
//console.log('Shape: ' + JSON.stringify(shape));
275282
const points = shape.extractPoints().shape;
276283
var x = [];
277284
var y = [];
@@ -292,17 +299,16 @@ class BuildingShapeUtils extends ShapeUtils {
292299
*
293300
* @return {[number, number, number, number]} the extents of the object.
294301
*/
295-
static extents(shape, angle = 0) {
296-
if (!Array.isArray(shape)) {
297-
shape = [shape];
302+
static extents(shapes, angle = 0) {
303+
if (!Array.isArray(shapes)) {
304+
shapes = [shapes];
298305
}
299306
var x = [];
300307
var y = [];
301308
var vec;
302-
for (let i = 0; i < shape.length; i++) {
303-
const points = shape[i].extractPoints().shape;
304-
for (let i = 0; i < points.length; i++) {
305-
vec = points[i];
309+
for (const shape of shapes) {
310+
const points = shape.extractPoints().shape;
311+
for (const vec of points) {
306312
x.push(vec.x * Math.cos(angle) - vec.y * Math.sin(angle));
307313
y.push(vec.x * Math.sin(angle) + vec.y * Math.cos(angle));
308314
}
@@ -314,14 +320,6 @@ class BuildingShapeUtils extends ShapeUtils {
314320
return [left, bottom, right, top];
315321
}
316322

317-
/**
318-
* Assuming the shape is all right angles,
319-
* Find the orientation of the longest edge.
320-
*/
321-
static primaryDirection(shape) {
322-
const points = shape.extractPoints().shape;
323-
}
324-
325323
/**
326324
* Calculate the length of each of a shape's edge
327325
*
@@ -334,14 +332,11 @@ class BuildingShapeUtils extends ShapeUtils {
334332
const lengths = [];
335333
var p1;
336334
var p2;
337-
for (let i = 0; i < points.length - 1; i++) {
335+
for (const i in points) {
338336
p1 = points[i];
339-
p2 = points[i + 1];
337+
p2 = points[(i + 1) % points.length];
340338
lengths.push(Math.sqrt((p1.x - p2.x) ** 2 + (p1.y - p2.y) ** 2));
341339
}
342-
p1 = points[points.length - 1];
343-
p2 = points[0];
344-
lengths.push(Math.sqrt((p1.x - p2.x) ** 2 + (p1.y - p2.y) ** 2));
345340
return lengths;
346341
}
347342

@@ -370,13 +365,8 @@ class BuildingShapeUtils extends ShapeUtils {
370365
return angle;
371366
}
372367

373-
p0 = points[points.length - 1];
374-
p1 = points[0];
375-
p2 = points[1];
376-
377-
angles.push(calcAngle(p0, p1, p2));
378-
for (let i = 1; i < points.length; i++) {
379-
p0 = points[i - 1];
368+
for (const i in points) {
369+
p0 = points[i - 1 < 0 ? points.length - 1 : i - 1];
380370
p1 = points[i];
381371
p2 = points[(i + 1) % points.length];
382372
angles.push(calcAngle(p0, p1, p2));
@@ -394,13 +384,12 @@ class BuildingShapeUtils extends ShapeUtils {
394384
*/
395385
static edgeDirection(shape) {
396386
const points = shape.extractPoints().shape;
397-
points.push(points[0]);
398387
const angles = [];
399388
var p1;
400389
var p2;
401-
for (let i = 0; i < points.length - 1; i++) {
390+
for (const i in points) {
402391
p1 = points[i];
403-
p2 = points[i + 1];
392+
p2 = points[(i + 1) % points.length];
404393
let angle = Math.atan2((p2.y - p1.y), (p2.x - p1.x));
405394
if (angle >= Math.PI) {
406395
angle -= 2 * Math.PI;

test/utils.test.js

Lines changed: 85 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -13,29 +13,42 @@ import { Shape } from 'three';
1313
import { BuildingShapeUtils } from '../src/extras/BuildingShapeUtils.js';
1414
// import { JSDOM } from 'jsdom';
1515

16+
17+
/** Test createShape */
18+
// test('', () => {
19+
//
20+
// });
21+
22+
/** Test isClosed */
1623
test('Test Closed Way', () => {
1724
var way = '<way id="1"><nd ref="2"/><nd ref="3"/><nd ref="4"/><nd ref="5"/><nd ref="2"/></way>';
1825
let parser = new window.DOMParser();
1926
let xmlData = parser.parseFromString(way, 'text/xml');
2027
expect(BuildingShapeUtils.isClosed(xmlData)).toBe(true);
2128
});
2229

23-
test('Reverse way', () => {
24-
var way1 = '<way id="1"><nd ref="1"/><nd ref="2"/><nd ref="3"/></way>';
25-
var way2 = '<way id="1"><nd ref="3"/><nd ref="2"/><nd ref="1"/></way>';
26-
let parser = new window.DOMParser();
27-
let xml1 = parser.parseFromString(way1, 'text/xml').getElementsByTagName('way')[0];
28-
let result = BuildingShapeUtils.reverseWay(xml1);
29-
expect(result.outerHTML).toBe(way2);
30-
});
31-
3230
test('Test Open Way', () => {
3331
var way = '<way id="1"><nd ref="2"/><nd ref="3"/><nd ref="4"/><nd ref="5"/><nd ref="6"/></way>';
3432
let parser = new window.DOMParser();
3533
let xmlData = parser.parseFromString(way, 'text/xml');
3634
expect(BuildingShapeUtils.isClosed(xmlData)).toBe(false);
3735
});
3836

37+
/** Test isSelfIntersecting */
38+
describe.each([
39+
['<way id="1"><nd ref="1"/><nd ref="2"/></way>', false, 'open non-intersecting'],
40+
['<way id="1"><nd ref="1"/><nd ref="2"/><nd ref="3"/><nd ref="1"/></way>', false, 'closed non-intersecting'],
41+
['<way id="1"><nd ref="1"/><nd ref="2"/><nd ref="3"/><nd ref="2"/></way>', true, 'open intersecting'],
42+
['<way id="1"><nd ref="1"/><nd ref="2"/><nd ref="3"/><nd ref="4"/><nd ref="3"/><nd ref="1"/></way>', true, 'closed intersecting'],
43+
])('isSelfIntersecting', (way, expected, description) => {
44+
test(`${description}`, () => {
45+
let parser = new window.DOMParser();
46+
let xml = parser.parseFromString(way, 'text/xml').getElementsByTagName('way')[0];
47+
expect(BuildingShapeUtils.isSelfIntersecting(xml)).toBe(expected);
48+
});
49+
});
50+
51+
/** Test joinWays */
3952
test('Test joining 2 ways', () => {
4053
var way1 = '<way id="1"><nd ref="1"/><nd ref="2"/><nd ref="3"/></way>';
4154
var way2 = '<way id="2"><nd ref="3"/><nd ref="4"/><nd ref="1"/></way>';
@@ -47,6 +60,44 @@ test('Test joining 2 ways', () => {
4760
expect(result.outerHTML).toBe(way3);
4861
});
4962

63+
/** Test joinAllWays */
64+
test('Test joining 2 ways', () => {
65+
var way1 = '<way id="1"><nd ref="1"/><nd ref="2"/><nd ref="3"/></way>';
66+
var way2 = '<way id="2"><nd ref="3"/><nd ref="4"/><nd ref="1"/></way>';
67+
var way3 = '<way id="1"><nd ref="1"/><nd ref="2"/><nd ref="3"/><nd ref="4"/><nd ref="1"/></way>';
68+
let parser = new window.DOMParser();
69+
let xml1 = parser.parseFromString(way1, 'text/xml').getElementsByTagName('way')[0];
70+
let xml2 = parser.parseFromString(way2, 'text/xml').getElementsByTagName('way')[0];
71+
let result = BuildingShapeUtils.joinAllWays([xml1, xml2]);
72+
expect(result.outerHTML).toBe(way3);
73+
});
74+
75+
/** Test reverseWay */
76+
test('Reverse way', () => {
77+
var way1 = '<way id="1"><nd ref="1"/><nd ref="2"/><nd ref="3"/></way>';
78+
var way2 = '<way id="1"><nd ref="3"/><nd ref="2"/><nd ref="1"/></way>';
79+
let parser = new window.DOMParser();
80+
let xml1 = parser.parseFromString(way1, 'text/xml').getElementsByTagName('way')[0];
81+
let result = BuildingShapeUtils.reverseWay(xml1);
82+
expect(result.outerHTML).toBe(way2);
83+
});
84+
85+
/** Test center */
86+
test('Center', () => {
87+
expect(BuildingShapeUtils.center(rightTriangle)).toStrictEqual([0, 0]);
88+
});
89+
90+
/** Test getWidth */
91+
test('Get Width', () => {
92+
expect(BuildingShapeUtils.getWidth(rightTriangle)).toBe(2);
93+
});
94+
95+
/** Test combineCoordinates */
96+
test('Combine Coordinates', () => {
97+
expect(BuildingShapeUtils.combineCoordinates(rightTriangle)).toStrictEqual([[1, 1, -1], [1, -1, 1]]);
98+
});
99+
100+
/** Test extents */
50101
const rightTriangle = new Shape();
51102
rightTriangle.moveTo(1, 1);
52103
rightTriangle.lineTo(1, -1);
@@ -67,51 +118,31 @@ test('Extents Rotation', () => {
67118
expect(BuildingShapeUtils.extents(rightTriangle, angle)).toBeDeepCloseTo([-sqrt2, 0, sqrt2, sqrt2], 10);
68119
});
69120

121+
/** Test edgeLength */
70122
test('Edge Lengths', () => {
71123
expect(BuildingShapeUtils.edgeLength(rightTriangle)).toBeDeepCloseTo([2, Math.sqrt(2) * 2, 2]);
72124
});
73125

74-
test('Edge Direction', () => {
75-
expect(BuildingShapeUtils.edgeDirection(rightTriangle)).toBeDeepCloseTo([-Math.PI / 2, 3 * Math.PI / 4, 0]);
76-
});
77-
78-
test('Edge Direction2', () => {
79-
expect(BuildingShapeUtils.edgeDirection(rightTriangle2)).toBeDeepCloseTo([-Math.PI, -Math.PI / 4, Math.PI / 2]);
126+
/** Test vertexAngle */
127+
test('Vertex Angles', () => {
128+
expect(BuildingShapeUtils.vertexAngle(rightTriangle)).toStrictEqual([Math.PI / 2, Math.PI / 4, Math.PI / 4]);
80129
});
81130

82-
test('Longest side angle', () => {
83-
expect(BuildingShapeUtils.longestSideAngle(rightTriangle)).toBe(3 * Math.PI / 4);
131+
test('Vertex Angles counterclockwise', () => {
132+
expect(BuildingShapeUtils.vertexAngle(rightTriangle2)).toStrictEqual([-Math.PI / 2, -Math.PI / 4, -Math.PI / 4]);
84133
});
85134

135+
/** Test edgeDirection */
86136
describe.each([
87-
['<way id="1"><nd ref="1"/><nd ref="2"/></way>', false, 'open non-intersecting'],
88-
['<way id="1"><nd ref="1"/><nd ref="2"/><nd ref="3"/><nd ref="1"/></way>', false, 'closed non-intersecting'],
89-
['<way id="1"><nd ref="1"/><nd ref="2"/><nd ref="3"/><nd ref="2"/></way>', true, 'open intersecting'],
90-
['<way id="1"><nd ref="1"/><nd ref="2"/><nd ref="3"/><nd ref="4"/><nd ref="3"/><nd ref="1"/></way>', true, 'closed intersecting'],
91-
])('isSelfIntersecting', (way, expected, description) => {
137+
[rightTriangle, [-Math.PI / 2, 3 * Math.PI / 4, 0], 'CW'],
138+
[rightTriangle2, [-Math.PI, -Math.PI / 4, Math.PI / 2], 'CCW'],
139+
])('Edge Direction', (shape, expected, description) =>{
92140
test(`${description}`, () => {
93-
let parser = new window.DOMParser();
94-
let xml = parser.parseFromString(way, 'text/xml').getElementsByTagName('way')[0];
95-
expect(BuildingShapeUtils.isSelfIntersecting(xml)).toBe(expected);
141+
expect(BuildingShapeUtils.edgeDirection(shape)).toBeDeepCloseTo(expected);
96142
});
97143
});
98144

99-
test('Center', () => {
100-
expect(BuildingShapeUtils.center(rightTriangle)).toStrictEqual([0, 0]);
101-
});
102-
103-
test('Get Width', () => {
104-
expect(BuildingShapeUtils.getWidth(rightTriangle)).toBe(2);
105-
});
106-
107-
test('Vertex Angles', () => {
108-
expect(BuildingShapeUtils.vertexAngle(rightTriangle)).toStrictEqual([Math.PI / 2, Math.PI / 4, Math.PI / 4]);
109-
});
110-
111-
test('Vertex Angles counterclockwise', () => {
112-
expect(BuildingShapeUtils.vertexAngle(rightTriangle2)).toStrictEqual([-Math.PI / 2, -Math.PI / 4, -Math.PI / 4]);
113-
});
114-
145+
/** Test surrounds */
115146
describe.each([
116147
[[-1, -1], false, 'Outside'],
117148
[[1, 1], true, 'Share Node'],
@@ -123,7 +154,20 @@ describe.each([
123154
});
124155
});
125156

157+
/** Test calculateRadius */
126158
test('Calculate Radius', () => {
127159
expect(BuildingShapeUtils.calculateRadius(rightTriangle)).toBe(1);
128160
});
129161

162+
/** Test longestSideAngle */
163+
test('Longest side angle', () => {
164+
expect(BuildingShapeUtils.longestSideAngle(rightTriangle)).toBe(3 * Math.PI / 4);
165+
});
166+
167+
/** Test repositionPoint */
168+
test('Reposition Point', () => {
169+
const point = [11.0155721, 49.583313];
170+
const home = [11.015512, 49.5833659];
171+
const expected = [4.332747472234555, -5.882209888874915];
172+
expect(BuildingShapeUtils.repositionPoint(point, home)).toStrictEqual(expected);
173+
});

0 commit comments

Comments
 (0)