Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 4 additions & 0 deletions data/4!types.csv
Original file line number Diff line number Diff line change
Expand Up @@ -325,3 +325,7 @@ DEFAULT,548,区間快速(福間~鳥栖間快速・南福岡~博多間各駅
DEFAULT,549,区間快速(折尾~鳥栖間快速),クカンカイソク,Regional Rapid(Orio–Tosu),区间快速(折尾~鸟栖间快速),구간쾌속(오리오~도스 구간 쾌속),#DC143C,1,2,0,鹿児島本線,COMPLETE
DEFAULT,550,区間快速(折尾~羽犬塚間快速),クカンカイソク,Regional Rapid(Orio–Hainuzuka),区间快速(折尾~羽犬塚间快速),구간쾌속(오리오~하이누즈카 구간 쾌속),#DC143C,1,2,0,鹿児島本線,COMPLETE
DEFAULT,551,区間快速(福間~羽犬塚間快速),クカンカイソク,Regional Rapid(Fukuma–Hainuzuka),区间快速(福间~羽犬塚间快速),구간쾌속(후쿠마~하이누즈카 구간 쾌속),#DC143C,1,2,0,鹿児島本線,COMPLETE
DEFAULT,552,A列車で行こう(三角方面),エーレッシャデイコウ,A-Train (Misumi),A列车(三角方向),A열차(미스미 방면),#C71585,2,4,0,鹿児島本線直通・運転日限定,COMPLETE
DEFAULT,553,A列車で行こう(熊本方面),エーレッシャデイコウ,A-Train (Kumamoto),A列车(熊本方向),A열차(구마모토 방면),#C71585,1,4,0,鹿児島本線直通・運転日限定,COMPLETE
DEFAULT,554,かんぱち,カンパチ,Kanpachi,Kanpachi,칸파치,#C71585,2,4,0,鹿児島本線直通・運転日限定,COMPLETE
DEFAULT,555,いちろく,イチロク,Ichiroku,Ichiroku,이치로쿠,#C71585,1,4,0,鹿児島本線直通・運転日限定,COMPLETE
154 changes: 153 additions & 1 deletion data/5!station_station_types.csv
Original file line number Diff line number Diff line change
Expand Up @@ -10158,7 +10158,7 @@ DEFAULT,1190213,102,259,1,陣原
DEFAULT,1190214,102,259,0,折尾
DEFAULT,1190215,102,259,1,水巻
DEFAULT,1190216,102,259,1,遠賀川
DEFAULT,1190217,102,259,2,海老津
DEFAULT,1190217,102,259,0,海老津
DEFAULT,1190218,102,259,1,教育大前
DEFAULT,1190219,102,259,0,赤間
DEFAULT,1190220,102,259,0,東郷
Expand Down Expand Up @@ -42404,3 +42404,155 @@ DEFAULT,1190318,551,1195,0,久留米
DEFAULT,1190319,551,1195,0,荒木
DEFAULT,1190320,551,1195,1,西牟田
DEFAULT,1190321,551,1195,0,羽犬塚
DEFAULT,1190341,552,1196,0,熊本
DEFAULT,1192401,552,1196,0,熊本
DEFAULT,1190351,552,1196,1,西熊本
DEFAULT,1190342,552,1196,1,川尻
DEFAULT,1192402,552,1196,1,川尻
DEFAULT,1190350,552,1196,1,富合
DEFAULT,1192412,552,1196,1,富合
DEFAULT,1190343,552,1196,0,宇土
DEFAULT,1192403,552,1196,0,宇土
DEFAULT,1192404,552,1196,1,緑川
DEFAULT,1192405,552,1196,1,住吉
DEFAULT,1192406,552,1196,1,肥後長浜
DEFAULT,1192407,552,1196,0,網田
DEFAULT,1192408,552,1196,1,赤瀬
DEFAULT,1192409,552,1196,1,石打ダム
DEFAULT,1192410,552,1196,1,波多浦
DEFAULT,1192411,552,1196,0,三角
DEFAULT,1190341,553,1197,0,熊本
DEFAULT,1192401,553,1197,0,熊本
DEFAULT,1190351,553,1197,1,西熊本
DEFAULT,1190342,553,1197,1,川尻
DEFAULT,1192402,553,1197,1,川尻
DEFAULT,1190350,553,1197,1,富合
DEFAULT,1192412,553,1197,1,富合
DEFAULT,1190343,553,1197,0,宇土
DEFAULT,1192403,553,1197,0,宇土
DEFAULT,1192404,553,1197,1,緑川
DEFAULT,1192405,553,1197,1,住吉
DEFAULT,1192406,553,1197,1,肥後長浜
DEFAULT,1192407,553,1197,1,網田
DEFAULT,1192408,553,1197,1,赤瀬
DEFAULT,1192409,553,1197,1,石打ダム
DEFAULT,1192410,553,1197,1,波多浦
DEFAULT,1192411,553,1197,0,三角
DEFAULT,1190301,554,1198,0,博多
DEFAULT,1190302,554,1198,1,竹下
DEFAULT,1190303,554,1198,1,笹原
DEFAULT,1190304,554,1198,1,南福岡
DEFAULT,1190305,554,1198,1,春日
DEFAULT,1190306,554,1198,1,大野城
DEFAULT,1190307,554,1198,1,水城
DEFAULT,1190308,554,1198,1,都府楼南
DEFAULT,1190309,554,1198,1,二日市
DEFAULT,1190310,554,1198,1,天拝山
DEFAULT,1190311,554,1198,1,原田
DEFAULT,1190312,554,1198,1,けやき台
DEFAULT,1190313,554,1198,1,基山
DEFAULT,1190314,554,1198,1,弥生が丘
DEFAULT,1190315,554,1198,1,田代
DEFAULT,1190316,554,1198,1,鳥栖
DEFAULT,1190317,554,1198,1,肥前旭
DEFAULT,1190318,554,1198,1,久留米
DEFAULT,1191301,554,1198,1,久留米
DEFAULT,1191337,554,1198,1,久留米高校前
DEFAULT,1191302,554,1198,1,南久留米
DEFAULT,1191303,554,1198,1,久留米大学前
DEFAULT,1191304,554,1198,1,御井
DEFAULT,1191305,554,1198,1,善導寺
DEFAULT,1191306,554,1198,1,筑後草野
DEFAULT,1191307,554,1198,0,田主丸
DEFAULT,1191308,554,1198,1,筑後吉井
DEFAULT,1191309,554,1198,1,うきは
DEFAULT,1191310,554,1198,1,筑後大石
DEFAULT,1191311,554,1198,1,夜明
DEFAULT,1191312,554,1198,1,光岡
DEFAULT,1191313,554,1198,1,日田
DEFAULT,1191314,554,1198,1,豊後三芳
DEFAULT,1191315,554,1198,1,豊後中川
DEFAULT,1191316,554,1198,1,天ケ瀬
DEFAULT,1191317,554,1198,1,杉河内
DEFAULT,1191318,554,1198,1,北山田
DEFAULT,1191319,554,1198,1,豊後森
DEFAULT,1191320,554,1198,0,恵良
DEFAULT,1191321,554,1198,1,引治
DEFAULT,1191322,554,1198,1,豊後中村
DEFAULT,1191323,554,1198,1,野矢
DEFAULT,1191324,554,1198,0,由布院
DEFAULT,1191325,554,1198,1,南由布
DEFAULT,1191326,554,1198,1,湯平
DEFAULT,1191327,554,1198,1,庄内
DEFAULT,1191328,554,1198,1,天神山
DEFAULT,1191329,554,1198,1,小野屋
DEFAULT,1191330,554,1198,1,鬼瀬
DEFAULT,1191331,554,1198,1,向之原
DEFAULT,1191332,554,1198,1,豊後国分
DEFAULT,1191333,554,1198,1,賀来
DEFAULT,1191334,554,1198,1,南大分
DEFAULT,1191335,554,1198,1,古国府
DEFAULT,1191336,554,1198,0,大分
DEFAULT,1190643,554,1198,0,大分
DEFAULT,1190642,554,1198,1,西大分
DEFAULT,1190641,554,1198,1,東別府
DEFAULT,1190640,554,1198,0,別府
DEFAULT,1190301,555,1199,0,博多
DEFAULT,1190302,555,1199,1,竹下
DEFAULT,1190303,555,1199,1,笹原
DEFAULT,1190304,555,1199,1,南福岡
DEFAULT,1190305,555,1199,1,春日
DEFAULT,1190306,555,1199,1,大野城
DEFAULT,1190307,555,1199,1,水城
DEFAULT,1190308,555,1199,1,都府楼南
DEFAULT,1190309,555,1199,1,二日市
DEFAULT,1190310,555,1199,1,天拝山
DEFAULT,1190311,555,1199,1,原田
DEFAULT,1190312,555,1199,1,けやき台
DEFAULT,1190313,555,1199,1,基山
DEFAULT,1190314,555,1199,1,弥生が丘
DEFAULT,1190315,555,1199,1,田代
DEFAULT,1190316,555,1199,1,鳥栖
DEFAULT,1190317,555,1199,1,肥前旭
DEFAULT,1190318,555,1199,0,久留米
DEFAULT,1191301,555,1199,0,久留米
DEFAULT,1191337,555,1199,1,久留米高校前
DEFAULT,1191302,555,1199,1,南久留米
DEFAULT,1191303,555,1199,1,久留米大学前
DEFAULT,1191304,555,1199,1,御井
DEFAULT,1191305,555,1199,1,善導寺
DEFAULT,1191306,555,1199,1,筑後草野
DEFAULT,1191307,555,1199,1,田主丸
DEFAULT,1191308,555,1199,1,筑後吉井
DEFAULT,1191309,555,1199,0,うきは
DEFAULT,1191310,555,1199,1,筑後大石
DEFAULT,1191311,555,1199,1,夜明
DEFAULT,1191312,555,1199,1,光岡
DEFAULT,1191313,555,1199,1,日田
DEFAULT,1191314,555,1199,1,豊後三芳
DEFAULT,1191315,555,1199,1,豊後中川
DEFAULT,1191316,555,1199,0,天ケ瀬
DEFAULT,1191317,555,1199,1,杉河内
DEFAULT,1191318,555,1199,1,北山田
DEFAULT,1191319,555,1199,1,豊後森
DEFAULT,1191320,555,1199,1,恵良
DEFAULT,1191321,555,1199,1,引治
DEFAULT,1191322,555,1199,1,豊後中村
DEFAULT,1191323,555,1199,1,野矢
DEFAULT,1191324,555,1199,0,由布院
DEFAULT,1191325,555,1199,1,南由布
DEFAULT,1191326,555,1199,1,湯平
DEFAULT,1191327,555,1199,1,庄内
DEFAULT,1191328,555,1199,1,天神山
DEFAULT,1191329,555,1199,1,小野屋
DEFAULT,1191330,555,1199,1,鬼瀬
DEFAULT,1191331,555,1199,1,向之原
DEFAULT,1191332,555,1199,1,豊後国分
DEFAULT,1191333,555,1199,1,賀来
DEFAULT,1191334,555,1199,1,南大分
DEFAULT,1191335,555,1199,1,古国府
DEFAULT,1191336,555,1199,0,大分
DEFAULT,1190643,555,1199,0,大分
DEFAULT,1190642,555,1199,1,西大分
DEFAULT,1190641,555,1199,1,東別府
DEFAULT,1190640,555,1199,0,別府
1 change: 1 addition & 0 deletions data/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -323,3 +323,4 @@ Worker を再ビルドしてください。根拠は各行の `source` に記載
## 鹿児島本線の区間快速

快速運転区間ごとの系統と停車駅の出典は [鹿児島本線の区間快速](../docs/kagoshima-sectional-rapid.md) を参照してください。
観光特急の追加、快速の補正、未対応列車の制約は [鹿児島本線の追加種別監査](../docs/kagoshima-services-audit.md) を参照してください。
4 changes: 4 additions & 0 deletions data/route_service_rules.csv
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,7 @@ type_cd,line_group_id,requires_timetable,boarding_wait_seconds,source,type_name,
510,,true,,https://www.keio.co.jp/zasekishitei/index_mt.html,Mt.TAKAO,土休日・少数便・方向別乗降制限,2026-10-13
519,,true,,https://www.tobu.co.jp/railway/th/timetable/,THライナー,朝夕夜限定・方向別乗降制限,2026-10-13
413,,true,,https://www.keio.co.jp/zasekishitei/index_n.html,京王ライナー(高尾山口方面),時間帯限定・方向別乗降制限,2026-10-16
552,1196,true,,https://www.jrkyushu.co.jp/trains/atrain/,A列車で行こう(三角方面),公式運行カレンダーに限定(毎日運転ではない),2026-10-21
553,1197,true,,https://www.jrkyushu.co.jp/trains/atrain/,A列車で行こう(熊本方面),公式運行カレンダーに限定(毎日運転ではない),2026-10-21
554,1198,true,,https://www.jrkyushu-kanpachiichiroku.jp/info/,かんぱち,公式運行カレンダーに限定(毎日運転ではない),2026-10-21
555,1199,true,,https://www.jrkyushu-kanpachiichiroku.jp/info/,いちろく,公式運行カレンダーに限定(毎日運転ではない),2026-10-21
13 changes: 13 additions & 0 deletions data/route_stop_rules.csv
Original file line number Diff line number Diff line change
@@ -1,2 +1,15 @@
type_cd,station_group_id,forward_board,forward_alight,reverse_board,reverse_alight,source
316,2200106,false,true,false,false,https://www.seiburailway.jp/railway/station/nerima/
554,1190101,true,false,false,false,https://www.jrkyushu-kanpachiichiroku.jp/faq/
554,1191307,false,false,false,false,https://www.jrkyushu-kanpachiichiroku.jp/faq/
554,1191320,false,false,false,false,https://www.jrkyushu-kanpachiichiroku.jp/faq/
554,1191324,false,true,false,false,https://www.jrkyushu-kanpachiichiroku.jp/faq/
554,1190643,false,true,false,false,https://www.jrkyushu-kanpachiichiroku.jp/faq/
554,1190640,false,true,false,false,https://www.jrkyushu-kanpachiichiroku.jp/faq/
555,1190101,false,false,false,true,https://www.jrkyushu-kanpachiichiroku.jp/faq/
555,1190318,false,false,false,true,https://www.jrkyushu-kanpachiichiroku.jp/faq/
555,1191309,false,false,false,false,https://www.jrkyushu-kanpachiichiroku.jp/faq/
555,1191316,false,false,false,false,https://www.jrkyushu-kanpachiichiroku.jp/faq/
555,1191324,false,false,true,false,https://www.jrkyushu-kanpachiichiroku.jp/faq/
555,1190643,false,false,true,false,https://www.jrkyushu-kanpachiichiroku.jp/faq/
555,1190640,false,false,true,false,https://www.jrkyushu-kanpachiichiroku.jp/faq/
133 changes: 133 additions & 0 deletions data_validator/tests/kagoshima_sightseeing.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
use std::{collections::BTreeMap, path::Path};

use csv::StringRecord;
use stationapi::domain::service_rules::{parse_stop_rules, service_rule};

fn records(path: &Path) -> Vec<StringRecord> {
csv::Reader::from_path(path)
.unwrap()
.records()
.collect::<Result<_, _>>()
.unwrap()
}

#[test]
fn sightseeing_patterns_match_official_directional_stops() {
let data = Path::new(env!("CARGO_MANIFEST_DIR")).join("../data");
let rows = records(&data.join("5!station_station_types.csv"));
let types = records(&data.join("4!types.csv"));
let stations = records(&data.join("3!stations.csv"));
let names: BTreeMap<_, _> = stations.iter().map(|r| (&r[0], &r[2])).collect();
// Official A-Train timetable and Kanpachi/Ichiroku route information,
// checked 2026-10-21; sources and hospitality stops are documented in
// docs/kagoshima-services-audit.md. Stored order is Kumamoto/Hakata first.
for (ty, group, direction, stops) in [
(552, 1196, "2", vec!["熊本", "宇土", "網田", "三角"]),
(553, 1197, "1", vec!["熊本", "宇土", "三角"]),
(
554,
1198,
"2",
vec!["博多", "田主丸", "恵良", "由布院", "大分", "別府"],
),
(
555,
1199,
"1",
vec![
"博多",
"久留米",
"うきは",
"天ケ瀬",
"由布院",
"大分",
"別府",
],
),
] {
let actual: Vec<_> = rows.iter().filter(|r| r[3] == group.to_string()).collect();
let mut actual_stops: Vec<_> = actual
.iter()
.filter(|r| &r[4] == "0")
.map(|r| names[&r[1]])
.collect();
actual_stops.dedup();
assert_eq!(actual_stops, stops);
assert!(actual
.iter()
.all(|r| r[2] == ty.to_string() && matches!(&r[4], "0" | "1")));
let metadata = types.iter().find(|r| r[1] == ty.to_string()).unwrap();
assert_eq!(&metadata[8], direction);
assert_eq!(&metadata[9], "4");
assert!(
service_rule(Some(ty), Some(group))
.unwrap()
.requires_timetable
);

let expected: Vec<i32> = if ty <= 553 {
vec![
1190341, 1192401, 1190351, 1190342, 1192402, 1190350, 1192412, 1190343, 1192403,
1192404, 1192405, 1192406, 1192407, 1192408, 1192409, 1192410, 1192411,
]
} else {
(1190301..=1190318)
.chain([1191301, 1191337])
.chain(1191302..=1191336)
.chain((1190640..=1190643).rev())
.collect()
};
assert_eq!(
actual
.iter()
.map(|r| r[1].parse::<i32>().unwrap())
.collect::<Vec<_>>(),
expected
);
}
}

#[test]
fn hospitality_stops_do_not_allow_boarding_and_directional_permissions_match_faq() {
let rules = parse_stop_rules(include_str!("../../data/route_stop_rules.csv")).unwrap();
for (ty, gid, permissions) in [
(554, 1190101, [true, false, false, false]),
(554, 1191307, [false; 4]),
(554, 1191320, [false; 4]),
(554, 1191324, [false, true, false, false]),
(554, 1190643, [false, true, false, false]),
(554, 1190640, [false, true, false, false]),
(555, 1190640, [false, false, true, false]),
(555, 1190643, [false, false, true, false]),
(555, 1191324, [false, false, true, false]),
(555, 1191316, [false; 4]),
(555, 1191309, [false; 4]),
(555, 1190318, [false, false, false, true]),
(555, 1190101, [false, false, false, true]),
] {
let r = rules
.iter()
.find(|r| r.type_cd == ty && r.station_group_id == gid)
.unwrap();
assert_eq!(
[
r.forward_board,
r.forward_alight,
r.reverse_board,
r.reverse_alight
],
permissions
);
}
}

#[test]
fn all_kagoshima_rapid_trains_stop_at_ebitsu() {
let data = Path::new(env!("CARGO_MANIFEST_DIR")).join("../data");
let rows = records(&data.join("5!station_station_types.csv"));
let ebitsu = rows
.iter()
.find(|r| &r[3] == "259" && &r[1] == "1190217")
.unwrap();
assert_eq!(&ebitsu[4], "0");
}
42 changes: 42 additions & 0 deletions docs/kagoshima-services-audit.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# 鹿児島本線の追加種別監査

2026-10-21確認。区間快速に続き、鹿児島本線に乗り入れる列車の登録漏れを確認した。
通常の快速、ソニック、リレーかもめ、かささぎ、きらめき、みどり、ハウステンボス、
にちりんシーガイア、ゆふ、ゆふいんの森には既存の種別・系統がある。
既存列車の全停車パターンを再監査したものではない。

## 今回追加する特急

| 種別ID | 系統ID | 名称 | 実際の運行順の停車駅 |
| --- | --- | --- | --- |
| 552 | 1196 | A列車で行こう(三角方面) | 熊本・宇土・網田・三角 |
| 553 | 1197 | A列車で行こう(熊本方面) | 三角・宇土・熊本 |
| 554 | 1198 | かんぱち | 博多・田主丸・恵良・由布院・大分・別府 |
| 555 | 1199 | いちろく | 別府・大分・由布院・天ケ瀬・うきは・久留米・博多 |

- [A列車で行こう:公式時刻表・運転日](https://www.jrkyushu.co.jp/trains/atrain/)(2026年3月14日改正)。網田は下りのみ停車するため上下を分離した。CSVの駅順は両系統とも熊本→三角、directionは下り2・上り1。
- [かんぱち・いちろく:公式運行情報](https://www.jrkyushu-kanpachiichiroku.jp/info/)。博多→久留米→久大本線→大分→別府の全区間を登録。CSVは博多→別府順、かんぱちはdirection=2、いちろくはdirection=1。
- [かんぱち・いちろく:公式FAQ](https://www.jrkyushu-kanpachiichiroku.jp/faq/)のQ11に従い、かんぱちは博多のみ乗車、由布院・大分・別府のみ降車。いちろくは別府・大分・由布院のみ乗車、久留米・博多のみ降車とした。おもてなし駅は停車として表示するが途中乗降は不可。`route_stop_rules.csv`に方向別に記録する。

各系統の運転日は公式カレンダーに限定される。`route_service_rules.csv`に
`requires_timetable=true`と出典・確認日を記録し、日時を扱わない自動経路探索から除外する。
手動の種別選択・経路表示では使用できる。観光停車の長い滞在時間や正確な所要時間を
既存の距離ベースETAで再現する変更ではない。

三角線の熊本・川尻・富合・宇土は鹿児島本線との両駅IDを保持し、西熊本も通過駅として登録。
かんぱち・いちろくの久留米・大分も両路線の駅IDを保持する。
博多は南側から発着し北側へ直通しないので1190301のみを使用する。

## 既存快速の補正

[JR九州2025年3月ダイヤ改正資料](https://www.jrkyushu.co.jp/news/__icsFiles/afieldfile/2024/12/13/241213_2025daiya_kaisei_1.pdf)
により快速は全列車海老津停車となった。快速の系統259の海老津1190217を
`pass=2`(一部通過)から`pass=0`(停車)に修正する。

## 追加を保留する列車

- [或る列車](https://www.jrkyushu-aruressha.jp/train-status-info):博多~由布院の運行を確認したが、[公式FAQ](https://www.jrkyushu-aruressha.jp/faq)では募集型企画旅行商品。既存の`kind`に団体専用列車の区分がないため、特急・快速と推測して登録しない。団体専用列車の分類方針が必要。
- [36ぷらす3](https://www.jrkyushu-36plus3.jp/about/dia/):日曜は門司港、月曜午前は肥前浜で折り返し、同一駅を再訪する。`get_train_route`は指定駅IDの最初の出現位置を採用するため、CSVへ再訪駅を足すだけでは小倉などからの乗車区間を誤る。駅の訪問回数を識別する経路表現とAPIの検討を伴う別変更が必要。なお木曜ルートは[公式運行再開案内](https://www.jrkyushu-36plus3.jp/api/uploads/26100601.pdf)では2026年11月5日再開予定。

`data_validator/tests/kagoshima_sightseeing.rs`で駅順・方向別停車・接続駅の両ID・
運転日制約・乗降制限・海老津の停車を回帰検証する。
Loading
Loading