mirror of
https://github.com/Turfjs/turf.git
synced 2026-01-25 16:07:00 +00:00
361 lines
9.4 KiB
TypeScript
361 lines
9.4 KiB
TypeScript
import fs from "fs";
|
|
import test from "tape";
|
|
import path from "path";
|
|
import { fileURLToPath } from "url";
|
|
import { loadJsonFileSync } from "load-json-file";
|
|
import { writeJsonFileSync } from "write-json-file";
|
|
import { featureEach } from "@turf/meta";
|
|
import {
|
|
point,
|
|
lineString,
|
|
multiPoint,
|
|
polygon,
|
|
featureCollection,
|
|
round,
|
|
} from "@turf/helpers";
|
|
import { getCoords } from "@turf/invariant";
|
|
import { lineSplit } from "./index.js";
|
|
import type {
|
|
Feature,
|
|
FeatureCollection,
|
|
LineString,
|
|
MultiLineString,
|
|
MultiPoint,
|
|
MultiPolygon,
|
|
Point,
|
|
Polygon,
|
|
} from "geojson";
|
|
|
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
|
|
const directories = {
|
|
in: path.join(__dirname, "test", "in") + path.sep,
|
|
out: path.join(__dirname, "test", "out") + path.sep,
|
|
};
|
|
|
|
let fixtures = fs.readdirSync(directories.in).map((filename) => {
|
|
return {
|
|
filename,
|
|
name: path.parse(filename).name,
|
|
geojson: loadJsonFileSync(directories.in + filename) as FeatureCollection,
|
|
};
|
|
});
|
|
// fixtures = fixtures.filter(({ name }) => name === "issue-#1075");
|
|
|
|
test("turf-line-split", (t) => {
|
|
for (const { filename, name, geojson } of fixtures) {
|
|
const line = geojson.features[0] as Feature<LineString>;
|
|
const splitter = geojson.features[1] as Feature<
|
|
Point | MultiPoint | LineString | MultiLineString | Polygon | MultiPolygon
|
|
>;
|
|
const results = colorize(lineSplit(line, splitter));
|
|
featureEach(geojson, (feature) => results.features.push(feature));
|
|
|
|
if (process.env.REGEN)
|
|
writeJsonFileSync(directories.out + filename, results);
|
|
t.deepEquals(results, loadJsonFileSync(directories.out + filename), name);
|
|
}
|
|
t.end();
|
|
});
|
|
|
|
test("turf-line-split -- lines should split the same feature 1 with 2 as 2 with 1", (t) => {
|
|
const featureOne = lineString([
|
|
[114.58215786065353825, -14.82470576519326144],
|
|
[137.21678649707752129, -16.71692980416107588],
|
|
]);
|
|
const featureTwo = lineString([
|
|
[119.1412061636556956, -19.83670052919270788],
|
|
[133.06640625, -12.64033830684678961],
|
|
]);
|
|
|
|
const resultsOne = lineSplit(featureOne, featureTwo);
|
|
const resultsTwo = lineSplit(featureTwo, featureOne);
|
|
|
|
const midCoordOne = getCoords(resultsOne.features[0])[1];
|
|
const midCoordTwo = getCoords(resultsTwo.features[1])[0];
|
|
|
|
// Round precision to 6 decimals
|
|
midCoordOne[0] = round(midCoordOne[0], 6);
|
|
midCoordOne[1] = round(midCoordOne[1], 6);
|
|
midCoordTwo[0] = round(midCoordTwo[0], 6);
|
|
midCoordTwo[1] = round(midCoordTwo[1], 6);
|
|
t.deepEquals(
|
|
midCoordOne,
|
|
midCoordTwo,
|
|
"Splits were made in different locations"
|
|
);
|
|
t.end();
|
|
});
|
|
|
|
test("turf-line-split -- throws", (t) => {
|
|
const pt = point([9, 50]);
|
|
const line = lineString([
|
|
[7, 50],
|
|
[8, 50],
|
|
[9, 50],
|
|
]);
|
|
|
|
// @ts-expect-error passing null for line
|
|
t.throws(() => lineSplit(null, pt), "<geojson> is required");
|
|
// @ts-expect-error passing null for splitter
|
|
t.throws(() => lineSplit(line, null), "<geojson> is required");
|
|
// @ts-expect-error passing wrong type for line
|
|
t.throws(() => lineSplit(pt, pt), "<line> must be LineString");
|
|
t.throws(
|
|
// @ts-expect-error passing wrong type for splitter
|
|
() => lineSplit(line, featureCollection([pt, line])),
|
|
"<splitter> cannot be a FeatureCollection"
|
|
);
|
|
t.end();
|
|
});
|
|
|
|
test("turf-line-split -- splitter exactly on end of line", (t) => {
|
|
const pt = point([9, 50]);
|
|
const line = lineString([
|
|
[7, 50],
|
|
[8, 50],
|
|
[9, 50],
|
|
]);
|
|
const features = lineSplit(line, pt).features;
|
|
|
|
t.deepEqual(features, [line], "should only contain 1 line of 3 vertices");
|
|
t.end();
|
|
});
|
|
|
|
test("turf-line-split -- lines should only contain 2 vertices #688", (t) => {
|
|
const middlePoint = point([8, 50]);
|
|
const line = lineString([
|
|
[7, 50],
|
|
[8, 50],
|
|
[9, 50],
|
|
]);
|
|
const [line1, line2] = lineSplit(line, middlePoint).features;
|
|
|
|
t.deepEqual(
|
|
line1,
|
|
lineString([
|
|
[7, 50],
|
|
[8, 50],
|
|
]),
|
|
"line1 should have 2 vertices"
|
|
);
|
|
t.deepEqual(
|
|
line2,
|
|
lineString([
|
|
[8, 50],
|
|
[9, 50],
|
|
]),
|
|
"line2 should have 2 vertices"
|
|
);
|
|
t.end();
|
|
});
|
|
|
|
test("turf-line-split -- precision issue #852", (t) => {
|
|
const line = lineString([
|
|
[9.2202022, 49.1438226],
|
|
[9.2199531, 49.1439048],
|
|
[9.2196177, 49.1440264],
|
|
]);
|
|
const startPoint = point([9.2202022, 49.1438226]);
|
|
const middlePoint = point([9.2199531, 49.1439048]);
|
|
const endPoint = point([9.2196177, 49.1440264]);
|
|
const [line1, line2] = lineSplit(line, middlePoint).features;
|
|
|
|
t.deepEqual(
|
|
line1,
|
|
lineString([
|
|
[9.2202022, 49.1438226],
|
|
[9.2199531, 49.1439048],
|
|
]),
|
|
"middlePoint: line1 should have 2 vertices"
|
|
);
|
|
t.deepEqual(
|
|
line2,
|
|
lineString([
|
|
[9.2199531, 49.1439048],
|
|
[9.2196177, 49.1440264],
|
|
]),
|
|
"middlePoint: line2 should have 2 vertices"
|
|
);
|
|
t.deepEqual(
|
|
lineSplit(line, startPoint).features,
|
|
[line],
|
|
"startPoint: should only contain 1 line of 3 vertices"
|
|
);
|
|
t.deepEqual(
|
|
lineSplit(line, endPoint).features,
|
|
[line],
|
|
"endPoint: should only contain 1 line of 3 vertices"
|
|
);
|
|
t.end();
|
|
});
|
|
|
|
test("turf-line-split -- prevent input mutation", (t) => {
|
|
const line = lineString([
|
|
[9.2202022, 49.1438226],
|
|
[9.2199531, 49.1439048],
|
|
[9.2196177, 49.1440264],
|
|
]);
|
|
const lineBefore = JSON.parse(JSON.stringify(line));
|
|
lineSplit(line, point([9.2196177, 49.1440264]));
|
|
|
|
t.deepEqual(line, lineBefore, "line should be the same");
|
|
t.end();
|
|
});
|
|
|
|
test("turf-line-split -- issue #1075", (t) => {
|
|
const line = lineString([
|
|
[-87.168433, 37.946093],
|
|
[-87.16851, 37.960085],
|
|
]);
|
|
const splitter = multiPoint([
|
|
[-87.168446, 37.947929],
|
|
[-87.168445, 37.948301],
|
|
]);
|
|
const split = lineSplit(line, splitter);
|
|
t.assert(split);
|
|
t.end();
|
|
});
|
|
|
|
test("lineSplit - incorrect split - issue #1075", (t) => {
|
|
let line, splitter, split;
|
|
|
|
// Example sourced from https://github.com/Turfjs/turf/issues/1232#issue-290515769
|
|
line = lineString([
|
|
[13.8716, 56.2783],
|
|
[13.8715, 56.2785],
|
|
[13.8743, 56.2794],
|
|
[13.8796, 56.2746],
|
|
]);
|
|
|
|
splitter = polygon([
|
|
[
|
|
[13.8726, 56.2786],
|
|
[13.8716, 56.2786],
|
|
[13.8713, 56.2784],
|
|
[13.8726, 56.2786],
|
|
],
|
|
]);
|
|
|
|
split = lineSplit(line, splitter);
|
|
t.equal(split.features.length, 3, "Line split into 3 pieces example 1");
|
|
|
|
// Example sourced from https://github.com/Turfjs/turf/issues/1232#issuecomment-361970429
|
|
line = lineString([
|
|
[10.424716, 50.024888],
|
|
[10.417643, 50.029512],
|
|
]);
|
|
|
|
splitter = polygon([
|
|
[
|
|
[10.41993839, 50.0301184],
|
|
[10.42587086, 50.02630702],
|
|
[10.41993839, 50.02249594],
|
|
[10.41400592, 50.02630702],
|
|
[10.41993839, 50.0301184],
|
|
],
|
|
]);
|
|
|
|
split = lineSplit(line, splitter);
|
|
t.equal(split.features.length, 3, "Line split into 3 pieces example 2");
|
|
|
|
// Example sourced from https://github.com/Turfjs/turf/issues/1232#issuecomment-2033181347
|
|
line = lineString([
|
|
[-111.570323, 49.587462],
|
|
[-111.570824, 49.587462],
|
|
[-111.571218, 49.587212],
|
|
[-111.571075, 49.587212],
|
|
[-111.566432, 49.584359],
|
|
]);
|
|
|
|
splitter = lineString([
|
|
[-111.57071881384209, 49.58746705929172],
|
|
[-111.57072743959235, 49.587462],
|
|
[-111.57106608768505, 49.58726337153985],
|
|
[-111.57109709453526, 49.587212],
|
|
[-111.5711022620136, 49.58720343862349],
|
|
]);
|
|
|
|
split = lineSplit(line, splitter);
|
|
t.equal(split.features.length, 3, "Line split into 3 pieces example 3");
|
|
|
|
// Example sourced from https://github.com/Turfjs/turf/issues/1232#issuecomment-2231554080
|
|
line = lineString([
|
|
[0, 44],
|
|
[25, 38],
|
|
[27, 40],
|
|
[0, 62],
|
|
]);
|
|
|
|
splitter = polygon([
|
|
[
|
|
[0, 20],
|
|
[42, 20],
|
|
[42, 39],
|
|
[28, 39],
|
|
[0, 52],
|
|
[0, 20],
|
|
],
|
|
]);
|
|
|
|
split = lineSplit(line, splitter);
|
|
|
|
t.equal(split.features.length, 2, "Line split into 2 pieces example 4");
|
|
t.end();
|
|
});
|
|
|
|
test("lineSplit - wavy lines - issue #2288", (t) => {
|
|
// Example sourced from https://github.com/Turfjs/turf/issues/2288#issuecomment-1125555752
|
|
const line = lineString([
|
|
[-122.7779211637529, 38.46929673131614],
|
|
[-122.78647173567292, 38.46208580491829],
|
|
]);
|
|
|
|
const splitter = polygon([
|
|
[
|
|
[-122.784210824, 38.46577859000006, 0],
|
|
[-122.783497375, 38.46577665500005, 0],
|
|
[-122.78349775899989, 38.46574340700003, 0],
|
|
[-122.78337219700002, 38.46574404700004, 0],
|
|
[-122.7833724819999, 38.46570876200008, 0],
|
|
[-122.783186362, 38.46571185100002, 0],
|
|
[-122.78318417300001, 38.46569283300004, 0],
|
|
[-122.782172859, 38.46568571000005, 0],
|
|
[-122.7821622549999, 38.46587288700003, 0],
|
|
[-122.783391339, 38.465877436, 0],
|
|
[-122.78339171499998, 38.46589273900003, 0],
|
|
[-122.78420487999992, 38.46590174800005, 0],
|
|
[-122.784210824, 38.46577859000006, 0],
|
|
],
|
|
]);
|
|
|
|
const split = lineSplit(line, splitter);
|
|
|
|
t.equal(split.features.length, 3, "Line split into 3 pieces");
|
|
t.end();
|
|
});
|
|
|
|
/**
|
|
* Colorize FeatureCollection
|
|
*
|
|
* @param {FeatureCollection|Feature<any>} geojson Feature or FeatureCollection
|
|
* @returns {FeatureCollection<any>} colorized FeatureCollection
|
|
*/
|
|
function colorize(geojson: FeatureCollection) {
|
|
const results: Feature[] = [];
|
|
featureEach(geojson, (feature, index) => {
|
|
const r = index % 2 === 0 ? "F" : "0";
|
|
const g = "0";
|
|
const b = index % 2 === 0 ? "0" : "F";
|
|
feature.properties = Object.assign(
|
|
{
|
|
stroke: "#" + r + g + b,
|
|
"stroke-width": 10,
|
|
},
|
|
feature.properties
|
|
);
|
|
results.push(feature);
|
|
});
|
|
return featureCollection(results);
|
|
}
|