mirror of
https://github.com/Turfjs/turf.git
synced 2025-12-08 20:26:16 +00:00
Typescript-ifying turf-great-circle (#2733)
* Added typing to index.ts, tests to test.ts * Update pnpm-lock.yaml after dependency updates * Replace embedded arc.js with external TypeScript arc package - Add arc@^0.2.0 (WIP bump) as dependency to replace embedded lib/arc.js - Update import from './lib/arc.js' to 'arc' package - Fix TypeScript type compatibility issues: - Handle null properties with fallback to empty object - Add proper type assertion for return value - All tests pass (9/9) with new TypeScript arc.js integration - Maintains 100% backward compatibility while adding full TypeScript support * Remove arc.d.ts which is no longer needed, regenerate pnpm-lock --------- Co-authored-by: mfedderly <24275386+mfedderly@users.noreply.github.com>
This commit is contained in:
parent
b43a4d51e8
commit
14f354ffca
@ -11,5 +11,5 @@ suite
|
||||
.add("greatCircle", () => {
|
||||
greatCircle(point1, point2);
|
||||
})
|
||||
.on("cycle", (e) => console.log(String(e.target)))
|
||||
.on("cycle", (e: any) => console.log(String(e.target)))
|
||||
.run();
|
||||
|
||||
23
packages/turf-great-circle/index.d.ts
vendored
23
packages/turf-great-circle/index.d.ts
vendored
@ -1,23 +0,0 @@
|
||||
import {
|
||||
LineString,
|
||||
MultiLineString,
|
||||
Feature,
|
||||
GeoJsonProperties,
|
||||
} from "geojson";
|
||||
import { Coord } from "@turf/helpers";
|
||||
|
||||
/**
|
||||
* http://turfjs.org/docs/#greatcircle
|
||||
*/
|
||||
declare function greatCircle(
|
||||
start: Coord,
|
||||
end: Coord,
|
||||
options?: {
|
||||
properties?: GeoJsonProperties;
|
||||
npoints?: number;
|
||||
offset?: number;
|
||||
}
|
||||
): Feature<LineString | MultiLineString>;
|
||||
|
||||
export { greatCircle };
|
||||
export default greatCircle;
|
||||
@ -1,6 +1,14 @@
|
||||
import type {
|
||||
Feature,
|
||||
GeoJsonProperties,
|
||||
LineString,
|
||||
MultiLineString,
|
||||
Point,
|
||||
Position,
|
||||
} from "geojson";
|
||||
import { lineString } from "@turf/helpers";
|
||||
import { getCoord } from "@turf/invariant";
|
||||
import { GreatCircle } from "./lib/arc.js";
|
||||
import { GreatCircle } from "arc";
|
||||
|
||||
/**
|
||||
* Calculate great circles routes as {@link LineString} or {@link MultiLineString}.
|
||||
@ -8,7 +16,7 @@ import { GreatCircle } from "./lib/arc.js";
|
||||
* be split into a `MultiLineString`. If the `start` and `end` positions are the same
|
||||
* then a `LineString` will be returned with duplicate coordinates the length of the `npoints` option.
|
||||
*
|
||||
* @function
|
||||
* @name greatCircle
|
||||
* @param {Coord} start source point feature
|
||||
* @param {Coord} end destination point feature
|
||||
* @param {Object} [options={}] Optional parameters
|
||||
@ -26,37 +34,39 @@ import { GreatCircle } from "./lib/arc.js";
|
||||
* //addToMap
|
||||
* var addToMap = [start, end, greatCircle]
|
||||
*/
|
||||
function greatCircle(start, end, options) {
|
||||
function greatCircle(
|
||||
start: Feature<Point, GeoJsonProperties> | Point | Position,
|
||||
end: Feature<Point, GeoJsonProperties> | Point | Position,
|
||||
options: {
|
||||
properties?: GeoJsonProperties;
|
||||
npoints?: number;
|
||||
offset?: number;
|
||||
} = {}
|
||||
): Feature<LineString | MultiLineString> {
|
||||
// Optional parameters
|
||||
options = options || {};
|
||||
if (typeof options !== "object") throw new Error("options is invalid");
|
||||
var properties = options.properties;
|
||||
var npoints = options.npoints;
|
||||
var offset = options.offset;
|
||||
const { properties = {}, npoints = 100, offset = 10 } = options;
|
||||
|
||||
start = getCoord(start);
|
||||
end = getCoord(end);
|
||||
const startCoord = getCoord(start);
|
||||
const endCoord = getCoord(end);
|
||||
|
||||
properties = properties || {};
|
||||
npoints = npoints || 100;
|
||||
|
||||
if (start[0] === end[0] && start[1] === end[1]) {
|
||||
const arr = Array(npoints);
|
||||
arr.fill([start[0], start[1]]);
|
||||
if (startCoord[0] === endCoord[0] && startCoord[1] === endCoord[1]) {
|
||||
const arr = Array(npoints).fill([startCoord[0], startCoord[1]]);
|
||||
return lineString(arr, properties);
|
||||
}
|
||||
|
||||
offset = offset || 10;
|
||||
|
||||
var generator = new GreatCircle(
|
||||
{ x: start[0], y: start[1] },
|
||||
{ x: end[0], y: end[1] },
|
||||
properties
|
||||
const generator = new GreatCircle(
|
||||
{ x: startCoord[0], y: startCoord[1] },
|
||||
{ x: endCoord[0], y: endCoord[1] },
|
||||
properties || {}
|
||||
);
|
||||
|
||||
var line = generator.Arc(npoints, { offset: offset });
|
||||
const line = generator.Arc(npoints, { offset: offset });
|
||||
|
||||
return line.json();
|
||||
return line.json() as Feature<
|
||||
LineString | MultiLineString,
|
||||
GeoJsonProperties
|
||||
>;
|
||||
}
|
||||
|
||||
export { greatCircle };
|
||||
@ -6,7 +6,8 @@
|
||||
"contributors": [
|
||||
"Dane Springmeyer <@springmeyer>",
|
||||
"Stepan Kuzmin <@stepankuzmin>",
|
||||
"Denis Carriere <@DenisCarriere>"
|
||||
"Denis Carriere <@DenisCarriere>",
|
||||
"Thomas Hervey <@thomas-hervey>"
|
||||
],
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
@ -66,11 +67,14 @@
|
||||
"tape": "^5.9.0",
|
||||
"tsup": "^8.4.0",
|
||||
"tsx": "^4.19.4",
|
||||
"typescript": "^5.8.3",
|
||||
"write-json-file": "^6.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@turf/helpers": "workspace:*",
|
||||
"@turf/invariant": "workspace:*",
|
||||
"@types/geojson": "^7946.0.10"
|
||||
"@types/geojson": "^7946.0.10",
|
||||
"arc": "^0.2.0",
|
||||
"tslib": "^2.8.1"
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,6 +4,13 @@ import path from "path";
|
||||
import { fileURLToPath } from "url";
|
||||
import { loadJsonFileSync } from "load-json-file";
|
||||
import { writeJsonFileSync } from "write-json-file";
|
||||
import type {
|
||||
FeatureCollection,
|
||||
LineString,
|
||||
Feature,
|
||||
Geometry,
|
||||
Point,
|
||||
} from "geojson";
|
||||
import { truncate } from "@turf/truncate";
|
||||
import { featureCollection, point, lineString } from "@turf/helpers";
|
||||
import { greatCircle } from "./index.js";
|
||||
@ -15,23 +22,32 @@ const directories = {
|
||||
out: path.join(__dirname, "test", "out") + path.sep,
|
||||
};
|
||||
|
||||
let fixtures = fs.readdirSync(directories.in).map((filename) => {
|
||||
const fixtures = fs.readdirSync(directories.in).map((filename) => {
|
||||
return {
|
||||
filename,
|
||||
name: path.parse(filename).name,
|
||||
geojson: loadJsonFileSync(path.join(directories.in, filename)),
|
||||
geojson: loadJsonFileSync(
|
||||
path.join(directories.in, filename)
|
||||
) as FeatureCollection,
|
||||
};
|
||||
});
|
||||
|
||||
// Function to get the start and end points from the fixture
|
||||
function getStartEndPoints(fixture: (typeof fixtures)[0]) {
|
||||
const geojson = fixture.geojson;
|
||||
const start = geojson.features[0] as Feature<Point>;
|
||||
const end = geojson.features[1] as Feature<Point>;
|
||||
return { start, end };
|
||||
}
|
||||
|
||||
test("turf-great-circle", (t) => {
|
||||
fixtures.forEach((fixture) => {
|
||||
const name = fixture.name;
|
||||
const filename = fixture.filename;
|
||||
const geojson = fixture.geojson;
|
||||
const start = geojson.features[0];
|
||||
const end = geojson.features[1];
|
||||
const { start, end } = getStartEndPoints(fixture);
|
||||
|
||||
const line = truncate(greatCircle(start, end));
|
||||
const results = featureCollection([line, start, end]);
|
||||
const results = featureCollection<Geometry>([line, start, end]);
|
||||
|
||||
if (process.env.REGEN)
|
||||
writeJsonFileSync(directories.out + filename, results);
|
||||
@ -54,12 +70,74 @@ test("turf-great-circle with same input and output", (t) => {
|
||||
[0, 0],
|
||||
[0, 0],
|
||||
]),
|
||||
line
|
||||
line as Feature<LineString>
|
||||
);
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
test("turf-great-circle accepts Feature<Point> inputs", (t) => {
|
||||
const { start, end } = getStartEndPoints(fixtures[0]);
|
||||
t.doesNotThrow(
|
||||
() => greatCircle(start, end),
|
||||
"accepts Feature<Point> inputs"
|
||||
);
|
||||
t.end();
|
||||
});
|
||||
|
||||
test("turf-great-circle accepts Point geometry inputs", (t) => {
|
||||
const { start, end } = getStartEndPoints(fixtures[0]);
|
||||
t.doesNotThrow(
|
||||
() => greatCircle(start.geometry, end.geometry),
|
||||
"accepts Point geometry inputs"
|
||||
);
|
||||
t.end();
|
||||
});
|
||||
|
||||
test("turf-great-circle accepts Position inputs", (t) => {
|
||||
const { start, end } = getStartEndPoints(fixtures[0]);
|
||||
t.doesNotThrow(
|
||||
() => greatCircle(start.geometry.coordinates, end.geometry.coordinates),
|
||||
"accepts Position inputs"
|
||||
);
|
||||
t.end();
|
||||
});
|
||||
|
||||
test("turf-great-circle applies custom properties", (t) => {
|
||||
const { start, end } = getStartEndPoints(fixtures[0]);
|
||||
const withProperties = greatCircle(start, end, {
|
||||
properties: { name: "Test Route" },
|
||||
});
|
||||
t.equal(
|
||||
withProperties.properties?.name,
|
||||
"Test Route",
|
||||
"applies custom properties"
|
||||
);
|
||||
t.end();
|
||||
});
|
||||
|
||||
test("turf-great-circle respects npoints option", (t) => {
|
||||
const { start, end } = getStartEndPoints(fixtures[0]);
|
||||
const withCustomPoints = greatCircle(start, end, { npoints: 5 });
|
||||
t.equal(
|
||||
(withCustomPoints.geometry as LineString).coordinates.length,
|
||||
5,
|
||||
"respects npoints option"
|
||||
);
|
||||
t.end();
|
||||
});
|
||||
|
||||
test("turf-great-circle respects offset and npoints options", (t) => {
|
||||
const { start, end } = getStartEndPoints(fixtures[0]);
|
||||
const withOffset = greatCircle(start, end, { offset: 100, npoints: 10 });
|
||||
t.equal(
|
||||
(withOffset.geometry as LineString).coordinates.length,
|
||||
10,
|
||||
"respects offset and npoints options"
|
||||
);
|
||||
t.end();
|
||||
});
|
||||
|
||||
test("turf-great-circle with antipodal start and end", (t) => {
|
||||
const start = point([0, 90]);
|
||||
const end = point([0, -90]);
|
||||
|
||||
15
pnpm-lock.yaml
generated
15
pnpm-lock.yaml
generated
@ -3047,6 +3047,12 @@ importers:
|
||||
'@types/geojson':
|
||||
specifier: ^7946.0.10
|
||||
version: 7946.0.14
|
||||
arc:
|
||||
specifier: ^0.2.0
|
||||
version: 0.2.0
|
||||
tslib:
|
||||
specifier: ^2.8.1
|
||||
version: 2.8.1
|
||||
devDependencies:
|
||||
'@turf/truncate':
|
||||
specifier: workspace:*
|
||||
@ -3072,6 +3078,9 @@ importers:
|
||||
tsx:
|
||||
specifier: ^4.19.4
|
||||
version: 4.19.4
|
||||
typescript:
|
||||
specifier: ^5.8.3
|
||||
version: 5.8.3
|
||||
write-json-file:
|
||||
specifier: ^6.0.0
|
||||
version: 6.0.0
|
||||
@ -7962,6 +7971,10 @@ packages:
|
||||
aproba@2.0.0:
|
||||
resolution: {integrity: sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==}
|
||||
|
||||
arc@0.2.0:
|
||||
resolution: {integrity: sha512-8NFOo126uYKQJyXNSLY/jSklgfLQL+XWAcPXGo876JwEQ8nSOPXWNI3TV2jLZMN8QEw8uksJ1ZwS4npjBca8MA==}
|
||||
engines: {node: '>=0.4.0'}
|
||||
|
||||
argparse@1.0.10:
|
||||
resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==}
|
||||
|
||||
@ -13778,6 +13791,8 @@ snapshots:
|
||||
|
||||
aproba@2.0.0: {}
|
||||
|
||||
arc@0.2.0: {}
|
||||
|
||||
argparse@1.0.10:
|
||||
dependencies:
|
||||
sprintf-js: 1.0.3
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user