web-dev-qa-db-ja.com

マップに表示するテキストをリーフレットのgeojsonオブジェクトに追加する方法

そのため、リーフレットにgeojsonレイヤーがあり、geojsonオブジェクトをこのレイヤーに追加して、結果のマップに表示できます。

次に、オブジェクトの近くに表示するテキストラベルを追加したいと思います。

この例は、カスタムL.control()オブジェクトを使用してマップに追加情報を表示する方法を示しています。これは私がやりたいことに近いようです。

この例では、各州の上に配置された州の初期テキストラベル(つまり、「TX」、「FL」)を追加したいと思います。 L.control()を使用してこれを行うことはできますか、それとも別の方法がありますか?

http://leaflet.cloudmade.com/examples/choropleth.html

var info = L.control();

info.onAdd = function (map) {
    this._div = L.DomUtil.create('div', 'info'); // create a div with a class "info"
    this.update();
    return this._div;
};

// method that we will use to update the control based on feature properties passed
info.update = function (props) {
    this._div.innerHTML = '<h4>US Population Density</h4>' +  (props ?
        '<b>' + props.name + '</b><br />' + props.density + ' people / mi<sup>2</sup>'
        : 'Hover over a state');
};

info.addTo(map);
16
monkut

私は最近同じ質問を探していましたが、グーグルグループへの投稿に基づいて昨日それを実装しました。 https://groups.google.com/forum/#!topic/leaflet-js/sA2HnU5W9Fw

元のコードサンプルを提供してくれたAdrianに感謝します。

解決策は次のとおりです。

次のクラスを以下のように拡張します。

<script>

    L.LabelOverlay = L.Class.extend({
        initialize: function(/*LatLng*/ latLng, /*String*/ label, options) {
            this._latlng = latLng;
            this._label = label;
            L.Util.setOptions(this, options);
        },
        options: {
            offset: new L.Point(0, 2)
        },
        onAdd: function(map) {
            this._map = map;
            if (!this._container) {
                this._initLayout();
            }
            map.getPanes().overlayPane.appendChild(this._container);
            this._container.innerHTML = this._label;
            map.on('viewreset', this._reset, this);
            this._reset();
        },
        onRemove: function(map) {
            map.getPanes().overlayPane.removeChild(this._container);
            map.off('viewreset', this._reset, this);
        },
        _reset: function() {
            var pos = this._map.latLngToLayerPoint(this._latlng);
            var op = new L.Point(pos.x + this.options.offset.x, pos.y - this.options.offset.y);
            L.DomUtil.setPosition(this._container, op);
        },
        _initLayout: function() {
            this._container = L.DomUtil.create('div', 'leaflet-label-overlay');
        }
    });   

</script>

さらに、このcssを追加します。

<style>
    .leaflet-popup-close-button {
        display:none;
    }

    .leaflet-label-overlay {
        line-height:0px;
        margin-top: 9px;
        position:absolute;
    }
</style>

次に、次のようにテキストラベルを表示します。

<script>
    var map = L.map('map').setView([51.898712, 6.7307100000001], 4);

    // add markers
    // ...

    // add text labels:
    var labelLocation = new L.LatLng(51.329219337279405, 10.454119349999928);
    var labelTitle = new L.LabelOverlay(labelLocation, '<b>GERMANY</b>');
    map.addLayer(labelTitle);


    var labelLocation2 = new L.LatLng(47.71329162782909, 13.34573480000006);
    var labelTitle2 = new L.LabelOverlay(labelLocation2, '<b>AUSTRIA</b>');
    map.addLayer(labelTitle2);

    // In order to prevent the text labels to "jump" when zooming in and out,
    // in Google Chrome, I added this event handler:

    map.on('movestart', function () {
        map.removeLayer(labelTitle);
        map.removeLayer(labelTitle2);
    });
    map.on('moveend', function () {
        map.addLayer(labelTitle);
        map.addLayer(labelTitle2);
    });
</script>

結果:

enter image description here

15
Mathias Conradt

「html」プロパティを持つマーカークラスとDivIconクラスを使用したリーフレットのラベルオーバーレイ

個人的には、このメソッドを使用して、マップにテキストラベルを実装しています。このようにして、余分な労力をかけずに、既存のすべてのマーカークラスのメソッドとイベントを使用できるようになります。アイコンの代わりにテキストラベルを使用するのと少し似ていると思います。

        var textLatLng = [35.1436, -111.5632];  
        var myTextLabel = L.marker(textLatLng, {
            icon: L.divIcon({
                className: 'text-labels',   // Set class for CSS styling
                html: 'A Text Label'
            }),
            zIndexOffset: 1000     // Make appear above other map features
        });

私のCSSは次のようになります:

        .text-labels {
            font-size: 2em;
            font-weight: 700;
            color: white;
            /* Use color, background, set margins for offset, etc */
        }

また、これについてはまだ説明していませんが、CSSにpngを追加してからテキストをオフセットして、LeafletDivIconクラスを使用して同じMarkerオブジェクトでアイコンとラベルをラップできるようにすることはできますか?これはdivシェイプ(ボックス、円など)を使用すると簡単ですが、私はCSSの第一人者ではないため、MarkerオブジェクトのCSSにpngを追加するかどうかはわかりません。

20
jhickok

現在のバージョンではこのコードを採用しています。

    <style>
        .leaflet-popup-close-button {
            display:none;
        }

        .leaflet-label-overlay {
            line-height:0px;
            margin-top: 9px;
            position:absolute;
        }
    </style>    

    <script>
        L.LabelOverlay = L.Layer.extend({
            initialize: function(/*LatLng*/ latLng, /*String*/ label, options) {
                this._latlng = latLng;
                this._label = label;
                L.Util.setOptions(this, options);
            },
            options: {
                offset: new L.Point(0, 2)
            },
            onAdd: function(map) {
                this._map = map;
                if (!this._container) {
                    this._initLayout();
                }
                map.getPanes().popupPane.appendChild(this._container);
                this._container.innerHTML = this._label;
                map.on('movestart', this._update_start, this);
                map.on('moveend', this._update_end, this);
                this._update_end();
            },
            onRemove: function(map) {
                map.getPanes().popupPane.removeChild(this._container);
                map.off('movestart', this._update_start, this);
                map.off('moveend', this._update_end, this);
            },
            _update_start: function(){
                L.DomUtil.setPosition(this._container, 0);
            },
            _update_end: function() {
                var pos = this._map.latLngToLayerPoint(this._latlng);
                var op = new L.Point(pos.x + this.options.offset.x, pos.y - this.options.offset.y);
                L.DomUtil.setPosition(this._container, op);
            },
            _initLayout: function() {
                this._container = L.DomUtil.create('div', 'leaflet-label-overlay');
            }
        });   
    </script>   
1
Evgeny Ivanov