LoginSignup
4
3

More than 1 year has passed since last update.

【GAS】GoogleAppsScriptで地図に線や円を描写する【GoogleMap】

Last updated at Posted at 2022-06-15

概要

GASでGoogleマップを表示する際、地図上にピンを立てたり線を引くメソッドがある。
でも円を描写するメソッドがない・・・。

任意の中心点と半径でGoogleマップに円を描写したいなぁと思い、やってみた。

関連記事
GoogleAppsScriptで地図を扱うTips
GoogleAppsScriptで2点間のルートと道中の標高を表示

線を描く

まずは線の描写から。

公式リファレンスを見ると、Maps.encodePolyline([緯度,経度,緯度,経度,緯度,経度,...])って感じに点を決めて、Maps.addPath()してやると線が引けるとのこと。

点を用意

皇居のお堀外周に線を引いてみる。

Googleマイマップを使い、次のようにお堀をなぞる線を繋ぐ点をゲットした。

・お堀外周のポリゴン作成
・KMLファイルに書き出す
・拡張子をtxt変更
・ポリゴンの各点の経緯度が並んでる

Googleマップ上で経緯度を拾うことも可能だけど、完成形をイメージしやすかったのでマイマップを使用してみた。

※この方法だと "経度,緯度" の順で並んでるので注意。GASに入力するときは "緯度,経度" の順番で記述する。

コード

function koukyo() {

  var point = [35.6889765,139.745822,
               35.6887848,139.7456289,
               35.6866238,139.7454143,
               35.6835737,139.7445775,
               35.6828069,139.7447921,
               35.6799484,139.7462512,
               35.6794604,139.7476245,
               35.6785889,139.748354,
               35.6775431,139.749384,
               35.6774036,139.7509719,
               35.6779614,139.753461,
               35.6754514,139.7596837,
               35.6840269,139.762559,
               35.6844452,139.7604132,
               35.687408,139.7613145,
               35.6891508,139.7607136,
               35.6891508,139.7600699,
               35.6899176,139.7600699,
               35.6907542,139.7563363,
               35.6926363,139.7551347,
               35.6932637,139.7535468,
               35.6936471,139.7513581,
               35.6950063,139.750371,
               35.6943441,139.7477961,
               35.6923575,139.7479249,
               35.6916952,139.7470666,
               35.6897434,139.7482682,
               35.6889765,139.745822];

  var polyline = Maps.encodePolyline(point);
  var map = Maps.newStaticMap()
                .setLanguage('ja')
                .setSize(300,300)
                .setZoom(14)
                .setCenter('皇居')
                .addPath(polyline);

  SpreadsheetApp.getActiveSheet().insertImage(map,1,1);
}

点を決めてencodePolylineして、地図の各パラメータと一緒にaddPathして、シートに表示。中心点はランドマークでも行けるのでシンプルに皇居と指定。

こんな感じ

image.png
^^)b イイネ

円を描く

円を描くメソッドがなくたって、線が引けるんだから直接描けばいい。中心点を決めて等距離にある点を繋いだら円になるよなと、試してみた。

失敗例

x=rcosθ y=rsinθで円の座標が求められる。と思って計算して描写したところ、楕円になってしまった。
image.png
どうやら緯度によって経度当たりの長さが変わるので補正が必要っぽい。

補正付き数式

よく分からなくてググったところ、OKWAVEでいい感じに意見交換されてたので、書き込みを参考にして数式を作成。

\begin{align}
&y=緯度+\frac{円の半径×\sin\theta}{地球の半径}\\
&x=経度+\frac{円の半径×\cos\theta}{地球の半径}×\frac{1}{cosy}
\end{align}

x=rcosθ y=rsinθの考え方はそのままに、xにはcosyの逆数をかければ良いっぽい。で、角度と長さから分かった座標分、元の経緯度からずらしてやる。

地球の半径は6371008mなので、あとは元の経緯度と円の半径が決まれば円が描けるはず!
Qiita記事:【GoogleMap】地球を半径6371008mの球体として距離計算していた
OKWAVE:距離から緯度経度を求める方法

コード

というわけで、皇居を中心に半径1kmの円を描いてみる。

function en() {

  var lat = 35.68523;  //皇居の緯度
  var lng = 139.75279; //皇居の経度
  var len = 1000;      //円の半径m

  var I = Math.PI/180; //ラジアン変換
  var R = 6371008 * I; //地球の半径m(×ラジアン変換)

  var point = [];

  //基準点から全方位へlenだけ離れた位置を計算して並べていく
  for(var A=0; A<=360; A++){
    var y = lat + len * Math.sin(A*I) / R ;
    var x = lng + len * Math.cos(A*I) / R / Math.cos(y*I);
    point.push(y,x);
  }

  var polyline = Maps.encodePolyline(point);
  var map = Maps.newStaticMap()
                .setLanguage('ja')
                .setSize(300,300)
                .setZoom(14)
                .setCenter(lat,lng)
                .addPath(polyline);

  SpreadsheetApp.getActiveSheet().insertImage(map,1,1);
}

事前に、分母に来る地球の半径にラジアン変換をかけておき、度数に戻す式を省略。for文中の数式を見やすくしたつもりだけど・・・好みの問題?

こんな感じ

image.png
できた^^
厳密には円ではなく360角形。

おまけ

Maps.setPathStyle(線の太さ, 線の色, 塗りつぶし)で描写スタイルを指定できる。コードの地図設定部分を次のようにすると・・・

Maps.newStaticMap()
    .setLanguage('ja')
    .setSize(300,300)
    .setZoom(14)
    .setCenter(lat,lng)
    .setPathStyle(5,'red','blue')
    .addPath(polyline);

こんな感じになる。
image.png
塗りつぶし部分をnullにすれば塗りつぶしなし。

おしまい

4
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
3