中国地图开发
1.首先,第一步,我们需要拿到中国各个省份的边界经纬度数据
China.json地址:China.json数据地址
演示地址:China-V2.html演示地址
{
"type": "Feature",
"geometry": {
"type": "Polygon",
"coordinates": [
[
[114.2732, 40.4803],
[114.2716, 40.4605],
[114.2987, 40.4456],
...
]
]
},
"properties": {
"name": "山西省",
"adcode": "140000",
"telecode": null,
"level": "province",
"parent": {
"name": "中华人民共和国",
"level": "country",
"adcode": "100000",
"center": {
"crs": {
"type": "name",
"properties": {
"name": "urn:ogc:def:crs:EPSG:6.3:4326"
}
},
"type": "Point",
"coordinates": [116.3683244, 39.915085]
}
},
"center": {
"lng": 112.549248,
"lat": 37.857014
}
}
}
拿山西省为例,可以看到,在coordinates这个字段中放了一系列的经纬度信息,这就是我们要的省份边界数据
2.第二步,加载经纬度数据
我这里使用的是AJAX请求(防止跨域,需要自己启一个服务,可以使用http-server后者直接用Hbuildx编译器),或者使用jsonp的方式加载China.json
AJAX请求:
var chinaJson;
// 异步加载数据 从china.json中读取中国地图的经纬度数据
var loadChinaJson = new Promise( function(resolve,reject) {
var url = "./json/china.json"
var request = new XMLHttpRequest();
request.open("get", url);
request.send(null);
request.onload = function () {
if (request.status == 200) {
chinaJson = JSON.parse(request.responseText);
console.log('loadChinaData success!',chinaJson);
resolve(chinaJson);
}
}
})
// 读取数据完成后
loadChinaJson.then(function(chinaJson) {
// 在svg上写出各个省份的名字
drawText(chinaJson);
// 在svg上画出各个省份的边界,并填充颜色
drawAreas(chinaJson);
})
不会自己启服务的同学可以使用Jsonp的方式:
<script>
// fetchData()是加载test.json成功后执行的回调
function fetchData(res) {
// ES6中的反单引号``,是一种字符串模板(Template literals)的写法,并且支持多行字符串和字符串插补特性
console.log(`${Object.keys(res)[0]}:${Object.values(res)[0]},`);
}
</script>
<!-- 使用jsonp的方式加载本地的json数据,这样就不需要启一个服务,避免了跨域的问题 -->
<script src="./json/test.json?callback=fetchData"></script>
3.第三步,在svg上画出各个省份的边界线,并且填充颜色
// 在svg中画出各个省份的边界线,并且填充颜色
function drawAreas(chinaJson) {
// projection为投影方式
var projection = d3.geoMercator().fitSize([900,600],chinaJson);
// 这里的pathGenerator就是geoPath实例化的一个path地理路径生成器(个人理解是将三维的经纬度坐标转化成二维的平面坐标)
var pathGenerator = d3.geoPath().projection(projection);
// 获取<svg>的DOM节点
var chinaMapSvg = document.getElementById('chinaMap');
chinaJson.features.map( (d,i) => {
var NS = 'http://www.w3.org/2000/svg';
var path = document.createElementNS(NS, 'path');
path.setAttribute('id',i);
path.setAttribute('stroke','#4A89BE');
path.setAttribute('fill','#5078AB');
path.setAttribute('strokeWidth',2);
path.setAttribute('d',pathGenerator(d));
chinaMapSvg.appendChild(path);
})
}
// 在svg地图上写上各个省份的名字
function drawText(chinaJson) {
// 调用d3的库,使用墨卡托投影的方式
var projection = d3.geoMercator().fitSize([900,600],chinaJson);
chinaJson.features.map( d => {
// 根据给定的地理特征计算中心位置坐标
var center = d3.geoCentroid(d);
center = projection(center);
if (center[0] && center[1]) {
// 获取<svg>的DOM节点
var mapText = document.getElementById('mapText');
// 创建一个<span>
var spanItem = document.createElement('span');
spanItem.style.fontSize = '8px';
spanItem.style.position = 'absolute';
spanItem.style.left = center[0] + 'px';
spanItem.style.top = center[1] + 'px';
spanItem.innerHTML = d.properties.name;
mapText.appendChild(spanItem);
};
})
}
好,那么一个地图就开发完毕了,看下效果
源码地址:GitHub地址源码