mcpField
S
searoute

searoute

本地服务
github.com/mayurrawte地图与出行102 周前更新

关于 searoute

searoute-ts 是用于海上路线规划的 TypeScript/JavaScript 库,支持坐标和 UN/LOCODE 港口输入。它生成 GeoJSON 航线,并可设置航道限制、船舶吃水条件、备选路线、多段行程和预计航时。

主要功能

  1. 01海上航程计算与 GeoJSON 输出
  2. 02限制或指定运河及海峡
  3. 03按船舶吃水限制运河
  4. 04备选路线与多段航线
  5. 05按航速估算航时
  6. 06坐标与 UN/LOCODE 输入

适用场景

  1. 01比较港口间航程和预计航时
  2. 02因运河或海峡受阻而改道
  3. 03规划适配船舶吃水的航线

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"mayurrawte-searoute": {
"command": "npx",
"args": [
"-y",
"@searoute-ts/mcp"
]
}
}
}
启动命令npx -y @searoute-ts/mcp

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
npm@searoute-ts/mcp0.1.1

工具

2

收录的工具列表 · 更新于 2 周前

参数类型必填说明
unitsenum否返回距离的单位。nauticalmiles | kilometers | miles
originany是UN/LOCODE 港口代码字符串,或 [longitude, latitude] 坐标对。
speedKnotsnumber否船舶速度,单位为节;提供此值时,将返回以小时为单位的预计时长。
allowArcticboolean否允许通过被冰封的西北/东北航道(默认禁止)。
destinationany是
restrictionsarray否路线必须避开的指定海峡。例如,["suez","babelmandeb"] 会在红海中断期间强制改走好望角航线。
includeGeometryboolean否在结果中包含航线 LineString GeoJSON。
maxSnapDistanceKmnumber否拒绝距离海上航运网络超过此值(km)的输入。
vesselDraftMetersnumber否船舶吃水深度,单位为米;水深不足以通行的运河会自动避开。

详细介绍

searoute-ts

地球上任意两点之间的最短海上航线。 一个用于规划海上航线、计算港口间距离、估算到达时间和可视化航运路线的 TypeScript / JavaScript 库,基于 2025 Eurostat 海事网络构建。

npm version npm downloads CI license types

npm install searoute-ts
import { seaRoute } from 'searoute-ts';

const route = seaRoute([121.5, 31.0], [4.4, 51.9]);
// Shanghai → Rotterdam → GeoJSON LineString, ~10,664 nm via Suez Canal

🗺️ 试用交互式演示 — 在地图上点击两个点,即可查看航线,并实时调整所有选项。(源代码)

📏 港口间海上距离 — 常见主要港口航线的距离、航行时间和运河通行情况。

也可直接使用纯 JavaScript — 软件包包含编译后的 .js 文件和 .d.ts 声明文件。名称中的 -ts 只是为了便于搜索,并非语言要求。


为什么选择 searoute-ts

  • 🚢 真实的航运路线,而非穿越欧亚大陆的球面大圆航线。
  • 🗺️ 返回 GeoJSON — 可直接用于 Leaflet、Mapbox、deck.gl、MapLibre。
  • 🌊 2025 Eurostat marnet,明确标注苏伊士、巴拿马、曼德海峡、 马六甲、直布罗陀、多佛、基尔、科林斯、白令、麦哲伦、西北/东北航道。
  • 🚫 运河和海峡限制 — 只需一个选项,即可在红海中断时强制绕行好望角。
  • 📦 船舶吃水限制 — 船舶超出运河限值时,自动限制通行巴拿马运河(15.2 m)、苏伊士运河(20.1 m)、基尔运河 (7 m)、科林斯运河(7.3 m)。
  • 🛤️ K 条最短备选路线 — seaRouteAlternatives 返回基准路线 以及最多 N 条真实可行的备选路线。
  • 🧭 多段航点 — 使用 seaRouteMulti 规划港口轮换和行程。
  • ⏱️ 根据速度估算到达时间 — speedKnots → durationHours。
  • 🛠️ 现代工具链 — TypeScript 5、ESM + CJS 双构建、包含类型定义、 Node 18+,无对等依赖。

快速示例

基础用法 — 最短航线
import { seaRoute } from 'searoute-ts';

const route = seaRoute([-74.04, 40.69], [-0.13, 51.5]); // NYC → London
// route.properties.length  // ≈ 3 362 nm
// route.properties.units   // 'nauticalmiles'
包含预计到达时间和单位
seaRoute(shanghai, rotterdam, {
  units: 'kilometers',
  speedKnots: 22,
});
// → 19 753 km, properties.durationHours ≈ 485 h (≈ 20 days)
红海 / 苏伊士中断 — 强制绕行好望角
seaRoute(shanghai, rotterdam, {
  restrictions: ['suez', 'babelmandeb'],
});
// → routes via Cape of Good Hope, ~25 800 km
感知船舶类型 — 超大型集装箱船
seaRoute(shanghai, newYork, {
  vesselDraftMeters: 16,  // exceeds Panama's 15.2 m TFW
});
// → Panama auto-blocked, route goes via Suez
港口代码(UN/LOCODE)
import 'searoute-ts/ports'; // enables UN/LOCODE strings on the core API
import { seaRoute } from 'searoute-ts';

seaRoute('CNSHA', 'NLRTM'); // Shanghai → Rotterdam
seaRoute('CNSHA', [4.4, 51.9]); // mixing a code and coordinates is fine too

约 1 600 个港口的数据集位于 searoute-ts/ports 子路径下,以保持核心部分精简 — 导入该子路径即可注册解析器。你也可以自行解析代码:

import { lookupPort, resolvePort } from 'searoute-ts/ports';

lookupPort('SGSIN'); // → { code, name: 'Singapore', country, coordinates: [lon, lat] }
resolvePort('SGSIN'); // → [103.85, 1.28]

未知代码会抛出 UnknownPortError。有关数据来源,请参阅下文的港口代码。

从 CDN 加载港口数据集,而非打包到项目中

不想打包约 135 KB 的数据集?可以使用 loadPorts 在运行时获取 — 它相当于 loadNetwork。 该数据集也以原始 dist/ports.json 文件形式提供,因此 jsDelivr/unpkg 可免费提供带版本号的文件:

import { seaRoute, loadPorts } from 'searoute-ts';

// Pin a version for reproducibility, or use @latest to always get the newest.
await loadPorts('https://cdn.jsdelivr.net/npm/searoute-ts@latest/dist/ports.json');

seaRoute('CNSHA', 'NLRTM'); // works — the fetched dataset is now registered
https://cdn.jsdelivr.net/npm/searoute-ts@latest/dist/ports.json      # newest
https://cdn.jsdelivr.net/npm/searoute-ts@<version>/dist/ports.json   # frozen/immutable

(dist/ports.json 从新增港口代码的版本起随发布包提供 — 为确保可复现性,请固定到该版本或更高版本。)

loadPorts 会注册获取的数据集(因此可以解析字符串代码),并返回该数据集。 它使用全局 fetch(Node ≥18 / 浏览器);传入 { fetch } 可覆盖默认值。

多段航线 / 港口轮换
import { seaRouteMulti } from 'searoute-ts';

seaRouteMulti(
  [shanghai, singapore, mumbai, rotterdam],
  { units: 'kilometers', returnPassages: true },
);
// → one concatenated LineString, total length, union of passages
备选航线(Yen 风格的运河排列)
import { seaRouteAlternatives } from 'searoute-ts';

const alts = seaRouteAlternatives(shanghai, rotterdam, { k: 4 });
//  baseline           19 753 km via Suez
//  no-malacca         20 759 km
//  no-suez            25 315 km (via Panama)
//  no-suez-no-panama  25 845 km (via Cape of Good Hope)
从 URL 获取网络,而不是将其打包(可选)

默认情况下,网络会随包一起打包,因此 seaRoute 无需任何设置即可离线运行。 如果你不想随包发布约 1 MB 的网络(例如为了缩减浏览器包体积, 或希望使用更新的网络而不升级软件包),可以在运行时获取网络,并通过现有的 network 选项传入:

import { seaRoute, loadNetwork } from 'searoute-ts';

// CORS-enabled, served from GitHub Pages (or point at your own host / a CDN).
const network = await loadNetwork('https://mayurrawte.github.io/searoute-ts/marnet.json');

const route = seaRoute(shanghai, rotterdam, { network });

只有获取操作是异步的,seaRoute 本身仍保持同步。loadNetwork 使用全局 fetch(Node ≥18 和所有浏览器均支持);传入 { fetch } 可使用 自定义实现。此功能完全可选;如果不使用它,一切保持不变。

我应该使用哪种方式?
方式用法数据版本支持离线最适合
随包打包(默认)seaRoute(a, b) — 不传入 network固定为已安装软件包中的版本✅大多数用户;无需配置,结果可确定
通过 URL 获取最新版本loadNetwork('…/marnet.json')始终使用托管的最新版本❌ 需要网络无需升级即可使用始终最新的数据
通过 CDN 固定版本loadNetwork('https://cdn.jsdelivr.net/npm/[email protected]/…')固定不变(不可变)❌ 需要网络可复现的构建
为托管的网络指定版本

通过选择 URL 来选择版本:

  • @latest / 滚动版本 — 上文的 GitHub Pages URL 始终提供当前网络。 使用方便,但网络可能会在你不知情的情况下发生变化。

  • 固定且不可变 — 由于该软件包发布在 npm 上,jsDelivr 和 unpkg 会自动提供所有已发布版本,并为每个版本提供不可变的 URL:

    https://cdn.jsdelivr.net/npm/searoute-ts@latest/dist/marnet.json   # newest
    https://cdn.jsdelivr.net/npm/searoute-ts@2/dist/marnet.json        # newest 2.x
    https://cdn.jsdelivr.net/npm/[email protected]/dist/marnet.json    # frozen
    

    固定的 URL 永不变化,因此路由结果可复现。(独立 JSON 的 CDN 路径要等到网络作为单独资源发布后才会随软件包提供 — 参见 issue #10;在此之前,请使用 GitHub Pages URL。)

在生产环境中,建议使用固定的 URL(或直接使用默认的随包打包方式),以免网络更新导致距离发生变化。

更高分辨率的网络(可选)

随包打包的网络是 Eurostat 的 100 km marnet_plus。Eurostat 还 发布了更高的分辨率,可提供更准确的沿海路径规划和更短的跳点,但代价是下载量更大, 首次构建路由图的速度也会略慢。两种适中的分辨率以子路径导出的形式提供,因此只有在导入时才会产生相应开销:

import { DEFAULT_MARNET } from 'searoute-ts/marnet-20km'; // or 'searoute-ts/marnet-50km'
import { seaRoute } from 'searoute-ts';

seaRoute(origin, destination, { network: DEFAULT_MARNET });

与默认的随包网络一样,每个变体只会作为共享的 dist/data/marnet-<res>.cjs 资源发布一次,CJS 和 ESM 构建都会在运行时加载它,因此导入变体不会导致网络在不同构建中重复打包。

导入分辨率线段数JSON 大小gzip 后大小沿海精度
searoute-ts(默认随包版本)100 km9,847~1.3 MB~0.18 MB基准 — 适用于全球路径规划
searoute-ts/marnet-50km50 km15,498~1.9 MB~0.27 MB精度略有提升
searoute-ts/marnet-20km20 km29,581~3.6 MB~0.51 MB沿海跳点精细得多
通过 loadNetwork(见下文)10 km48,301~5.9 MB~0.84 MB精度高 — 下载量较大
通过 loadNetwork(见下文)5 km72,478~9.0 MB~1.24 MB精度最高 — 下载量最大

10 km 和 5 km 网络体积足够大,打包后会占据安装内容的大部分,因此不会 随软件包发布。请使用 scripts/build-marnet.cjs 从 Eurostat 源数据生成它们(脚本头部介绍了 GDAL 转换),托管生成的 JSON,然后使用 loadNetwork 加载它,或直接向 network 选项传入任意 FeatureCollection<LineString>。

输出格式

{
  type: 'Feature',
  geometry: { type: 'LineString', coordinates: [[lon, lat], ...] },
  properties: {
    length: number,                    // in `units`, in-water only
    units: 'nauticalmiles' | 'kilometers' | 'miles' | ...,
    bbox: [minLon, minLat, maxLon, maxLat],
    greatCircleLength: number,         // haversine between inputs, same units
    detourRatio: number,               // routeKm / greatCircleKm
    originSnapKm: number,              // input → network distance
    destinationSnapKm: number,
    durationHours?: number,            // if `speedKnots` set
    passages?: ('suez' | 'panama' | ...)[],  // if `returnPassages: true`
    ecaKm?: number,                    // if `emissions` + `searoute-ts/eca` imported
    ecaFraction?: number,              // ecaKm / length (0–1)
    co2eTonnes?: number,               // if `emissions` + `vesselClass`/factor
  }
}

length 是两个吸附后的网络顶点之间的距离,不包括输入点到网络的路段(originSnapKm、destinationSnapKm,单位始终为 km),即使设置了 appendOriginDestination: true 也是如此;该选项只会将原始点添加到线路中。若要计算门到门的距离,请自行将它们加上:

const { length, originSnapKm, destinationSnapKm } = seaRoute(a, b, { units: 'kilometers' }).properties;
const doorToDoorKm = originSnapKm + length + destinationSnapKm;

对于短于网络分辨率的航段(默认约 100 km,使用 searoute-ts/marnet-20km 时约 20 km),吸附后的顶点可能比输入点更靠近彼此,因此 length 可能小于 greatCircleLength(detourRatio < 1)。如果两个输入点都吸附到同一个顶点,则会抛出 NoRouteError。

完整选项

seaRoute(origin, destination, {
  units:                   'nauticalmiles',          // any Turf unit
  restrictions:            ['suez', 'babelmandeb'],  // block passages (see table below)
  via:                     ['panama'],               // require passages (inverse of restrictions)
  allowArctic:             false,                    // default — blocks NWP & NEP
  vesselDraftMeters:       15,                       // auto-restrict canals
  speedKnots:              22,                       // → properties.durationHours
  appendOriginDestination: false,                    // prepend/append raw inputs
  returnPassages:          true,                     // populate properties.passages
  maxSnapDistanceKm:       50,                       // SnapFailedError if exceeded
  network:                 customMarnet,             // BYO FeatureCollection
  antimeridian:            'split',                  // 'unwrap' | 'split' dateline handling
  emissions:               true,                     // → properties.ecaKm / co2eTonnes
  vesselClass:             'panamax',                // CO₂e estimate class
  co2eFactorKgPerKm:       225,                      // override the class factor
  glecInflation:           0.15,                     // +15% distance for CO₂e (GLEC)
});

输入可以是 [lon, lat] 数组、GeoJSON Feature<Point>、裸 Point 对象,或 UN/LOCODE 字符串(例如 'CNSHA';需先导入 searoute-ts/ports)。

反子午线(国际日期变更线)处理

默认情况下,跨越 ±180° 子午线的航线(例如横滨 → 洛杉矶)会被限制在 [-180, 180] 范围内返回,许多地图渲染器会将其绘制成横跨整幅地图的直线。传入 antimeridian 可获取适用于地图的几何数据:

seaRoute(yokohama, la, { antimeridian: 'unwrap' }); // continuous LineString (may exceed ±180)
seaRoute(yokohama, la, { antimeridian: 'split' });  // MultiLineString cut at ±180 (RFC 7946)

'unwrap' 会将经度按 360° 的倍数平移,使线条不会在国际日期变更线处跳变(适用于 MapLibre/Leaflet/Deck.gl)。'split' 会在 ±180° 处切分航线,生成 MultiLineString,并确保所有坐标都在范围内。两种方式都适用于 seaRoute 和 seaRouteMulti;无论采用哪种方式,properties.length 都不会改变。

强制航线经过某条航道(via)

restrictions 会封锁一条航道;via 则会要求经过一条航道,作用正好相反。可用它来比较明确指定的航线,例如“经苏伊士运河”与“经好望角”,或强制亚洲与欧洲之间的航线经太平洋和巴拿马运河:

seaRoute('CNSHA', 'NLRTM', { via: ['suez'] });   // through Suez (the default)
seaRoute('CNSHA', 'NLRTM', { via: ['panama'] });  // across the Pacific + Panama instead

via 接受与 restrictions 相同的航道名称,并按给定顺序经过多条航道。它会通过多航段机制,沿每条航道的位置规划“起点 → 航道 → 终点”航线,因此可以与其他选项组合使用。via 中指定的航道不会被要求本身封锁(via: ['northeast'] 会经过东北航道,无需同时设置 allowArctic)。在 via 和 restrictions 中指定同一条航道会构成矛盾,并抛出 NoRouteError。

排放与 ECA/SECA 报告

设置 emissions: true,即可在 properties 中启用两项粗略估算:

import 'searoute-ts/eca';                 // load the ECA/SECA zones (enables ecaKm)
import { seaRoute } from 'searoute-ts';

const r = seaRoute('CNSHA', 'NLRTM', {
  emissions: true,
  vesselClass: 'panamax',                 // → co2eTonnes
});
r.properties.ecaKm;        // km of the route inside emission-control zones
r.properties.ecaFraction;  // that as a fraction of route length (0–1)
r.properties.co2eTonnes;   // rough CO₂e estimate for the voyage
  • ecaKm ——航线有多少里程位于 ECA/SECA 排放控制区域(波罗的海、北海、地中海、北美和美国加勒比海地区),这会影响燃料类型和成本。为保持核心精简,这些区域数据位于 searoute-ts/eca 子路径导出中;导入该模块即可注册这些区域。它们是 IMO MARPOL 附则 VI 区域的边界框近似值,适用于估算,不适用于合规判定。可通过 registerEcaZones 替换为精度更高的多边形。
  • co2eTonnes ——使用“距离 × 船舶类别系数”得出的简化估算值,不是经认证的数据。系数根据具有代表性的燃料消耗量和 IMO HFO CO₂ 转换值透明推算得出(参见 VESSEL_CLASSES);可通过 co2eFactorKgPerKm 覆盖。GLEC 建议将最短路径距离增加约 15 %,以反映实际偏差;请传入 glecInflation: 0.15。

可限制的航道

前 12 条在 Eurostat marnet 中原生标记(与要素的 pass 属性完全匹配)。其余 4 条通过边界框检测。

名称类型备注
suez原生苏伊士运河
panama原生巴拿马运河
gibraltar原生直布罗陀海峡
babelmandeb原生曼德海峡(别名为 babalmandab)
malacca原生马六甲海峡
dover原生多佛尔海峡
kiel原生基尔运河
corinth原生科林斯运河
bering原生白令海峡
magellan原生麦哲伦海峡
northwest原生西北航道(默认封锁)
northeast原生东北航道(默认封锁)
bosporus边界框博斯普鲁斯海峡
ormuz边界框霍尔木兹海峡
sunda边界框巽他海峡
cape_horn边界框合恩角区域

对于许多亚洲 ↔ 欧洲航线,西北航道和东北航道在数学上是最短路径,但一年中大部分时间都被冰封,因此默认封锁。使用 allowArctic: true 可启用。

根据行业距离数据验证

12 条真实世界航线与已发布的 Searoutes / Sea-Distances 数据相差在 ±10% 以内。

航线searoute-ts行业参考值
上海 → 鹿特丹(苏伊士)19 753 km~19 300 km
新加坡 → 鹿特丹(苏伊士)15 630 km~15 500 km
孟买 → 鹿特丹(苏伊士)11 918 km~11 800 km
纽约 → 鹿特丹6 227 km~6 200 km
纽约 → 洛杉矶(巴拿马)9 154 km~9 100 km
横滨 → 洛杉矶9 145 km~8 800 km
新加坡 → 洛杉矶(跨太平洋)14 364 km~14 300 km
卡尔德拉(CL)→ 布兰卡港(AR)4 810 km~5 180 km

所有检查均通过测试套件。

错误

  • SnapFailedError — 输入无法在 maxSnapDistanceKm 范围内投影到网络上。包含 .side: 'origin' | 'destination' 和 .distanceKm: number。
  • NoRouteError — 捕捉后的起点和终点之间不存在路径(例如,所有可用运河都被封锁)。

API 参考

import {
  seaRoute,                  // single shortest route
  seaRouteMulti,             // ordered waypoints (multi-leg)
  seaRouteAlternatives,      // K-shortest alternatives
  loadNetwork,               // optional: fetch a network from a URL/CDN
  CANAL_MAX_DRAFT_M,         // { panama: 15.2, suez: 20.1, kiel: 7, corinth: 7.3 }
  DEFAULT_MARNET,            // bundled FeatureCollection<LineString>
  PASSAGE_BBOXES,            // passage bbox lookup
  clearFinderCache,          // drop the PathFinder cache (tests / hot reload)
  SnapFailedError,
  NoRouteError,
  UnknownPortError,          // thrown for unresolved UN/LOCODE strings
  registerPortResolver,      // plug in a custom port dataset
  // types
  type Passage,
  type Antimeridian,
  type SeaRouteOptions,
  type SeaRouteFeature,
  type SeaRouteMultiFeature,
  type SeaRouteProperties,
  type LoadNetworkOptions,
  type MarnetNetwork,
  type MarnetProperties,
} from 'searoute-ts';

import {
  lookupPort,                // UN/LOCODE → { code, name, country, coordinates }
  resolvePort,               // UN/LOCODE → [lon, lat]
  PORTS,                     // the raw dataset (Record<code, PortRecord>)
  PORT_COUNT,
  type Port,
  type PortRecord,
} from 'searoute-ts/ports';

港口代码(UN/LOCODE)

起点和终点可使用 UN/LOCODE 字符串(例如 'CNSHA')而非坐标指定。港口数据集通过 searoute-ts/ports 子路径导出提供,因此只有在使用时才会产生相应开销——导入该子路径(无论使用其任一导出,还是仅利用其副作用)都会向核心注册解析器,因此 seaRoute('CNSHA', 'NLRTM') 可以正常工作。

  • 约 1 600 个海港,以 UN/LOCODE 为键(包含主代码和别名)。
  • 来源:marchah/sea-ports(MIT),其数据本身源自 UN/LOCODE。使用 scripts/build-ports.cjs 重新生成。
  • 坐标为近似值(精度为港口所在城市)——路由引擎无论如何都会将其捕捉到网络上,因此对于距离计算和可视化而言足够准确。
  • 未知或格式错误的代码会抛出 UnknownPortError。

在 AI Agent 中使用(MCP)

配套的 Model Context Protocol 服务, @searoute-ts/mcp(源代码), 可让 AI Agent(Claude Desktop、claude CLI 等)计算真实海上航线,而不是靠猜测——询问“从上海到鹿特丹的海上距离是多少,且避开苏伊士运河?”时,它会直接调用该库。它提供两个工具:sea_route 和 sea_route_alternatives,并接受港口代码('CNSHA')或坐标。

claude mcp add searoute -- npx -y @searoute-ts/mcp

也可以将其添加到任意 MCP 客户端配置中:

{
  "mcpServers": {
    "searoute": {
      "command": "npx",
      "args": ["-y", "@searoute-ts/mcp"]
    }
  }
}

完整的工具参考请参阅服务的 README。 对于铁路路段,可同时添加 @railroute-ts/mcp (claude mcp add railroute -- npx -y @railroute-ts/mcp)。

多式联运:添加铁路路段(railroute-ts)

海上距离很少能代表整段运输。姊妹库 railroute-ts 可在 OpenStreetMap 铁路网络上规划路线(内置欧洲网络、API 形式相同、GeoJSON 输出相同),因此只需再调用一次,即可获取港口到内陆的报价,或生成类似 GLEC/CountEmissions 的报告:

import 'searoute-ts/ports';
import { seaRoute } from 'searoute-ts';
import { railRoute } from 'railroute-ts';
import { EUROPE_NETWORK } from 'railroute-ts/networks/europe';

const sea  = seaRoute('CNSHA', 'NLRTM', { units: 'kilometers', emissions: true, vesselClass: 'panamax' });
const rail = railRoute([4.47, 51.92], [8.92, 44.41], { network: EUROPE_NETWORK, speedKmh: 60 }); // Rotterdam → Genoa

sea.properties.length;        // ≈ 19,753 km  Shanghai → Rotterdam via Suez
sea.properties.co2eTonnes;    // ≈ 4448 t CO₂e (rough, see Emissions above)
rail.properties.length;       // ≈ 1,180 km  Rotterdam → Genoa via the Gotthard base tunnel
rail.properties.gaugeChanges; // 0 — standard gauge all the way

npm install railroute-ts — 文档和交互式演示。 这两个库都提供 MCP 服务,因此 AI Agent 可以依次调用 sea_route → rail_route,计算门到门距离(见下文)。

工作原理

图数据、吸附、Dijkstra、限制、反经线修复、吃水逻辑和备选路线的两页深入介绍,请参阅 DOCS.md。

常见问题

此工具可用于导航吗? 不可以。这些路线是适用于可视化以及粗略距离/时长估算的网络路径,不能用于驾驶船舶。

支持天气航线规划吗? 不支持。有关天气感知航线规划,请参阅 VISIR-2。

为什么我的亚洲→欧洲航线会经过白令海峡? 默认情况下不会——西北航道和东北航道处于封锁状态。传入 allowArctic: true 即可启用。

可以使用自己的网络吗? 可以——seaRoute(origin, destination, { network })。 适用于内陆水道或基于 AIS 构建的自定义图。有关更高分辨率的 Eurostat 数据(5/10/20/50 km),请参阅 更高分辨率网络——20 km 和 50 km 版本以子路径导出的形式提供。

它能处理红海/苏伊士危机吗? 可以——传入 restrictions: ['suez', 'babelmandeb'],即可强制航线绕行好望角。

在 1.x 上出现 Cannot find module '…/searoute-ts/dist/lib/utils'? 1.x(截至 1.2.1)在 "main" 下提供了带无扩展名导入的 ESM 构建,因此未经修补的 Node 无法加载。此问题已在 2.0 中修复:请安装 searoute-ts@^2, 因为 ^1 范围不会安装此版本。升级时,请使用具名导入 import { seaRoute }。现在,失败时会抛出 NoRouteError / SnapFailedError, 而不是返回 null;海里长度也缩短了约 24%,因为 1.x 的计算值偏大。请参阅 CHANGELOG 中的 2.0.0 迁移说明。

跨越反经线时的大圆距离正确吗? 正确——marnet 已经过标准化,使太平洋成为连通图,且所有距离在内部都使用 haversine 计算。

包体积有多大? 运行时导入的内容很小:核心代码加上内置的 100 km marnet(约 1.1 MB JSON,仅作为共享的 dist/data/marnet.cjs 资源随包发布一次,由两种构建共同加载,而不是分别内嵌到每种构建中)。 它支持 Tree-shaking,因此只有在导入可选的 searoute-ts/marnet-20km / marnet-50km 网络时才会加载。不过,这些网络确实会增加 npm 压缩包的大小——包含它们时,包的压缩大小约为 1.1 MB/解压后约为 7 MB(每个变体都是单个共享资源,不会在每种构建中重复)。如果需要更精细的网络但又不想增加安装体积,可以自行生成并托管它们,然后改用 loadNetwork。

致谢

许可证

MIT © Mayur Rawte

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。