使用D3.js绘制地图并打点

本篇简单介绍一下使用D3.js绘制地图,并更具经纬度在地图打点。最后根据点生成voronoi图及其三角网。

下载地图geoJson文件

去网上下载要绘制地图的geoJson文件。

使用d3.json()加载地图文件,这里为了方便加载我把geoJson文件放在了js文件里。

使用D3.js绘制地图并打点

绘制地图


<!DOCTYPE html>
<html>

	<head>
		<meta charset="UTF-8">
		<title></title>
	</head>

	<body>
		<div >
		</div>
	</body>
	<script src="https://d3js.org/d3.v5.js"></script>
	<script type="text/javascript" src="js/china.js"></script>
	<script>
		window.onload = function() {

			var width = 1900,
				height = 800;

			var svg = d3.select("#test-svg")
				.append('svg')
				.attr('width', width + 'px')
				.attr('height', height + 'px');

			/*
			 * 创建一个地理投影
			 * .center 设置投影中心位置
			 * .scale 设置缩放系数
			 * 
			 */
			var projection = d3.geoMercator()
				.center([463, 36])
				.scale(850)
				.translate([width / 2, height / 2]);

			//  创建路径生成器path
			var path = d3.geoPath().projection(projection);

			//  获取GeoJSON数据:这里我放在了js中方便加载
			var features = china.features;

			// 设置颜色值
			var ss2 = d3.schemeSet2;
			var sp2 = d3.schemePastel2;

			/*
			 * 渲染地图
			 * 
			 * mouseover 鼠标移入变色
			 * 
			 */
			svg.append('g')
				.attr('class', 'map')
				.selectAll('.china')
				.data(features)
				.join('path')
				.attr('class', 'china')
				.attr("fill", function(d, i) {
					return ss2[i % 3]
				})
				.attr('d', path)
				.on("mouseover", function(d, i) {
					d3.select(this)
					  .attr("fill", sp2[i % 3]);
				})
				.on("mouseout", function(d, i) {
					d3.select(this)
					  .attr("fill", ss2[i % 3]);
				});

		}
	</script>

</html>

  • 绘制效果

使用D3.js绘制地图并打点

使用D3.js绘制地图并打点

地图打点

a) 首先去取一些点

http://geojson.io 在网站上找到我国疆土,标注几个城市,在右边获取到经纬度。

使用D3.js绘制地图并打点

b) 把点坐标放到我们的json中
使用D3.js绘制地图并打点


var points = china.points.features;
            
            var coo = function(d){
            	// 获取经纬度
				var lngLat = d.geometry.coordinates;

				// 转为映射在地图上的坐标
				var coo = projection(lngLat);
				return coo;
            }
            
			svg.selectAll('circle')
				.data(points)
				.join('circle')
				.attr("class", "point")
				.attr("cx", function(d){
					return coo(d)[0];
				})
				.attr("cy", function(d){
					return coo(d)[1];
				})
				.attr("fill", "#ff9")
				.attr("r", 4);

使用D3.js绘制地图并打点

添加Voronoi图

Voronoi图 又称沃罗诺伊图、泰森多边形,绘制的过程是将点都连起来构成许多三角形,然后利用中垂线找到三角形外心,再将所有外心连接即可。在几何、晶体学、建筑学、地理学、气象学、信息系统等许多领域有广泛的应用。


 // 获取所有点的经纬度
            var _points = points.map(function(d){
				return coo(d);
			});
            
            // 创建voronoi
            var voronoi = d3.voronoi().extent([
				[0, 0],
				[width, height]
			]);
			
			var polygons = voronoi(_points);
			
			function polygon(d) {
				return "M" + d.join("L") + "Z";
			}
			
			svg.append('g')
				.attr('class', 'map')
				.selectAll('.country')
				.data(voronoi.polygons(_points))
				.join('path')
				.attr("fill", "none")
				.attr("stroke", "#ff9")
				.attr('class', 'voronoi')
				.attr('d', polygon);

使用D3.js绘制地图并打点

绘制Voronoi图的三角网

  • 得到的三角网数据如下,这里将它们从sourcetarget依次连成线

使用D3.js绘制地图并打点


svg.append('g')
				.selectAll('line')
				.data(voronoi.links(_points))
				.join('line')
				.attr("stroke", "#ff9")
				.attr('stroke-dasharray', 10)
				.attr('class', 'line')
				.attr('x1', function(d) {
					return d.source[0];
				})
				.attr('y1', function(d) {
					return d.source[1];
				})
				.attr('x2', function(d) {
					return d.target[0]
				})
				.attr('y2', function(d) {
					return d.target[1]
				});

使用D3.js绘制地图并打点