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

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

Sponsored · Ship Features Fearlessly Turn features on and off without deploys. Used by thousands of Ruby developers.
Avatar for Yosuke Imairi Yosuke Imairi
September 11, 2022

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

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

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

Avatar for Yosuke Imairi

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/