searoute について
searoute-tsは、座標やUN/LOCODEの港を使って海上ルートを計画するTypeScript/JavaScriptライブラリです。GeoJSONの航路を出力し、通過制限、喫水条件、代替ルート、複数区間の行程、所要時間の推定に対応します。
主な機能
- 01海上距離の計算とGeoJSON出力
- 02運河・海峡の制限または指定
- 03喫水に応じた運河の通過制御
- 04代替ルートと複数区間の経路
- 05船速に基づく所要時間の推定
- 06座標とUN/LOCODEによる入力
活用シーン
- 01港間の航行距離と所要時間の比較
- 02運河や海峡の通行不可時の迂回
- 03船舶の喫水に合った航路の計画
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
ツール
2掲載時のツール一覧 · 2 週間前に更新
| パラメーター | 型 | 必須 | 説明 |
|---|---|---|---|
| units | enum | いいえ | 返される距離の単位。nauticalmiles | kilometers | miles |
| origin | any | はい | UN/LOCODE 港湾コード文字列、または [longitude, latitude] 座標のペア。 |
| speedKnots | number | いいえ | 船舶の速度(ノット単位)。指定すると、時間単位の推定所要時間が返されます。 |
| allowArctic | boolean | いいえ | 氷で閉ざされた北西航路/北東航路の通航を許可します(デフォルトでは禁止)。 |
| destination | any | はい | |
| restrictions | array | いいえ | 航路で回避する必要がある指定の海峡。例:["suez","babelmandeb"] を指定すると、紅海の航行が途絶した際に喜望峰経由の航路になります。 |
| includeGeometry | boolean | いいえ | 結果に航路の LineString GeoJSON を含めます。 |
| maxSnapDistanceKm | number | いいえ | 海上ネットワークからこの距離(km)を超える入力を拒否します。 |
| vesselDraftMeters | number | いいえ | 船舶の喫水(メートル)。水深が足りない運河は自動的に回避されます。 |
詳細
searoute-ts
地球上の任意の2地点間の最短海路。 TypeScript / JavaScript 用の海上ルート計画、港間距離、到着予定時刻の推定、航路の可視化を行うライブラリです。2025 年版 Eurostat の海上ネットワークを利用しています。
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
🗺️ インタラクティブデモを試す — 地図上の2地点をクリックすると、すべてのオプションをリアルタイムで反映したルートを確認できます。 (ソース)
📏 港間の海上距離 — 主要港間の一般的なルートについて、距離、航行時間、運河の通過情報を確認できます。
通常の JavaScript でも動作します。パッケージにはコンパイル済みの
.jsと.d.ts宣言が含まれています。名前の-tsは検索しやすくするためのもので、 TypeScript の使用は必須ではありません。
searoute-ts を選ぶ理由
- 🚢 現実的な航路。ユーラシア大陸を横切る大圏航路ではありません。
- 🗺️ GeoJSON を返します。Leaflet、Mapbox、deck.gl、MapLibre にそのまま取り込めます。
- 🌊 2025 年版 Eurostat marnet。スエズ、パナマ、バブ・エル・マンデブ、 マラッカ、ジブラルタル、ドーバー、キール、コリントス、ベーリング、マゼラン、 北西/北東航路のラベルを明示しています。
- 🚫 運河と海峡の通航制限。オプションを1つ指定するだけで、紅海の航行障害時に喜望峰経由を強制できます。
- 📦 船舶喫水に応じた制限。船舶が運河の制限を超える場合、パナマ(15.2 m)、スエズ(20.1 m)、キール (7 m)、コリントス(7.3 m)を自動的に通航不可にします。
- 🛤️ K 個の最短代替ルート。
seaRouteAlternativesは、基準ルートに加えて最大 N 個の現実的な代替ルートを返します。 - 🧭 複数区間の経由地。港を巡るローテーションや行程には
seaRouteMultiを使用できます。 - ⏱️ 速度から到着予定時刻を計算。
speedKnots→durationHours。 - 🛠️ 最新のツールチェーン。TypeScript 5、ESM + CJS のデュアルビルド、型定義を同梱、Node 18 以上、peer dependency は不要です。
簡単な使用例
基本 — 最短ルート
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 はさらに高解像度のデータも公開しており、ダウンロードサイズが大きくなり、最初のルート検索時のグラフ構築がわずかに遅くなる代わりに、沿岸ルートの精度と短い区間の忠実度が向上します。中程度の解像度のうち 2 種類はサブパスエクスポートとして提供されるため、インポートした場合にのみその分のデータを読み込みます。
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 km | 9,847 | 約 1.3 MB | 約 0.18 MB | 基準 — グローバルなルート検索に適しています |
searoute-ts/marnet-50km | 50 km | 15,498 | 約 1.9 MB | 約 0.27 MB | 適度に精度が向上 |
searoute-ts/marnet-20km | 20 km | 29,581 | 約 3.6 MB | 約 0.51 MB | 沿岸の区間が目に見えて細かくなります |
loadNetwork 経由(下記参照) | 10 km | 48,301 | 約 5.9 MB | 約 0.84 MB | 高精度 — ダウンロードサイズは大きめ |
loadNetwork 経由(下記参照) | 5 km | 72,478 | 約 9.0 MB | 約 1.24 MB | 最高精度 — ダウンロードサイズは最大 |
10 km と 5 km のネットワークは、同梱するとインストールサイズの大部分を占めるほど大きいため、パッケージには含まれていません。Eurostat のソースから scripts/build-marnet.cjs を使って生成し(GDAL による変換方法はスクリプトのヘッダーに記載されています)、生成した JSON をホストして、loadNetwork で読み込んでください。または、任意の FeatureCollection<LineString> を network オプションに直接渡すこともできます。
出力形式
{
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 オブジェクト、または searoute-ts/ports をインポートした後の UN/LOCODE 文字列(例:'CNSHA')を使用できます。
日付変更線の処理
±180°の子午線を横切るルート(例:横浜 → LA)は、デフォルトでは [-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 に概算値が 2 つ追加されます。
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 |
| NY → ロッテルダム | 6 227 km | ~6 200 km |
| NY → LA(パナマ) | 9 154 km | ~9 100 km |
| 横浜 → LA | 9 145 km | ~8 800 km |
| シンガポール → LA(太平洋横断) | 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 エージェント(MCP)から使用する
付属のModel Context Protocolサーバー、
@searoute-ts/mcp(ソース)
を使うと、AI エージェント(Claude Desktop、claude CLI など)が推測ではなく実際の海路を計算できます。「上海からロッテルダムまで海路でどれくらいの距離ですか。スエズ運河を避けると?」と尋ねると、ライブラリが直接呼び出されます。sea_route と sea_route_alternatives の2つのツールを公開し、港コード('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 形式のレポートも、呼び出しを1回追加するだけで作成できます。
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 エージェントはsea_route → rail_routeを連携させて、戸口から戸口までの距離を計算できます(以下を参照)。
仕組み
グラフデータ、スナップ処理、Dijkstra、通行制限、日付変更線への対応、喫水のロジック、代替ルートについて詳しく解説する2ページの資料をDOCS.mdでご覧いただけます。
FAQ
これは航海用ですか? いいえ。このルートは可視化や距離・所要時間の概算に適したネットワーク経路であり、船舶の操船用ではありません。
気象を考慮したルート設定に対応していますか? いいえ。気象を考慮したルート設定については、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 で修正されています。^1の範囲指定ではこのバージョンが選ばれないため、searoute-ts@^2をインストールしてください。アップグレード時は、名前付きインポートのimport { seaRoute }を使用してください。エラー時はnullを返すのではなく、NoRouteError/SnapFailedErrorがスローされるようになりました。また、1.x では海里の長さが過大に計算されていたため、値が約24%小さくなっています。CHANGELOGにある2.0.0の移行に関する注記をご覧ください。
大円距離は日付変更線を越える場合も正確ですか? はい。marnet は太平洋が連結グラフになるよう正規化されており、すべての距離は内部で haversine を使って計算されます。
バンドルサイズはどれくらいですか? 実行時にインポートするものは小さく、コアと同梱の100 km marnet(約1.1 MB の JSON。各ビルドにインライン化されるのではなく、両方のビルドで読み込まれる共有アセットdist/data/marnet.cjsとして一度だけ同梱)で構成されます。ツリーシェイキングに対応しているため、オプションのsearoute-ts/marnet-20km/marnet-50kmネットワークはインポートした場合にのみ読み込まれます。ただし、npm の tarball のサイズには追加されます。これらを含めると、パッケージのサイズは圧縮時で約1.1 MB、展開時で約7 MBです(各バリアントは共有アセット1つであり、ビルドごとに重複しません)。インストールサイズを増やさずにより高解像度のネットワークを使いたい場合は、それらを生成してホストし、代わりにloadNetworkを使用してください。
クレジット
- 海上ネットワーク — Eurostat searoute v3.5 (EUPL-1.2)。Oak Ridge National Labs の Global Shipping Lane Network に ヨーロッパの AIS データを追加したものです。
- Dijkstra — Per Liedman による
geojson-path-finder@2。 searoute-py(Apache-2.0)に着想を得ています。- JavaScript への最初の移植 — @johnx25bd。
- 地理空間プリミティブ — Turf.js。
ライセンス
MIT © Mayur Rawte
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。