もう一人のY君

iPhoneアプリのレビューやアップデートレビューなどを書いています. たまに数学の記事も書きます.

もう一人のY君 MENU  MENU

【iPhoneショートカット】国土地理院のタイル地図を取得する

f:id:thetheorier:20211105141157p:plain

 今回は国土地理院が提供する基本測量成果です.

 

 

ショートカット

ショートカット

  • Apple
  • 仕事効率化
  • 無料

※価格は記事執筆時のものです. 現在の価格はApp Storeから確認ください.

 レビュー時のiOSバージョン : iOS15.1

 

 

スポンサーリンク

 


 

 

国土地理院のタイル地図

maps.gsi.go.jp

 地球は(おおよそ)球体であるため、特定の位置を指定するのに角度(緯度・経度)を用いる方法と、球面を平面に移した座標系を用いる方法があります.

 

 我々が「地図」として見るそれは平面であるため、画像として地図を取得するにはその場所を含む範囲を平面に置き換えたものでなければなりません.

 その場合、どこを中心(基準)とするかで世界測地系とかピクセル座標系などと言われます.

 今回は我々が普段使っている緯度・経度によって結果を得ることにします.

 

 タイル地図は目的によって複数種類ありますが、どれも共通するのは3つのパラメータです.

 

 

基本情報

 まずひとつ目はズームレベルzです.

 名前の通り地図の倍率に関わるパラメータで値が大きいほど拡大されます.

 地図の種類によって値の範囲が異なります.

 

 次に位置を示すxとyです.

 ただし緯度経度と異なり、同じ場所でもズームレベルに応じて値が異なります.

 

 例えば名古屋駅を含むタイルの場合、ズームレベル10だとx=901、y=405、ズームレベル16だとx=57686、y=25920になります.

 以下にアクセスして違いを確認してみてください.

 

https://cyberjapandata.gsi.go.jp/xyz/std/10/901/405.png

 

https://cyberjapandata.gsi.go.jp/xyz/std/16/57686/25920.png

 

hosohashi.blog59.fc2.com

 

www.trail-note.net

 緯度経度からこのx,yの値をどう計算するか…はこちらが紹介しています.

 ややこしいのですが、紹介されている式x,yはピクセル座標であり、今回使うパラメタx,yはそこから更に256で割る必要があります(1つ目に紹介した記事の前半にその言及があり、後半でピクセル座標の式があります).

 

 というわけで今回の目的に沿って改めて書くと、緯度 \phi 、経度 \psi 、ズームレベルzに対して以下になります.

 

 \displaystyle x=\frac{2^{z+7}}{256}\left( \frac{\psi}{180}+1 \right)

 

 \displaystyle y=\frac{2^{z+7}}{256\pi}\left\{ -\tanh^{-1}\left( \sin{\left( \frac{\pi}{180} \right)\psi} \right)+\tanh^{-1}\left( \sin{\left( \frac{\pi}{180} \right)L} \right) \right\} 
 L:= 85.05112878

 

 結果はまず間違いなく整数ではないため、小数点以下を切り捨てることとなります.

 

 また指定位置が画像の中心に来るとは限りません.

 具体的にはこれらのx,yをそれぞれ256で割った余りが、画像のピクセル座標に一致します.

 なのでたまたま中心だったり、画像のギリギリ端っこだったりします.

 

 

 いずれにしろ、この変形式さえ分かれば後はどうとでもなります.

 以降はどれだけ機能を増やすか…ですね.

 

 

レシピ

 今回は位置の指定として

 

  • 予め緯度経度を指定
  • その場で入力(カスタム)
  • 現在位置(GPS)

 

の3つを考えます.

 

 またタイル地図もいくつか種類があるのですが、そのうち

 

  • 標準地図
  • 単色地図
  • 写真
  • 色別標高図

 

の4種を選択できるようにします.

 

 

f:id:thetheorier:20211105151634p:plain

 まずは位置情報からです.

 値は「辞書」にしておきます.

 

 

f:id:thetheorier:20211105151758p:plain

 値の中で緯度と経度をそれぞれキーとした値を入れておきます.

 これで各々の位置情報のセットができました.

 

 カスタムと現在位置は後で追加します.

 

 

f:id:thetheorier:20211105152024p:plain

 「メニューから選択」アクションを追加してタイル地図4種の名前を追加します.

 各々をタップしたときの処理は概ね共通なので以下では標準地図の場合のみ書きます.

 

 

f:id:thetheorier:20211105152234p:plain

 ズームレベルzの値を「入力を要求」で入力します.

 今回要求されるべき値が5~18という範囲になっているため、エラー処理のために入力値xに対して(x-5)(x-18)を計算します.

 もし入力した値xが5から18までの場合、この結果は0以下の数に、それ以外の場合は正整数になるためif文一つで場合分けできます.

 

 

f:id:thetheorier:20211105152629p:plain

 まず先の計算結果が0より大きい場合.

 このときは入力した値が範囲から外れているので例外処理を行います.

 レシピを再実行するか終了するか選べるようにしていますが見ての通りゴチャゴチャします.

 項目が増えれば増えるほど例外処理のアクション数も嵩みます、仕方ないですね.

 

 

f:id:thetheorier:20211105153834p:plain

 次に計算結果が正でない場合です.

 このときは入力した値が指定範囲となっているため、必要な処理を行います.

 まず入力したズームレベル値を正式に変数zに代入します.

 また位置情報タイトルも変数に置きます(必須ではないです).

 

 最後にタイル地図のURLを変数に置きます.

 但しこの時点ではまだパラメータx,yが決まっていないため、とりあえずパラメータが入る部分をstatusという文字列におき、最後に置換することにします.

 このメニュー選択の前でx,yを計算してもいいのですが、zの例外処理を前提とするなら、せっかくx,yを計算したのにzが範囲外でやりなおし…というのは非効率だからです.

 実際にはそう大して待たされることではないですが、まったく関係ない別のレシピを作るときに参考になるかもしれません.

 

 というわけで、これを残り3つについても同様に行います.

 

 

 

f:id:thetheorier:20211105154656p:plain

 ズームレベルzが決まったら次は緯度と経度を決めます.

 レシピの最初に作った「辞書」のキーに加え、手打ちするための「カスタム」と「現在位置」の文字列を「テキスト」アクションに並べ、「テキストを分割」で改行で分割した上で「リストから選択」で一つ選ばせます.

 リストはこのようにして繋げて分割することで項目を追加することができます.

 

 

f:id:thetheorier:20211105155021p:plain

 「リストから選択」の結果に応じて緯度と経度を取得します.

 まず「カスタム」が選ばれた場合です.

 このときは手打ちなので「入力を要求」で各々の値を取得します.

 

 

f:id:thetheorier:20211105155210p:plain

 次は現在位置を選んだ場合です.

 この場合は「場所」アクションで「現在地」を選択し、ここから緯度を経度を取り出します.

 ここで設定アプリの位置情報サービスから設定できる「正確な位置情報」をオフにすると、ズームレベルが高いほど結果がズレる可能性が当然考えられます.

 

 

f:id:thetheorier:20211105155619p:plain

 そしてそのどちらでもない場合です.

 このときは一番最初に追加した「辞書」に登録した緯度と経度を取得することになります.

 

 これで3つのパラメータz,φ,ψが決まったのでタイル座標x,yを求めることができます.

 

 

f:id:thetheorier:20211105155801p:plain

 まずはタイル座標xです.

 計算後「端数を処理」アクションで小数点以下を切り捨ててから変数に代入します.

 

 

f:id:thetheorier:20211105160100p:plain

 次にタイル座標yです.

 数式がそれなりに長く複雑なため、「計算式」アクション一発ではメチャクチャになるのでやむなく分割しています.

 

 

 

f:id:thetheorier:20211105160252p:plain

 これで選択肢に応じたパラメータz,x,yが求まりました.

 最後に既に与えておいたURLの"status"の箇所をパラメータ付きの正式なものに差し替え、結果を「入力からイメージを取得」で画像を取得、表示して終了です.

 

 

 

実行

f:id:thetheorier:20211105160507p:plain

 結果を確認します.

 タイル地図の種類を選び、ズームレベルを指定します.

 入力したズームレベルの値に問題があればここでやり直しです.

 

 

f:id:thetheorier:20211105160657p:plain
国土地理院提供のベースマップをもとに作成

 問題なければ画像のようにタイル地図が表示されます.

 

 

 国土地理院ではここで挙げた以外のタイル地図も公開されています.

 

 レシピの配布については、国土地理院への承認申請に関わると判断して控えることにします(これを見てレシピを作成し、個人利用する分には問題ありません).