使用leaflet在页面中动态的绘制一个圆形,主要需要解决的有两点,其一是如何确定圆的中心,其二是如何确定圆的半径。解决了这两点,剩下的就是把圆作为图层添加进map中了。
使用leaflet绘制多边形要稍微麻烦一点,在绘制的时候需要动态添加点击的点位以及实现新增的边的跟随移动。
引入js和css
首先需要引入leaflet的js和CSS。
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.6.0/dist/leaflet.css"
integrity="sha512-xwE/Az9zrjBIphAcBb3F6JVqxf46+CDLwfLMHloNu6KEQCAWi6HcDUbeOfBIptF7tcCzusKFjFw2yuvEpDL9wQ==" crossorigin="">
<script src="https://unpkg.com/leaflet@1.6.0/dist/leaflet.js"
integrity="sha512-gZwIG9x3wUXg2hdXF6+rVkLF/0Vi9U8D2Ntg4Ga5I5BZpVkVxlJWbSQtXPSiUTtC0TjtGOmxa1AJPuV0CPthew==" crossorigin=""></script>
然后创建一个div和五个button,div用来放置地图,五个button分别用来创建圆、多边形,删除圆、多边形、全部
<div id="map"></div>
<input type="button" id="circle" value="绘制圆" onclick="drawCircle()" />
<input type="button" value="绘制多边形" onclick="drawPolygon()">
<input type="button" id="clear" value="清除圆形" onclick="removeCircle()"/>
<input type="button" id="clear" value="清除多边形" onclick="removePolygon()"/>
<input type="button" id="clearAll" value="全部清除" onclick="removeAll()" />
添加底图
首先加载底图
<script>
//加载底图
var url = 'https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token=pk.eyJ1IjoibWFwYm94IiwiYSI6ImNpejY4NXVycTA2emYycXBndHRqcmZ3N3gifQ.rJcFIG214AriISLbB6B5aw';
var map = L.map('map').setView([51.505, -0.09], 13);
//图层
L.tileLayer(url, {
maxZoom: 18,
id: 'mapbox.streets'
}).addTo(map);
</script>
动态绘制圆
以下代码用来绘制圆(包括删除)
<script>
//读取点击位置坐标并返回其经纬度
// function onMapClick(e) { alert("You clicked the map at " + e.latlng); }
//r用来存储半径,i用来存储圆心经纬度
//tempCircle是用来存放圆的图层,pop用来返回圆半径的弹窗
var r ;
var i;
var tempCircle ;
var pop;
//移除圆图层
function removeCircle(){
map.removeLayer(tempCircle);
}
//绘制圆
function drawCircle(){
//在绘制圆之前需要先判断是否已经绘制过了,如果有,则清空再绘制
//如果需要绘制多个圆,则不必此句
if(tempCircle){
removeAll();
}
r = 0;
i = null;
tempCircle = new L.circle();
map.dragging.disable();//将mousemove事件移动地图禁用
//监听鼠标落下事件
map.on('mousedown', onmouseDown);
function onmouseDown(e) {
//确定圆心
i = e.latlng
pop=L.popup().setLatLng(e.latlng);
map.addLayer(pop);
//监听鼠标移动事件
map.on('mousemove', onMove);
//监听鼠标弹起事件
map.on('mouseup', onmouseUp);
}
function onMove(e) {
r = L.latLng(e.latlng).distanceTo(i);//计算半径
if(r<5000){
if (i) {
//绘制圆心位置与半径
tempCircle.setLatLng(i)
tempCircle.setRadius(r)
tempCircle.setStyle({ color: '#ff0000', fillOpacity: 0 })
map.addLayer(tempCircle)
}
//toFixed()方法用来保留两位小数(四舍五入)
pop.setContent("绘制圆半径为:"+r.toFixed(2)+"米");;
}else{
r=5000;
if (i) {
tempCircle.setLatLng(i)
tempCircle.setRadius(r)
tempCircle.setStyle({ color: '#ff0000', fillOpacity: 0 })
map.addLayer(tempCircle)
}
pop.setContent("绘制圆半径为:"+r+"米");;
}
}
function onmouseUp(e) {
/* r = L.latLng(e.latlng).distanceTo(i); */
map.removeLayer(pop);
L.circle(i, { radius: r, color: '#ff0000', fillOpacity: 0 });
map.addLayer(tempCircle);
map.dragging.enable();
map.setView(i,13);
i = null;
r = 0;
//取消监听事件
map.off('mousedown');
map.off('mouseup');
map.off('mousemove');
}
}
//移除所有图层(包括圆和多边形)
function removeAll() {
removePolygon()
removeCircle()
}
</script>
成果截图
动态绘制多边形
以下代码用来绘制多边形
<script>
//动态绘制多边形
var points, geometry,lines,tempLines,node;
function drawPolygon(){
if(tempLines){
removePolygon();
}
map.doubleClickZoom.disable();
lines = new L.polyline([]);
tempLines = new L.polyline([],{ dashArray: 5 });
points = [];
geometry = [];
map.on('click', onClick); //点击地图
map.on('dblclick', onDoubleClick);
map.on('mousemove', onMove)//双击地图
function onClick(e) {
points.push([e.latlng.lat, e.latlng.lng])
lines.addLatLng(e.latlng)
map.addLayer(tempLines)
map.addLayer(lines)
node=L.circle(e.latlng, { color: '#ff0000', fillColor: 'ff0000', fillOpacity: 1 })
map.addLayer(node)
geometry.push(node)
}
function onMove(e) {
if (points.length > 0) {
ls = [points[points.length - 1], [e.latlng.lat, e.latlng.lng], points[0]]
tempLines.setLatLngs(ls)
// map.addLayer(tempLines)
}
}
function onDoubleClick(e) {
geometry.push(L.polygon(points).addTo(map))
points = [];
node=null;
map.off('click', onClick); //点击地图
map.off('dblclick', onDoubleClick);
map.off('mousemove', onMove)//双击地图
map.doubleClickZoom.enable();
//isInPolygon(marker);
}
}
function removeCircle(){
map.removeLayer(tempCircle);
}
function removePolygon(){
for(let ooo of geometry){
ooo.remove();
}
map.removeLayer(lines);
map.removeLayer(tempLines);
}
</script>
小知识:
在实例化pop时可以使用className属性定义其样式,句式如下:
var pop=L.popup({className:‘你的class名称’}).setLatLng(e.latlng);
需要注意的是,必须使用英文单引号,否则报错。一开始使用双引号一直报错,后来比较了其他的程序,发现在这里引用的话基本都是使用单引号。
---------------------
作者:雨街空巷
来源:CSDN
原文:https://blog.csdn.net/qq_42751928/article/details/106011667
版权声明:本文为作者原创文章,转载请附上博文链接!
内容解析By:CSDN,CNBLOG博客文章一键转载插件