2016-07-01 4 views
2

Ich benutze Leaflet und es funktioniert gut. Ich benutze auch leaflet.label und das funktioniert auch gut. Das Problem ist, dass ich zwei Beschriftungen rechts neben dem Marker anzeigen möchte. Wenn ich zweimal bindLabel aufrufe, überschreibt die zweite die erste. Wie kann ich sicherstellen, dass ich zwei Etiketten habe, beide rechts neben der Markierung und die zweite Markierung über der ersten?Wie binden Sie mehrere Etiketten mit leaflet.label?

Dies ist, wie ich versucht:

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

Dank

EDIT:

ich es geschafft haben, mit einem einzigen Aufruf bindLabel, wie dies die Texte angezeigt werden:

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

aber das scheint eine zu hacky Lösung zu sein. Here sie sagen, es ist nicht möglich, aber das wurde 2014 geschrieben. Es könnte seitdem möglich sein.

+1

persönlich nichts Ich sehe falsch in HTML-Code (einschließlich des '
' Tag für einen Zeilenumbruch) in dem Inhalt des Etiketts mehr Informationen zur Verfügung zu stellen ... Da für mehrere Etiketten Ich denke, es gibt immer noch nichts Out-of-the-Box. – ghybs

+0

@ghybs, danke für den Kommentar. Wenn wir nicht die Möglichkeit haben, mehrere Labels zu binden, ist es unmöglich, einen nach links und einen nach rechts zu zeichnen. Ich weiß, dass das nicht mein gegenwärtiger Wunsch ist, aber das Fehlen dieser Möglichkeit ist nicht zu gut. Vielleicht lohnt es sich, in den Code des Plugins zu schauen und zu sehen, wie bindLabel funktioniert und das Plural macht. Ich weiß, dass es ein Hack ist, aber wenn es ein eleganter Code ist, könnten sie ihn zukünftigen Versionen hinzufügen. –

+1

In der Tat könnte es interessant sein, eine "Gruppen" -Option zu haben, so dass jedes Etikett beispielsweise an eine Gruppe mit einer bestimmten Position angehängt werden kann. Jetzt ist dieses Plugin Open Source, was bedeutet, dass "sie" gerne Pull Requests erhalten würden! :-) – ghybs

Antwort

4

Ich habe es geschafft, es zu lösen. Ich bin faul, es jetzt zu ihrem Repo zu schieben, aber ich werde es wahrscheinlich in der Zukunft tun. Die Logik der Lösung ist wie folgt:

  • this.label ->this.labels
  • this.labels ist ein Array von LeafletLabel s
  • die Änderung this.label
  • bewegen this._labelNoHide = options.noHide in die if enthält für Methoden gelten für Bugfix

Das Label ls wird ähnlich für die Teilmenge von options handeln, die singularly/marker behandelt wird. Entschuldigung, Leute, die noHide oder opacity auf Label-Ebene statt Marker-Ebene vereinheitlichen, würde den Rahmen dieser Frage sprengen. Ich könnte diese später aber auflösen.

Der Code ist wie folgt:

/* 
    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)); 
Verwandte Themen