静的な Google マップを JavaScript API で差し替える

Google Maps JavaScript API で Google マップを埋め込む場合、当然のことながら JavaScript が有効でない環境では何も起こらず真っ白になってしまう。これを回避するため、まず Google Static Maps API を利用して HTML に静的な画像のマップを埋め込み、そのパラメーターを読み出して JavaScript API に渡して、動的マップで静的マップを差し替える、とやるとうまい具合に解決できそうと思ってやってみた。

<div id="map-container">
    <img src="http://maps.googleapis.com/maps/api/staticmap?markers=35.6604005,139.7290428&zoom=14&size=480x320&sensor=false" alt="...">
</div>

まず HTML には img 要素でマップを画像として配置する。静的マップには JavaScript は不要で、このように src 属性でパラメーターを渡すだけで利用できる。位置は座標の代わりに住所でも指定できるし、マーカーやパスなどけっこうカスタマイズもできる。alt には地図の用途に応じて、たとえば駅からの道順などを入れましょう。

で、この src のパラメーターをパースして JavaScript API に渡す。まずは API の読み込み。

<script src="http://maps.google.com/maps/api/js?language=ja&sensor=false"></script>

そして静的マップからのパラメーターの読み出しとマップの生成。

function initGoogeMap () {
    var mapContainer = document.getElementById('map-container'),
        mapImageSrc = mapContainer.getElementsByTagName('img')[0].getAttribute('src'),
        mapParams = decodeURIComponent(mapImageSrc.split('?')[1]).split('&'),
        mapData = {},
        latLng,
        mapOptions,
        map,
        marker,
        markerLatLng,
        i,
        len,
        pair;
    for (i = 0, len = mapParams.length; i < len; i++) {
        pair = mapParams[i].split('=');
        mapData[pair[0]] = pair[1];
    }
    markerLatLng = mapData.markers? mapData.markers.split(','): null;
    latLng = mapData.center? mapData.center.split(','): markerLatLng;
    mapOptions = {
        center: new google.maps.LatLng(latLng[0], latLng[1]),
        zoom: +mapData.zoom || 16
    };
    map = new google.maps.Map(mapContainer, mapOptions);
    if (mapData.markers) {
        marker = new google.maps.Marker({
            position: new google.maps.LatLng(markerLatLng[0], markerLatLng[1]),
            map: map
        });
    }
}

window.onload = initGoogeMap;

ちょっと雑な気もするけど、center または markers の座標と zoom だけを想定した例だとだいたいこんな感じだと思う。これで <div id="map-container"> の中身が JavaScript API で書き換えられるので、静的マップは削除される。パラメーターの内容によってはもうちょっと複雑になると思うけど、やることは同じで、静的マップの src 属性をパースして JavaScript API に渡すだけ。

これで、JavaScrpt 無効時には静的な画像のマップ、有効時にはインタラクティブなやつ、という出し分けができる。