Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
5f58c4f
test: add antimeridian splitting tests for low npoints values
thomas-hervey Mar 30, 2026
cc9037e
fix(great-circle): replace GDAL heuristic with analytical antimeridia…
thomas-hervey Apr 9, 2026
d3598f2
test(antimeridian): assert exactly 2 segments at antimeridian split
thomas-hervey Apr 9, 2026
cbf2c4e
test(integration): replace brittle snapshots with semantic assertions
thomas-hervey Apr 9, 2026
a27ad91
chore: remove GDAL attribution now that heuristic is replaced
thomas-hervey Apr 9, 2026
19c506a
Merge pull request #76 from thomas-hervey/test/antimeridian-low-npoints
thomas-hervey Apr 13, 2026
807167d
docs: fix stale ArcOptions.offset JSDoc and DEVELOPING.md scripts
thomas-hervey Apr 9, 2026
98d42e7
chore: remove deprecated offset usage from tests, README, and demo
thomas-hervey Apr 9, 2026
496efc6
feat(great-circle): default npoints to 100
thomas-hervey Apr 11, 2026
6e9178d
refactor(tests): extract shared route fixtures to test/fixtures/
thomas-hervey Apr 11, 2026
970148d
chore(scripts): add dump-fixtures for visual route verification
thomas-hervey Apr 11, 2026
b154d4d
chore(scripts): add benchmark comparing bisection vs linear interpola…
thomas-hervey Apr 11, 2026
b4a8d1d
refactor(great-circle): extract bisection constant and add inline com…
thomas-hervey Apr 13, 2026
48fc6d6
Merge pull request #77 from thomas-hervey/docs/arc-options-cleanup
thomas-hervey Apr 13, 2026
86e5376
chore: bump version to 1.0.0 and update CHANGELOG
thomas-hervey Apr 13, 2026
f2a3623
docs(readme): show npoints is optional, defaults to 100
thomas-hervey Apr 13, 2026
c5ea41a
fix: address jgravois review comments on PR #79
thomas-hervey Apr 13, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 18 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ This project adheres to [Semantic Versioning](http://semver.org/).

## [Unreleased][unreleased]

## [1.0.0] - 2026-03-29
## [1.0.0] - 2026-04-12

### Breaking change

- arc.js is now a [pure](https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c) ESM package.
- arc.js is now a [pure](https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c) ESM package (from @jgravois).

If you need to `require()` arc.js as CJS (CommonJS), or have a runtime older than Node.js 18, please use `0.1.4`.

Expand All @@ -27,7 +27,22 @@ const gc = new GreatCircle(/* */);

### Fixed

- antimeridian splitting in GreatCircle.Arc (From @copilot)
- Antimeridian splitting in GreatCircle.Arc (from @thomas-hervey)

### Changed

- `GreatCircle.Arc()` now defaults to `npoints = 100` — calling `gc.Arc()` with no arguments produces a smooth 100-point arc instead of a 2-point stub
- Antimeridian splitting now uses analytical bisection (binary search on `interpolate()`) instead of the GDAL-ported linear heuristic. This approach is more accurate, especially at high latitudes and low `npoints` values
- `ArcOptions.offset` is now a no-op (kept for backwards compatibility); antimeridian handling is fully automatic

### Removed

- GDAL license file (`GDAL-LICENSE.md`). No GDAL-derived code remains in the codebase

### Added

- `scripts/benchmark.mjs` benchmarks bisection vs. prior linear approach across npoints and route types
- `scripts/dump-fixtures.mjs` exports all test routes as GeoJSON for use in visual verification (such as [https://geojson.io](https://geojson.io) or the index.html demo page)

## [0.2.0] - 2025-09-22
### Breaking
Expand Down
65 changes: 28 additions & 37 deletions DEVELOPING.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,26 +6,24 @@ This guide covers working with the TypeScript codebase for arc.js.

```bash
npm install # Install dependencies
npm run build # Build all outputs
npm run build # Build ESM output
npm test # Run TypeScript tests
npm run test:all # Run all tests (TypeScript + build validation)
```

## Project Structure

```
```text
src/
├── index.ts # Main entry point
├── coord.ts # Coordinate class
├── arc.ts # Arc class
├── arc.ts # Arc class
├── great-circle.ts # Great circle calculations
├── line-string.ts # Internal geometry helper
├── utils.ts # Utility functions
└── types.ts # TypeScript type definitions

test/
├── *.test.ts # Jest TypeScript tests (source code)
└── build-output.test.js # Build validation (compiled output)
└── *.test.ts # Jest TypeScript tests
```

## Development Workflow
Expand All @@ -36,14 +34,11 @@ test/
# Run TypeScript tests (fast, for development)
npm test

# Run build validation (slower, tests compiled output)
npm run test:build

# Run everything (recommended before committing)
npm run test:all

# Watch mode for development
npm run test:watch

# Coverage report
npm run test:coverage
```

### Building
Expand All @@ -52,10 +47,7 @@ npm run test:watch
npm run build
```

This generates:
- `dist/` - CommonJS output with `.d.ts` files
- `dist/esm/` - ES modules output
- `arc.js` - Browser bundle (UMD format)
This generates `dist/` — ESM output with `.d.ts` declaration files.

## Publishing

Expand All @@ -68,7 +60,7 @@ This generates:

### Pre-publish Checklist (for maintainers)

1. **Tests pass**: `npm run test:all`
1. **Tests pass**: `npm test`
2. **Build succeeds**: `npm run build`
3. **Version updated**: Update `package.json` version
4. **Changelog updated**: Document changes
Expand All @@ -77,49 +69,48 @@ This generates:
### Publishing Process (maintainers only)

```bash
npm run build # Builds automatically on prepublishOnly
npm publish
npm publish # prepublishOnly runs npm run build automatically
```

The `prepublishOnly` script ensures a fresh build before publishing.

### What Gets Published

- `dist/` folder (compiled JS + TypeScript definitions)
- `arc.js` browser bundle
- `dist/` folder (compiled ESM JS + TypeScript definitions)
- `src/` folder (TypeScript source files)
- `README.md`, `LICENSE.md`, `CHANGELOG.md`

## TypeScript Development

### TypeScript Configuration

- **Source**: Modern TypeScript with strict settings
- **Output**: ES2022 for broad compatibility
- **Paths**: `@/` alias maps to `src/` in tests
- **Output**: ES2022, ESM only
- **Declarations**: Full `.d.ts` generation for consumers

### Adding New Types

1. Add interfaces/types to `src/types.ts`. You can see that it makes use of some GeoJSON types, but in the future it may want to use more of them.
1. Add interfaces/types to `src/types.ts`
2. Export public types from `src/index.ts`
3. Import types with `import type { ... }`
4. Add tests in relevant `test/*.test.ts` files including typescript.test.ts

## Usage & Module Formats
4. Add tests in relevant `test/*.test.ts` files including `typescript.test.ts`

The package supports multiple import styles:
## Usage

```javascript
// CommonJS (Node.js)
const { GreatCircle } = require('arc');

// ES Modules
// ES Modules (Node.js or bundler)
import { GreatCircle } from 'arc';
```

// Browser (UMD bundle)
<script src="arc.js"></script>
## Visual Fixture Verification

To inspect all test routes as great circle arcs on a map:

```bash
npm run build # dist/ must exist
node scripts/dump-fixtures.mjs | pbcopy # macOS: copy to clipboard
```

All formats are tested in `test/build-output.test.js`.
Then, paste the geojson output into a visualization tool to visually verify routes, such as [geojson.io](https://geojson.io).
**Note:** route coordinates in the script are manually updated to keep in sync with `test/fixtures/routes.ts`.

## Common Tasks

Expand Down
57 changes: 0 additions & 57 deletions GDAL-LICENSE.md

This file was deleted.

23 changes: 9 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Calculate great circle routes as lines in GeoJSON or WKT format.
- Works in Node.js and browsers
- Generates GeoJSON and WKT output formats
- Handles dateline crossing automatically
- Based on [Ed Williams' Aviation Formulary](https://edwilliams.org/avform.htm#Intermediate) algorithms and the GDAL source code
- Based on [Ed Williams' Aviation Formulary](https://edwilliams.org/avform.htm#Intermediate) algorithms

## Installation

Expand All @@ -22,7 +22,7 @@ npm install arc
```js
import { GreatCircle } from 'arc';
const gc = new GreatCircle({x: -122, y: 48}, {x: -77, y: 39});
const line = gc.Arc(100);
const line = gc.Arc(); // npoints is optional, defaults to 100
console.log(line.json()); // GeoJSON output
```

Expand All @@ -40,8 +40,8 @@ const line = gc.Arc(100);
```html
<script type="module">
import { GreatCircle } from 'https://cdn.skypack.dev/arc@1';
const gc = new arc.GreatCircle({x: -122, y: 48}, {x: -77, y: 39});
const line = gc.Arc(100);
const gc = new GreatCircle({x: -122, y: 48}, {x: -77, y: 39});
const line = gc.Arc();
</script>
```

Expand All @@ -64,12 +64,12 @@ const gc = new GreatCircle(start, end, { name: 'Seattle to DC' });

#### 3. Generate the arc
```js
const line = gc.Arc(100, { offset: 10 });
const line = gc.Arc(); // defaults to 100 points
const line = gc.Arc(500); // or specify a custom value
```

**Parameters:**
- `npoints` (number): Number of intermediate points (higher = more accurate)
- `options.offset` (number): Dateline crossing threshold in degrees (default: 10)
- `npoints` (number, optional): Number of intermediate points (higher = more precise, default: 100)

### TypeScript Support

Expand All @@ -87,8 +87,7 @@ const end: CoordinatePoint = { x: -77, y: 39 };
const properties: RouteProperties = { name: 'Seattle to DC', color: 'blue' };

const gc = new GreatCircle(start, end, properties);
const options: ArcOptions = { offset: 10 };
const line = gc.Arc(100, options);
const line = gc.Arc(); // npoints is optional, defaults to 100

// Fully typed return values
const geojson = line.json(); // GeoJSONFeature
Expand Down Expand Up @@ -144,7 +143,7 @@ const wkt = line.wkt();

### Dateline Crossing

The library automatically handles routes that cross the international dateline. The `offset` option (default: 10) controls how close to the dateline a route must be before it gets split into multiple segments. For routes near the poles, you may need a higher offset value.
Routes that cross the international dateline are automatically detected and split into a `MultiLineString` with exact `±180°` boundary points. No configuration is needed.

## Examples

Expand All @@ -157,7 +156,3 @@ arc.js powers the [`greatCircle`](https://turfjs.org/docs/api/greatCircle) funct
## License

This project is licensed under the BSD license. See [LICENSE.md](LICENSE) for details.

### Third-Party Licenses

This project includes code ported from GDAL (Geospatial Data Abstraction Library), which is licensed under the MIT/X11 license. See [GDAL-LICENSE.md](GDAL-LICENSE.md) for the full GDAL license text and attribution details.
14 changes: 2 additions & 12 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -333,11 +333,6 @@ <h3>Settings</h3>
<input type="number" id="npoints" value="100" min="10" max="1000" />
</div>

<div class="control-group">
<label for="offset">Dateline offset (degrees):</label>
<input type="number" id="offset" value="20" min="1" max="90" step="1" />
</div>

<div class="control-group">
<button id="clear" class="btn">Clear All</button>
<button id="reset" class="btn btn-danger">Reset View</button>
Expand Down Expand Up @@ -377,7 +372,6 @@ <h4>Generated GeoJSON</h4>

// Configuration
var npoints = 100;
var offset = 20;
var coords = [];
var points = [];
var snap_tolerance = 500000;
Expand All @@ -390,10 +384,6 @@ <h4>Generated GeoJSON</h4>
npoints = parseInt(this.value) || 100;
});

document.getElementById('offset').addEventListener('change', function() {
offset = parseInt(this.value) || 20;
});

var start, end;

function draw(coords) {
Expand Down Expand Up @@ -469,7 +459,7 @@ <h4>Generated GeoJSON</h4>
};

var greatCircle = new GreatCircle(from, to, properties);
var gc = greatCircle.Arc(npoints, { offset: offset });
var gc = greatCircle.Arc(npoints);
var line = new L.geoJson().addTo(map);
var geojson_feature = gc.json();

Expand Down Expand Up @@ -592,7 +582,7 @@ <h4>Generated GeoJSON</h4>

try {
var greatCircle = new GreatCircle(nyc, london, properties);
var gc = greatCircle.Arc(npoints, { offset: offset });
var gc = greatCircle.Arc(npoints);
var line = new L.geoJson().addTo(map);
var geojson_feature = gc.json();

Expand Down
7 changes: 4 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "arc",
"version": "0.2.0",
"version": "1.0.0",
Copy link
Copy Markdown
Collaborator

@jgravois jgravois Apr 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just a note that we need to add src/ to the files array before we publish. doesn't matter to me whether that happens here or a follow-up PR.

when we do that, we should update the DEVELOPING.md file too.

https://github.com/springmeyer/arc.js/blob/f2a36235e11897d7a211c4cb20429e4fdd578361/DEVELOPING.md#what-gets-published

ref: #80

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, let's roll this into the release, so I'll make those changes in the next commit.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in c5ea41a.

"description": "draw great circle arcs",
"url": "https://github.com/springmeyer/arc.js",
"keywords": [
Expand All @@ -14,7 +14,8 @@
],
"contributors": [
"Dane Springmeyer <dane.springmeyer@gmail.com>",
"John Gravois <jagravois@gmail.com>"
"John Gravois <jagravois@gmail.com>",
"Thomas Hervey <thomasahervey@gmail.com>"
],
"repository": {
"type": "git",
Expand All @@ -28,9 +29,9 @@
},
"files": [
"dist/",
"src/",
"README.md",
"LICENSE.md",
"GDAL-LICENSE.md",
"CHANGELOG.md"
],
"engines": {
Expand Down
Loading
Loading