はじめに
このたび、勾配に特化した歩行者専用地図アプリ「アルケール(Arukeru)」 をリリースしました。
「坂が多くて歩きたくない」――そんな日常の小さな不満から生まれた、坂の緩やかさを基準にルートを提案する地図アプリ です。一般歩行者から高齢者・車いすユーザー・ベビーカー利用者・ランナー・観光客まで、あらゆる「歩く人」に寄り添うことを目指して開発しました。
- 🌐 Web版(PWA): https://aruke-ru-v2.web.app/
- 💻 GitHub: https://github.com/giant-shrimp/Chikuhou_frontend
本記事では、アルケールを作ったキッカケから、技術スタック、こだわりの実装ポイント(特に 9種類の数学的手法による勾配計算エンジン)までを紹介します。
アプリを作ったキッカケ
アルケールは、チャレンジキャラバン内のアイデアソンイベント をきっかけに生まれました。
チーム内でアイデアを議論する中で、ある一人のメンバーが何気なく口にした言葉がありました。
「坂が多い街って、歩きたくなくなるんだよね」
この一言を深掘りした結果、たどり着いたのが 「勾配」 というキーワードでした。
既存の地図アプリは「最短距離」「最速時間」を基準にルートを提案しますが、調べてみると 「坂の緩やかさ」を基準にルートを選べるアプリは世の中に存在しなかった のです。
| アルケール | Google マップ | OpenStreetMap | |
|---|---|---|---|
| 勾配計算 | ◯ | ◯ | ✕ |
| ステータス設定 | ◯ | △ | ✕ |
| 高度な計算手法 | ◯ | ✕ | ✕ |
「歩行者の属性に合わせて、その人にとって本当に楽なルートを提案する」――そんな地図アプリを作りたい。そう決意したのが、アルケール開発の出発点です。
アプリに込めた思い・実現したい未来
アルケールが掲げるコンセプトは、
「今ある景色をもっと豊かに、歩行者に寄り添う」
です。
ターゲットは 歩く人々すべて。
一般の歩行者だけでなく、
- 👵 高齢者の方
- ♿ 車いすユーザー
- 👶 ベビーカー利用者
- 🧳 旅行者(外国人観光客を含む)
- 🏃 ランナー・サイクリスト
といった、あらゆる属性の歩行者 が、自分にとって最も快適な道を選べる体験を届けたいと考えています。
ルート検索時にユーザーが自分の ステータス(属性) を設定することで、そのステータスに応じた最適ルートを提案。さらに 日本語・英語・韓国語の多言語対応 により、訪日観光客にもストレスなく使ってもらえるアプリを目指しました。
「歩くこと」を、もっと自由に。もっと楽しく。
これをコアフレーズとして開発をスタートしました。
サービス概要
アルケールの主な機能を紹介します。
🗺️ ホーム画面(地図)
Google マップ上に現在地・出発地・目的地を表示。ユーザーのステータスに応じた最適ルートを提案します。
📐 ルート検索・勾配計算
複数ルートを同時取得し、区間ごとに 9種類の数値計算手法 で勾配を算出。傾斜をグラフで可視化します。
🌧️ 雨雲レーダー
気象庁データを元にしたリアルタイム雨雲を表示し、外出前の天候判断をサポートします。
🏃 マラソンコース
地域のマラソンコースを地図上で確認できます(距離・推定時間・累積標高付き)。
その他の機能
| 機能 | 概要 |
|---|---|
| 🚶 ステータス設定 | ウォーカー・ランナー・シニア・トラベラー等の属性を設定し、ユーザーに合ったルートを提案 |
| 🔥 カロリー計算 | 歩行・ジョギング・ランニング・サイクリングの METs から消費カロリーを算出 |
| 🔐 認証 | Firebase Authentication によるメール+パスワード認証 |
| 🌏 多言語対応 | アプリ全体のUIを日本語・英語・韓国語に切り替え可能(ARB形式) |
使用技術
フロントエンド
| Category | Technology Stack |
|---|---|
| Language | Dart 3.5+
|
| Framework | Flutter 3.24.5
|
| State Management | hooks_riverpod 2.5.1, provider 6.1.2
|
| UI / UX | google_fonts, flutter_spinkit, settings_ui, cupertino_icons |
| 数式表示 | flutter_math_fork 0.7.4
|
| 環境変数管理 | flutter_dotenv 5.2.1
|
| 多言語対応 | flutter_localizations, l10n(ARB形式 ja / en / ko) |
| 永続化 | shared_preferences 2.1.2
|
バックエンド / インフラ
| Category | Technology Stack |
|---|---|
| Auth / DB | Firebase Authentication 5.3.3, Cloud Firestore 5.5.0, firebase_core 3.8.0
|
| Maps & Location | google_maps_flutter 2.9.0, geolocator 13.0.1
|
| Network | http 1.2.2
|
| Hosting | Firebase Hosting(PWA配信) |
| CI/CD | GitHub Actions(flutter analyze + flutter test) |
アーキテクチャ
- MVVM(Model / ViewModel / View)+ Riverpod Provider
- View はステートを持たず、ViewModel に処理を委譲
- 外部 I/O は Service 層に集約
lib/
├── config/ # ルーティング・テーマ・Provider 定義
├── core/
│ ├── services/ # 外部 API・Firebase ラッパー
│ └── utils/ # api_client / dialog_helpers / validators
├── l10n/ # ja / en / ko の ARB ファイル
├── models/ # データモデル
├── viewmodels/ # ビジネスロジック・状態管理
└── views/ # UI 層
ER図
主要モデル間の関係です(Firestore コレクション設計の基盤)。
こだわりポイント
① 9種類の数学的手法による勾配計算エンジン
アルケールの中核は、独自実装の 勾配計算エンジン です。
ルート上の各区間について Google Maps Elevation API から標高列を取得し、ハヴァーサイン式で水平距離を求め、勾配を算出します。
基本式
各区間の勾配 $g_i$(%)は、標高差を水平距離で割った値として定義します。
$$
g_i = \frac{\Delta h_i}{d_i} \times 100
$$
9種類の勾配積分手法
ルート全体の "勾配の重さ" を評価する方式として、以下9手法を切り替え可能にしました。
| # | 手法 | 概要 |
|---|---|---|
| 1 | 単純勾配 | 50 m 固定間隔で勾配絶対値を総和 |
| 2 | 区分求積法 | 区間長 × 高度差絶対値の総和(短冊面積) |
| 3 | 線形計算 | 区間勾配の絶対値の平均 |
| 4 | ベクトル積 | 3D ベクトルと水平射影の角度 |
| 5 | ハヴァーサイン勾配角 | 地球曲率を考慮した正確な水平距離で勾配角を算出 |
| 6 | シンプソン法 | 勾配関数を 1/3 則で数値積分 |
| 7 | フーリエ変換 (FFT) | 標高列を周波数領域に変換し、高周波成分エネルギーで急変動を評価 |
| 8 | ヘルムホルツ分解 | 勾配場をポテンシャル場と回転場に分解し、ポテンシャル場のエネルギーを評価 |
| 9 | リーマン計量 | $(x, y, z)$ 空間に計量テンソルを導入し、測地線長を計算 |
同じデータに対して「離散合計」「数値積分」「周波数解析」「微分幾何」と、異なる数学的アプローチをユーザーが切り替えて比較できる のは、教育・研究用途にも応用可能なユニークな実装だと考えています。
② ステータス別スコアリング戦略
「最も緩いルート」は属性ごとに定義が異なります。
本アプリではユーザーの currentStatus に応じて以下4つのスコア関数を切り替え、スコアが低いルートを優先選択 するように統一しました。
| ステータス | スコア関数 | 数式 | 意図 |
|---|---|---|---|
🚶 walker / ♿ wheelchair
|
上り勾配の二乗和 | $S = \sum_{g_i > 0} g_i^2$ | 急坂に強いペナルティ(緩やか優先) |
👵 senior / 👶 stroller
|
勾配絶対値の最大値 | $S = \max_i \lvert g_i \rvert$ | 最大傾斜を最小化(ベビーカー・車いす想定) |
🏃 runner
|
上り累積を負値化 | $S = -\sum_{g_i > 0} g_i$ | 上りが多いほど優先(トレーニング志向) |
🧳 traveler
|
距離最短 | $S = D_{\text{total}}$ | 観光客向け、最短経路 |
runner は本来「上りが多い=高スコア」になるべきですが、他ステータスと同じく「低いほど優先」に統一するため 負値化 することで、ルート選択ロジック側の分岐を完全に排除しました。これにより、コードがシンプルかつ拡張しやすくなっています。
③ ルート選択フロー
④ 完全クライアントサイド計算
標高列さえ取得すれば、サーバー側のルーティング再計算なしに任意の手法で再評価可能 な設計にしました。
ユーザーが計算手法を切り替えても即座にルートが再評価されるため、UX も損ないません。
⑤ 多言語対応(ja / en / ko)
ARB 形式を採用し、日本語・英語・韓国語の3言語に対応しました。
訪日観光客が多い九州エリアを想定して、韓国語対応は特にこだわった ポイントです。
今後実装したいこと
アルケールはリリースしたばかり。まだまだやりたいことが山積みです。
- 🎙️ 音声案内:ルート案内を音声でガイドし、画面を見ずに歩けるように
- 💬 口コミ機能:スポットや経路に関するユーザーレビューの閲覧・投稿
- 🚨 避難経路の確保:ハザードマップを参照しながら災害時の避難経路を提示
- 🌐 簡単翻訳:日本語・英語・韓国語間のインライン翻訳機能
- 📚 ルート履歴の保存:過去に検索したルートを Firestore に記録し振り返り可能に
- 🚶♀️ ウォーキングイベント連携:地域のウォーキングイベント情報の確認・参加登録
- ⌚ Apple Watch / Wear OS 対応:ウェアラブルデバイスでのルート表示・通知
- 📱 App Store / Google Play へのリリース:TestFlight および 内部テストを経て一般公開へ
「歩く人に寄り添う」というコンセプトを軸に、機能を一つひとつ丁寧に積み上げていきたいと思っています。
終わりに
ここまで読んでいただき、ありがとうございました。
アルケールは、「坂が多くて歩きたくない」という一人の何気ない声から始まり、チーム全員で議論を重ねながら形にしてきたプロダクトです。
「歩くこと」という当たり前の体験を、もう一歩豊かにする ――その思いをこれからも大切にしながら、開発を続けていきたいと思います。
開発メンバー
| 名前 | 所属 | 担当 |
|---|---|---|
| 山内 敬太 | 九州工業大学 | バックエンド |
| 越智 祐仁 | 麻生情報ビジネス専門学校 | フロントエンド |
| 前畑 遥哉 | 北九州市立大学 | フロントエンド |
| 藤木 弘也 | 北九州市立大学 | バックエンド |
最後に、もしアルケールに興味を持っていただけたら、ぜひ一度触ってみてください。
フィードバックや GitHub での Star、Issue や PR も大歓迎です!
- 🌐 Web版(PWA): https://aruke-ru-v2.web.app/
- 💻 GitHub: https://github.com/giant-shrimp/Chikuhou_frontend
