Yahoo Map API でオリジナルLayerを作るには

Yahoo Map APIGoogle Maps API のカスタムオーバーレイと同じようなことをやる方法。

おおまかな手順は次の通り。

  1. Layer を派生させて drawLayer を実装する
  2. 派生させた Layer を Y.Map に addLayer する

実際に Canvas 製の Layer を Yahoo Map に載っけてみましょう。


まず、Y.Layer を継承したクラスを作ります。
drawLayer はレイヤーの描画が必要なときに呼び出されるメソッドです。ひとまず空にしておきます。

init() は body タグの onLoad で呼び出します。 Y.Map("map"); の "map" は Yahoo Map を埋め込む先の div タグの id です。

function CanvasLayer() {
    CanvasLayer.prototype.drawLayer = function() {
    }
    return this;
}
CanvasLayer.prototype = new Y.Layer();

function init() {
    var ymap = new Y.Map("map");    // "map" はYahoo Map を埋め込む div タグの id
    ymap.drawMap(new Y.LatLng(35.66572, 139.73100), 17, Y.LayerSetId.NORMAL);

    layer = new CanvasLayer();
    ymap.addLayer(layer);
}

次に、 Yahoo Map を埋め込むHTML要素の id を渡せるようにします。

function CanvasLayer(targetid) {
    this.targetid_ = targetid;

    CanvasLayer.prototype.drawLayer = function() {
    }
    return this;
}
CanvasLayer.prototype = new Y.Layer();

function init() {
    var ymap = new Y.Map("map");    // "map" はYahoo Map を埋め込む div タグの id
    ymap.drawMap(new Y.LatLng(35.66572, 139.73100), 17, Y.LayerSetId.NORMAL);

    layer = new CanvasLayer("map");
    ymap.addLayer(layer);
}

続いて、はめ込み先の要素のサイズに合わせた canvas 要素を作り、Yahoo Map に組み込みます。

function CanvasLayer(targetid) {
    this.targetid_ = targetid;
    this.canvas_ = null;

    CanvasLayer.prototype.drawLayer = function() {
        if (!this.canvas_) {
            var elem = document.getElementById(this.targetid_)
            var canvas = document.createElement("canvas");
            canvas.style.position = "absolute";
            canvas.width = elem.offsetWidth;    // はめ込み先の幅
            canvas.height = elem.offsetHeight;  // はめ込み先の高さ
            this.canvas_ = canvas;

            var container = this.getMapContainer(); // canvas をはめ込む親要素を取得
            if (!container || !container[0])
                return;
            container[0].appendChild(canvas);   // canvas をはめ込む
        }
    }
    return this;
}
CanvasLayer.prototype = new Y.Layer();

function init() {
    var ymap = new Y.Map("map");    // "map" はYahoo Map を埋め込む div タグの id
    ymap.drawMap(new Y.LatLng(35.66572, 139.73100), 17, Y.LayerSetId.NORMAL);

    layer = new CanvasLayer("map");
    ymap.addLayer(layer);
}

このままだと、透明な canvas が載っかるだけで何も見えないので、canvas に描画するコードを追加します。

function CanvasLayer(targetid) {
    this.targetid_ = targetid;
    this.canvas_ = null;

    CanvasLayer.prototype.drawLayer = function() {
        if (!this.canvas_) {
            var elem = document.getElementById(this.targetid_)
            var canvas = document.createElement("canvas");
            canvas.style.position = "absolute";
            canvas.width = elem.offsetWidth;    // はめ込み先の幅
            canvas.height = elem.offsetHeight;  // はめ込み先の高さ
            this.canvas_ = canvas;

            var container = this.getMapContainer(); // canvas をはめ込む親要素を取得
            if (!container || !container[0])
                return;
            container[0].appendChild(canvas);   // canvas をはめ込む
        }

        // canvas に描画する
        var ctx = this.canvas_.getContext('2d');
        ctx.clearRect(0, 0, this.canvas_.width, this.canvas_.height);

        var w = this.canvas_.width;
        var h = this.canvas_.height;
        ctx.fillStyle = "yellow";
        ctx.strokeStyle = "black";
        ctx.beginPath();
        ctx.arc(w/2, h/2, 10, 0, Math.PI*2, false); // ○
        ctx.fill();
        ctx.closePath();
        ctx.stroke();
        ctx.beginPath();
        ctx.rect(0, 0, w, h);   // 枠線
        ctx.closePath();
        ctx.stroke();
    }

    return this;
}
CanvasLayer.prototype = new Y.Layer();

function init() {
    var ymap = new Y.Map("map");    // "map" はYahoo Map を埋め込む div タグの id
    ymap.drawMap(new Y.LatLng(35.66572, 139.73100), 17, Y.LayerSetId.NORMAL);

    layer = new CanvasLayer("map");
    ymap.addLayer(layer);
}

まとめると、こんな感じになります(要Yahoo API のアプリケーションID)。

<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" charset="utf-8" src="http://js.api.olp.yahooapis.jp/OpenLocalPlatform/V1/jsapi?appid=(Yahoo API のアプリケーションID)"></script>
<script type="text/javascript">
// Canvas を使った Yahoo Map Layer
function CanvasLayer(targetid) {
    this.targetid_ = targetid;
    this.canvas_ = null;

    CanvasLayer.prototype.drawLayer = function() {
        if (!this.canvas_) {
            var elem = document.getElementById(this.targetid_)
            var canvas = document.createElement("canvas");
            canvas.style.position = "absolute";
            canvas.width = elem.offsetWidth;    // はめ込み先の幅
            canvas.height = elem.offsetHeight;  // はめ込み先の高さ
            this.canvas_ = canvas;

            var container = this.getMapContainer(); // canvas をはめ込む親要素を取得
            if (!container || !container[0])
                return;
            container[0].appendChild(canvas);   // canvas をはめ込む
        }

        // canvas に描画する
        var ctx = this.canvas_.getContext('2d');
        ctx.clearRect(0, 0, this.canvas_.width, this.canvas_.height);

        var w = this.canvas_.width;
        var h = this.canvas_.height;
        ctx.fillStyle = "yellow";
        ctx.strokeStyle = "black";
        ctx.beginPath();
        ctx.arc(w/2, h/2, 10, 0, Math.PI*2, false); // ○
        ctx.fill();
        ctx.closePath();
        ctx.stroke();
        ctx.beginPath();
        ctx.rect(0, 0, w, h);   // 枠線
        ctx.closePath();
        ctx.stroke();
    }

    return this;
}
CanvasLayer.prototype = new Y.Layer();

function init() {
    var ymap = new Y.Map("map");    // "map" はYahoo Map を埋め込む div タグの id
    ymap.drawMap(new Y.LatLng(35.66572, 139.73100), 17, Y.LayerSetId.NORMAL);

    layer = new CanvasLayer("map");
    ymap.addLayer(layer);
}
</script>
</head>
<body onLoad="init()">
<div id="map" style="width:400px; height:300px"></div>
</body>
</html>