サンプル・プログラムの実行例
サンプル・プログラムのダウンロード
gmapSolarSystem.html | サンプル・プログラム本体。 |
準備
20: <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
21: <script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyB-LE2H8D9At3-J7aqwuQW2oJ-_ulXcozA®ion=JP&libraries=geometry"></script>
まず、GoogleマップAPIを利用するにはキーが必要となる。
「Google Maps APIs for Web」にアクセスし、「キーを取得」ボタンをクリックすると無料で取得できる。これを "https://maps.googleapis.com/maps/api/js?key=" に続く部分に記入すること。ダウンロードしたコンテンツに書かれているキーは、当サイトでしか利用できない。また、Google Cloud Console に入り、GoogleMaps JavaScript API、Google Maps Geocoding API を有効にする。
なお、後述するとおり geometryライブラリを利用するので、URLのオプションに libraries=geometry を加えてある。
23: //Googleマップ用パラメータ
24: var gmap;
25: var gmapid = 'gmap'; //マップID
26: var gwidth = 600; //地図幅
27: var gheight = 400; //地図高
28: var msize = 32; //惑星マーカーのサイズ
29:
30: //初期値
31: var lat_center = 35.681111; //地図の中心点(緯度)=東京駅
32: var lng_center = 139.766667; // (経度)
33: var lat_sun = 35.681111; //太陽の位置(緯度)=東京駅
34: var lng_sun = 139.766667; // (経度)
35: var lat_earth = 35.466111; //地球の位置(緯度)=横浜駅
36: var lng_earth = 139.6225; // (経度)
37: var zoom = 7; //ズームの初期値
38: var maptype = 'roadmap'; //マップタイプ
なお、惑星マーカーのサイズ msize は、後述する太陽のアイコン、惑星の基本情報に指定するものと同じであること。
44: //太陽のアイコン
45: const sun = {
46: icon: 'http://iconhoihoi.oops.jp/sozai/icon/166-planet/icon_1r_32.png'
47: }
48: //惑星の基本情報
49: // radius:軌道半長径(AU),icon:アイコンファイル,
50: // color:軌道描画色,weight:軌道の太さ,
51: // heading:アイコン配置位置(真北から時計回りの角度)
52: let planets = {
53: mercury: {
54: radius: 0.3871,
55: icon: 'http://iconhoihoi.oops.jp/sozai/icon/166-planet/icon_2y_32.png',
56: color: '#FF0000',
57: weight: 1,
58: heading: 45
59: },
60: venus: {
61: radius: 0.7233,
62: icon: 'http://iconhoihoi.oops.jp/sozai/icon/166-planet/icon_3g_32.png',
63: color: '#FF0000',
64: weight: 1,
65: heading: 90
66: },
惑星の情報は、コメントにあるように、radius:軌道半長径(AU),icon:アイコンファイル,color:軌道描画色,weight:軌道の太さ,heading:アイコン配置位置(真北から時計回りの角度)から成る。
円軌道でよければ、変数 planets に情報を追加することで、いくつでも描くことができる。
解説:Googleマップとイベントの準備
280: /**
281: * Googleマップ関係
282: */
283: google.maps.event.addDomListener(window, 'load', function() {
284: var mapdiv = document.getElementById(gmapid);
285: var myOptions = {
286: zoom: zoom,
287: center: new google.maps.LatLng(lat_center, lng_center),
288: mapTypeId: google.maps.MapTypeId.maptype,
289: mapTypeControl: true,
290: scaleControl: true
291: };
292: gmap = new google.maps.Map(mapdiv, myOptions);
293:
294: //初期化
295: initialize();
296:
297: //event.addListener
298: google.maps.event.addListener(gmap, 'click', function(e) {
299: onClickMap(e.latLng);
300: });
301: });
解説:初期化処理
231: /**
232: * 初期化処理
233: * @param なし
234: * @return なし
235: */
236: function initialize() {
237: //太陽の位置、マーカー
238: l_sun = new google.maps.LatLng(lat_sun, lng_sun);
239: //描画済みのマーカーがあれば消去
240: if (markers['sun'] != null) {
241: markers['sun'].setMap(null);
242: }
243: //マーカーを描く
244: markers['sun'] = new google.maps.Marker({
245: position: l_sun,
246: icon: new google.maps.MarkerImage(
247: sun.icon,
248: new google.maps.Size(msize, msize),
249: new google.maps.Point(0, 0),
250: new google.maps.Point(msize / 2, msize / 2), //位置調整
251: ),
252: map: gmap
253: });
254:
255: //地球の位置、マーカー
256: l_earth = new google.maps.LatLng(lat_earth, lng_earth);
257: //描画済みのマーカーがあれば消去
258: if (markers['earth'] != null) {
259: markers['earth'].setMap(null);
260: }
261: //マーカーを描く
262: markers['earth'] = new google.maps.Marker({
263: position: l_earth,
264: icon: new google.maps.MarkerImage(
265: planets['earth'].icon,
266: new google.maps.Size(msize, msize),
267: new google.maps.Point(0, 0),
268: new google.maps.Point(msize / 2, msize / 2), //位置調整
269: ),
270: map: gmap
271: });
272:
273: //距離計算
274: var distance = google.maps.geometry.spherical.computeDistanceBetween(markers['sun'].position, markers['earth'].position);
275:
276: //太陽系を描く
277: drawSolarSystem(markers['sun'].position, distance);
278: }
まず、太陽の位置(緯度・経度)を取り出し、マーカーとして表示する。このとき、あとでマーカーを移動するために、マーカーはオブジェクト変数 markers に代入しておく。
地球についても同様に処理する。
次に、惑星軌道を描く基準となる、太陽=地球間の距離を求める。
GoogleマップAPIの geometryライブラリには2点間の距離計算メソッド spherical.computeDistanceBetween が用意されているので、これを利用することにする。
これらが揃ったら、太陽系を描画するユーザー関数 drawSolarSystem を呼び出す。
解説:各惑星の軌道を描き、マーカーを設置する
121: /**
122: * 惑星の軌道を描く
123: * @param object latlng 太陽の位置(緯度・経度)
124: * @param double distance 太陽=地球距離(メートル)
125: * @return なし
126: */
127: function drawSolarSystem(latlng, distance) {
128: //惑星の数だけ繰り返す
129: for (let key in planets) {
130: radius = distance * planets[key].radius; //軌道半長径
131: //描画済みの円があれば消去
132: if (orbits[key] != null) {
133: orbits[key].setMap(null);
134: }
135: //円を描く
136: orbits[key] = new google.maps.Circle({
137: map: gmap,
138: clickable: false,
139: center: latlng, //中心点
140: radius: radius, //半径(メートル)
141: fillOpacity: 0.0, //塗りつぶし透過度
142: strokeColor: planets[key].color, //外周色
143: strokeWeight: planets[key].weight //外周太さ(ピクセル)
144: });
145:
146: //惑星マーカーを設置
147: if (key != 'earth') {
148: p_latlng = google.maps.geometry.spherical.computeOffset(latlng, radius, planets[key].heading);
149: //描画済みのマーカーがあれば消去
150: if (markers[key] != null) {
151: markers[key].setMap(null);
152: }
153: //マーカーを描く
154: markers[key] = new google.maps.Marker({
155: position: p_latlng,
156: icon: new google.maps.MarkerImage(
157: planets[key].icon,
158: new google.maps.Size(msize, msize),
159: new google.maps.Point(0, 0),
160: new google.maps.Point(msize / 2, msize / 2), //位置調整
161: ),
162: map: gmap
163: });
164: }
165: }
166: }
GoogleマップAPIには円を描画するメソッド Circle が用意されている。
惑星の軌道は、正確には楕円であるが、今回はメソッド Circle を利用することでプログラムを簡素化した。軌道がかなり楕円になっている冥王星は、今回は除外した。
あとで軌道を移動するために、メソッド Circle で描いたオブジェクト情報はオブジェクト変数 orbits に格納しておく。
ユーザー関数 initialize と同様に、各惑星のマーカーを軌道上に設置してゆく。
設置場所(緯度・経度)は、太陽の位置から planets[].heading で指定する方向に、軌道半長径だけ離れた位置に設置することにする。GoogleマップAPIの geometryライブラリに用意されているメソッド spherical.computeOffset を利用することで、その位置を求めている。
なお、太陽や地球と同様、あとで軌道を移動するために、マーカーはオブジェクト変数 markers に代入しておく。
解説:各惑星の軌道、マーカーを消去する
168: /**
169: * 各惑星の軌道、マーカーを消去する
170: * @param なし
171: * @return なし
172: */
173: function clearSolarSystem() {
174: for (let key in planets) {
175: //描画済みのマーカーがあり、地球以外なら消去
176: if ((markers[key] != null) && (key != 'earth')) {
177: markers[key].setMap(null);
178: }
179: //描画済みの円があれば消去
180: if (orbits[key] != null) {
181: orbits[key].setMap(null);
182: }
183: }
184: };
描画時に代入したオブジェクト変数 orbits および markers を参照しながら、GoogleマップAPIメソッド setMap で消去していく。
解説:地図クリック時の処理
186: /**
187: * 地図クリック時の処理
188: * @param object lat_lng クリックされた座標
189: * @return なし
190: */
191: function onClickMap(lat_lng) {
192: //太陽と地球のどちらが選ばれているか
193: var radios = document.myform.selector;
194: for (var i = 0; i < radios.length; i++) {
195: if (radios[i].checked) {
196: selector = radios[i].value;
197: break;
198: }
199: }
200: var longitude = 'lng_' + selector;
201: var latitude = 'lat_' + selector;
202: if (selector == 'sun') {
203: icon = sun.icon;
204: } else {
205: icon = planets['earth'].icon;
206: }
207:
208: //描画済みのマーカーがあれば消去
209: if (markers[selector] != null) {
210: markers[selector].setMap(null);
211: }
212: //マーカーを描く
213: markers[selector] = new google.maps.Marker({
214: position: lat_lng,
215: icon: new google.maps.MarkerImage(
216: icon,
217: new google.maps.Size(msize, msize),
218: new google.maps.Point(0, 0),
219: new google.maps.Point(msize / 2, msize / 2), //位置調整
220: ),
221: map: gmap
222: });
223:
224: //距離計算
225: var distance = google.maps.geometry.spherical.computeDistanceBetween(markers['sun'].position, markers['earth'].position);
226:
227: //太陽系を描く
228: drawSolarSystem(markers['sun'].position, distance);
229: }
違う点は、冒頭で、太陽と地球のどちらのラジオボタンが選ばれているかを調べ、それによって、クリックされた座標を太陽に割り当てるか、地球に割り当てるかを場合分けしているところである。
学生時代、この太陽系の広さを実感してもらうために、東京駅に太陽が、横浜駅に地球があったとしたら、太陽系はどこまで広がっているか、日本地図の上にマッピングし、各地を撮影した8ミリ映画を作ったことがある。
今回は、同じことをGoogleマップとJavaScriptで実装してみることにする。