我正在使用open source Leaflet.js library创建一个简单的地图。
不过,我正在尝试解决一个特定的问题。标记被绑定到地图上的特定纬度/经度,这是有道理的,但是我需要能够使一个标记相对于另一个标记具有固定的偏移位置,而不必将其绑定到纬度/经度中心。
我真正想要的是将右标记与左标记保持固定的偏移量,而不是像这样绑在latlng上:
我尝试过尝试unproject,但我认为我走了错误的处理方式。我正在做的事与众不同,但是如果有人对我该怎么做有任何见解,将不胜感激。
答案 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 © <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事件侦听器:
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: '© <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,通常使用预定义的offset
,permanent: 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: '© <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: '© <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>