gpt4 book ai didi

javascript - 如何使用 leaflet.label 绑定(bind)多个标签?

转载 作者:行者123 更新时间:2023-11-29 17:57:04 25 4
gpt4 key购买 nike

我正在使用 Leaflet,它运行良好。我也在使用 leaflet.label 并且效果很好。问题是我想在标记的右侧显示两个标签。如果我调用 bindLabel 两次,那么第二个会覆盖第一个。我如何确保我有两个标签,都在标记的右侧并且第二个标签在第一个标签上方?

我是这样尝试的:

newMarker.bindLabel(result, { noHide: true }).bindLabel("secondlabel", { noHide: true });

谢谢

编辑:

我已经设法通过调用 bindLabel 来显示文本,如下所示:

newMarker.bindLabel(result + "<br>secondLabel", { noHide: true });

但这似乎是一个过于老套的解决方案。 Here他们说这是不可能的,但那是在 2014 年写的。从那时起就有可能。

最佳答案

我已经设法解决了。我现在懒得把它推送到他们的仓库,但我可能会在未来这样做。解决逻辑如下:

  • this.label -> this.labels
  • this.labelsLeafletLabel 的数组
  • 对包含 this.label 的方法应用更改
  • this._labelNoHide = options.noHide 移动到 if 中以防止错误

对于单独处理的 options 子集,标签的作用类似/标记。抱歉,伙计们,将 noHideopacity 单数化为标签级别而不是标记级别超出了这个问题的范围。不过,我可能会在稍后解决这些问题。

代码如下:

/*
Leaflet.label, a plugin that adds labels to markers and vectors for Leaflet powered maps.
(c) 2012-2013, Jacob Toye, Smartrak

https://github.com/Leaflet/Leaflet.label
http://leafletjs.com
https://github.com/jacobtoye
*/
(function (factory, window) {

// define an AMD module that relies on 'leaflet'
if (typeof define === 'function' && define.amd) {
define(['leaflet'], factory);

// define a Common JS module that relies on 'leaflet'
} else if (typeof exports === 'object') {
module.exports = factory(require('leaflet'));
}

// attach your plugin to the global 'L' variable
if (typeof window !== 'undefined' && window.L) {
window.LeafletLabel = factory(L);
}
}(function (L) {
L.labelVersion = '0.2.4';


var LeafletLabel = L.Class.extend({

includes: L.Mixin.Events,

options: {
className: '',
clickable: false,
direction: 'right',
noHide: false,
offset: [12, -15], // 6 (width of the label triangle) + 6 (padding)
opacity: 1,
zoomAnimation: true
},

initialize: function (options, source) {
L.setOptions(this, options);

this._source = source;
this._animated = L.Browser.any3d && this.options.zoomAnimation;
this._isOpen = false;
},

onAdd: function (map) {
this._map = map;

this._pane = this.options.pane ? map._panes[this.options.pane] :
this._source instanceof L.Marker ? map._panes.markerPane : map._panes.popupPane;

if (!this._container) {
this._initLayout();
}

this._pane.appendChild(this._container);

this._initInteraction();

this._update();

this.setOpacity(this.options.opacity);

map
.on('moveend', this._onMoveEnd, this)
.on('viewreset', this._onViewReset, this);

if (this._animated) {
map.on('zoomanim', this._zoomAnimation, this);
}

if (L.Browser.touch && !this.options.noHide) {
L.DomEvent.on(this._container, 'click', this.close, this);
map.on('click', this.close, this);
}
},

onRemove: function (map) {
this._pane.removeChild(this._container);

map.off({
zoomanim: this._zoomAnimation,
moveend: this._onMoveEnd,
viewreset: this._onViewReset
}, this);

this._removeInteraction();

this._map = null;
},

setLatLng: function (latlng) {
this._latlng = L.latLng(latlng);
if (this._map) {
this._updatePosition();
}
return this;
},

setContent: function (content) {
// Backup previous content and store new content
this._previousContent = this._content;
this._content = content;

this._updateContent();

return this;
},

close: function () {
var map = this._map;

if (map) {
if (L.Browser.touch && !this.options.noHide) {
L.DomEvent.off(this._container, 'click', this.close);
map.off('click', this.close, this);
}

map.removeLayer(this);
}
},

updateZIndex: function (zIndex) {
this._zIndex = zIndex;

if (this._container && this._zIndex) {
this._container.style.zIndex = zIndex;
}
},

setOpacity: function (opacity) {
this.options.opacity = opacity;

if (this._container) {
L.DomUtil.setOpacity(this._container, opacity);
}
},

_initLayout: function () {
this._container = L.DomUtil.create('div', 'leaflet-label ' + this.options.className + ' leaflet-zoom-animated');
this.updateZIndex(this._zIndex);
},

_update: function () {
if (!this._map) { return; }

this._container.style.visibility = 'hidden';

this._updateContent();
this._updatePosition();

this._container.style.visibility = '';
},

_updateContent: function () {
if (!this._content || !this._map || this._prevContent === this._content) {
return;
}

if (typeof this._content === 'string') {
this._container.innerHTML = this._content;

this._prevContent = this._content;

this._labelWidth = this._container.offsetWidth;
}
},

_updatePosition: function () {
var pos = this._map.latLngToLayerPoint(this._latlng);

this._setPosition(pos);
},

_setPosition: function (pos) {
var map = this._map,
container = this._container,
centerPoint = map.latLngToContainerPoint(map.getCenter()),
labelPoint = map.layerPointToContainerPoint(pos),
direction = this.options.direction,
labelWidth = this._labelWidth,
offset = L.point(this.options.offset);

// position to the right (right or auto & needs to)
if (direction === 'right' || direction === 'auto' && labelPoint.x < centerPoint.x) {
L.DomUtil.addClass(container, 'leaflet-label-right');
L.DomUtil.removeClass(container, 'leaflet-label-left');

pos = pos.add(offset);
} else { // position to the left
L.DomUtil.addClass(container, 'leaflet-label-left');
L.DomUtil.removeClass(container, 'leaflet-label-right');

pos = pos.add(L.point(-offset.x - labelWidth, offset.y));
}

L.DomUtil.setPosition(container, pos);
},

_zoomAnimation: function (opt) {
var pos = this._map._latLngToNewLayerPoint(this._latlng, opt.zoom, opt.center).round();

this._setPosition(pos);
},

_onMoveEnd: function () {
if (!this._animated || this.options.direction === 'auto') {
this._updatePosition();
}
},

_onViewReset: function (e) {
/* if map resets hard, we must update the label */
if (e && e.hard) {
this._update();
}
},

_initInteraction: function () {
if (!this.options.clickable) { return; }

var container = this._container,
events = ['dblclick', 'mousedown', 'mouseover', 'mouseout', 'contextmenu'];

L.DomUtil.addClass(container, 'leaflet-clickable');
L.DomEvent.on(container, 'click', this._onMouseClick, this);

for (var i = 0; i < events.length; i++) {
L.DomEvent.on(container, events[i], this._fireMouseEvent, this);
}
},

_removeInteraction: function () {
if (!this.options.clickable) { return; }

var container = this._container,
events = ['dblclick', 'mousedown', 'mouseover', 'mouseout', 'contextmenu'];

L.DomUtil.removeClass(container, 'leaflet-clickable');
L.DomEvent.off(container, 'click', this._onMouseClick, this);

for (var i = 0; i < events.length; i++) {
L.DomEvent.off(container, events[i], this._fireMouseEvent, this);
}
},

_onMouseClick: function (e) {
if (this.hasEventListeners(e.type)) {
L.DomEvent.stopPropagation(e);
}

this.fire(e.type, {
originalEvent: e
});
},

_fireMouseEvent: function (e) {
this.fire(e.type, {
originalEvent: e
});

// TODO proper custom event propagation
// this line will always be called if marker is in a FeatureGroup
if (e.type === 'contextmenu' && this.hasEventListeners(e.type)) {
L.DomEvent.preventDefault(e);
}
if (e.type !== 'mousedown') {
L.DomEvent.stopPropagation(e);
} else {
L.DomEvent.preventDefault(e);
}
}
});


/*global LeafletLabel */

// This object is a mixin for L.Marker and L.CircleMarker. We declare it here as both need to include the contents.
L.BaseMarkerMethods = {
showLabel: function () {
if (this.labels && this._map) {
for (var labelIndex in this.labels) {
this.labels[labelIndex].setLatLng(this._latlng);
this._map.showLabel(this.labels[labelIndex]);
}
}

return this;
},

hideLabel: function () {
if (this.labels) {
for (var labelIndex in this.labels) {
this.labels[labelIndex].close();
}
}
return this;
},

setLabelNoHide: function (noHide) {
if (this._labelNoHide === noHide) {
return;
}

this._labelNoHide = noHide;

if (noHide) {
this._removeLabelRevealHandlers();
this.showLabel();
} else {
this._addLabelRevealHandlers();
this.hideLabel();
}
},

bindLabel: function (content, options) {
var labelAnchor = this.options.icon ? this.options.icon.options.labelAnchor : this.options.labelAnchor,
anchor = L.point(labelAnchor) || L.point(0, 0);

anchor = anchor.add(LeafletLabel.prototype.options.offset);

if (options && options.offset) {
anchor = anchor.add(options.offset);
}

options = L.Util.extend({ offset: anchor }, options);

if (!this.labels) {
this._labelNoHide = options.noHide;
this.labels = [];
if (!this._labelNoHide) {
this._addLabelRevealHandlers();
}

this
.on('remove', this.hideLabel, this)
.on('move', this._moveLabel, this)
.on('add', this._onMarkerAdd, this);

this._hasLabelHandlers = true;
}

this.labels.push(new LeafletLabel(options, this).setContent(content));

return this;
},

unbindLabel: function () {
if (this.labels) {
this.hideLabel();

this.labels = null;

if (this._hasLabelHandlers) {
if (!this._labelNoHide) {
this._removeLabelRevealHandlers();
}

this
.off('remove', this.hideLabel, this)
.off('move', this._moveLabel, this)
.off('add', this._onMarkerAdd, this);
}

this._hasLabelHandlers = false;
}
return this;
},

updateLabelContent: function (content, index) {
if ((this.labels) && (index < this.labels.length)) {
this.labels[index].setContent(content);
}
},

getLabels: function () {
return this.labels;
},

_onMarkerAdd: function () {
if (this._labelNoHide) {
this.showLabel();
}
},

_addLabelRevealHandlers: function () {
this
.on('mouseover', this.showLabel, this)
.on('mouseout', this.hideLabel, this);

if (L.Browser.touch) {
this.on('click', this.showLabel, this);
}
},

_removeLabelRevealHandlers: function () {
this
.off('mouseover', this.showLabel, this)
.off('mouseout', this.hideLabel, this);

if (L.Browser.touch) {
this.off('click', this.showLabel, this);
}
},

_moveLabel: function (e) {
this.label.setLatLng(e.latlng);
}
};


// Add in an option to icon that is used to set where the label anchor is
L.Icon.Default.mergeOptions({
labelAnchor: new L.Point(9, -20)
});

// Have to do this since Leaflet is loaded before this plugin and initializes
// L.Marker.options.icon therefore missing our mixin above.
L.Marker.mergeOptions({
icon: new L.Icon.Default()
});

L.Marker.include(L.BaseMarkerMethods);
L.Marker.include({
_originalUpdateZIndex: L.Marker.prototype._updateZIndex,

_updateZIndex: function (offset) {
var zIndex = this._zIndex + offset;

this._originalUpdateZIndex(offset);

if (this.labels) {
for (var labelIndex in this.labels) {
this.labels[labelIndex].updateZIndex(zIndex);
}
}
},

_originalSetOpacity: L.Marker.prototype.setOpacity,

setOpacity: function (opacity, labelHasSemiTransparency) {
this.options.labelHasSemiTransparency = labelHasSemiTransparency;

this._originalSetOpacity(opacity);
},

_originalUpdateOpacity: L.Marker.prototype._updateOpacity,

_updateOpacity: function () {
var absoluteOpacity = this.options.opacity === 0 ? 0 : 1;

this._originalUpdateOpacity();

if (this.labels) {
for (var labelIndex in labels) {
this.labels[labelIndex].setOpacity(this.options.labelHasSemiTransparency ? this.options.opacity : absoluteOpacity);
}
}
},

_originalSetLatLng: L.Marker.prototype.setLatLng,

setLatLng: function (latlng) {
if (this.labels && !this._labelNoHide) {
this.hideLabel();
}

return this._originalSetLatLng(latlng);
}
});

// Add in an option to icon that is used to set where the label anchor is
L.CircleMarker.mergeOptions({
labelAnchor: new L.Point(0, 0)
});


L.CircleMarker.include(L.BaseMarkerMethods);

/*global LeafletLabel */

L.Path.include({
bindLabel: function (content, options) {
if (!this.label || this.label.options !== options) {
this.label = new LeafletLabel(options, this);
}

this.label.setContent(content);

if (!this._showLabelAdded) {
this
.on('mouseover', this._showLabel, this)
.on('mousemove', this._moveLabel, this)
.on('mouseout remove', this._hideLabel, this);

if (L.Browser.touch) {
this.on('click', this._showLabel, this);
}
this._showLabelAdded = true;
}

return this;
},

unbindLabel: function () {
if (this.label) {
this._hideLabel();
this.label = null;
this._showLabelAdded = false;
this
.off('mouseover', this._showLabel, this)
.off('mousemove', this._moveLabel, this)
.off('mouseout remove', this._hideLabel, this);
}
return this;
},

updateLabelContent: function (content) {
if (this.label) {
this.label.setContent(content);
}
},

_showLabel: function (e) {
this.label.setLatLng(e.latlng);
this._map.showLabel(this.label);
},

_moveLabel: function (e) {
this.label.setLatLng(e.latlng);
},

_hideLabel: function () {
this.label.close();
}
});


L.Map.include({
showLabel: function (label) {
return this.addLayer(label);
}
});

L.FeatureGroup.include({
// TODO: remove this when AOP is supported in Leaflet, need this as we cannot put code in removeLayer()
clearLayers: function () {
this.unbindLabel();
this.eachLayer(this.removeLayer, this);
return this;
},

bindLabel: function (content, options) {
return this.invoke('bindLabel', content, options);
},

unbindLabel: function () {
return this.invoke('unbindLabel');
},

updateLabelContent: function (content) {
this.invoke('updateLabelContent', content);
}
});

return LeafletLabel;
}, window));

关于javascript - 如何使用 leaflet.label 绑定(bind)多个标签?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38147775/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com