前言

根据大家的私信、留言,还是决定对地图这块的东西进行拓展讲解一下,希望大家能够真正了解、使用、绘制自己想要的地图效果,让大家彻底弄懂Echarts地图,涉及绘制原理、行政区划、SVG地图、地图打点、线路图、飞线图等内容。开始吧!

gitee: echarts-map

Echarts渲染地图原理

// Echarts 官网案例

$.get('map/china_geo.json', function (chinaJson) {

echarts.registerMap('china', {geoJSON: geoJson});

var chart = echarts.init(document.getElementById('main'));

chart.setOption({

geo: [{

map: 'china',

...

}]

});

});

Echarts 允许我们加载 json 文件(地图渲染文件),进而使用 registerMap 注册地图名称,通过 setOption来渲染地图。因此,地图json文件就是Echarts Map 的核心,可以根据不同的 json 文件渲染出不同效果的地图。(所以,自定义地图也是绘制的图形,生成json文件,供map使用)

Echarts基础地图

我们上一篇文章Vue 使用 Apache Echarts 绘制地图(省市、地区、自定义)中,已经给出了地图渲染数据,根据dataV.数据可视化平台中的中国地图,我们渲染出以下地图:

但是这个南海区域拖的太长了,我们需要处理一下,根据上一节原理,是渲染的json数据太多了。我们目前是axios请求得来,不能直接修改,因此,我们需要下载下来,手动处理。

我们把海南的下地市数据删除,仅剩一个海南省主数据时,得到了下图:

还是剩一条线,因此,它可能是独立的数据了,我们看一下拿到的json数据,

最后一项数据没有表明名称,因此,我们可以删除,

如果Echarts没有提供右侧的南海诸岛的缩略图的话,自已一定一定要补上!不然中国地图不完整!!!

如果Echarts没有提供右侧的南海诸岛的缩略图的话,自已一定一定要补上!不然中国地图不完整!!!

如果Echarts没有提供右侧的南海诸岛的缩略图的话,自已一定一定要补上!不然中国地图不完整!!!

如果,Echarts 没有默认提供该缩略图,我们该如何处理?

使用边界生成器,绘制边界,导出为svg,得到下图:

在定位处理一下,即可得到想要的完整的中国地图。

**温馨提示**

这里说一下,Echarts默认使用 china注册的地图,都会加上南海诸岛缩略图,不论你的JSON文件是什么内容,如下:

甚至!,空的json文件,也能渲染出缩略图!这个问题我找了一上午,所以大家注册名字时,尽量规范取名。

Echarts行政区划

中国区划

中国区划:https://github.com/echarts-maps/echarts-china-misc-js

Echarts官网默认给我们提供了很多类型的地图,包括各种区划,但是提供给我们的是地图JS文件,包装了导出方法,不能直接使用,需要使用 map-maker 工具转换,具体方法我就不再这细说了,可以百度一下 echarts-mapmaker 的使用,我们研究一下源码,看它的实现思路:

gulp.task('华中', function(){

utils.disolve_internal_borders('./node_modules/echarts-china-provinces-js/echarts-china-provinces-js/henan.js', 'henan.geojson', '河南').then(()=>{

utils.disolve_internal_borders('./node_modules/echarts-china-provinces-js/echarts-china-provinces-js/hubei.js', 'hubei.geojson', '湖北').then(()=>{

utils.disolve_internal_borders('./node_modules/echarts-china-provinces-js/echarts-china-provinces-js/hunan.js', 'hunan.geojson', '湖南').then(()=>{

maker.merge('hubei.geojson', 'henan.geojson');

maker.merge('hunan.geojson', 'merged_hubei.geojson');

maker.makeJs('merged_hunan.geojson', path.join(constants.dist, 'hua_zhong.js'), '华中');

});

});

});

});

核心就是加载区划所属省份的json文件,进行合并,得到区划的json文件,进行地图渲染。

自定义区划

根据上诉原理,我们可以自定义区划了,我们已经有了全国省份的json文件,就是china.json文件里的数据项,实现步骤:

计算名称映射

json文件中 adcode是唯一标识每一个省份的,因此,我们需要获取到省份名称及adcode 的映射文件

// 生成映射文件

setDataMap() {

const data = require("./json/china.json");

this.map = [];

data.features.forEach((i) => {

this.map.push({

name: i.properties.name,

adcode: i.properties.adcode,

});

});

},

拿到对应省份的json文件

// 拿到省份对应的 json 文件

getGeoJson(list) {

const adcodeList = [];

const json = {

type: "FeatureCollection",

features: [],

};

const data = require("./json/china.json");

// 先获取 adcode

list.forEach((item) => {

adcodeList.push(this.map.find((i) => i.name === item)?.adcode);

});

adcodeList.forEach((code) => {

json.features.push(data.features.find((i) => i.properties.adcode === code));

});

// 返回拼凑的json文件

return json;

},

这个 name与adcode的转换,大家不要觉得没用,用name也能检索,使用adcode是为了数据库存储唯一ID,作为唯一值时,不推荐使用中文。

渲染返回结果

mounted() {

this.setDataMap();

const qhJson = this.getGeoJson(["广西壮族自治区", "广东省"]);

echarts.registerMap("mapName", {

geoJSON: qhJson,

});

var chart = echarts.init(this.$refs.map);

chart.setOption({

geo: [

{

map: "mapName",

},

],

});

},

中国的七大区划如下(Echarts官网给出的 preview):

区划包含的省份苏皖浙苏州、安徽、浙江,三省合体华南广东、广西、海南、香港、澳门华南2广东、广西、海南(海南诸岛)、香港、澳门华北内蒙古、河北、山西、北京,天津华中河南、湖北、湖南西北宁夏、'新疆、青海、陕西、甘肃西南四川、云南、贵州、西藏、重庆

我们直接验证一个西北(名称一定以我们 json文件为准哈):

mounted() {

this.setDataMap();

// 宁夏 新疆 青海 陕西 甘肃

const qhJson = this.getGeoJson(["宁夏回族自治区", "新疆维吾尔自治区", "青海省", "陕西省", "甘肃省"]);

echarts.registerMap("mapName", {

geoJSON: qhJson,

});

var chart = echarts.init(this.$refs.map);

chart.setOption({

geo: [

{

map: "mapName",

},

],

});

},

我们的实现思路没问题。

取消内部线

mapshaper 是强大的地图文件编辑器,可以用于合并地图json数据。上一节我们说了,渲染地图的核心是 json文件,文件中的 coordinates 是二维点数据,因此,实现的原理是边界点重复出现时,删除该点:

如上,广东、广西公用一条边界线。下面演示下,如何使用 mapshaper 删除内部边界线:

拖拽文件或手动选择要合并的json,

选择导入 import

点击右上角 console,输入:

dissolve -o result.json

// dissolve 合并命令

// -o output edited content(输出编辑内容,就是另存为)

// result.json 要输出的文件名

可以输入 help 查看所有的命令,包括 删除、合并等操作。

选择某几个省:

使用工具选择:(ctrl 可多选,以两广为例)

delete 从原json 中删除选中;

keep 仅保留选中;

split 与delete相似;

clear 清除操作;

选择 keep 后,点击 console,输入合并命令:

dissolve -o result.json

然后,打开输出的文件,就是合并后的json文件啦:

通常实现的效果是添加省级、国界线,需要取消内部边界,实现效果如下:

单列市

单列市的存在比较特殊,是某些特殊的地市级,需要单独以单元出现在中国地图上,简单来说,我想看 北上广深的经济情况,很明显,深圳不是省份,正常是不能与上广深同时出现的。如何处理呢?

下载单列市的json文件【第一个能看到单列市的层级:意思是你要深圳,你在那一层最先看到它?广东省嘛,因此,下载广东省的json】

深圳太小了,我拿新疆的地市做测试,道理是一样的

// 处理单列市

dlsHandle(adcode = 440300) {

// 在单列市json中找到单列市的json配置项

const dlsJson = xjJson.features.find(

(i) => i.properties.adcode === adcode

);

const newJson = chinaJson;

// json 文件渲染存在先后顺序,先渲染的在图层底,后渲染的在顶层(canvas)

newJson.features.push(dlsJson);

return newJson;

},

上诉,自治州也能在全国地图显示了。这样,就能根据自己的业务,实现单列市的处理了。

原理是:

{

"type": "Feature",

"properties": {

"adcode": 110000,

"name": "北京市",

            ....

}

这个是北京市的 json数据

{

"type": "Feature",

"properties": {

"adcode": 652800,

"name": "巴音郭楞蒙古自治州",

            ...

}

这个是单列市的json数据,类型都是 Feature 一样的,因此,可以直接添加到 全国json数据。

绘制世界地图

世界各地json文件映射:https://github.com/echarts-maps/echarts-countries-js

世界各地 json文件地址:https://github.com/pissang/starbucks/tree/gh-pages/json

上诉两个地址,就是世界地图的json,直接爬虫下来,汇总处理数据就行了(文件我已经处理好了,放在项目里了)

效果图如下:

自定义地图

掌握了原理之后,你想绘制啥,那不是手到擒来。

自定义地图,多用在绘制非常规地图上,比如,绘制校园建筑人数热力、公园景点旅游热度等这些自定义的。下面还是举例说明一下吧(以上海海洋大学人员分布图为例)

使用 边界生成器绘制地图基础数据

上一篇文章中提到了区域相同导致浮窗都一样,添加了自定义name属性,建议在属性面板中处理,不然导出文件太大,根本处理不了,这样也能在绘制的时候,做合并、裁剪操作,使得绘制更加清晰,数据结构合理。

裁剪:想要两个面是独立的,就需要裁剪

先勾选减数,再勾选裁剪,后勾选被减数

执行完后,只会留下一个面,这个面是剪掉被减数后的

但是这个区域我们是需要的,因此,再绘制一遍

这两个面都是独立的面,导出json,看看效果:

这就是面的处理,已经很详细了,下面我就不细说了。需要注意点我会说一下。

再修饰一下,基本上就能出来了

加载SVG地图

加载SVG地图相对简单,但是我们加载自己的svg图的话,需要每一个 都有name属性,才可以进行交互。如下:

边界生成器导出为svg,加载svg:

// 该加载svg的方式会报错

echarts.registerMap("map", {

svg: require('../public/svg/data.svg'),

});

var chart = echarts.init(this.$refs.map);

chart.setOption({

geo: [

{

map: "map",

},

],

});

因此,不能直接 require或者 import ,应该使用网络请求:

mounted() {

// 这里用请求的形式,

axios.get("/svg/data.svg").then((res) => {

echarts.registerMap("map", {

svg: res.data,

});

var chart = echarts.init(this.$refs.map);

chart.setOption({

geo: [

{

map: "map",

},

],

});

});

},

得到如下:

但是这样子是没有交互的,就是鼠标放上去,也没有显示名称啥的,因此,需要手动添加 name属性:

这样就行了,我们实现一下官网的飞机选座图:

边界生成器自定义地图,就可以得到空的页面

绘制 飞机座位

标记name

导出,并处理的name,配置多选及选中颜色等,

geo: {

map: "iceland_svg",

roam: true,

selectedMode: "multiple",

select: {

itemStyle: {

color: "green",

},

},

},

就这样,剩下的不可选中,直接判断一下就行了。

地图打点

地图打点,需要svg底图实现,不可以加载 json文件。

按上例,先加载SVG,然后处理打点:

// 添加series配置项,

series: {

type: "effectScatter",

coordinateSystem: "geo",

geoIndex: 0,

data: [[...positionMap[0].position, 100]],

},

positionMap 就是点数据坐标,可以通过下方法,快速获取点在svg中的坐标

myChart.getZr().on("click", function (params) {

var pixelPoint = [params.offsetX, params.offsetY];

var dataPoint = myChart.convertFromPixel({ geoIndex: 0 }, pixelPoint);

// 在 SVG 上点击时,坐标会被打印。

// 这些坐标可以在 `series.data` 里使用。

console.log(dataPoint);

});

地图的打点,还可以做线路图 series type = lines

路径图

用于带有起点和终点信息的线数据的绘制,主要用于地图上的航线,路线的可视化。

连续位置的线段(用于绘制线路图等连续性坐标)

非连续的位置,可以实现飞线图:

名称数据映射

这个问题通常出现在请求后端数据时,返回的数据与渲染地图数据不一致,使用nameMap处理(如官网香港18区人口密度 (2011))

思路就是找到两者数据的id,对名称进行数据映射即可。

总结

其实这些东西都是官网的样例,好好研究官网配置文件,相信大家也可以写出来的。以上就是Echarts地图的拓展,有问题交流呀。

好文链接

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: