@arcnautical/maritime-routing

中文文档
1.0.1发布于 2026/09/18MITTypeScriptES Module零依赖近 30 天下载 2306

Production-grade maritime routing engine — A* ocean pathfinding, Dijkstra waypoint routing, 510+ port database, weather-aware ETA, EEZ analysis. Zero dependencies.

原始使用文档
文档目录21 节
  1. Why this exists
  2. Features
  3. Install
  4. Quick Start
  5. API Reference
  6. Route Computation
  7. Ocean Pathfinding
  8. Port Database
  9. Weather Speed Model
  10. EEZ Transit Analysis
  11. Geodesic Utilities
  12. Data Sources
  13. Performance
  14. Comparison with searoute-js
  15. Advanced Usage
  16. Custom Ocean Grid
  17. Generate Your Own Ocean Grid
  18. Ocean Regions
  19. Vessel Types
  20. License
  21. About

@arcnautical/maritime-routing

npm version npm downloads License: MIT Tests: 42 passing Zero dependencies GitHub stars

Production-grade maritime routing engine for JavaScript/TypeScript. Zero dependencies.

Compute realistic ocean routes between any two ports worldwide, with guaranteed land avoidance, weather-aware ETA, and EEZ transit analysis.

Why this exists

Every shipping tech startup reinvents maritime routing. The existing open-source options (searoute-js — unmaintained since 2020, uses year-2000 data) are inadequate for production use. Commercial APIs charge EUR 600-6,900/year.

This library is extracted from ArcNautical, a maritime risk intelligence platform. It has been tested against 1,790 real-world routes with 0% land crossing.

This engine powers a live voyage-risk product. @arcnautical/maritime-routing is the open-source core of ArcNautical's lane-risk intelligence. The live app takes any origin -> destination lane and scores it for sanctions exposure, piracy/conflict, chokepoint dependency and weather, then emails you a dated lane-risk brief for that specific corridor.

Try it on one of your own lanes -- the full computed result is shown with no signup: https://arcnautical.com

Features

FeatureDescription
A* Ocean PathfindingRoutes on a 0.05° ocean bitmap (7200x3600 cells) derived from OpenStreetMap. Routes are guaranteed to never cross land.
Dijkstra Waypoint Routing48 strategic chokepoints (Suez, Panama, Malacca, Gibraltar, etc.) with distance-weighted graph routing.
510+ Port DatabaseUN/LOCODE standard. Search by name, country, or code. Includes coordinates, port type, and ocean region.
Weather Speed ModelBeaufort-based speed reduction (Kwon 2008, Lu et al. 2015). Per vessel type and load condition. Direction-aware with Cbeta factors.
EEZ Transit AnalysisDetect which Exclusive Economic Zones a route transits. Sanctions flagging included.
Avoid ZonesRoute around user-specified polygons (e.g., piracy areas, conflict zones).
Via WaypointsForce routes through specific coordinates.
GeoJSON OutputAll routes returned as GeoJSON LineString, ready for map rendering.

Install

npm install @arcnautical/maritime-routing

Requires Node.js >= 18.

Quick Start

import { computeRoute } from '@arcnautical/maritime-routing';

// Compute a route from Singapore to Rotterdam
const route = computeRoute('SGSIN', 'NLRTM');

console.log(route.distance_nm);        // ~8,440 nm
console.log(route.duration_hours);      // ~603 hours at 14 knots
console.log(route.waypoints.length);    // waypoints transited
console.log(route.hazard_zones_crossed); // chokepoints on route

// GeoJSON for map rendering
const geojson = route.route_geojson;
// -> FeatureCollection with LineString geometry

API Reference

Route Computation

import {
  computeRoute,
  computeRouteInternal,
} from '@arcnautical/maritime-routing';

// Simple route (returns handler-compatible format)
const route = computeRoute('SGSIN', 'NLRTM');

// Route with options
const route = computeRoute('SGSIN', 'NLRTM', {
  avoid_zones: [[[30, 12], [50, 12], [50, 32], [30, 32], [30, 12]]], // avoid Red Sea
  via_waypoints: [{ lat: -34.4, lon: 18.5 }], // force via Cape of Good Hope
});

// Internal format (with segment breakdown)
const internal = computeRouteInternal('SGSIN', 'NLRTM');
console.log(internal.segments);       // per-leg distance + bearing
console.log(internal.totalDistanceNm);
console.log(internal.geojson);        // GeoJSON Feature

Ocean Pathfinding

import { findOceanPath } from '@arcnautical/maritime-routing';

// Find a path between two coordinates
// Returns [lon, lat][] (GeoJSON convention)
const path = findOceanPath(1.26, 103.84, 51.90, 4.50);
// -> ~500 coordinate pairs, guaranteed to never cross land

// Performance: 8-50ms for typical segments
// Automatically subdivides routes > 5,000nm

Port Database

import {
  searchPorts,
  getPortByLocode,
  getPortsByRegion,
  resolveAisDestination,
  findNearestPort,
  PORTS,
} from '@arcnautical/maritime-routing';

// Search by name, country, or LOCODE
const ports = searchPorts('Singapore');    // [{ locode: 'SGSIN', ... }]
const ports = searchPorts('Japan', 50);   // up to 50 results

// Exact lookup
const sg = getPortByLocode('SGSIN');      // { name: 'Singapore', lat: 1.26, ... }

// By region
const medPorts = getPortsByRegion('mediterranean'); // 30+ ports

// Parse messy AIS destination strings
const port = resolveAisDestination('NL RTM');   // -> Rotterdam
const port = resolveAisDestination('>>SGSIN<<'); // -> Singapore

// Find nearest port to coordinates
const port = findNearestPort(51.9, 4.5);  // -> Rotterdam

// All 510+ ports
console.log(PORTS.length);

Weather Speed Model

import {
  computeSeaStateFactor,
  computeRouteEta,
  windToBeaufort,
  waveToBeaufort,
} from '@arcnautical/maritime-routing';

// Compute speed reduction from weather
const result = computeSeaStateFactor({
  baseSpeedKnots: 14,
  waveHeightM: 3.0,
  windSpeedKt: 25,
  swellHeightM: 1.5,
  vesselType: 'bulk',     // container | bulk | tanker | lng | general
  loadCondition: 'laden', // laden | ballast
  // Optional direction-aware inputs:
  waveDirectionDeg: 270,
  vesselHeadingDeg: 90,   // heading into waves = worst case
});

console.log(result.effectiveSpeedKnots); // reduced speed
console.log(result.beaufortNumber);      // 6
console.log(result.speedReductionPct);   // % reduction
console.log(result.seaStateFactor);      // 0-1 retention

// Compute ETA for a full route
const eta = computeRouteEta(
  segments,          // [{ distanceNm, bearing }]
  segmentWeather,    // per-segment weather data
  14,                // base speed (knots)
  'container',       // vessel type
  'laden',           // load condition
);
console.log(eta.totalTransitHours);
console.log(eta.worstSegmentIndex);

EEZ Transit Analysis

import { analyzeRouteEezTransit } from '@arcnautical/maritime-routing';

const result = analyzeRouteEezTransit(segments, totalDistanceNm);

for (const eez of result.transitEezs) {
  console.log(`${eez.countryName}: ${(eez.routeFraction * 100).toFixed(1)}%`);
  if (eez.isSanctioned) console.log('  ⚠ SANCTIONED');
}

console.log(result.sanctionedEezFraction); // 0-1
console.log(result.summary);              // human-readable

Geodesic Utilities

import {
  haversineDistance,
  haversineDistanceNm,
  bearing,
  interpolateGreatCircle,
  pointInPolygon,
} from '@arcnautical/maritime-routing';

// Distance in nautical miles
const nm = haversineDistanceNm(1.26, 103.84, 51.90, 4.50); // ~5,700

// Initial bearing (degrees)
const brg = bearing(1.26, 103.84, 51.90, 4.50); // ~315°

// Great circle arc interpolation
const points = interpolateGreatCircle(0, 0, 45, 90, 100);
// -> 101 [lat, lon] pairs along the arc

// Point-in-polygon test
const inside = pointInPolygon(5, 5, [[0,0], [10,0], [10,10], [0,10]]);

Data Sources

DataSourceLicense
Ocean gridOpenStreetMap water polygonsODbL
Port databaseUN/LOCODE + public maritime dataPublic domain
Speed modelKwon 2008, Lu et al. 2015Academic literature
EEZ boundariesUN CLCS / Flanders Marine InstitutePublic domain
Waypoint graphPublic maritime knowledgeN/A

Performance

OperationTime
Port lookup (by LOCODE)< 0.1ms
Port search (by name)< 1ms
Ocean pathfinding (single segment)8-50ms
Full route computation (Singapore → Rotterdam)~250ms
Speed model computation< 0.1ms
Grid loading (first call only)~900ms

Package size: ~200KB (compiled JS) + 106KB (ocean grid) + 90KB (EEZ data).

Comparison with searoute-js

Feature@arcnautical/maritime-routingsearoute-js
Last updated20262020
TypeScriptNativeNo
DependenciesZeroMultiple
Land avoidanceGuaranteed (bitmap)No (graph only)
Port database510+ portsNone
Weather modelBeaufort + CbetaNone
EEZ analysisYesNone
Avoid zonesYesNo
Via waypointsYesNo
Narrow passagesSuez, Panama, Bosphorus, etc.Limited
Resolution0.05° (~5.5km)Variable
Data sourceOSM (2024)ORNL (2000)

Advanced Usage

Custom Ocean Grid

import { setGridPath, loadGridFromBuffer } from '@arcnautical/maritime-routing';

// Use a custom grid file
setGridPath('/path/to/my-ocean-grid.bin.gz');

// Or load from a buffer (e.g., fetched from CDN)
const buffer = await fetch('https://cdn.example.com/ocean-grid.bin.gz')
  .then(r => r.arrayBuffer());
loadGridFromBuffer(new Uint8Array(buffer));

Generate Your Own Ocean Grid

The ocean grid is generated from OSM water polygon shapefiles:

# Download water polygons from osmdata.openstreetmap.de
# Then run the generator:
npx tsx scripts/generate-ocean-grid.ts /path/to/water_polygons.shp

Ocean Regions

Ports are classified into 16 ocean regions used for routing:

pacific, south_china_sea, southeast_asia, indian_ocean, persian_gulf, red_sea, mediterranean, atlantic_north, atlantic_south, caribbean, north_sea, baltic, black_sea, arctic, oceania, east_pacific

Vessel Types

The speed model supports 5 vessel types with distinct sea-keeping characteristics:

TypeReference SpeedTypical DWT
container20 kt50,000-200,000
bulk14 kt30,000-400,000
tanker14 kt50,000-320,000
lng19 kt70,000-180,000
general14 kt5,000-40,000

License

MIT - see LICENSE.

About

Built by ArcNautical — maritime risk intelligence for fleet managers, underwriters, and compliance teams.

ArcNautical provides voyage risk scoring, sanctions screening, piracy/conflict threat intelligence, and automated compliance reports. The routing engine you're using here powers our commercial platform.

If you need maritime risk intelligence beyond routing, get in touch.

版本与发布记录

@arcnautical/maritime-routing 共发布 2 个版本,首次发布于 2026/03/23;过去 12 个月发布了 2 个版本。

版本发布日期距今
1.0.1latest2026/09/181 个月前
1.0.02026/03/237 个月前

关于 @arcnautical/maritime-routing 的常见问题

@arcnautical/maritime-routing 是什么?

Production-grade maritime routing engine — A* ocean pathfinding, Dijkstra waypoint routing, 510+ port database, weather-aware ETA, EEZ analysis. Zero dependencies.

如何安装 @arcnautical/maritime-routing?

在项目目录运行 npm install @arcnautical/maritime-routing,或使用 pnpm add / yarn add / bun add。

@arcnautical/maritime-routing 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@arcnautical/maritime-routing 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@arcnautical/maritime-routing 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=18.0.0。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@arcnautical/maritime-routing 可以商用吗?

@arcnautical/maritime-routing 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@arcnautical/maritime-routing 的下载量有多少?

根据 npm 官方下载统计,@arcnautical/maritime-routing 在 2026/10/07 – 2026/11/05 这 30 天内被下载 2,306 次,日均约 77 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@arcnautical/maritime-routing 还在维护吗?

最新版本 1.0.1 发布于 2026/09/18(1 个月前);至今共发布 2 个版本,其中过去 12 个月发布了 2 个;首次发布于 2026/03/23。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。