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

前言

根据大家私信留言还是决定对地图这块的东西进行拓展讲解一下,希望大家能够真正了解、使用绘制自己想要的地图效果,让大家彻底弄懂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文件包装导出方法,不能直接使用需要使用 mapmaker 工具转换,具体方法我就不再这细说了,可以百度一下 echartsmapmaker 的使用,我们研究一下源码,看它的实现思路

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 文件
    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;
    },
 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 仅保留选中

splitdelete相似

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 文件渲染存在先后顺序,先渲染的在图层底,后渲染的在顶层(canvasnewJson.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图的话,需要每一个 <g> 都有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属性

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

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

  1. 绘制 飞机座位

标记name

导出,并处理<g>的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地图的拓展,有问题交流呀。

原文地址:https://blog.csdn.net/weixin_47746452/article/details/129672275

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任

如若转载,请注明出处:http://www.7code.cn/show_38776.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱suwngjj01@126.com进行投诉反馈,一经查实,立即删除

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注