プログラマーのメモ書き

伊勢在住のプログラマーが気になることを気ままにメモったブログです

ポップアップするマーカー

Vectorレイヤーによるマーカーの表示 だけだと、静的なマーカーと何が違うかよくわかりません。まずは、マーカーにポップアップ機能をつけたいと思います。

 

marker_popup_sample_2.js

//
// Marker and Popup Sample
// http://dev.openlayers.org/examples/osm-marker-popup.html
//
// 画像は下記ディレクトリから拝借
// http://dev.openlayers.org/img/
//
var map;
var select;
function marker_popup_sample_2() {
        
    // The overlay layer for our marker, with a simple diamond as symbol
    var overlay = new OpenLayers.Layer.Vector('Overlay', {
        styleMap: new OpenLayers.StyleMap({
            externalGraphic: 'http://dev.openlayers.org/img/marker.png',
            graphicWidth: 20, graphicHeight: 24, graphicYOffset: -24,
            title: '${tooltip}'
        })
    });

    var features = new Array(50);
    for (var i=0; i<features.length; i++) {
        features[i] = new OpenLayers.Feature.Vector(
                new OpenLayers.Geometry.Point(
                        (360 * Math.random()) - 180, (180 * Math.random()) - 90
                )
                .transform(
                    new OpenLayers.Projection("EPSG:4326"),
                    new OpenLayers.Projection("EPSG:900913")
                ), {
                    tooltip: "random marker",
                    description: "number is " + (5 + parseInt(5 * Math.random()))
                }
        );
    }
    
    // We add the marker with a tooltip text to the overlay
    overlay.addFeatures(features);

    overlay.events.on({
        'featureselected': onFeatureSelect,
        'featureunselected': onFeatureUnselect
    });

    // Finally we create the map
    map = new OpenLayers.Map("demoMap");
    
    map.addLayers([new OpenLayers.Layer.OSM(), overlay]);
    
    // Create a select feature control and add it to the map.
    select = new OpenLayers.Control.SelectFeature(overlay);
    map.addControl(select);
    select.activate();
    
    map.setCenter(new OpenLayers.LonLat(0, 0), 1);
}

function onPopupClose(evt) {
    select.unselect(this.feature);
}
function onFeatureSelect(evt) {
    var feature = evt.feature;
    var content = '<a target="_blank" href="http://openlayers.org/">We</a> ' + 'could be here.<br>number: ';

    popup = new OpenLayers.Popup.FramedCloud("featurePopup",
                        feature.geometry.getBounds().getCenterLonLat(),
                        new OpenLayers.Size(100, 100),
                        content + feature.attributes.description,
                        null, true, onPopupClose);
    feature.popup = popup;
    popup.feature = feature;
    map.addPopup(popup);
}
function onFeatureUnselect(evt) {
    var feature = evt.feature;
    if (feature.popup) {
        popup.feature = null;
        map.removePopup(feature.popup);
        feature.popup.destroy();
        feature.popup = null;
    }
}

マーカーがランダムに設定されます。マーカーをクリックするとポップアップが表示され、×ボタンを押すか、ポップアップ外をクリックすると消えます。また、別のマーカーをクリックするとそちらのポップアップに切り替わります。 

 

 

このサンプルでは、マーカーをランダムに生成しています。それぞれのマーカーに、乱数によるdescriptionを設定して、マーカーごとに異なる文字列を与えています。

Vectorレイヤーに対して40~43行にて、イベントを設定しています。マーカーを選択した場合と選択が解除された場合に呼び出す関数を与えています(ここでは、onFeatureSelect と onFeatureUnselect)。

Mapオブジェクトに、レイヤーを追加後、51行目で、マーカーを選択するためのコントロールを生成しています。次に、Mapへ追加して、有効にしています。

このようにすることで、マーカーを選択・選択解除したとき、登録した関数がイベントハンドラとして呼び出されることになります。

 

61-71行目は、ポップアップの生成です。イベントの引数に選択されたマーカーに関する情報が与えられるので、それを使って、Popupウィンドウの生成を行っています。

72行目で作成したポップアップをmapオブジェクトに追加して完了です。

74行目以降の選択解除では、ポップアップウィンドウをmapオブジェクトから削除しています。

また、58-60行では、クローズボタンが押されたときの処理を記述しています。また、これはポップアップ生成時(69行目)にクローズボタンを押した際の処理を行う関数として渡しています。

onFeatureSelect、onFeatureUnselect、onPopupCloseで使うために、selectとmapはブローバル変数としています。

 

このような処理を記述することで、マーカーに対するポップアップ機能を追加できます。

 

参考

元々、複数のマーカー表示やポップアップといった機能は、Text Layer により実現されていたようです。テキストレイヤーによるポップアップのサンプルもあります。上の2つ目のリンク先にもあるように、Text Layer はMarker Overlay の一種で、スタイルとしては古いとされているようです。