本篇文章会记录如何完成地图两级联动,以及过程中遇到的一些问题,希望能帮到大家!
1、环境
<script src="https://s1.pstatp.com/cdn/expire-1-M/jquery/1.10.2/jquery.min.js"></script>
<script type="text/javascript" src="echarts.min.js"></script>
注意:echarts.min.js是本地文件,你可以去echarts官网下载,也可以直接去我后面发布的实例里找。
2、分类
利用文件命名的方式确定好要绘制地区的层级关系,并且绘制重庆市地图,你就先获得重庆市下各个区的边界坐标然后拼接成重庆地图,准备绘制区地图就要获得乡镇级别的边界坐标然后拼接成整体。具体情况如下:
重庆市要装的是各个区县的坐标数据,长寿区,忠县等文件夹装的是各自的乡镇级别的坐标数据。
3、获取边界坐标
下载”bigemap”或其他地图软件,然后根据第一步下载需要的地区边界坐标到分好类的文件夹里,文件后缀为”.kml”。本次用的是“bigemap”:
4、检查kml文件
有了坐标我们还不能直接拼接地图,因为有的区域划分会有很多小块闭合的区域,echarts无法绘制出由kml文件内部衔接起的多个闭合的区域坐标,不然在绘制地图的时候会报错:
Invalid geoJson format Cannot read property ‘length’ of undefined。
所以在拼接地图生成对应的json文件之前需要确保一个kml文件里只有一个<Polygon></Polygon>标签,我们直接把kml文件在文本编辑器打开,利用ctrl+f查询的方式整理后,来看有多少个<Polygon>标签,有多个时就新建kml文件把原文件拆分开来。下面是拆分前后的样子:
拆分前
拆分后
注意:拆分的时候一定要确保几个kml文件只有<Polygon>标签内的内容不一样。
5、拼接地图生成对应的json文件
进相关网站,引入kml文件就可以拼接地图了,当你一个文件夹内的区域拼接完了之后,复制右侧的全部代码,粘贴到一个新建的json文件里然后新建“方法名()”的括号里(这是为了解决本地引用时候的跨域问题),方法名跟文件名一致(方便后面调用)。
拼接
生成json文件
6、引入json数据
第一层地图的数据因为只有一个文件,我选择的是直接通过引入js的方式引进来,不存在跨域问题,但是要在json文件里声名变量名,方便调用数据。
点击事件引入二级地图数据用ajax然后通过jsonp的形式读取json数据(解决本地引入的跨域问题)。
$.ajax({
type: "get",
url:'/ZHZM/javaScript/wis/yxtj/mapdata/'+provinces[params.name]+'.json',
dataType: 'jsonp',
crossDomain: true,
jsonp: "callback",
jsonpCallback:provinces[params.name],
success: function(data){
map2Data= [];
for (var i = 0; i < data.features.length; i++) {
map2Data.push({
name: data.features[i].properties.name
})
}
echarts.registerMap(params.name, data);
renderMap(params.name, map2Data);
},
});
parames.name 是点击事件传进来所点击的区域名称,provinces[]是为了区域名称与对应的文件名称形成映射关系,provinces[ parames.name]表示文件名。
此处解决跨域的注意点:
①jsonp
②crossDomain: true,
③生成json文件时,复制的坐标代码放在“方法名()”的括号内,见第五步。
7、完整的js代码
var chart = echarts.init(document.getElementById('chongqing-map'));
var provinces = {
'大渡口区':'dadukou',
'巴南区':'banan',
'北碚区':'beibei',
'璧山区':'bishan',
'城口县':'chengkou',
'大足区':'dazu',
'垫江县':'dianjiang',
'丰都县':'fengdu',
'奉节县':'fengjie',
'万州区':'wanzhou',
'涪陵区':'fuling',
'合川区':'hechuan',
'江北区':'jiangbei',
'江津区':'jiangjin',
'九龙坡区':'jiulongpo',
'开州区':'kaizhou',
'梁平区':'liangping',
'南岸区':'nanan',
'南川区':'nanchuan',
'彭水苗族土家族自治县':'pengshui',
'綦江区':'qijiang',
'黔江区':'qianjiang',
'荣昌区':'rongchang',
'沙坪坝区':'shapingba',
'石柱土家族自治县':'shizhu',
'铜梁区':'tongliang',
'潼南区':'tongnan',
'巫山县':'wushan',
'巫溪县':'wuxi',
'武隆区':'wulong',
'秀山土家族苗族自治县':'xiushan',
'永川区':'yongchuan',
'酉阳土家族苗族自治县':'youyang',
'渝北区':'yubei',
'渝中区':'yuzhong',
'云阳县':'yunyang',
'长寿区':'changshou',
'忠县':'zhongxian'
};
//加载重庆初始地图
$(document).ready(function(){
mapData = [];
//把json里的name提取出来装入mapData
for (var i = 0; i < cq.features.length; i++) {
mapData.push({
name: cq.features[i].properties.name
})
};
//注册地图
echarts.registerMap('重庆', cq);
//绘制地图(自己的方法)
renderMap('重庆', mapData);
console.log(cq);
})
//声名全局变量绘制全国地图配置
var option = {
title: {
left: 'center',
textStyle: {
color: '#fff',
fontSize: 16,
fontWeight: 'normal',
fontFamily: "Microsoft YaHei"
},
subtextStyle: {
color: '#ccc',
fontSize: 13,
fontWeight: 'normal',
fontFamily: "Microsoft YaHei"
},
},
tooltip: {
trigger: 'item',
formatter: '{b}'
},
animation:true,
animationDuration: 1000,
animationEasing: 'cubicOut',
animationDurationUpdate: 1000,
};
//声名绘制地图的函数
function renderMap(map, data) {
//option.title.subtext = map;
option.series = [{
name: map,
type: 'map',
mapType: map,
zoom: 1,
hoverAnimation:false,
nameMap: {
'china': '中国'
},
label: {
emphasis: {
show: false
}
},
roam: true, //设置是否开启拖动与缩放
scaleLimit: { //滚轮缩放的极限控制
min: 1,
max: 2.5
},
itemStyle: {
normal: {
borderColor: 'rgba(147, 235, 248, 1)',
borderWidth: 1,
areaColor: {
type: 'radial',
x: 0.5,
y: 0.5,
r: 0.8,
colorStops: [{
offset: 0,
color: 'rgba(175,238,238, 0)' // 0% 处的颜色
}, {
offset: 1,
color: 'rgba( 47,79,79, .1)' // 100% 处的颜色
}],
globalCoord: false // 缺省为 false
},
shadowColor: 'rgba(128, 217, 248, 1)',
shadowOffsetX: -2,
shadowOffsetY: 2,
shadowBlur: 10
},
emphasis: {
areaColor: '#389BB7',
borderWidth: 0
}
},
data: data
}];
//渲染地图
chart.setOption(option);
//关闭单击事件
chart.off("click");
//关闭双击事件
chart.off("dblclick");
//如果在第一层只有单击事件
if(map=="重庆"){
chart.on('click',function(params){
chart.clear();
console.log(params.name);
console.log(provinces[params.name]);
$.ajax({
type: "get",
url:'mapdata/'+provinces[params.name]+'.json',
dataType: 'jsonp',
crossDomain: true,
jsonp: "callback",
jsonpCallback:provinces[params.name],
success: function(data){
console.log(data);
map2Data= [];
for (var i = 0; i < data.features.length; i++) {
map2Data.push({
name: data.features[i].properties.name
})
}
echarts.registerMap(params.name, data);
renderMap(params.name, map2Data);
},
});
});
//在第二层双击回第一层
}else{
chart.on('dblclick', function (params) {
chart.clear();
renderMap('重庆', mapData);
});
}
}
后面我会把以重庆为实例的完整地图资源发出来(包含区-乡镇的json数据),如有需要的小伙伴可以自行下载。