Share
Embed
タクシーアプリ「GO」から学ぶ Google Maps SDK 活用術
iOSDC Japan 2022 にて登壇した内容となります。
https://fortee.jp/iosdc-japan-2022/proposal/cf0d2912-8f56-42e4-9800-b8eced98f48e
Yosuke Imairi
September 11, 2022
Transcript
45 slides
-
Mobility Technologies Co., Ltd. ❏ 株式会社 Mobility Technologies (MoT) ❏
タクシーアプリ「GO」の iOS アプリ開発 ❏ アーキテクチャの選定・導⼊ ❏ アプリ全体の設計、新機能開発 ❏ CI 環境の構築・整備、⾃動化の促進 ❏ チームビルディング 2 Yosuke Imairi ⾃⼰紹介 -
Mobility Technologies Co., Ltd. 4 タクシーが呼べるアプリ「GO」は地図をベースとしたアプリ Google Maps SDK を活⽤して
タクシーアプリ「GO」の機能がどのように実現されているか 具体例を交えて紹介します -
Mobility Technologies Co., Ltd. 1. タクシー⾞両動態の表⽰ 2. 配⾞できないエリアの可視化 3. 近くの道路に引き込ませる
4. 緯度経度の誤差 5. 地図の可視領域 6. アプリの世界観にあった地図 7. 地図のパフォーマンス調整 8. バグ事例とその解決策 5 この登壇で話す内容 Google Maps を活⽤した機能の紹介 Google Maps 特有の仕様 -
Mobility Technologies Co., Ltd. ❏ GOアプリ内で乗⾞地ピンを置くと、周辺の⾞両動態が地 図に描画される ❏ タクシー会社によって⾞両動態の画像が異なる 7
タクシー⾞両動態とは ❏ タクシー⾞両から送られる情報 ❏ GPS 位置 ❏ ⽅⾓ ❏ 速度 ❏ メーター情報 etc… -
Mobility Technologies Co., Ltd. 8 タクシーの⾞両動態を地図に描画させて動かす ❏ GMSMarker として描画 ❏
地図上の特定の地点にマーカーを配置させる ❏ UIView, UIImage で表⽰するコンテンツを指定 ❏ マーカーのどの位置を地図上の緯度経度に合わせるか ❏ groundAnchor (0.5, 1) (0.5, 0.5) -
Mobility Technologies Co., Ltd. 9 タクシーの⾞両動態を地図に描画させて動かす ❏ CoreAnimation (CATransaction) でアニメーションを付与
❏ 緯度経度、⾞両の⽅向、データ取得時間を元に計算 次の動態位置のデータ取得時間との差分からアニメーション時間を割り出す -
Mobility Technologies Co., Ltd. 11 タクシーが呼べないエリアを明⽰する ❏ 「配⾞禁⽌エリア」として明⽰する ❏ 海や湖など明らかにタクシーが呼べないエリアは描画なし
❏ ⾚いポリゴンとしてエリアを明⽰させる ❏ ピンを置くとタクシーが呼べない旨が提⽰される ❏ アプリでタクシーが呼べないエリアが存在する ❏ 駅周辺(駅前のタクシー乗り場など) ❏ 特定の施設内、商店街 ❏ ⼤学の敷地内、公園 -
Mobility Technologies Co., Ltd. 12 タクシーが呼べないエリアを明⽰する ❏ GMSPolygon として描画 ❏
GMSPath の始点と終点を繋いでポリゴンを描画 ❏ GMSPath は CLLocationCoordinate2D の集合体 ❏ fillColor, strokeColor, strokeWidth などで外観を整える ❏ GO アプリで利⽤されているポリゴンの管理 ❏ 社内の管理ツールで地図上でポリゴンを登録 -
Mobility Technologies Co., Ltd. 13 タクシーが呼べないエリアを明⽰する ❏ ポリゴンの中に⽳を空ける ❏ 配⾞禁⽌エリアだが、部分的に配⾞可能エリアがある
❏ GMSPolygon.holes で指定可能 ❏ holes は GMSPath の配列なので複数の⽳を空けられる -
Mobility Technologies Co., Ltd. 15 近くの道路に引き込ませる ❏ アプリ起動直後に⼀度だけ処理される ❏ サーバから道路情報を取得して⼀番近い地点に引き込ませる
❏ 道幅が広い場合は、起点に少し寄った場所にする ❏ なぜ引き込ませるのか ❏ タクシーは建物内まで⼊ることができない ❏ 乗務員さんにとっては道路に乗⾞ピンを置いてほしい ❏ アプリを起動してその場ですぐ呼びたい ❏ 近くの道路に引き込ませることでひと⼿間省かせる 13m 〜 5 〜 13m 3 〜 5m 0 〜 3m 道幅 ※ デバッグ機能で道路情報を可視化 -
Mobility Technologies Co., Ltd. 17 Google Maps での地点移動 ❏ コードで地図の中⼼を移動させる
❏ GMSCamera : 地図の中⼼を表す ❏ GMSCameraUpdate : 地図の中⼼を変更する(地図を移動させる) ❏ 現在地に移動させる ❏ 検索結果の地点に移動させる let gmsCameraUpdate = GMSCameraUpdate.setTarget(myLocation.coordinate2D) gmsMapView.animate(with: gmsCameraUpdate) -
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) 🤔 -
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) -
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点間の距離が求められる(メートル) -
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 から得られた緯度経度を利⽤すると誤差はない ✅ -
Mobility Technologies Co., Ltd. 22 Google Maps SDK における座標の扱い ❏
Google Maps SDK から取得できる座標を指定すれば誤差がなくなる ❏ それ以外から取得した位置情報では誤差が⽣じる ❏ GPS から取得 ❏ 外部サイトからの連携で指定された緯度経度 ❏ ⼿動で⼊⼒した値 ❏ 誤差があったとしても無視できる程度(数cm) ❏ 誤差が⽣じることを前提とした実装が必要 ❏ GMSCamera の座標を == で判定しない ❏ GO アプリでは誤差が 1m 以内なら同じ地点という判定をしている -
Mobility Technologies Co., Ltd. 24 Google Maps における可視領域 ( ʼvisibleʼ
region) ❏ GMSUIPaddingSettingView ❏ GMSMapView 上に配置される透明の View ❏ GMSMapView の padding に応じて変形する ❏ 現在表⽰させている領域を指定させる ❏ 左下の Google ロゴが矩形の⾓に当たる ❏ Google ロゴは隠れないように表⽰させる必要がある GMSMapView GMSUIPaddingSettingView -
Mobility Technologies Co., Ltd. 25 Google Maps における可視領域の活⽤場⾯ ❏ GMSCameraUpdate.fitBounds
❏ GMSCoordinateBounds として地点の緯度経度の集合体を渡す ❏ 可視領域内にそれらがすべて収まるようにズームレベルが⾃動調整される ❏ ⽅⾓は北固定、地図の傾きはリセットされる ❏ GO アプリでの利⽤例 ❏ 乗⾞地と⾏き先とルートが収まるようにする ❏ 乗⾞地候補となる地点がすべて⾒えるようにする -
Mobility Technologies Co., Ltd. 26 Google Maps における可視領域の活⽤場⾯ ❏ 乗⾞地と⾏き先とルートが収まるようにする
地図を⼿動で動かす (拡⼤ / 移動) 調整ボタンをタップ ( fitBounds の処理が実⾏) -
Mobility Technologies Co., Ltd. 28 Google Maps における可視領域の活⽤場⾯ ❏ 緯度経度
の集合体がすべて収まるように調整 -
Mobility Technologies Co., Ltd. 29 Google Maps における可視領域の活⽤場⾯ ❏ 緯度経度に加えて
GMSMarker の画像サイズなどの考慮も必要(Insets で設定) safeArea -
Mobility Technologies Co., Ltd. 32 Google Maps のスタイルは⾃由に変更できる ❏ GMSMapStyle
❏ JSON 形式で設定 ❏ かなり細かい設定が可能で Styling Wizard で調整することが望ましい ❏ https://mapstyle.withgoogle.com/ ❏ 動的に切り替えることができる ❏ 夜は地図を暗めの⾊にする -
Mobility Technologies Co., Ltd. 34 レンダリングするフレームレートの調整 ❏ GMSFrameRate ❏ GMSMapView.preferredFrameRate
で設定 ❏ .maximum( 30 FPS - 60 FPS ) ❏ デフォルトとして設定されている ❏ SDK 側で端末の確認をして古い端末なら 30 FPS になる ❏ .conservative ❏ .powerSave( 15 FPS ) ❏ バッテリー消費を抑えたい場⾯で利⽤ ❏ 端末のバッテリー残量が少ない ❏ Modal で別画⾯を表⽰しているなど、地図との直接的な接点がない場合 -
Mobility Technologies Co., Ltd. 35 レンダリングするフレームレートの調整 ❏ .powerSave と .maximum
の差(実機での検証) .maximum .powerSave -
Mobility Technologies Co., Ltd. 36 Graphic API の選択 ❏ GMSServices.setMetalRendererEnabled
❏ OpenGL の代わりに Metal でレンダリングが可能 ❏ GMSService の初期化前に設定 ❏ OpenGL での課題 ❏ OpenGL + M1Max + シミュレータ だと地図のスクロールの挙動に問題あり ❏ スクロールの慣性が効きすぎて細かい地点移動が困難 ❏ Metal による恩恵 ❏ Metal + M1Max + シミュレータ で地図の挙動が圧倒的に軽い ❏ スクロールの慣性が効きづらくなった -
Mobility Technologies Co., Ltd. ❏ UIViewController の present, dismiss と同時に
GMSMapView animate を 実⾏ ❏ present, dismiss は正常に⾏われる ❏ GMSMapView animate はアニメーションの終点が⼀瞬適⽤される ❏ その後にアニメーションが再⽣される ❏ present, dismiss をアニメーションなしで実⾏しても発⽣する ❏ 回避策 ❏ 地図のアニメーション実⾏を少し遅延させることで回避している ❏ 10 - 100ms 38 画⾯の切り替えと同時に地図のアニメーション処理が⾏えない -
Mobility Technologies Co., Ltd. 39 地図の初期位置がストーンヘンジになる ❏ アプリを起動すると地図の初期位置がストーンヘンジになる ❏ 原因は
GMSMapView の初期化に問題があった ❏ 初期化時に最初に表⽰させる場所の緯度経度を与える ❏ 最初に表⽰させる場所︓ユーザの現在地 ❏ GPS の取得状況によっては GMSMapView 初期化時 に緯度経度を渡せていないことがあった -
Mobility Technologies Co., Ltd. 41 タクシーアプリ「GO」では Google Maps SDK を活⽤している
❏ Google Maps の様々な機能を活⽤してアプリが作られている ❏ タクシー⾞両動態表⽰ ❏ 配⾞禁⽌エリア ❏ 近くの道路への引き込み ❏ 地図まわりの実装は難しい ❏ 緯度経度の誤差 ❏ 地図の可視領域の考慮 ❏ パフォーマンスの考慮 ❏ 今回紹介した GO での活⽤事例が参考になれば幸いです -
Mobility Technologies Co., Ltd. 44 iOSDC Japan 2022 After Talk
のご参加お待ちしています 2022年10⽉5⽇ (⽔) 19:00〜20:50 https://sansan.connpass.com/event/255645/