背景
以下の記事の続きです。
iOSだと、正常に動作しない事が発覚しました。
ピンをタップしても反応しません。
なので、iOSでも動作させる事が出来ないか?と試行錯誤した話です。
本題
First Stage
現象の調査
まず、画面をタップした時、どの座標をタップした判定になっているのか?を調べました。
すると、期待とは全く違う座標をタップした判定になっていました。
これにより、ピンをタップしても反応しない事に合点がいきました。
検証
では、前記事における、どの処理で座標のズレが発生したのか?を見ていきました。
まず見たのは、
次の問題(5) ピンの経緯度を、地図中央を原点としたGoogleMap上の座標系(pixel単位)に変換する
における、 1[pixel]あたりの経緯度 でした。
(座標のズレに直結する所なので。)
修正
それで、
次の問題(3) 経緯度を、地図中央を原点としたGoogleMap上の座標系(pixel単位)に変換する
に従い、iOSでの 1[pixel]あたりの経緯度 を算出しました。以下の通りです。
ZoomLevel=1における1[pixel]あたりの緯度 = -0.596166093
ZoomLevel=1における1[pixel]あたりの経度 = 0.703125
効果確認
画面中央に位置するピンに限り、タップすると反応しました。
しかし、画面中央以外に位置するピンは、タップしても反応しませんでした。
Second Stage
現象の調査
先の 効果確認 の通りです。
検証
画面中央付近のピンではどうなるか?と考え、試してみました。
すると、期待する範囲とはやや異なるものの、反応する事が確認できました。
しかし、中央から一定以上離れたピンだと、反応しませんでした。
この事から、**中央から離れるにつれ、ピンの(x,y)座標のズレが大きくなるのでは?**という仮説を立てました。
そこで、「期待するピンの(x,y)座標」と「実際のピンの(x,y)座標が、期待からどれ程ズレているか?」を、グラフにプロットしてみました。
x方向
横軸が「期待するピンのx座標」
縦軸が「実際のピンのx座標の、期待からのズレ具合」
y方向
横軸が「期待するピンのy座標」
縦軸が「実際のピンのy座標の、期待からのズレ具合」
見ての通り、1次関数的にズレが大きくなっていく事が分かりました。
修正
先の検証のグラフでは、「期待するピンの(x,y)座標」が分かっていないといけません。
しかし、プログラムは、実行中にその事は分かりません。
そこで、「実際のピンの(x,y)座標」に変えて、再度グラフにプロットしました。
x方向
横軸が「実際のピンのx座標」
縦軸が「実際のピンのx座標の、期待からのズレ具合」
y方向
横軸が「実際のピンのy座標」
縦軸が「実際のピンのy座標の、期待からのズレ具合」
これらのグラフから、期待するピンの(x,y)座標とのズレを算出する式を導出しました。
以下のように定義する. \\
実際のピンのx座標:x \\
実際のピンのy座標:y \\
期待するピンのx座標とのズレ:x' \\
期待するピンのy座標とのズレ:y' \\
x' = 1.861214202 x \\
y' = 2.1844121085492 y + 24.813884593318
これらを用いて、期待するピンの(x,y)座標を算出するコードを作成しました。
expectPinX = actualPinX + 1.861214202 * actualPinX
expectPinY = actualPinY + 2.1844121085492 * actualPinY + 24.813884593318
効果確認
任意の位置のピンでも、タップすると反応するようになりました。
最後に
背景の背景
"iPhone 13 Pro Max"で動作確認してた時に、この問題を発見しました。
当初は、「なんでこの端末だけ!?」と驚きました。
思い返すと、"Pixel 4"でのみしか動作確認してこなかった事に気付き、
端末問題では?と思い、切り分けをしました。
結果、iOS固有問題だと分かり、ちょっとだけ安心しましたね。
感想
この記事の内容をやり切る事に、ほぼ1日を費やしました。。
終わった時には、「あれ?Flutterで開発をしてたんじゃなかったっけ?」と、作成したExcelシートを見ながら思いました。
追加したコードも、30行程度でしたしね。(iOS/Androidで処理を分けるので、少し膨らんだ印象です)
まー、何はともあれ、ちゃんと終わって良かった。。
安心して2021年を終えられます。
では。