Thomas Hervey 14f354ffca
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>
2025-12-08 08:47:38 -05:00

74 lines
2.4 KiB
TypeScript

import type {
Feature,
GeoJsonProperties,
LineString,
MultiLineString,
Point,
Position,
} from "geojson";
import { lineString } from "@turf/helpers";
import { getCoord } from "@turf/invariant";
import { GreatCircle } from "arc";
/**
* Calculate great circles routes as {@link LineString} or {@link MultiLineString}.
* If the `start` and `end` points span the antimeridian, the resulting feature will
* 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.
*
* @name greatCircle
* @param {Coord} start source point feature
* @param {Coord} end destination point feature
* @param {Object} [options={}] Optional parameters
* @param {Object} [options.properties={}] line feature properties
* @param {number} [options.npoints=100] number of points
* @param {number} [options.offset=10] offset controls the likelyhood that lines will
* be split which cross the dateline. The higher the number the more likely.
* @returns {Feature<LineString | MultiLineString>} great circle line feature
* @example
* var start = turf.point([-122, 48]);
* var end = turf.point([-77, 39]);
*
* var greatCircle = turf.greatCircle(start, end, {properties: {name: 'Seattle to DC'}});
*
* //addToMap
* var addToMap = [start, end, greatCircle]
*/
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
if (typeof options !== "object") throw new Error("options is invalid");
const { properties = {}, npoints = 100, offset = 10 } = options;
const startCoord = getCoord(start);
const endCoord = getCoord(end);
if (startCoord[0] === endCoord[0] && startCoord[1] === endCoord[1]) {
const arr = Array(npoints).fill([startCoord[0], startCoord[1]]);
return lineString(arr, properties);
}
const generator = new GreatCircle(
{ x: startCoord[0], y: startCoord[1] },
{ x: endCoord[0], y: endCoord[1] },
properties || {}
);
const line = generator.Arc(npoints, { offset: offset });
return line.json() as Feature<
LineString | MultiLineString,
GeoJsonProperties
>;
}
export { greatCircle };
export default greatCircle;