Upgrade to Pro — share decks privately, control downloads, hide ads and more …

タクシーアプリ「GO」から学ぶ Google Maps SDK 活用術

Yosuke Imairi
September 11, 2022

タクシーアプリ「GO」から学ぶ Google Maps SDK 活用術

iOSDC Japan 2022 にて登壇した内容となります。

https://fortee.jp/iosdc-japan-2022/proposal/cf0d2912-8f56-42e4-9800-b8eced98f48e

Yosuke Imairi

September 11, 2022
Tweet

More Decks by Yosuke Imairi

Other Decks in Technology

Transcript

  1. Mobility Technologies Co., Ltd. ❏ 株式会社 Mobility Technologies (MoT) ❏

    タクシーアプリ「GO」の iOS アプリ開発 ❏ アーキテクチャの選定・導⼊ ❏ アプリ全体の設計、新機能開発 ❏ CI 環境の構築・整備、⾃動化の促進 ❏ チームビルディング 2 Yosuke Imairi ⾃⼰紹介
  2. Mobility Technologies Co., Ltd. 4 タクシーが呼べるアプリ「GO」は地図をベースとしたアプリ Google Maps SDK を活⽤して

    タクシーアプリ「GO」の機能がどのように実現されているか 具体例を交えて紹介します
  3. Mobility Technologies Co., Ltd. 1. タクシー⾞両動態の表⽰ 2. 配⾞できないエリアの可視化 3. 近くの道路に引き込ませる

    4. 緯度経度の誤差 5. 地図の可視領域 6. アプリの世界観にあった地図 7. 地図のパフォーマンス調整 8. バグ事例とその解決策 5 この登壇で話す内容 Google Maps を活⽤した機能の紹介 Google Maps 特有の仕様
  4. Mobility Technologies Co., Ltd. ❏ GOアプリ内で乗⾞地ピンを置くと、周辺の⾞両動態が地 図に描画される ❏ タクシー会社によって⾞両動態の画像が異なる 7

    タクシー⾞両動態とは ❏ タクシー⾞両から送られる情報 ❏ GPS 位置 ❏ ⽅⾓ ❏ 速度 ❏ メーター情報 etc…
  5. Mobility Technologies Co., Ltd. 8 タクシーの⾞両動態を地図に描画させて動かす ❏ GMSMarker として描画 ❏

    地図上の特定の地点にマーカーを配置させる ❏ UIView, UIImage で表⽰するコンテンツを指定 ❏ マーカーのどの位置を地図上の緯度経度に合わせるか ❏ groundAnchor (0.5, 1) (0.5, 0.5)
  6. Mobility Technologies Co., Ltd. 9 タクシーの⾞両動態を地図に描画させて動かす ❏ CoreAnimation (CATransaction) でアニメーションを付与

    ❏ 緯度経度、⾞両の⽅向、データ取得時間を元に計算 次の動態位置のデータ取得時間との差分からアニメーション時間を割り出す
  7. Mobility Technologies Co., Ltd. 11 タクシーが呼べないエリアを明⽰する ❏ 「配⾞禁⽌エリア」として明⽰する ❏ 海や湖など明らかにタクシーが呼べないエリアは描画なし

    ❏ ⾚いポリゴンとしてエリアを明⽰させる ❏ ピンを置くとタクシーが呼べない旨が提⽰される ❏ アプリでタクシーが呼べないエリアが存在する ❏ 駅周辺(駅前のタクシー乗り場など) ❏ 特定の施設内、商店街 ❏ ⼤学の敷地内、公園
  8. Mobility Technologies Co., Ltd. 12 タクシーが呼べないエリアを明⽰する ❏ GMSPolygon として描画 ❏

    GMSPath の始点と終点を繋いでポリゴンを描画 ❏ GMSPath は CLLocationCoordinate2D の集合体 ❏ fillColor, strokeColor, strokeWidth などで外観を整える ❏ GO アプリで利⽤されているポリゴンの管理 ❏ 社内の管理ツールで地図上でポリゴンを登録
  9. Mobility Technologies Co., Ltd. 15 近くの道路に引き込ませる ❏ アプリ起動直後に⼀度だけ処理される ❏ サーバから道路情報を取得して⼀番近い地点に引き込ませる

    ❏ 道幅が広い場合は、起点に少し寄った場所にする ❏ なぜ引き込ませるのか ❏ タクシーは建物内まで⼊ることができない ❏ 乗務員さんにとっては道路に乗⾞ピンを置いてほしい ❏ アプリを起動してその場ですぐ呼びたい ❏ 近くの道路に引き込ませることでひと⼿間省かせる 13m 〜 5 〜 13m 3 〜 5m 0 〜 3m 道幅 ※ デバッグ機能で道路情報を可視化
  10. Mobility Technologies Co., Ltd. 17 Google Maps での地点移動 ❏ コードで地図の中⼼を移動させる

    ❏ GMSCamera : 地図の中⼼を表す ❏ GMSCameraUpdate : 地図の中⼼を変更する(地図を移動させる) ❏ 現在地に移動させる ❏ 検索結果の地点に移動させる let gmsCameraUpdate = GMSCameraUpdate.setTarget(myLocation.coordinate2D) gmsMapView.animate(with: gmsCameraUpdate)
  11. Mobility Technologies Co., Ltd. latitude: 34.99999996412221, longitude: 138.0000001564622 18 指定した緯度経度に移動できないことがある

    ❏ 緯度経度 (35.0, 138.0) に移動する let location = CLLocationCoordinate2D(latitude: 35.0, longitude: 138.0) let gmsCameraUpdate = GMSCameraUpdate.setTarget(location) gmsMapView.animate(with: gmsCameraUpdate) print(gmsMapView.camera.target) 🤔
  12. Mobility Technologies Co., Ltd. 19 指定した緯度経度に移動できないことがある ❏ 適当な緯度経度を与えて検証 微妙な誤差がある (35.12,

    138.1) ⇒ (35.119999892554176, 138.09999994933605) (35.123, 138.12) ⇒ (35.12300000931186, 138.1199998408556) (35.1234, 138.123) ⇒ (35.12340010794013, 138.12299989163876) (35.12345, 138.1234) ⇒ (35.123450017295305, 138.1233998760581) (35.123456 138.12345) ⇒ (35.123456050292205, 138.12345016747713) (35.1234567, 138.123456) ⇒ (35.12345659874645, 138.1234558671713) (35.12345678, 138.1234567) ⇒ (35.12345687297357, 138.12345653772354) (35.123456789, 138.12345678) ⇒ (35.12345687297357, 138.1234568729997)
  13. Mobility Technologies Co., Ltd. (35.12, 138.1) ⇒ (35.119999892554176, 138.09999994933605) 0.013m

    (35.123, 138.12) ⇒ (35.12300000931186, 138.1199998408556) 0.014m (35.1234, 138.123) ⇒ (35.12340010794013, 138.12299989163876) 0.016m (35.12345, 138.1234) ⇒ (35.123450017295305, 138.1233998760581) 0.012m (35.123456 138.12345) ⇒ (35.123456050292205, 138.12345016747713) 0.016m (35.1234567, 138.123456) ⇒ (35.12345659874645, 138.1234558671713) 0.016m (35.12345678, 138.1234567) ⇒ (35.12345687297357, 138.12345653772354) 0.018m (35.123456789, 138.12345678) ⇒ (35.12345687297357, 138.1234568729997) 0.012m 20 指定した緯度経度に移動できないことがある ❏ 適当な緯度経度を与えて検証 CLLocation の distance(from:) で2点間の距離が求められる(メートル)
  14. Mobility Technologies Co., Ltd. (35.119999892554176, 138.09999994933605) ⇒ (35.119999892554176, 138.09999994933605) (35.12300000931186,

    138.1199998408556) ⇒ (35.12300000931186, 138.1199998408556) (35.12340010794013, 138.12299989163876) ⇒ (35.12340010794013, 138.12299989163876) (35.123450017295305, 138.1233998760581) ⇒ (35.123450017295305, 138.1233998760581) (35.123456050292205, 138.12345016747713) ⇒ (35.123456050292205, 138.12345016747713) (35.12345659874645, 138.1234558671713) ⇒ (35.12345659874645, 138.1234558671713) (35.12345687297357, 138.12345653772354) ⇒ (35.12345687297357, 138.12345653772354) (35.12345687297357, 138.1234568729997) ⇒ (35.12345687297357, 138.1234568729997) 21 指定した緯度経度に移動できないことがある ❏ Google Maps から得られた緯度経度を与えて検証 Google Maps から得られた緯度経度を利⽤すると誤差はない ✅
  15. Mobility Technologies Co., Ltd. 22 Google Maps SDK における座標の扱い ❏

    Google Maps SDK から取得できる座標を指定すれば誤差がなくなる ❏ それ以外から取得した位置情報では誤差が⽣じる ❏ GPS から取得 ❏ 外部サイトからの連携で指定された緯度経度 ❏ ⼿動で⼊⼒した値 ❏ 誤差があったとしても無視できる程度(数cm) ❏ 誤差が⽣じることを前提とした実装が必要 ❏ GMSCamera の座標を == で判定しない ❏ GO アプリでは誤差が 1m 以内なら同じ地点という判定をしている
  16. Mobility Technologies Co., Ltd. 24 Google Maps における可視領域 ( ʼvisibleʼ

    region) ❏ GMSUIPaddingSettingView ❏ GMSMapView 上に配置される透明の View ❏ GMSMapView の padding に応じて変形する ❏ 現在表⽰させている領域を指定させる ❏ 左下の Google ロゴが矩形の⾓に当たる ❏ Google ロゴは隠れないように表⽰させる必要がある GMSMapView GMSUIPaddingSettingView
  17. Mobility Technologies Co., Ltd. 25 Google Maps における可視領域の活⽤場⾯ ❏ GMSCameraUpdate.fitBounds

    ❏ GMSCoordinateBounds として地点の緯度経度の集合体を渡す ❏ 可視領域内にそれらがすべて収まるようにズームレベルが⾃動調整される ❏ ⽅⾓は北固定、地図の傾きはリセットされる ❏ GO アプリでの利⽤例 ❏ 乗⾞地と⾏き先とルートが収まるようにする ❏ 乗⾞地候補となる地点がすべて⾒えるようにする
  18. Mobility Technologies Co., Ltd. 26 Google Maps における可視領域の活⽤場⾯ ❏ 乗⾞地と⾏き先とルートが収まるようにする

    地図を⼿動で動かす (拡⼤ / 移動) 調整ボタンをタップ ( fitBounds の処理が実⾏)
  19. Mobility Technologies Co., Ltd. 29 Google Maps における可視領域の活⽤場⾯ ❏ 緯度経度に加えて

    GMSMarker の画像サイズなどの考慮も必要(Insets で設定) safeArea
  20. Mobility Technologies Co., Ltd. 32 Google Maps のスタイルは⾃由に変更できる ❏ GMSMapStyle

    ❏ JSON 形式で設定 ❏ かなり細かい設定が可能で Styling Wizard で調整することが望ましい ❏ https://mapstyle.withgoogle.com/ ❏ 動的に切り替えることができる ❏ 夜は地図を暗めの⾊にする
  21. Mobility Technologies Co., Ltd. 34 レンダリングするフレームレートの調整 ❏ GMSFrameRate ❏ GMSMapView.preferredFrameRate

    で設定 ❏ .maximum( 30 FPS - 60 FPS ) ❏ デフォルトとして設定されている ❏ SDK 側で端末の確認をして古い端末なら 30 FPS になる ❏ .conservative ❏ .powerSave( 15 FPS ) ❏ バッテリー消費を抑えたい場⾯で利⽤ ❏ 端末のバッテリー残量が少ない ❏ Modal で別画⾯を表⽰しているなど、地図との直接的な接点がない場合
  22. Mobility Technologies Co., Ltd. 36 Graphic API の選択 ❏ GMSServices.setMetalRendererEnabled

    ❏ OpenGL の代わりに Metal でレンダリングが可能 ❏ GMSService の初期化前に設定 ❏ OpenGL での課題 ❏ OpenGL + M1Max + シミュレータ だと地図のスクロールの挙動に問題あり ❏ スクロールの慣性が効きすぎて細かい地点移動が困難 ❏ Metal による恩恵 ❏ Metal + M1Max + シミュレータ で地図の挙動が圧倒的に軽い ❏ スクロールの慣性が効きづらくなった
  23. Mobility Technologies Co., Ltd. ❏ UIViewController の present, dismiss と同時に

    GMSMapView animate を 実⾏ ❏ present, dismiss は正常に⾏われる ❏ GMSMapView animate はアニメーションの終点が⼀瞬適⽤される ❏ その後にアニメーションが再⽣される ❏ present, dismiss をアニメーションなしで実⾏しても発⽣する ❏ 回避策 ❏ 地図のアニメーション実⾏を少し遅延させることで回避している ❏ 10 - 100ms 38 画⾯の切り替えと同時に地図のアニメーション処理が⾏えない
  24. Mobility Technologies Co., Ltd. 39 地図の初期位置がストーンヘンジになる ❏ アプリを起動すると地図の初期位置がストーンヘンジになる ❏ 原因は

    GMSMapView の初期化に問題があった ❏ 初期化時に最初に表⽰させる場所の緯度経度を与える ❏ 最初に表⽰させる場所︓ユーザの現在地 ❏ GPS の取得状況によっては GMSMapView 初期化時 に緯度経度を渡せていないことがあった
  25. Mobility Technologies Co., Ltd. 41 タクシーアプリ「GO」では Google Maps SDK を活⽤している

    ❏ Google Maps の様々な機能を活⽤してアプリが作られている ❏ タクシー⾞両動態表⽰ ❏ 配⾞禁⽌エリア ❏ 近くの道路への引き込み ❏ 地図まわりの実装は難しい ❏ 緯度経度の誤差 ❏ 地図の可視領域の考慮 ❏ パフォーマンスの考慮 ❏ 今回紹介した GO での活⽤事例が参考になれば幸いです
  26. Mobility Technologies Co., Ltd. 44 iOSDC Japan 2022 After Talk

    のご参加お待ちしています 2022年10⽉5⽇ (⽔) 19:00〜20:50 https://sansan.connpass.com/event/255645/