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.
    タクシーアプリ「GO」から学ぶ
    Google Maps SDK 活⽤術
    Yosuke Imairi

    View full-size slide

  2. Mobility Technologies Co., Ltd.
    ❏ 株式会社 Mobility Technologies (MoT)
    ❏ タクシーアプリ「GO」の iOS アプリ開発
    ❏ アーキテクチャの選定・導⼊
    ❏ アプリ全体の設計、新機能開発
    ❏ CI 環境の構築・整備、⾃動化の促進
    ❏ チームビルディング
    2
    Yosuke Imairi
    ⾃⼰紹介

    View full-size slide

  3. Mobility Technologies Co., Ltd.
    3
    タクシーが呼べるアプリ「GO」は地図をベースとしたアプリ

    View full-size slide

  4. Mobility Technologies Co., Ltd.
    4
    タクシーが呼べるアプリ「GO」は地図をベースとしたアプリ
    Google Maps SDK を活⽤して
    タクシーアプリ「GO」の機能がどのように実現されているか
    具体例を交えて紹介します

    View full-size slide

  5. Mobility Technologies Co., Ltd.
    1. タクシー⾞両動態の表⽰
    2. 配⾞できないエリアの可視化
    3. 近くの道路に引き込ませる
    4. 緯度経度の誤差
    5. 地図の可視領域
    6. アプリの世界観にあった地図
    7. 地図のパフォーマンス調整
    8. バグ事例とその解決策
    5
    この登壇で話す内容
    Google Maps を活⽤した機能の紹介
    Google Maps 特有の仕様

    View full-size slide

  6. Mobility Technologies Co., Ltd.
    タクシー⾞両動態の表⽰
    6
    01

    View full-size slide

  7. Mobility Technologies Co., Ltd.
    ❏ GOアプリ内で乗⾞地ピンを置くと、周辺の⾞両動態が地
    図に描画される
    ❏ タクシー会社によって⾞両動態の画像が異なる
    7
    タクシー⾞両動態とは
    ❏ タクシー⾞両から送られる情報
    ❏ GPS 位置
    ❏ ⽅⾓
    ❏ 速度
    ❏ メーター情報 etc…

    View full-size slide

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

    View full-size slide

  9. Mobility Technologies Co., Ltd.
    9
    タクシーの⾞両動態を地図に描画させて動かす
    ❏ CoreAnimation (CATransaction) でアニメーションを付与
    ❏ 緯度経度、⾞両の⽅向、データ取得時間を元に計算
    次の動態位置のデータ取得時間との差分からアニメーション時間を割り出す

    View full-size slide

  10. Mobility Technologies Co., Ltd.
    配⾞できないエリアの可視化
    10
    02

    View full-size slide

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

    View full-size slide

  12. Mobility Technologies Co., Ltd.
    12
    タクシーが呼べないエリアを明⽰する
    ❏ GMSPolygon として描画
    ❏ GMSPath の始点と終点を繋いでポリゴンを描画
    ❏ GMSPath は CLLocationCoordinate2D の集合体
    ❏ fillColor, strokeColor, strokeWidth などで外観を整える
    ❏ GO アプリで利⽤されているポリゴンの管理
    ❏ 社内の管理ツールで地図上でポリゴンを登録

    View full-size slide

  13. Mobility Technologies Co., Ltd.
    13
    タクシーが呼べないエリアを明⽰する
    ❏ ポリゴンの中に⽳を空ける
    ❏ 配⾞禁⽌エリアだが、部分的に配⾞可能エリアがある
    ❏ GMSPolygon.holes で指定可能
    ❏ holes は GMSPath の配列なので複数の⽳を空けられる

    View full-size slide

  14. Mobility Technologies Co., Ltd.
    近くの道路に引き込ませる
    14
    03

    View full-size slide

  15. Mobility Technologies Co., Ltd.
    15
    近くの道路に引き込ませる
    ❏ アプリ起動直後に⼀度だけ処理される
    ❏ サーバから道路情報を取得して⼀番近い地点に引き込ませる
    ❏ 道幅が広い場合は、起点に少し寄った場所にする
    ❏ なぜ引き込ませるのか
    ❏ タクシーは建物内まで⼊ることができない
    ❏ 乗務員さんにとっては道路に乗⾞ピンを置いてほしい
    ❏ アプリを起動してその場ですぐ呼びたい
    ❏ 近くの道路に引き込ませることでひと⼿間省かせる
    13m 〜
    5 〜 13m
    3 〜 5m
    0 〜 3m
    道幅
    ※ デバッグ機能で道路情報を可視化

    View full-size slide

  16. Mobility Technologies Co., Ltd.
    緯度経度の誤差
    16
    04

    View full-size slide

  17. Mobility Technologies Co., Ltd.
    17
    Google Maps での地点移動
    ❏ コードで地図の中⼼を移動させる
    ❏ GMSCamera : 地図の中⼼を表す
    ❏ GMSCameraUpdate : 地図の中⼼を変更する(地図を移動させる)
    ❏ 現在地に移動させる
    ❏ 検索結果の地点に移動させる
    let gmsCameraUpdate = GMSCameraUpdate.setTarget(myLocation.coordinate2D)
    gmsMapView.animate(with: gmsCameraUpdate)

    View full-size slide

  18. 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)
    🤔

    View full-size slide

  19. 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)

    View full-size slide

  20. 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点間の距離が求められる(メートル)

    View full-size slide

  21. 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 から得られた緯度経度を利⽤すると誤差はない ✅

    View full-size slide

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

    View full-size slide

  23. Mobility Technologies Co., Ltd.
    地図の可視領域
    23
    05

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  26. Mobility Technologies Co., Ltd.
    26
    Google Maps における可視領域の活⽤場⾯
    ❏ 乗⾞地と⾏き先とルートが収まるようにする
    地図を⼿動で動かす
    (拡⼤ / 移動)
    調整ボタンをタップ
    ( fitBounds の処理が実⾏)

    View full-size slide

  27. Mobility Technologies Co., Ltd.
    27
    Google Maps における可視領域の活⽤場⾯
    ❏ fitBounds に与える緯度経度 の集合体

    View full-size slide

  28. Mobility Technologies Co., Ltd.
    28
    Google Maps における可視領域の活⽤場⾯
    ❏ 緯度経度 の集合体がすべて収まるように調整

    View full-size slide

  29. Mobility Technologies Co., Ltd.
    29
    Google Maps における可視領域の活⽤場⾯
    ❏ 緯度経度に加えて GMSMarker の画像サイズなどの考慮も必要(Insets で設定)
    safeArea

    View full-size slide

  30. Mobility Technologies Co., Ltd.
    アプリの世界観にあった地図
    30
    06

    View full-size slide

  31. Mobility Technologies Co., Ltd.
    31
    Google Maps のスタイルは⾃由に変更できる
    ❏ アプリの世界観に合わせた⾊合いに変更できる
    GO JapanTaxi

    View full-size slide

  32. Mobility Technologies Co., Ltd.
    32
    Google Maps のスタイルは⾃由に変更できる
    ❏ GMSMapStyle
    ❏ JSON 形式で設定
    ❏ かなり細かい設定が可能で Styling Wizard で調整することが望ましい
    ❏ https://mapstyle.withgoogle.com/
    ❏ 動的に切り替えることができる
    ❏ 夜は地図を暗めの⾊にする

    View full-size slide

  33. Mobility Technologies Co., Ltd.
    地図のパフォーマンス調整
    33
    07

    View full-size slide

  34. Mobility Technologies Co., Ltd.
    34
    レンダリングするフレームレートの調整
    ❏ GMSFrameRate
    ❏ GMSMapView.preferredFrameRate で設定
    ❏ .maximum( 30 FPS - 60 FPS )
    ❏ デフォルトとして設定されている
    ❏ SDK 側で端末の確認をして古い端末なら 30 FPS になる
    ❏ .conservative
    ❏ .powerSave( 15 FPS )
    ❏ バッテリー消費を抑えたい場⾯で利⽤
    ❏ 端末のバッテリー残量が少ない
    ❏ Modal で別画⾯を表⽰しているなど、地図との直接的な接点がない場合

    View full-size slide

  35. Mobility Technologies Co., Ltd.
    35
    レンダリングするフレームレートの調整
    ❏ .powerSave と .maximum の差(実機での検証)
    .maximum
    .powerSave

    View full-size slide

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

    View full-size slide

  37. Mobility Technologies Co., Ltd.
    バグ事例とその解決策
    37
    08

    View full-size slide

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

    View full-size slide

  39. Mobility Technologies Co., Ltd.
    39
    地図の初期位置がストーンヘンジになる
    ❏ アプリを起動すると地図の初期位置がストーンヘンジになる
    ❏ 原因は GMSMapView の初期化に問題があった
    ❏ 初期化時に最初に表⽰させる場所の緯度経度を与える
    ❏ 最初に表⽰させる場所︓ユーザの現在地
    ❏ GPS の取得状況によっては GMSMapView 初期化時
    に緯度経度を渡せていないことがあった

    View full-size slide

  40. Mobility Technologies Co., Ltd.
    40
    09 まとめ

    View full-size slide

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

    View full-size slide

  42. Mobility Technologies Co., Ltd.
    42
    10 お知らせ

    View full-size slide

  43. Mobility Technologies Co., Ltd.
    43
    タクシーアプリ「GO」の開発を⼀緒にしませんか
    https://hrmos.co/pages/m
    o-t/jobs/2100002

    View full-size slide

  44. Mobility Technologies Co., Ltd.
    44
    iOSDC Japan 2022 After Talk のご参加お待ちしています
    2022年10⽉5⽇ (⽔) 19:00〜20:50
    https://sansan.connpass.com/event/255645/

    View full-size slide

  45. 文章·画像等の内容の無断転載及び複製等の行為はご遠慮ください。
    Mobility Technologies Co., Ltd.
    45

    View full-size slide