前言:
虽然Leaflet提供了强大的画图工具,不过它的速度不是很尽人意,当数据量较大的时候,需要较长的渲染时间,交互好感度会降低。因此我们可以考虑使用D3,在leaflet的地图上蒙上一个svg,在svg上画图会加快一些速度,获得更好的交互体验。
D3官网上有Leaflet+D3的相关介绍https://bost.ocks.org/mike/leaflet/
效果图如下:
实现效果代码:
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="http://d3js.org/d3.v3.min.js"></script>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"
">
<link rel=" stylesheet" href="https://unpkg.com/leaflet@1.1.0/dist/leaflet.css" integrity="sha512-wcw6ts8Anuw10Mzh9Ytw4pylW8+NAD4ch3lqm9lzAsTxg0GFeJgoAtxuCLREZSC5lUXdVyo/7yfsqFjQ4S+aKw=="
crossorigin="" />
<script src="https://unpkg.com/leaflet@1.1.0/dist/leaflet.js" integrity="sha512-mNqn2Wg7tSToJhvHcqfzLMU6J4mkOImSPTxVZAdo+lcPlk+GhZmYgACEe0x35K7YzW1zJ7XyJV/TT1MrdXvMcA=="
crossorigin=""></script>
<style>
body {
padding: 0;
margin: 0;
}
html,
body,
#mapid {
height: 100%;
width: 100%;
}
</style>
</head>
<body>
<script src="http://d3js.org/d3.v3.min.js"></script>
<div id="mapid"></div>
<script>
var mymap = L.map('mapid').setView([30.555684, 114.295488], 12);
L.tileLayer(
'https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token=pk.eyJ1IjoibWFwYm94IiwiYSI6ImNpejY4NXVycTA2emYycXBndHRqcmZ3N3gifQ.rJcFIG214AriISLbB6B5aw', {
maxZoom: 18,
id: 'mapbox.streets'
}).addTo(mymap);
//加载SVG
//The data for our line
var lines = new Array();
var circleData = [{
"lat": "30.653658",
"lng": "114.296638"
},
{
"lat": "30.529309",
"lng": "114.428294"
},
{
"lat": "30.520847",
"lng": "114.171307"
},
{
"lat": "30.475042",
"lng": "114.306412"
},
{
"lat": "30.596726",
"lng": "114.546726"
},
{
"lat": "30.618608",
"lng": "114.428294"
},
{
"lat": "30.624575",
"lng": "114.258119"
},
{
"lat": "30.777598",
"lng": "114.219025"
},
{
"lat": "30.512509",
"lng": "114.405872"
},
{
"lat": "30.560225",
"lng": "114.347626"
}
];
//加载SVG
var svg = d3.select(mymap.getPanes().overlayPane).append("svg").attr("class", "leaflet-zoom-hide"),
g = svg.append("g");
var jsonCircles = new Array();
function drawCircle() {
circleData.forEach(function(d) {
console.log(d);
jsonCircles.push({
"x_axis": d.lat,
"y_axis": d.lng,
"radius": 12,
"color": "green"
});
});
console.log("drawCircle");
console.log(jsonCircles);
var t = svg.selectAll("circle")
.data(jsonCircles);
var circleAttributes =
t
.enter()
.append("circle")
.attr("cx", function(d) {
console.log(mymap.latLngToLayerPoint(L.latLng(d.x_axis, d.y_axis)));
return mymap.latLngToLayerPoint(L.latLng(d.x_axis, d.y_axis)).x;
})
.attr("cy", function(d) {
return mymap.latLngToLayerPoint(L.latLng(d.x_axis, d.y_axis)).y;
})
.attr("r", function(d) {
return d.radius;
})
.style("fill", function(d) {
return d.color;
});
}
//调整圆的大小,在onMapZoom中调用
function adjustCircle() {
console.log("draw");
d3.selectAll("circle")
.attr('cx', o => mymap.latLngToLayerPoint([o.x_axis, o.y_axis]).x)
.attr('cy', o => mymap.latLngToLayerPoint([o.x_axis, o.y_axis]).y);
}
//鼠标缩放操作
function onMapZoom() {
//adjustSVG();
adjustCircle();
}
function initial() {
svg.attr("width", 1500)
.attr("height", 800);
drawCircle();
}
//初始化画图的函数
initial();
//事件响应
mymap.on('zoom', onMapZoom);
</script>
</body>
</html>