如何在树叶.js地图的中心画一个圆圈

  • 本文关键字:一个 js 地图 javascript leaflet
  • 更新时间 :
  • 英文 :


如何绘制一个位于leaflet.js地图中心的圆?例如,圆圈的半径为1公里。无论用户如何平移,我都希望画出圆圈并保持在图像的中心。如果用户缩放,则圆的大小应相应地更改。

我想知道我是否必须在传单之外创作另一幅画布,或者有一种简单的方法来实现这一点?

监听映射上的move事件。

var circle = L.circleMarker(mymap.getCenter(), {
radius: 50,
color: 'red',
fillOpacity: 0.2,
}).addTo(mymap);

mymap.on('move',function(e){
circle.setLatLng(mymap.getCenter());
mymap._renderer._update();
});

也可以添加scrollWheelZoom: 'center'以始终按圆缩放。

L.map('mapid',{scrollWheelZoom: 'center'})

示例:https://jsfiddle.net/falkedesign/q2mdow5c/

Falke Design的公认答案很好,非常直接,但它使用了L.Map私有方法(未记录(。

一个更通用的解决方案是:

  1. 在地图上方创建一个div来容纳你的圆圈。每次缩放地图时,都会重新计算div的位置和大小(您需要使用传单地图功能进行这些计算(
  2. 这个div捕获的鼠标事件需要被分派到map(它们不会冒泡,因为中心div不是mapdiv的子级(

以下是一个示例:https://yafred.github.io/leaflet-tests/20200412-draw-circle-in-the-middle-of-the-map/

这是代码:

<!DOCTYPE html>
<html>
<head>
<title>Quick Start - Leaflet</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="shortcut icon" type="image/x-icon" href="docs/images/favicon.ico" />
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.0.2/dist/leaflet.css" />
<script src="https://unpkg.com/leaflet@1.0.2/dist/leaflet.js"></script>
<style>
#center {
visibility: hidden;
top: -215px; 
left: 285px;
height: 30px;
width: 30px;
border-radius: 50%;
opacity: 0.4;
background-color: blue;
z-index: 650;
position: relative;
}
</style>
</head>
<body>

<div style="width: 600px; height: 400px; overflow: hidden">
<div id="map" style="width: 600px; height: 400px;"></div>
<div id="center"></div>
</div>
<p>Zoom in or out.</p>
<p>The circle is redrawn to have a 1km diameter.</p>
<div id="events">
</div>
<script>
var map = L.map('map').setView([48.858475, 2.338285], 13);
L.tileLayer('//a.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '&copy; <a href="//www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
}).addTo(map);
L.control.scale().addTo(map);
// Map event handlers
function zoomEnd(e) {
var widthMeters = map.distance(map.getBounds().getNorthWest(), map.getBounds().getNorthEast());
var widthPixels = map.getSize().x;
var heightPixels = map.getSize().y; 
var radiusPixels = Math.round(1000 * widthPixels / widthMeters);
// change style
document.getElementById('center').style.height = 2*radiusPixels + 'px';
document.getElementById('center').style.width = 2*radiusPixels + 'px';
document.getElementById('center').style.left = (Math.round(widthPixels/2) - radiusPixels) + 'px';
document.getElementById('center').style.top = '-' + (Math.round(heightPixels/2) + radiusPixels) + 'px';
document.getElementById('center').style.visibility = "visible";
// log
document.getElementById('events').innerHTML += 'zoom ' + map.getZoom() + '<br/>'; 
document.getElementById('events').innerHTML += 'width in meters ' + Math.round(widthMeters) + '<br/>'; 
document.getElementById('events').innerHTML += 'width in pixels ' + widthPixels + '<br/>'; 
document.getElementById('events').innerHTML += 'radiusPixels ' + radiusPixels + '<br/>'; 
document.getElementById('events').innerHTML += 'top ' + (0 - Math.round(heightPixels/2) + radiusPixels) + '<br/>'; 
}
function zoomStart(e) {
document.getElementById('events').innerHTML = '';
document.getElementById('center').style.visibility = "hidden"; 
}
map.on('zoomstart', zoomStart);
map.on('zoomend', zoomEnd);
centerEventDispatcher = function(e) {
new_e = new e.constructor(e.type, e);
document.getElementById("map").dispatchEvent(new_e);
}
document.getElementById("center").addEventListener("mousedown", centerEventDispatcher);
document.getElementById("center").addEventListener("mouseup", centerEventDispatcher);
document.getElementById("center").addEventListener("mousemove", centerEventDispatcher);
// initial circle
zoomEnd();
</script>

<!-- analytics -->
<script>
if(window.location.hostname != "localhost") {
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-21317761-7', 'auto');
ga('send', 'pageview');
}
</script>
</body>
</html>

YaFred的方法很好,但通过在圆上使用newishpointer-events: none;css属性将鼠标事件通过圆传递到地图要简单得多。

所以基本上:

  • 绘制地图
  • 在下面添加一个圆形div,使用css之类的
.radius-circle {
border-radius: 50%;
opacity: 0.4;
background-color: blue;
z-index: 650;
position: relative;
height: 160px;
width: 158px;
left: 220px;
top: -280px;
pointer-events: none;    
}

请注意,负上边距可将其拉到地图上,指针事件设置可使鼠标事件通过。

这基本上就是你需要做的。

最新更新