简单的Leaflet.js标记放置

时间:2018-10-21 22:24:42

标签: javascript google-maps leaflet openstreetmap projection

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

不过,我正在尝试解决一个特定的问题。标记被绑定到地图上的特定纬度/经度,这是有道理的,但是我需要能够使一个标记相对于另一个标记具有固定的偏移位置,而不必将其绑定到纬度/经度中心。

例如,地图可能如下所示: a leaflet.js map of two markers

但是当您缩小时,它看起来像这样: enter image description here


我真正想要的是将右标记与左标记保持固定的偏移量,而不是像这样绑在latlng上: enter image description here


我尝试过尝试unproject,但我认为我走了错误的处理方式。我正在做的事与众不同,但是如果有人对我该怎么做有任何见解,将不胜感激。

2 个答案:

答案 0 :(得分:2)

除了用于计算第二标记位置的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;">

我希望这会有所帮助!

答案 1 :(得分:0)

对我来说,这听起来像XY problem:您想在标记A(具有一些像素偏移)旁边显示一些额外的信息(可能看起来与普通标记相似),然后尝试使用另一个标记B ;但是标记B绑定到纬度/经度坐标,而不是像素偏移,因此您需要使用unproject方面的帮助。

要实现您的原始目标,请使用DivIcon小叶indeed是更合适的解决方案:<div>的一部分将包含您的实际标记图标,而另一部分将包含您的标记图标您的额外信息。这样,它始终保持在所需的位置,而无需计算任何(非)投影,并且无需涉及任何JS事件侦听器:

Screenshot map with Marker in DivIcon with extra info box

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>

一种更合适的解决方案是使用传单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>

然后,如果您真的希望像普通的Leaflet Marker一样对额外信息进行样式设置和操作,则另一种可能的解决方案是使用经过修改的iconAnchor的自定义Marker,以解决您所需的像素偏移量:

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>