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
41 changes: 24 additions & 17 deletions docs/nearby-bus-stops.md
Original file line number Diff line number Diff line change
@@ -1,30 +1,32 @@
# 近傍バス停検索機能

鉄道駅から半径300m以内のバス停を同一グループとして返す機能の仕様
鉄道駅から半径300m以内のバス停・バス路線を取得する機能の仕様

## 概要

各APIで`transport_type`パラメータを使用して、鉄道駅に加えて近くのバス停を含めるかどうかを制御できる
各APIで`transport_type`パラメータを使用して、鉄道駅・バス停のフィルタリングを制御できる。デフォルトでは後方互換性のため鉄道駅のみを返す

## パラメータ

### TransportType

```protobuf
enum TransportType {
TransportTypeUnspecified = 0; // 鉄道駅 + 近くのバス停を含める
TransportTypeUnspecified = 0; // 鉄道駅のみ(デフォルト)
Rail = 1; // 鉄道駅のみ
Bus = 2; // バス停のみ
RailAndBus = 3; // 鉄道駅 + バス停
}
```

## 動作仕様

| transport_type | 動作 |
|----------------|------|
| **未指定 / Unspecified** | 鉄道駅を取得し、最初の鉄道駅から半径300m以内のバス停も追加して返す |
| **未指定 / Unspecified** | 鉄道駅のみを返す(デフォルト) |
| **Rail** | 鉄道駅のみを返す |
| **Bus** | 最初の鉄道駅から半径300m以内のバス停のみを返す |
| **Bus** | バス停のみを返す |
| **RailAndBus** | 鉄道駅とバス停の両方を返す。`lines`配列にも近傍バス路線を含める |

## 対象API

Expand All @@ -44,34 +46,40 @@ enum TransportType {

- **アルゴリズム**: Haversine公式(地球の曲率を考慮)
- **半径**: 300メートル(定数 `NEARBY_BUS_STOP_RADIUS_METERS`)
- **基準点**: 取得した鉄道駅の最初の1件の座標
- **基準点**: 取得した鉄道駅の座標

## 使用例

### 鉄道駅 + 近くのバス停を取得
### 鉄道駅のみを取得(デフォルト)

```protobuf
// transport_type未指定で鉄道駅と近くのバス停を両方取得
// transport_type未指定で鉄道駅のみを取得
GetStationByGroupIdRequest {
group_id: 1130201
}

// または明示的にRailを指定
GetStationByGroupIdRequest {
group_id: 1130201
transport_type: Rail
}
```

### 鉄道駅のみを取得
### バス停のみを取得

```protobuf
GetStationByGroupIdRequest {
group_id: 1130201
transport_type: Rail
transport_type: Bus
}
```

### 近くのバス停のみを取得
### 鉄道駅とバス停の両方を取得

```protobuf
GetStationByGroupIdRequest {
group_id: 1130201
transport_type: Bus
transport_type: RailAndBus
}
```

Expand All @@ -93,12 +101,11 @@ const NEARBY_BUS_STOP_RADIUS_METERS: f64 = 300.0;
### ヘルパーメソッド

```rust
/// 指定座標から半径300m以内のバス停を取得
async fn get_nearby_bus_stops(&self, ref_lat: f64, ref_lon: f64) -> Result<Vec<Station>, UseCaseError>
/// 指定座標から半径300m以内のバス路線を取得
async fn get_nearby_bus_lines(&self, ref_lat: f64, ref_lon: f64) -> Result<Vec<Line>, UseCaseError>
```

## 注意事項

- バス停検索は最大50件の候補を取得し、その中から300m以内のものをフィルタリング
- 鉄道駅が存在しない場合、`transport_type: Bus`は空の結果を返す
- 複数の鉄道駅がある場合、最初の1件の座標を基準点として使用
- バス路線検索は最大50件のバス停候補を取得し、その中から300m以内のものをフィルタリング
- 鉄道駅の`lines`配列に近傍バス路線が追加されるのは`transport_type: RailAndBus`を指定した場合のみ
39 changes: 19 additions & 20 deletions docs/technical_debt.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# StationAPI 技術負債分析レポート

> 最終更新: 2025年12月
> 最終更新: 2026年1月

## 目次

Expand Down Expand Up @@ -109,27 +109,26 @@ let includes_requested_station = stops

### 3. 過度な clone() の使用

- **ファイル**: `stationapi/src/use_case/interactor/query.rs`
- **clone() 呼び出し回数**: 94回
> **ステータス**: ✅ **対応済み** (2026年1月)
>
> 以下の最適化を実施しました。

主な箇所:
#### 対応済みの改善

| 行番号 | 内容 |
|--------|------|
| 508, 578 | `line.clone()` |
| 209, 244 | `station.clone()`, `station_ref.clone()` |
| 230-231 | ベクタフィルタリング時の clone |
| 改善内容 | 詳細 |
|----------|------|
| HashMap ベースの検索 | O(n) 線形検索を O(1) HashMap 検索に変更 (Company, TrainType, Station) |
| `build_route_tree_map` の参照化 | `BTreeMap<i32, Vec<Station>>` → `BTreeMap<i32, Vec<&Station>>` で Station クローン回避 |
| `train_types.clone()` 削除 | ベクター全体のクローンを回避し、必要な要素のみ HashMap に格納 |
| バス停検索の最適化 | `get_nearby_bus_lines` で HashMap ベース検索に変更 |

```rust
// 行230-231: ベクタ操作時のクローン
let mut lines: Vec<Line> = lines
.iter()
.filter(|&l| { ... })
.cloned() // <-- 64フィールドの構造体を全てクローン
.collect();
```
#### 残存する clone()

一部の clone() は構造体フィールドへの所有権移動のため回避不可:

**影響**: Station が 64 フィールド × clone → メモリ使用量増加、不要なアロケーション
- `line.station = Some(station.clone())` - Line 構造体が `Option<Station>` を所有
- `line.company = ...` - Line 構造体が `Option<Company>` を所有
- フィルタリング後の Vec 構築時の `.cloned()`

---

Expand Down Expand Up @@ -285,7 +284,7 @@ let station_numbers_raw = [
### 短期改善

1. **SQL 最適化**: `get_route_stops` でのフィルタリングを SQL 側に移動
2. **Clone 削減**: 参照ベースの処理を検討
2. ~~**Clone 削減**: 参照ベースの処理を検討~~ ✅ 対応済み
3. **命名改善**: `get_by_line_group_id_vec_for_routes()` をより明確な名前に変更
4. **定数化**: ハードコードされた値を定数として定義

Expand Down Expand Up @@ -315,7 +314,7 @@ let station_numbers_raw = [
|--------|------|---------|------|
| **高** | Station 構造体の設計見直し | `src/domain/entity/station.rs` | 保守性、パフォーマンス |
| **高** | SQL クエリの最適化 (TODO対応) | `src/use_case/interactor/query.rs:604,702` | パフォーマンス |
| **高** | Clone の過度な使用削減 | `src/use_case/interactor/query.rs` | メモリ効率 |
| ~~高~~ | ~~Clone の過度な使用削減~~ | ✅ 対応済み (HashMap検索、参照化) | メモリ効率 |
| ~~高~~ | ~~アーキテクチャドキュメント作成~~ | ✅ 対応済み ([docs/architecture.md](./architecture.md)) | オンボーディング、保守性 |
| **中** | Row 構造体のコード生成検討 | `src/infrastructure/*.rs` | メンテナンス性 |
| **中** | メソッド命名の改善 | `src/domain/repository/line_repository.rs:23` | 可読性 |
Expand Down
Loading