19

所以我在传单中有一个 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);
4

3 回答 3

26

使用标记类和具有“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,然后偏移文本,这样你就可以使用 Leaflet DivIcon 类将图标和标签包装在同一个 Marker 对象中?使用 div 形状(例如框、圆)会很容易,但我不确定是否要为 Marker 对象在 CSS 中添加 png - 因为无论如何我都不是 CSS 专家。

于 2014-03-19T08:53:54.220 回答
17

我最近在寻找同样的问题,昨天刚刚根据谷歌组中的帖子实现了它。 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>

结果:

在此处输入图像描述

于 2013-07-31T07:52:26.060 回答
2

我正在为当前版本采用此代码。

    <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>   
于 2020-01-28T05:15:28.800 回答