|
1 | 1 | import test from "tape";
|
2 |
| -import path from "path"; |
3 |
| -import { fileURLToPath } from "url"; |
4 |
| -import { glob } from "glob"; |
5 |
| -import { loadJsonFileSync } from "load-json-file"; |
6 |
| -import { writeJsonFileSync } from "write-json-file"; |
7 |
| -import { sector } from "@turf/sector"; |
8 |
| -import { bearing } from "@turf/bearing"; |
9 |
| -import { truncate } from "@turf/truncate"; |
10 |
| -import { distance } from "@turf/distance"; |
11 |
| -import { point, round, lineString, featureCollection } from "@turf/helpers"; |
| 2 | +import { point, round } from "@turf/helpers"; |
12 | 3 | import { angle } from "./index.js";
|
13 | 4 |
|
14 |
| -const __dirname = path.dirname(fileURLToPath(import.meta.url)); |
15 |
| - |
16 |
| -test("turf-angle", (t) => { |
17 |
| - glob |
18 |
| - .sync(path.join(__dirname, "test", "in", "*.json")) |
19 |
| - .forEach((filepath) => { |
20 |
| - // Input |
21 |
| - const { name } = path.parse(filepath); |
22 |
| - const geojson = loadJsonFileSync(filepath); |
23 |
| - const [start, mid, end] = geojson.features; |
24 |
| - |
25 |
| - // Results |
26 |
| - const angleProperties = { |
27 |
| - interiorAngle: round(angle(start, mid, end), 6), |
28 |
| - interiorMercatorAngle: round( |
29 |
| - angle(start, mid, end, { mercator: true }), |
30 |
| - 6 |
31 |
| - ), |
32 |
| - explementary: false, |
33 |
| - fill: "#F00", |
34 |
| - stroke: "#F00", |
35 |
| - "fill-opacity": 0.3, |
36 |
| - }; |
37 |
| - const angleExplementaryProperties = { |
38 |
| - explementaryAngle: round( |
39 |
| - angle(start, mid, end, { explementary: true }), |
40 |
| - 6 |
41 |
| - ), |
42 |
| - explementaryMercatorAngle: round( |
43 |
| - angle(start, mid, end, { explementary: true, mercator: true }), |
44 |
| - 6 |
45 |
| - ), |
| 5 | +test("turf-angle -- across 0 bearing", (t) => { |
| 6 | + t.equal(round(angle([-1, 1], [0, 0], [1, 1])), 90, "90 degrees"); |
| 7 | + |
| 8 | + t.end(); |
| 9 | +}); |
| 10 | + |
| 11 | +test("turf-angle -- 90 degrees", (t) => { |
| 12 | + t.equal( |
| 13 | + round(angle([124, -17], [124, -22], [131, -22]), 6), |
| 14 | + 91.312527, |
| 15 | + "91.312527 degrees" |
| 16 | + ); |
| 17 | + t.equal( |
| 18 | + round(angle([124, -17], [124, -22], [131, -22], { explementary: true }), 6), |
| 19 | + 268.687473, |
| 20 | + "268.687473 degrees explementary" |
| 21 | + ); |
| 22 | + t.equal( |
| 23 | + round(angle([124, -17], [124, -22], [131, -22], { mercator: true }), 6), |
| 24 | + 90, |
| 25 | + "90 degrees mercator" |
| 26 | + ); |
| 27 | + t.equal( |
| 28 | + round( |
| 29 | + angle([124, -17], [124, -22], [131, -22], { |
| 30 | + explementary: true, |
| 31 | + mercator: true, |
| 32 | + }), |
| 33 | + 6 |
| 34 | + ), |
| 35 | + 270, |
| 36 | + "270 degrees explementary mercator" |
| 37 | + ); |
| 38 | + t.end(); |
| 39 | +}); |
| 40 | + |
| 41 | +test("turf-angle -- 180 degrees", (t) => { |
| 42 | + t.equal(round(angle([3, -1], [2, 0], [1, 1]), 6), 180, "180 degrees"); |
| 43 | + |
| 44 | + t.end(); |
| 45 | +}); |
| 46 | + |
| 47 | +test("turf-angle -- obtuse", (t) => { |
| 48 | + t.equal( |
| 49 | + round(angle([48.5, 5.5], [51.5, 12], [59, 15.5]), 6), |
| 50 | + 218.715175, |
| 51 | + "218.715175 degrees" |
| 52 | + ); |
| 53 | + t.equal( |
| 54 | + round( |
| 55 | + angle([48.5, 5.5], [51.5, 12], [59, 15.5], { explementary: true }), |
| 56 | + 6 |
| 57 | + ), |
| 58 | + 141.284825, |
| 59 | + "141.284825 degrees explementary" |
| 60 | + ); |
| 61 | + t.equal( |
| 62 | + round(angle([48.5, 5.5], [51.5, 12], [59, 15.5], { mercator: true }), 6), |
| 63 | + 219.826106, |
| 64 | + "219.826106 degrees mercator" |
| 65 | + ); |
| 66 | + t.equal( |
| 67 | + round( |
| 68 | + angle([48.5, 5.5], [51.5, 12], [59, 15.5], { |
| 69 | + explementary: true, |
| 70 | + mercator: true, |
| 71 | + }), |
| 72 | + 6 |
| 73 | + ), |
| 74 | + 140.173894, |
| 75 | + "140.173894 degrees explementary mercator" |
| 76 | + ); |
| 77 | + t.end(); |
| 78 | +}); |
| 79 | + |
| 80 | +test("turf-angle -- obtuse bigger", (t) => { |
| 81 | + t.equal( |
| 82 | + round(angle([48.5, 5.5], [51.5, 12], [46.5, 19]), 6), |
| 83 | + 121.330117, |
| 84 | + "121.330117 degrees" |
| 85 | + ); |
| 86 | + t.equal( |
| 87 | + round( |
| 88 | + angle([48.5, 5.5], [51.5, 12], [46.5, 19], { explementary: true }), |
| 89 | + 6 |
| 90 | + ), |
| 91 | + 238.669883, |
| 92 | + "238.669883 degrees explementary" |
| 93 | + ); |
| 94 | + t.equal( |
| 95 | + round(angle([48.5, 5.5], [51.5, 12], [46.5, 19], { mercator: true }), 6), |
| 96 | + 120.970546, |
| 97 | + "120.970546" |
| 98 | + ); |
| 99 | + t.equal( |
| 100 | + round( |
| 101 | + angle([48.5, 5.5], [51.5, 12], [46.5, 19], { |
| 102 | + explementary: true, |
| 103 | + mercator: true, |
| 104 | + }), |
| 105 | + 6 |
| 106 | + ), |
| 107 | + 239.029454, |
| 108 | + "239.029454 degrees explementary mercator" |
| 109 | + ); |
| 110 | + t.end(); |
| 111 | +}); |
| 112 | + |
| 113 | +test("turf-angle -- acute", (t) => { |
| 114 | + t.equal( |
| 115 | + round(angle([48.5, 5.5], [51.5, 12], [44.5, 10.5]), 6), |
| 116 | + 53.608314, |
| 117 | + "53.608314 degrees" |
| 118 | + ); |
| 119 | + t.equal( |
| 120 | + round( |
| 121 | + angle([48.5, 5.5], [51.5, 12], [44.5, 10.5], { explementary: true }), |
| 122 | + 6 |
| 123 | + ), |
| 124 | + 306.391686, |
| 125 | + "306.391686 degrees explementary" |
| 126 | + ); |
| 127 | + t.equal( |
| 128 | + round(angle([48.5, 5.5], [51.5, 12], [44.5, 10.5], { mercator: true }), 6), |
| 129 | + 53.166357, |
| 130 | + "53.166357 degrees mercator" |
| 131 | + ); |
| 132 | + t.equal( |
| 133 | + round( |
| 134 | + angle([48.5, 5.5], [51.5, 12], [44.5, 10.5], { |
46 | 135 | explementary: true,
|
47 |
| - fill: "#00F", |
48 |
| - stroke: "#00F", |
49 |
| - "fill-opacity": 0.3, |
50 |
| - }; |
51 |
| - const results = featureCollection([ |
52 |
| - truncate( |
53 |
| - sector( |
54 |
| - mid, |
55 |
| - distance(mid, start) / 3, |
56 |
| - bearing(mid, start), |
57 |
| - bearing(mid, end), |
58 |
| - { properties: angleProperties } |
59 |
| - ) |
60 |
| - ), |
61 |
| - truncate( |
62 |
| - sector( |
63 |
| - mid, |
64 |
| - distance(mid, start) / 2, |
65 |
| - bearing(mid, end), |
66 |
| - bearing(mid, start), |
67 |
| - { properties: angleExplementaryProperties } |
68 |
| - ) |
69 |
| - ), |
70 |
| - lineString( |
71 |
| - [ |
72 |
| - start.geometry.coordinates, |
73 |
| - mid.geometry.coordinates, |
74 |
| - end.geometry.coordinates, |
75 |
| - ], |
76 |
| - { "stroke-width": 4, stroke: "#222" } |
77 |
| - ), |
78 |
| - start, |
79 |
| - mid, |
80 |
| - end, |
81 |
| - ]); |
82 |
| - |
83 |
| - // Save results |
84 |
| - const expected = filepath.replace( |
85 |
| - path.join("test", "in"), |
86 |
| - path.join("test", "out") |
87 |
| - ); |
88 |
| - if (process.env.REGEN) writeJsonFileSync(expected, results); |
89 |
| - t.deepEqual(results, loadJsonFileSync(expected), name); |
90 |
| - }); |
| 136 | + mercator: true, |
| 137 | + }), |
| 138 | + 6 |
| 139 | + ), |
| 140 | + 306.833643, |
| 141 | + "306.833643 degrees explementary mercator" |
| 142 | + ); |
| 143 | + t.end(); |
| 144 | +}); |
| 145 | + |
| 146 | +test("turf-angle -- acute inverse", (t) => { |
| 147 | + t.equal( |
| 148 | + round(angle([44.5, 10.5], [51.5, 12], [48.5, 5.5]), 6), |
| 149 | + 306.391686, |
| 150 | + "306.391686 degrees" |
| 151 | + ); |
| 152 | + t.equal( |
| 153 | + round( |
| 154 | + angle([44.5, 10.5], [51.5, 12], [48.5, 5.5], { explementary: true }), |
| 155 | + 6 |
| 156 | + ), |
| 157 | + 53.608314, |
| 158 | + "53.608314 degrees explementary" |
| 159 | + ); |
| 160 | + t.equal( |
| 161 | + round(angle([44.5, 10.5], [51.5, 12], [48.5, 5.5], { mercator: true }), 6), |
| 162 | + 306.833643, |
| 163 | + "306.833643 degrees mercator" |
| 164 | + ); |
| 165 | + t.equal( |
| 166 | + round( |
| 167 | + angle([44.5, 10.5], [51.5, 12], [48.5, 5.5], { |
| 168 | + explementary: true, |
| 169 | + mercator: true, |
| 170 | + }), |
| 171 | + 6 |
| 172 | + ), |
| 173 | + 53.166357, |
| 174 | + "53.166357 degrees explementary mercator" |
| 175 | + ); |
91 | 176 | t.end();
|
92 | 177 | });
|
93 | 178 |
|
94 | 179 | test("turf-angle -- simple", (t) => {
|
95 | 180 | t.equal(round(angle([5, 5], [5, 6], [3, 4])), 45, "45 degrees");
|
96 |
| - t.equal(round(angle([3, 4], [5, 6], [5, 5])), 45, "45 degrees -- inverse"); |
| 181 | + t.equal(round(angle([3, 4], [5, 6], [5, 5])), 315, "315 degrees -- inverse"); |
97 | 182 | t.equal(
|
98 |
| - round(angle([3, 4], [5, 6], [5, 5], { explementary: true })), |
| 183 | + round(angle([5, 5], [5, 6], [3, 4], { explementary: true })), |
99 | 184 | 360 - 45,
|
100 | 185 | "explementary angle"
|
101 | 186 | );
|
@@ -139,3 +224,19 @@ test("turf-angle -- throws", (t) => {
|
139 | 224 |
|
140 | 225 | t.end();
|
141 | 226 | });
|
| 227 | + |
| 228 | +test("turf-angle -- 2703", (t) => { |
| 229 | + const start = [0, 1]; |
| 230 | + const mid = [0, 0]; |
| 231 | + const end = [1, 0]; |
| 232 | + const a = angle(start, mid, end); |
| 233 | + t.equal(a, 90, "90 clockwise"); |
| 234 | + |
| 235 | + const start2 = [0, 1]; |
| 236 | + const mid2 = [0, 0]; |
| 237 | + const end2 = [-1, 0]; |
| 238 | + const a2 = angle(start2, mid2, end2); |
| 239 | + t.equal(a2, 270, "270 clockwise"); |
| 240 | + |
| 241 | + t.end(); |
| 242 | +}); |
0 commit comments