Skip to content

Commit

Permalink
Merge branch 'Turfjs:master' into random-poly-fix
Browse files Browse the repository at this point in the history
  • Loading branch information
smallsaucepan authored Sep 21, 2024
2 parents 3e2badd + 2907628 commit 2038910
Show file tree
Hide file tree
Showing 14 changed files with 216 additions and 1,407 deletions.
18 changes: 11 additions & 7 deletions packages/turf-angle/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,19 +49,23 @@ function angle(
const B = endPoint;

// Main
const azimuthAO = bearingToAzimuth(
options.mercator !== true ? bearing(A, O) : rhumbBearing(A, O)
const azimuthOA = bearingToAzimuth(
options.mercator !== true ? bearing(O, A) : rhumbBearing(O, A)
);
const azimuthBO = bearingToAzimuth(
options.mercator !== true ? bearing(B, O) : rhumbBearing(B, O)
let azimuthOB = bearingToAzimuth(
options.mercator !== true ? bearing(O, B) : rhumbBearing(O, B)
);
const angleAO = Math.abs(azimuthAO - azimuthBO);
// If OB "trails" OA advance OB one revolution so we get the clockwise angle.
if (azimuthOB < azimuthOA) {
azimuthOB = azimuthOB + 360;
}
const angleAOB = azimuthOB - azimuthOA;

// Explementary angle
if (options.explementary === true) {
return 360 - angleAO;
return 360 - angleAOB;
}
return angleAO;
return angleAOB;
}

export { angle };
Expand Down
277 changes: 189 additions & 88 deletions packages/turf-angle/test.ts
Original file line number Diff line number Diff line change
@@ -1,101 +1,186 @@
import test from "tape";
import path from "path";
import { fileURLToPath } from "url";
import { glob } from "glob";
import { loadJsonFileSync } from "load-json-file";
import { writeJsonFileSync } from "write-json-file";
import { sector } from "@turf/sector";
import { bearing } from "@turf/bearing";
import { truncate } from "@turf/truncate";
import { distance } from "@turf/distance";
import { point, round, lineString, featureCollection } from "@turf/helpers";
import { point, round } from "@turf/helpers";
import { angle } from "./index.js";

const __dirname = path.dirname(fileURLToPath(import.meta.url));

test("turf-angle", (t) => {
glob
.sync(path.join(__dirname, "test", "in", "*.json"))
.forEach((filepath) => {
// Input
const { name } = path.parse(filepath);
const geojson = loadJsonFileSync(filepath);
const [start, mid, end] = geojson.features;

// Results
const angleProperties = {
interiorAngle: round(angle(start, mid, end), 6),
interiorMercatorAngle: round(
angle(start, mid, end, { mercator: true }),
6
),
explementary: false,
fill: "#F00",
stroke: "#F00",
"fill-opacity": 0.3,
};
const angleExplementaryProperties = {
explementaryAngle: round(
angle(start, mid, end, { explementary: true }),
6
),
explementaryMercatorAngle: round(
angle(start, mid, end, { explementary: true, mercator: true }),
6
),
test("turf-angle -- across 0 bearing", (t) => {
t.equal(round(angle([-1, 1], [0, 0], [1, 1])), 90, "90 degrees");

t.end();
});

test("turf-angle -- 90 degrees", (t) => {
t.equal(
round(angle([124, -17], [124, -22], [131, -22]), 6),
91.312527,
"91.312527 degrees"
);
t.equal(
round(angle([124, -17], [124, -22], [131, -22], { explementary: true }), 6),
268.687473,
"268.687473 degrees explementary"
);
t.equal(
round(angle([124, -17], [124, -22], [131, -22], { mercator: true }), 6),
90,
"90 degrees mercator"
);
t.equal(
round(
angle([124, -17], [124, -22], [131, -22], {
explementary: true,
mercator: true,
}),
6
),
270,
"270 degrees explementary mercator"
);
t.end();
});

test("turf-angle -- 180 degrees", (t) => {
t.equal(round(angle([3, -1], [2, 0], [1, 1]), 6), 180, "180 degrees");

t.end();
});

test("turf-angle -- obtuse", (t) => {
t.equal(
round(angle([48.5, 5.5], [51.5, 12], [59, 15.5]), 6),
218.715175,
"218.715175 degrees"
);
t.equal(
round(
angle([48.5, 5.5], [51.5, 12], [59, 15.5], { explementary: true }),
6
),
141.284825,
"141.284825 degrees explementary"
);
t.equal(
round(angle([48.5, 5.5], [51.5, 12], [59, 15.5], { mercator: true }), 6),
219.826106,
"219.826106 degrees mercator"
);
t.equal(
round(
angle([48.5, 5.5], [51.5, 12], [59, 15.5], {
explementary: true,
mercator: true,
}),
6
),
140.173894,
"140.173894 degrees explementary mercator"
);
t.end();
});

test("turf-angle -- obtuse bigger", (t) => {
t.equal(
round(angle([48.5, 5.5], [51.5, 12], [46.5, 19]), 6),
121.330117,
"121.330117 degrees"
);
t.equal(
round(
angle([48.5, 5.5], [51.5, 12], [46.5, 19], { explementary: true }),
6
),
238.669883,
"238.669883 degrees explementary"
);
t.equal(
round(angle([48.5, 5.5], [51.5, 12], [46.5, 19], { mercator: true }), 6),
120.970546,
"120.970546"
);
t.equal(
round(
angle([48.5, 5.5], [51.5, 12], [46.5, 19], {
explementary: true,
mercator: true,
}),
6
),
239.029454,
"239.029454 degrees explementary mercator"
);
t.end();
});

test("turf-angle -- acute", (t) => {
t.equal(
round(angle([48.5, 5.5], [51.5, 12], [44.5, 10.5]), 6),
53.608314,
"53.608314 degrees"
);
t.equal(
round(
angle([48.5, 5.5], [51.5, 12], [44.5, 10.5], { explementary: true }),
6
),
306.391686,
"306.391686 degrees explementary"
);
t.equal(
round(angle([48.5, 5.5], [51.5, 12], [44.5, 10.5], { mercator: true }), 6),
53.166357,
"53.166357 degrees mercator"
);
t.equal(
round(
angle([48.5, 5.5], [51.5, 12], [44.5, 10.5], {
explementary: true,
fill: "#00F",
stroke: "#00F",
"fill-opacity": 0.3,
};
const results = featureCollection([
truncate(
sector(
mid,
distance(mid, start) / 3,
bearing(mid, start),
bearing(mid, end),
{ properties: angleProperties }
)
),
truncate(
sector(
mid,
distance(mid, start) / 2,
bearing(mid, end),
bearing(mid, start),
{ properties: angleExplementaryProperties }
)
),
lineString(
[
start.geometry.coordinates,
mid.geometry.coordinates,
end.geometry.coordinates,
],
{ "stroke-width": 4, stroke: "#222" }
),
start,
mid,
end,
]);

// Save results
const expected = filepath.replace(
path.join("test", "in"),
path.join("test", "out")
);
if (process.env.REGEN) writeJsonFileSync(expected, results);
t.deepEqual(results, loadJsonFileSync(expected), name);
});
mercator: true,
}),
6
),
306.833643,
"306.833643 degrees explementary mercator"
);
t.end();
});

test("turf-angle -- acute inverse", (t) => {
t.equal(
round(angle([44.5, 10.5], [51.5, 12], [48.5, 5.5]), 6),
306.391686,
"306.391686 degrees"
);
t.equal(
round(
angle([44.5, 10.5], [51.5, 12], [48.5, 5.5], { explementary: true }),
6
),
53.608314,
"53.608314 degrees explementary"
);
t.equal(
round(angle([44.5, 10.5], [51.5, 12], [48.5, 5.5], { mercator: true }), 6),
306.833643,
"306.833643 degrees mercator"
);
t.equal(
round(
angle([44.5, 10.5], [51.5, 12], [48.5, 5.5], {
explementary: true,
mercator: true,
}),
6
),
53.166357,
"53.166357 degrees explementary mercator"
);
t.end();
});

test("turf-angle -- simple", (t) => {
t.equal(round(angle([5, 5], [5, 6], [3, 4])), 45, "45 degrees");
t.equal(round(angle([3, 4], [5, 6], [5, 5])), 45, "45 degrees -- inverse");
t.equal(round(angle([3, 4], [5, 6], [5, 5])), 315, "315 degrees -- inverse");
t.equal(
round(angle([3, 4], [5, 6], [5, 5], { explementary: true })),
round(angle([5, 5], [5, 6], [3, 4], { explementary: true })),
360 - 45,
"explementary angle"
);
Expand Down Expand Up @@ -139,3 +224,19 @@ test("turf-angle -- throws", (t) => {

t.end();
});

test("turf-angle -- 2703", (t) => {
const start = [0, 1];
const mid = [0, 0];
const end = [1, 0];
const a = angle(start, mid, end);
t.equal(a, 90, "90 clockwise");

const start2 = [0, 1];
const mid2 = [0, 0];
const end2 = [-1, 0];
const a2 = angle(start2, mid2, end2);
t.equal(a2, 270, "270 clockwise");

t.end();
});
38 changes: 0 additions & 38 deletions packages/turf-angle/test/in/90-degrees.json

This file was deleted.

Loading

0 comments on commit 2038910

Please sign in to comment.