Vue 使用 Apache Echarts 绘制地图(省市、地区、自定义)_vue 地图-程序员宅基地

技术标签: 地图系列  echarts地图  apache  地图  中国地图  echarts  省市级联动  javascript  

        大家好呀,时隔半年,最近在忙项目,没空写文章了,最近项目需要,研究了一下地图的绘制,分享给大家,这篇主要简单讲述Echarts渲染地图,下一篇Vue 使用 Apache Echarts 绘制地图(拓展篇)中,详细讲述了渲染原理,以及如何去除内部边界线,炫酷的地图效果。先安利两个网址,是制作地图的资源:

DataV.地图GeoJSON数据

Apache Echarts 地图配置示例-香港

一. 配置vue项目

这个就不再赘述了。

二. 安装 Apache Echarts 

2.1 安装

npm install echarts --save

 2.2 引用

 这个不用在main中注册使用,直接在需要echarts的页面中引入即可。

三. 新建目录

api:用于存放获取(后端、地图JSON数据)数据的文件夹;

json:存放map的GeoJSON数据;

 四. 获取地图的GeoJSON

点击DataV.地图GeoJSON数据

左侧是地图,右侧是JSON数据路径,点击你想要生成的地图省市、地级(以广西省为例);

 

点进去是一级,再点进去是二级,直到你想要的省市地区(点击旁边的空白可以返回上一级);

 然后其右侧有JSON数据的链接地址,可以选择下载下来(放在json文件夹中),也可以使用在线地址!(json API与geoJSON数据地址均可用)

五. 配置api

使用axios获取数据(使用在线链接):

代码不难,我就不解释了

六. 配置地图信息 

数据都准备好了,我们开始绘制地图:

6.1 引入 Echarts、广西地图数据

import * as echarts from 'echarts';

import getGuangXiMap from './api/getGuangXiMap';

 6.2 准备容器:(使用div、canvas均可)

<div style="width:800px;height:600px" ref="chartsDOM"></div>

解释一下: 1. 需要先指定宽高 ;2. ref标记是为了应和vue获取dom的方式。

6.3 绘制地图

vue在mounted时才能获取到页面DOM,故而地图写在mounted中:

 mounted() {
    // 初始化统计图对象
    var myChart = echarts.init(this.$refs["chartsDOM"]);
    // 显示 loading 动画
    myChart.showLoading();
    // 再得到数据的基础上,进行地图绘制
    getGuangXiMap.then(res => {
      // 得到结果后,关闭动画
      myChart.hideLoading();
      // 注册地图(数据放在axios返回对象的data中哦)
      echarts.registerMap('GX', res.data);
      var option = {
        series: [
          {
            name: '广西地图',
            type: 'map',
            map: 'GX',// 这个是上面注册时的名字哦,registerMap('这个名字保持一致')
            label: {
              show: true
            }
          }
        ]
      };
      myChart.setOption(option);
    })
  }
}

6.4 即可得到广西的地图啦

 七. Apache Echarts配置项

大家有可能看过apache echarts 的地图配置项,非常多,只是为了实现其他的效果,可以参考配置项手册 ;后期我会推出【配置式统计图工具】,就是不用大家查阅配置手册啦,通过按钮点击、选择,即可得到你想要的效果,望大家持续关注呀。

7.1 配置数据项

现在大家还是通过查阅配置项手册完善地图信息,下面简单演示一下其他效果:

7.1.1 配置数据

var option = {
        series: [
          {
            name: '广西地图',
            type: 'map',
            map: 'GX',// 这个是上面注册时的名字哦,registerMap('这个名字保持一致')
            label: {
              show: true
            },
            data: [
              { name: '南宁市', value: 12001 },
              { name: '崇左市', value: 12001 },
              { name: '柳州市', value: 12001 },
              { name: '来宾市', value: 12001 },
              { name: '桂林市', value: 12001 },
              { name: '梧州市', value: 12001 },
              { name: '贺州市', value: 12001 },
              { name: '玉林市', value: 12001 },
              { name: '贵港市', value: 12001 },
              { name: '百色市', value: 12001 },
              { name: '钦州市', value: 12001 },
              { name: '河池市', value: 12001 },
              { name: '北海市', value: 12001 },
              { name: '防城港市', value: 12001 },
            ]
          },
        ]
      };

 7.1.2 配置提示框

var option = {
        tooltip: {},// 配置提示框,有这个配置项即可
        series: [
          {
            name: '广西地图',
            type: 'map',
            map: 'GX',// 这个是上面注册时的名字哦,registerMap('这个名字保持一致')
            label: {
              show: true
            },
            data: [
              { name: '南宁市', value: 12001 },
              { name: '崇左市', value: 12001 },
              { name: '柳州市', value: 12001 },
              { name: '来宾市', value: 12001 },
              { name: '桂林市', value: 12001 },
              { name: '梧州市', value: 12001 },
              { name: '贺州市', value: 12001 },
              { name: '玉林市', value: 12001 },
              { name: '贵港市', value: 12001 },
              { name: '百色市', value: 12001 },
              { name: '钦州市', value: 12001 },
              { name: '河池市', value: 12001 },
              { name: '北海市', value: 12001 },
              { name: '防城港市', value: 12001 },
            ]
          },
        ]
      };

7.1.3 加标题 

var option = {
        title:{
            text:'广西GDP统计图(/万元)'
        },
        tooltip: {},// 配置提示框,有这个配置项即可
        series: [
          {
            name: '广西地图',
            type: 'map',
            map: 'GX',// 这个是上面注册时的名字哦,registerMap('这个名字保持一致')
            label: {
              show: true
            },
            data: [
              { name: '南宁市', value: 12001 },
              { name: '崇左市', value: 12001 },
              { name: '柳州市', value: 12001 },
              { name: '来宾市', value: 12001 },
              { name: '桂林市', value: 12001 },
              { name: '梧州市', value: 12001 },
              { name: '贺州市', value: 12001 },
              { name: '玉林市', value: 12001 },
              { name: '贵港市', value: 12001 },
              { name: '百色市', value: 12001 },
              { name: '钦州市', value: 12001 },
              { name: '河池市', value: 12001 },
              { name: '北海市', value: 12001 },
              { name: '防城港市', value: 12001 },
            ]
          },
        ]
      };

7.1.4 根据数据配置不同显示颜色

 Apache Echarts 配置项手册-visualMap

详情参考上链接(颜色能否区分,取决于数据的差距程度);

实现如上。

完整代码如下:

 mounted() {
    // 初始化统计图对象
    var myChart = echarts.init(this.$refs["chartsDOM"]);
    // 显示 loading 动画
    myChart.showLoading();
    // 再得到数据的基础上,进行地图绘制
    getGuangXiMap.then(res => {
      // 得到结果后,关闭动画
      myChart.hideLoading();
      // 注册地图(数据放在axios返回对象的data中哦)
      echarts.registerMap('GX', res.data);
      var option = {
        visualMap: {
          min: 1111,
          max: 333332,
          realtime: false,
          calculable: true,
          inRange: {
            color: ['lightskyblue', 'yellow', 'orangered']
          }
        },
        title: {
          text: '广西GDP统计图(/万元)'
        },
        tooltip: {},
        series: [
          {
            name: '广西地图',
            type: 'map',
            map: 'GX',// 这个是上面注册时的名字哦,registerMap('这个名字保持一致')
            label: {
              show: true
            },
            data: [
              { name: '南宁市', value: 11111 },
              { name: '崇左市', value: 22221 },
              { name: '柳州市', value: 33333 },
              { name: '来宾市', value: 22231 },
              { name: '桂林市', value: 44441 },
              { name: '梧州市', value: 555525 },
              { name: '贺州市', value: 162475 },
              { name: '玉林市', value: 65454 },
              { name: '贵港市', value: 77771 },
              { name: '百色市', value: 88884 },
              { name: '钦州市', value: 99995 },
              { name: '河池市', value: 10001 },
              { name: '北海市', value: 122222 },
              { name: '防城港市', value: 333332 },
            ]
          },
        ]
      };
      myChart.setOption(option);
    })
  }

八. 绘制中国地图 

步骤同上,演示一下效果:

(修改请求json路径)

mounted() {
    // 初始化统计图对象
    var myChart = echarts.init(this.$refs["chartsDOM"]);
    // 显示 loading 动画
    myChart.showLoading();
    // 再得到数据的基础上,进行地图绘制
    getChinaMap.then(res => {
      // 得到结果后,关闭动画
      myChart.hideLoading();
      // 注册地图(数据放在axios返回对象的data中哦)
      echarts.registerMap('China', res.data);
      var option = {
        series: [
          {
            name: '中国地图',
            type: 'map',
            map: 'China',// 这个是上面注册时的名字哦,registerMap('这个名字保持一致')
            label: {
              show: true
            },
          },
        ]
      };
      myChart.setOption(option);
    })
  }

九. 绘制县级地图

 

就不能再往下绘制了,因为Data V仅支持到县级。如果我就想绘制我们村GDP的情况呢??哈哈哈  可以使用自定义地图功能。

十.实现省市县联动

        【20230714新增内容】我们知道,渲染地图的原理是json文件,因此,实现省市县的联动无非就是在点击的时候,实现json文件切换,并重新渲染地图即可。下面简单演示下:

10.1 准备省市县的json文件(以广西为例【中国-广西-柳州-柳城】)

 目前我们先这么命名,后面再跟大家说几个方案。

10.2 获取点击的参数

Echart 可以通过监听鼠标事件实现监听地图的操作:

 echarts.registerMap("china", {
      geoJSON: chinaJson,
    });

    var chart = echarts.init(this.$refs.map);
    chart.setOption({
      geo: [
        {
          map: "china",
        },
      ],
    });
    chart.on("click", (params) => {
      console.log(params);
    });

 可以在事件参数中获取到点击的名称 name属性,这个是你的注册的json文件中的name属性

 如下,我修改为 666,参数显示则是:

 这样,我就知道它渲染的省份了,下面实现:

10.3 渲染点击的省份

import * as echarts from "echarts";
import chinaJson from "./alljson/china.json";
import guangxi from "./alljson/guangxi.json";
import liuzhou from "./alljson/liuzhou.json";
import liucheng from "./alljson/liucheng.json";
export default {
  name: "App",

  data() {
    return {
      map: [],
    };
  },

  methods: {
    initParamsCity(name) {
      // 要有城市映射
      const map = {
        中国: chinaJson,
        广西壮族自治区: guangxi,
      };
      echarts.registerMap("mapJson", {
        geoJSON: map[name],
      });

      var chart = echarts.init(this.$refs.map);
      chart.setOption({
        geo: [
          {
            map: "mapJson",
          },
        ],
      });
      chart.on("click", (params) => {
        this.initParamsCity(params.name);
      });
    },
  },
  mounted() {
    this.initParamsCity("中国");
  },
};

效果如下:

 添加更多的映射及返回按钮:

提供 links记录点击的名称,同时,需要渲染下一个的时候,销毁上一个,不然会多次创建 dom,导致监听数据异常。

 data() {
    return {
      map: [],
      links: [],
      myChart: null,
    };
  },

  watch: {
    links: {
      handler(val) {
        if (!val.length) return;
        this.initParamsCity(val[val.length - 1]); // 始终渲染最后一个数据
      },
      immediate: true,
      deep: true,
    },
  },

  methods: {
    initParamsCity(name) {
      // 有返回记录
      // 要有城市映射
      const map = {
        中国: chinaJson,
        广西壮族自治区: guangxi,
        柳州市: liuzhou,
        柳城县: liucheng,
      };
      echarts.registerMap("mapJson", {
        geoJSON: map[name],
      });

      // 销毁上一次地图实例
      if (this.myChart) this.myChart.dispose();
      this.myChart = echarts.init(this.$refs.map);

      this.myChart.setOption({
        geo: [
          {
            map: "mapJson",
          },
        ],
      });
      this.myChart.on("click", (params) => {
        this.links.push(params.name);
      });
    },

    toback() {
      if (this.links.length === 1) return; // 最后的中国地图不能再删除了
      this.links.pop();
    },
  },
  mounted() {
    this.links.push("中国");
  },

 

 以上就是实现联动的基本思路。但是!有些问题哈,

 36个省份的地级市数据不可能事先导入,,其二,

这里也不能提前写完所有的映射。因此,建立一套城市名称与json文件的映射体系就非常重要的。

常用的方案有:税务机关代码、adcode、名称简称、data数据映射。下面我以 adcode为例,说一下使用,其他的类似的。 

async initParamsCity(adcode) {
      // 如果传了adcode ,则渲染指定 adcode的省份,不然渲染中国地图
      const { data } = await axios.get(`/alljson/${adcode || "100000"}.json`);

      echarts.registerMap("mapJson", { geoJSON: data });

      // 销毁上一次地图实例
      if (this.myChart) this.myChart.dispose();

      this.myChart = echarts.init(this.$refs.map);

      this.myChart.setOption({ geo: [{ map: "mapJson" }] });

      this.myChart.on("click", (params) => {
        // 通过注册的json获取adcode
        console.log(this.getAdocode(data, params.name));
      });
    },

    // 查找 adcode
    getAdocode(list, name) {
      return list.features.find((i) => i.properties.name === name).properties
        .adcode;
    },

动态请求的adcode json文件,

 实现的效果跟上面是一样,这样设计的原理是 所有adcode都是事先定义好的,不需要人为修改。因此,项目中经常会看到类似下图的json文件列表:

10.4 爬虫代码 

通过爬虫实现所有省市县的json数据获取。好了,省市县的联动就讲到这里,代码在https://gitee.com/wfeng0/echarts-map

想要所有省市县的json文件的,可以私信,给大家爬虫代码,执行一下就行了。

爬虫代码在这:Puppeteer 使用教程-实战篇(爬取图片、视频、音频,页面数据)

10.5 地图资源 map json 合集

        我也帮大家已经把省市级的json数据爬取下来了,地址在:

Vue 使用 Apache Echarts 绘制地图(资源篇)-程序员宅基地文章浏览阅读2次。很多小伙伴后台私信我,我想要省市级JSON数据,我已经写了爬虫程序,叫运行下,也搞不定。今天就帮大家把文件爬取下来,免费分享给大家!目前仅是爬取了省市级数据,基本上够用了,我看了下,如果将地级市数据也爬取的话,一共有3238个,在实际的项目中,仅展示地级市的数据好像也没意义,因此这里不做深究,如果实在需要,可以私信,帮大家弄https://blog.csdn.net/weixin_47746452/article/details/137584540?spm=1001.2014.3001.5502puppeteer-demo: Puppeteer 是一个 Node 库,它提供了一个高级 API 来通过 DevTools 协议控制 Chromium 或 Chrome。Puppeteer 默认以 headless 模式运行,但是可以通过修改配置文件运行“有头”模式。无头模式 headless 是否标记无头模式,在创建 browser 是传入配置项实现对浏览器无头模式的控制 - Gitee.comicon-default.png?t=N7T8https://gitee.com/wfeng0/puppeteer-demo/tree/master/map-json

十一. 自定义地图

 DataV.GeoAtlas 使用文档

这里有详细的操作教程。

11.1 选择边界生成器

 (绘制上海海洋大学为例)

 

 缩放到合适的尺寸,使得你需要绘制的在视图中心;

使用左侧多边形工具:(千万不要在绘制过程中移动地图!!不然什么都没有了)

 如果绘制不够完整,一定要先双击结束!!然后缩放微调!!!

使用顶点编辑工具,可以新增点,移动点,使得地图的尺寸更加合适(顶点编辑状态下,可以平移地图、缩放操作):

编辑完成后,得到整个区域地图(仅作为示范,不表示实际面积!!):

 地图是由一个区域一个区域组成的,现在只是一块区域,如何拆分呢?

在原地图上,在画一个区域:

 使用差集实现【差集有两种状态,一个是点一下,编程,然后依次点击差集得面,就是谁减谁,点了两个面后!再点一下,就能实现差集了,两个面就在空间上是一个层次了】:

两个面层叠,很难选择,可以使用下面的属性面板:直接点击即可

 差集后,得到如下结果:

完成差集后,会空出来,在画一个,填补该位置:

 这样就有两个图层了

道路使用线:

以上就是基础的线面的使用(注意,有的不能识别点!!!

导出JSON,在vue中使用:

11.2 vue中使用自定义地图

保存的自定义地图json文件:

 使用:

<script>
import * as echarts from 'echarts';
import userJSON from './json/1.json'
export default {
  name: 'App',
  mounted() {
    // 初始化统计图对象
    var myChart = echarts.init(this.$refs["chartsDOM"]);
    // 显示 loading 动画
    myChart.showLoading();
    // 关闭动画
    myChart.hideLoading();
    // 注册地图(数据放在axios返回对象的data中哦)
    echarts.registerMap('user', userJSON);
    var option = {
      series: [
        {
          name: '自定义地图',
          type: 'map',
          map: 'user',// 这个是上面注册时的名字哦,registerMap('这个名字保持一致')
          label: {
            show: true
          },
        }]
    }
    myChart.setOption(option);

  }
}
</script>

z 不难理解,不解释啦,不懂的可以提问。

得到下图:

 这样两个面全是一样的了,因此,我们需要在json数据中手动配置些选项:

我们先看看json数据:

两个面、两条线,4个features,在每一个properties中添加name属性:

 

 

 两者不再关联。更多细节需要耐心去刻画,大家加油哈哈哈!

好了,本文就到这里吧,点个赞再走嘛~

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_47746452/article/details/125600385

智能推荐

华为WLAN AirEngine 9700S AC控制器如何开启双SSID_华为ac9700s-sweb配置教程-程序员宅基地

文章浏览阅读6.2k次。业务场景:家庭大户型上下2层住宅用户通过WLAN接入网络业务需求:扫地机器人只正常2.4G网络,目前默认2.4G和5G频段合二为一,导致扫地机器人不能正常接收命令上传数据,无法正常使用。目的:5G和2.4G信号都单独显示出,让扫地机器人连上2.4G网络AC版本9700S-SV200R020C00SPC300web配置步骤1.配置向导–无线业务–新建SSIDxx5G生效射频只选1(5G)其他参数和现有ssid一样,保存2.更改原有SSIDxx生效射频只保留0(2.4G)其它不变,保存3_华为ac9700s-sweb配置教程

PeakDo毫米波投屏器Hybrid新玩法-程序员宅基地

文章浏览阅读302次。毫米波在如今的网络通信领域可以称得上是第一梯队的高频词汇,作为5G时代的重要组成部分,毫米波是波长为毫米级的电磁波,通常占据了30~300GHz的网络频段,从速度来看,毫米波甚至要比我国现行5G网络普遍使用的Sub-6 GHz还要更快。不过毫米波对信号条件有着更高要求,这也是为什么如今我们能见到的毫米波实际应用并不多。但在室内良好环境下,毫米波技术仍然具备很大的潜力,替代室内场景的各种屏幕HDMI连接线材,就成了毫米波技术首先盯上的领域。在毫米波60GHz频段有着2.4GHz和5.0GHz W._毫米波投屏

超市出了新的活动:4个空汽水瓶可以换1瓶汽水。小明现在手上有n个空汽水瓶,他最多可以换多少瓶汽水喝?_商店规定每4个空瓶可以换一瓶汽水-程序员宅基地

文章浏览阅读1.5k次。#include<stdio.h>int main(){int n;//初始空瓶数int total;//总共喝到的可乐数int m=0;//上一次喝到的可乐数int t=0;//上一次喝完剩下的空瓶数int i=1;//进入循环结构while(i>0)/循环次数,可以自己定义/{total=0;scanf("%d",&n);m=n/4;t=m+n%4;total+=m;while(t>3){m=t/4;t=m+t%4;total+=m;}_商店规定每4个空瓶可以换一瓶汽水

LoadRunner参数化MySQL-程序员宅基地

文章浏览阅读41次。准备:安装【msql-ODBC驱动】一、配置数据源1、Win7,打开控制面板-系统和安全-管理工具,点击“数据源(ODBC)”.打开数据源(ODBC),在用户DSN选项卡中点击“添加”按钮,弹出“创建新数据源”窗口。点击“添加”,如下图:选中“MYSQLODBC5.2 ANSI Driver”,点击“完成”按钮。配置mysql的IP、用户名与密码,如下..._lr11利用mysql进行参数化设计

WCF初探-19:WCF消息协定-程序员宅基地

文章浏览阅读62次。WCF消息协定概述在生成 WCF应用程序时,开发人员通常会密切关注数据结构和序列化问题,而不必关心携带数据的消息结构。 对于这些应用程序,为参数或返回值创建数据协定的过程很简单。但是,有时完全控制 SOAP 消息的结构与控制其内容一样重要。 当必须提供互操作性或需要在消息或消息部分级别特别控制安全问题时,更是如此。 在这些情况下,您可以创建消息协定 ,使您可以指定所需的精确的 SOA...

L2TP/IPSec一键安装脚本-程序员宅基地

文章浏览阅读101次。本脚本适用环境:系统支持:CentOS6+,Debian7+,Ubuntu12+内存要求:≥128M更新日期:2017 年 05 月 28 日关于本脚本:名词解释如下L2TP(Layer 2 Tunneling Protocol)IPSec(Internet Protocol Security)IKEv2 (Internet Key Exchange v2)能实现 IPsec 的目前总体上有 ..._l2tp/ipsec一键安装脚本

随便推点

softmax_cross_entropy_with_logits与sparse_softmax_cross_entropy_with_logits的区别_softmax_cross_entropy_with_logits_v2 spars_softmax-程序员宅基地

文章浏览阅读4.5k次,点赞2次,收藏4次。softmax_cross_entropy_with_logits与sparse_softmax_cross_entropy_with_logits的区别没有sparse:有sparse:对比代码最近学习了Policy Gradients,里面用到了sparse_softmax_cross_entropy_with_logits,很惊诧这是个what,查询了许多资料,做了一点实验,终于明白,这就..._softmax_cross_entropy_with_logits_v2 spars_softmax_cross_entropy_with_logits

2024年腾讯云免费服务器申请入口,个人和企业均可申请-程序员宅基地

文章浏览阅读337次,点赞5次,收藏8次。腾讯云免费服务器申请入口https://curl.qcloud.com/FJhqoVDP免费服务器可选轻量应用服务器和云服务器CVM,轻量配置可选2核2G3M、2核8G7M和4核8G12M,CVM云服务器可选2核2G3M和2核4G3M配置,腾讯云服务器网txyfwq.com分享2024年最新腾讯云免费服务器申请入口、限制条件

Eclipse中安装Java Swing图形界面开发插件windowbuilder_eclipse中java图形用户界面语言装插件吗-程序员宅基地

文章浏览阅读1.8k次。今天给大家讲解一下,如何在eclipse中安装swing 插件windowbuilder,首先点击打开windowbuilder的官网下载地址,http://www.eclipse.org/windowbuilder/download.php ,打开后会看到有个eclipse的表格,我的eclipse是Oxygen,Oxygen没有发布版本,只有嵌入安装的版本,我就点击Oxygen那一行的link_eclipse中java图形用户界面语言装插件吗

使用tomcat打开html文件,为什么tomcat可以打开html文件,不能打开jsp文件呢?-程序员宅基地

文章浏览阅读6.5w次。慕莱坞6523339https://ditu.so.com/site/k/%E5%B9%BF%E5%B7%9E%E8%87%AA%E5%88%B6%E5%9C%9F%E6%B3%95%E8%BF%B7%E9%A6%99%E8%8D%AF%28%D0%97%D0%97%EF%BC%90%E2%92%907%E2%92%95%E2%92%8E4VX%29%E8%89%B0%E9%85%92%E5%BA..._%e7%be%8e%e5%9b%bd%e8%8a%af%e7%89%87%e5%b7%a8%e5%a4%b4%e4%b8%80%e5%a4%9c

使用delphi 10.2 开发linux 上的webservice-程序员宅基地

文章浏览阅读101次。前几天做了linux下apache的开发,今天做一个linux 下的webservice ,以供客户端调用。闲话少说,直接干。新建一个工程。选other...,选择如图。继续输入服务名然后就生成对应的单元。增加linux 平台。完善对应的单元代码{ Invokable implementation File for Txalion..._使用delphi 10.2 开发web应用

python学习第三个坑-程序员宅基地

文章浏览阅读50次。##########################python 第三章 ################################这一章呢,主要是文件的操作,还有涉及到函数的一部分.PS:整理博客很是费事,这就是我写的笔记,本来在线下挺好看的。拿到这里就成这熊样了,没办法。。。凑活着看吧文件操作:文件操作一般用open,或者用file,格式如下:变量名 = open('文件路径..._python3 wand optimize_layers

推荐文章

热门文章

相关标签