Skip to content

Instantly share code, notes, and snippets.

@nekoneko-wanwan
Last active November 4, 2019 03:10
Show Gist options
  • Save nekoneko-wanwan/6684168ae4011a359360 to your computer and use it in GitHub Desktop.
Save nekoneko-wanwan/6684168ae4011a359360 to your computer and use it in GitHub Desktop.
動的にGoogleMapのiframeを生成する

目的

  • GoogleMapのiframeをユーザが自由に描画できる
  • iframeのsrcパラメータに入力フォームの値を渡すことで、リアルタイムでの地図描画が可能
  • ただし表示や動作の細かい制御はできない

javaScriptAPIに比べて、2,000,000/dayとリクエスト制限が緩い(2015年5月18日現在) 課金も現状ない様子

仕様

  • フォームに入力された値を元に、GoogleMapのiframeをDOM生成する
  • フォームには住所・言語・ズームレベルを用意
  • 住所をエンコードするどうかをプログラム上で制御できるようにしている
  • ちなみに既にiframeが存在する場合は、srcから入力フォームの初期値を書き換える仕掛けも用意している
.map-area {
background-color: #eee;
/* デフォルトのサイズ */
margin: 0 auto;
height: 400px;
width: 600px;
}
.map-area iframe {
height: 100%;
width: 100%;
}
/* 400px以下の場合は、縮小して全体表示される */
/* それ以外は横スクロールバーが出る */
@media (max-width: 400px) {
.map-area {
position: relative;
padding-bottom: 56.25%; /* 縦横比に影響  */
padding-top: 30px;
height: 0;
overflow: hidden;
width: 100%;
}
.map-area iframe,
.map-area object,
.map-area embed {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
}
<div id="js-map-field">
<label>
住所: <input type="text" name="q" placeholder="渋谷区" value="">
</label>
<label>
日本語: <input type="radio" name="hl" value="ja" checked>
</label>
<label>
英語: <input type="radio" name="hl" value="en">
</label>
<label>
Zoomレベル:
<select name="z">
<option value=""></option>
<option value="13">13</option>
<option value="14">14</option>
<option value="15">15</option>
<option value="16" selected>16</option>
<option value="17">17</option>
<option value="18">18</option>
<option value="19">19</option>
<option value="20">20</option>
</select>
</label>
<label>
<input type="button" value="地図を作成する" id="js-map-create">
</label>
</div>
<div id="gmap" class="map-area">
</div>
<script src="//code.jquery.com/jquery-2.1.4.min.js"></script>
<script src="./index.js"></script>
(function() {
// 住所クエリをエンコードするかどうか
var useEncodeURI = false;
/**
* 地図オブジェクト
* どこに、どのように地図を表示するかをまとめ
*/
var map = {
$drawArea: $('#gmap'),
$iframe: $('<iframe />').attr({
src: '',
frameborder: 0,
marginwidth: 0,
marginheight: 0,
}),
src: '//maps.google.co.jp/maps?&output=embed',
params: {
q : '', // 住所
hl: '', // ロケーション
z : 16, // zoomレベル
t : 'm', // 地図タイプ(m:マップ, k:衛星写真, p:地形, e:googleEarth)
},
/**
* paramsを更新する
* @param {hash} this.paramsと同じ形式・keyを渡す
*/
updateParams: function(hash) {
var key;
for (key in hash) {
this.params[key] = hash[key];
}
},
/**
* iframeを更新する
* srcにはparamsを全て繋げて追加
*/
updateIframe: function() {
var str = '',
key;
for (key in this.params) {
str += '&' + key + '=' + this.params[key];
}
this.$iframe.attr('src', this.src + str);
},
/**
* 地図を描画する
* 既にiframeがあっても書き換えられる
*/
draw: function(params) {
this.updateParams(params);
this.updateIframe();
this.$drawArea.html(this.$iframe);
}
};
/* 地図関連のイベントハンドラー */
var mapEventHandler = {
click: function() {
/* 入力フィールドの値を取得 */
var $mapField = $('#js-map-field'),
data = {
address: $mapField.find('input[name=q]').val(),
lang : $mapField.find('input[name=hl]:checked').val(),
zoom : $mapField.find('select').val()
};
if (data.address === '') {
alert('住所を入力してください');
return false;
}
if (useEncodeURI) {
data.address = encodeURIComponent(data.address); // 日本語クエリをエンコード
}
map.draw({
q: data.address,
hl: data.lang,
z: data.zoom
});
return false;
},
/* 既にiframeが存在している場合は、入力フィールドに値を設定する */
load: function() {
/* ガード節 */
if (map.$drawArea.find('iframe').size() === 0) {
return false;
}
var $iframe = map.$drawArea.find('iframe'),
$mapField = $('#js-map-field'),
params = $iframe.attr('src').replace(map.src, '').split('&'),
param = '',
i = 0,
len = params.length;
/* パラメータに応じて入力フィールドの値を書き換えていく */
for (; i < len; i++) {
param = params[i].split('=');
switch (param[0]){
case 'q':
if (useEncodeURI) {
param[1] = decodeURIComponent(param[1]);
}
$mapField.find('input[name=q]').val(param[1]);
break;
case 'hl':
$mapField.find('input[name=hl]').prop('checked', false);
$mapField.find('input[name=hl][value='+param[1]+']').prop('checked', true);
break;
case 'z':
$mapField.find('select[name=z] option').prop('selected', false);
$mapField.find('select[name=z] option[value='+param[1]+']').prop('selected', true);
break;
default:
break;
}
}
}
};
$(function() {
$(window).on('load', mapEventHandler.load);
$('#js-map-create').on('click', mapEventHandler.click);
});
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment