【问题标题】:Simple Leaflet.js Marker Placement简单的 Leaflet.js 标记放置
【发布时间】:2019-03-26 00:05:23
【问题描述】:

我正在使用open source Leaflet.js library 创建一个简单的地图。

不过,我正在尝试解决一个特定问题。标记与地图上的特定 lat/lng 相关联,这是有道理的,但我需要能够使标记与另一个标记具有固定的偏移位置,而不会将其绑定到 lat/lng 中心。

例如,地图可能如下所示:

但是当你缩小时,它会是这样的:


我真正想要的是右标记与左标记有一个固定的偏移量,而不是绑定到一个 latlng,如下所示:


我尝试过使用unproject,但我相信我在处理这个问题上走错了路。我正在做的事情非常规,但如果有人对我如何做到这一点有任何见解,将不胜感激。

【问题讨论】:

    标签: javascript google-maps leaflet openstreetmap projection


    【解决方案1】:

    除了计算第二个标记位置的project()unproject() 方法外,您还可以监听地图上的缩放事件并更新第二个标记的位置,以保持所需的像素距离。

    看看下面的例子。

    var marker;
    var pos = L.latLng(28.478226,-16.313488);
    var mymap = L.map('mapid').setView(pos, 13);
    	
    L.tileLayer('https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token=pk.eyJ1IjoibWFwYm94IiwiYSI6ImNpejY4NXVycTA2emYycXBndHRqcmZ3N3gifQ.rJcFIG214AriISLbB6B5aw', {
    		maxZoom: 18,
    		attribution: 'Map data &copy; <a href="https://www.openstreetmap.org/">OpenStreetMap</a> contributors, ' +
    			'<a href="https://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, ' +
    			'Imagery © <a href="https://www.mapbox.com/">Mapbox</a>',
    		id: 'mapbox.streets'
    }).addTo(mymap);
    
    L.marker(pos).addTo(mymap);
      
    setLinkedMarkerAtDistance(180);
      
    mymap.on('zoomstart', function() {
      if (marker) {
      	mymap.removeLayer(marker);
      }
    });
      
    mymap.on('zoomend', function() {
     	setLinkedMarkerAtDistance(180);
    });
    
    function setLinkedMarkerAtDistance(d) {
      var p = mymap.project(pos, mymap.getZoom());
      var p1 = p.add(L.point(d,0));
      var pos1 = mymap.unproject(p1, mymap.getZoom());
      if (marker) {
        marker.setLatLng(pos1).addTo(mymap);
      } else {
      	marker = L.marker(pos1).addTo(mymap);
      }
    }
    <link rel="stylesheet" href="https://unpkg.com/leaflet@1.3.4/dist/leaflet.css" integrity="sha512-puBpdR0798OZvTTbP4A8Ix/l+A4dHDD0DGqYW6RQ+9jxkRFclaxxQb/SJAWZfWAkuyeQUytO7+7N4QKrDh+drA==" crossorigin=""/>
    <script src="https://unpkg.com/leaflet@1.3.4/dist/leaflet.js" integrity="sha512-nMMmRyTVoLYqjP9hrbed9S+FzjZHW5gY1TWCHA5ckwXZBadntCNs8kEqAWdrb9O7rxbCaA4lKTIWjDXZxflOcA==" crossorigin=""></script>
    <div id="mapid" style="width: 600px; height: 400px;">

    我希望这会有所帮助!

    【讨论】:

    • 非常感谢@xomena。就我所经历的而言,该解决方案似乎很优雅。我问的原因是因为我试图将三个图像缩略图放置在标记的右侧。我认为最好的方法是使用L.divIcon 类,基本上是使用html 选项创建一个精美的标记。我选择了这个,因为ImageOverlay 似乎限制了我无法添加额外的 html。这种方法对您来说是否有意义,或者您会以不同的方式处理它吗?
    【解决方案2】:

    这听起来像XY problem 对我来说:您想在标记 A(有一些像素偏移)旁边显示一些额外信息(可能看起来类似于普通标记),然后尝试使用另一个标记 B;但是标记 B 与 Lat/Lng 坐标相关联,而不是像素偏移量,因此您寻求有关如何使用 unproject 的帮助。

    为了实现您最初的目标,传单DivIconindeed 是一个更合适的解决方案:&lt;div&gt; 的一部分将包含您的实际标记图标,另一部分将包含您的额外信息。这样,它始终保持在所需位置,无需计算任何(非)投影,也无需涉及任何 JS 事件侦听器:

    var paris = [48.86, 2.35];
    var map = L.map('map').setView(paris, 11);
    
    var divIcon = L.divIcon({
      html: `
        <img src="https://unpkg.com/leaflet@1.3.4/dist/images/marker-icon.png" />
        <div class="extra-info">
          Some extra info
        </div>
      `,
      className: 'my-div-icon',
      iconAnchor: [12, 41]
    });
    
    L.marker(paris, {
      icon: divIcon
    }).addTo(map);
    
    L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
      attribution: '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
    }).addTo(map);
    html,
    body,
    #map {
      height: 100%;
      margin: 0;
    }
    
    .extra-info {
      position: absolute;
      left: 188px;
      bottom: -20px;
      min-width: 120px;
      background: yellow;
      border: 1px solid red;
    }
    <link rel="stylesheet" href="https://unpkg.com/leaflet@1.3.4/dist/leaflet.css" integrity="sha512-puBpdR0798OZvTTbP4A8Ix/l+A4dHDD0DGqYW6RQ+9jxkRFclaxxQb/SJAWZfWAkuyeQUytO7+7N4QKrDh+drA==" crossorigin="" />
    <script src="https://unpkg.com/leaflet@1.3.4/dist/leaflet-src.js" integrity="sha512-+ZaXMZ7sjFMiCigvm8WjllFy6g3aou3+GZngAtugLzrmPFKFK7yjSri0XnElvCTu/PrifAYQuxZTybAEkA8VOA==" crossorigin=""></script>
    
    <div id="map"></div>

    更合适的解决方案是使用 Leaflet Tooltip,通常使用预定义的 offsetpermanent: true 选项、特定的 direction 和自定义样式(使用 className):

    var paris = [48.86, 2.35];
    var map = L.map('map').setView(paris, 11);
    
    L.marker(paris).bindTooltip('Some extra info', {
      offset: [188, 0],
      className: 'my-tooltip',
      permanent: true,
      direction: 'right',
      interactive: true
    }).addTo(map);
    
    L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
      attribution: '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
    }).addTo(map);
    html,
    body,
    #map {
      height: 100%;
      margin: 0;
    }
    
    .leaflet-tooltip.my-tooltip {
      background-color: yellow;
      border: 1px solid red;
      box-shadow: none;
    }
    
    .leaflet-tooltip.my-tooltip::before {
      content: none;
    }
    <link rel="stylesheet" href="https://unpkg.com/leaflet@1.3.4/dist/leaflet.css" integrity="sha512-puBpdR0798OZvTTbP4A8Ix/l+A4dHDD0DGqYW6RQ+9jxkRFclaxxQb/SJAWZfWAkuyeQUytO7+7N4QKrDh+drA==" crossorigin="" />
    <script src="https://unpkg.com/leaflet@1.3.4/dist/leaflet-src.js" integrity="sha512-+ZaXMZ7sjFMiCigvm8WjllFy6g3aou3+GZngAtugLzrmPFKFK7yjSri0XnElvCTu/PrifAYQuxZTybAEkA8VOA==" crossorigin=""></script>
    
    <div id="map"></div>

    然后,如果您真的希望您的额外信息像普通的传单标记一样进行样式设置和操作,另一种可能的解决方案是使用带有修改后的iconAnchor 的自定义标记,以满足您的需要像素偏移:

    var paris = [48.86, 2.35];
    var map = L.map('map').setView(paris, 11);
    
    var OffsetIcon = L.Icon.Default.extend({
      options: {
        // Subtract your desired offset.
        iconAnchor: [12 - 188, 41]
      }
    });
    
    L.marker(paris).addTo(map);
    L.marker(paris, {
      icon: new OffsetIcon()
    }).addTo(map);
    
    L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
      attribution: '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
    }).addTo(map);
    html,
    body,
    #map {
      height: 100%;
      margin: 0;
    }
    <link rel="stylesheet" href="https://unpkg.com/leaflet@1.3.4/dist/leaflet.css" integrity="sha512-puBpdR0798OZvTTbP4A8Ix/l+A4dHDD0DGqYW6RQ+9jxkRFclaxxQb/SJAWZfWAkuyeQUytO7+7N4QKrDh+drA==" crossorigin="" />
    <script src="https://unpkg.com/leaflet@1.3.4/dist/leaflet-src.js" integrity="sha512-+ZaXMZ7sjFMiCigvm8WjllFy6g3aou3+GZngAtugLzrmPFKFK7yjSri0XnElvCTu/PrifAYQuxZTybAEkA8VOA==" crossorigin=""></script>
    
    <div id="map"></div>

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-12-10
      • 1970-01-01
      • 2016-12-21
      • 2021-12-16
      • 1970-01-01
      相关资源
      最近更新 更多