Vue使用echarts渲染地图并根据地区编码展示区域地图

1 功能介绍

  • 默认展示主地图,点击某个省市区根据地区编码展示对应的省市区地图,当匹配不到对应的省市区编码则展示主地图。
  • 根据地理位置坐标加标记。
    最终效果图
  • 点击省市区展示省市区地图
    省市区效果
  • 如果觉得地名位置歪/想让省市区位置在区域中心位置,则需下载地图JSON地图文件进行手动修改(一般名字的位置为省会坐标点),具体修改会在 --- 2.3创建echarts地图 --- 区域写到,因为现在写好像并不清楚到底在写什么。

2 功能实现

2.1 下载所需NPM
npm i axios

npm i echarts
2.2 引入所需配置文件与初始化
2.2.1编码JSON数据项(由于数据量过大,有需要麻烦移步下面文章获取)

省市区编码JSON数据

2.2.2 初始化
<template>
  <div>
    <div id="echatsMap" style="width: 100%; height: 800px"></div>
  </div>
</template>

<script>
import * as echarts from "echarts";
import axios from "axios";
import { cityCode } from "@/components/cityCode.js";
export default {
  name: "echatsMap",
  components: {},
  data() {
    return {
      cityCode: cityCode,
      myChart: "",
      distributionOptions: "",
    };
  },
  mounted() {},
  methods: {},
};
</script>
2.3 创建echarts地图
2.3.1 上面有提到省市区名字可能不在中心位置,可以按以下操作:
  • 点击红框里的下载,就会得到一份本地的JSON文件,2.3.2的代码块为动态获取方式,将本地的JSON地图文件进行修改即可,示例:
// 此处只举例子
      // 直接在下载的文件里搜甘肃省 --- 这样是默认的
      "properties": {
        "adcode": 620000,
        "name": "甘肃省",
        "center": [
          103.823557,
          36.058039
        ],
        "childrenNum": 14,
        "level": "province",
        "parent": {
          "adcode": 100000
        },
        "subFeatureIndex": 27,
        "acroutes": [
          100000
        ]
      },
      // 在里面加上  用来改变文字展示坐标点
        "cp": [
          103.823557,
          36.058039
        ],
      // 修改后--
      "properties": {
        "adcode": 620000,
        "name": "甘肃省",
        "center": [
          103.823557,
          36.058039
        ],
        "cp": [
          103.823557,
          36.058039
        ],
        "childrenNum": 14,
        "level": "province",
        "parent": {
          "adcode": 100000
        },
        "subFeatureIndex": 27,
        "acroutes": [
          100000
        ]
      },
  • 修改后就不能用动态获取了,需要存放到本地,让其使用本地的文件示例如下(具体改哪来,):
// 初始化地图数据
    init() {
      // 主地图的JSON文件下载
      let path =  require('../../../../../public/mapJson/china.json');
        echarts.registerMap("china", path );
        this.changeOptions("china");
        this.myChart = echarts.init(document.querySelector("#echatsMap"));
        this.myChart.setOption(this.distributionOptions)
      window.onresize = function () {
        if (this.myChart) this.myChart.resize();
      };
    },
2.3.2 代码实现
<template>
  <div>
    <div id="echatsMap" style="width: 100%; height: 800px"></div>
  </div>
</template>

<script>
import * as echarts from "echarts";
import axios from "axios";
import { cityCode } from "@/components/cityCode.js";
export default {
  name: "echatsMap",
  components: {},
  data() {
    return {
      cityCode: cityCode,
      myChart: "",
      distributionOptions: "",
    };
  },
  mounted() {
    this.$nextTick(() => {
      this.init();
    });
  },
  methods: {
    // 初始化地图数据
    init() {
      // 主地图的JSON文件下载
      let path = `https://geo.datav.aliyun.com/areas_v3/bound/100000_full.json`;
      axios.get(path).then((res) => {
        echarts.registerMap("china", res.data);
        this.changeOptions("china");
        this.myChart = echarts.init(document.querySelector("#echatsMap"));
        this.myChart.setOption(this.distributionOptions)
      });
      window.onresize = function () {
        if (this.myChart) this.myChart.resize();
      };
    },
    // echarts 配置项
    changeOptions(name) {
      // 经纬度数据
      const seriesList = [
        {
          data: [{ value: [106.9, 27.7] }, { value: [105.29, 27.32] }],
        },
      ];
      // 图标
      const series = seriesList.map((v) => {
        return {
          type: "scatter", //配置显示方式为用户自定义
          coordinateSystem: "geo",
          data: v.data,
          // 自定义图标的样式  支持svg与bse64
          symbol: function (params, key) {
            return "image://" + require("@/assets/logo.png");
          },
          symbolSize: 16,
        };
      });

      // options
      this.distributionOptions = {
        tooltip: {
          // 提示框组件
          show: true, // 显示提示框组件
          trigger: "item", // 触发类型
          triggerOn: "mousemove", // 触发条件
          formatter: "名称:{b}<br/>坐标:{c}",
        },
        series, // 数据
        geo: {
          map: name || "china", // 引入地图 省份或者 国家
          layoutCenter: ["50%", "50%"], //设置后left/right/top/bottom等属性无效
          layoutSize: "45%",
          roam: true, //开启鼠标缩放
          zoom: 2,
          label: {
            normal: {
              //静态的时候展示样式
              show: true, //是否显示地图省份得名称
              textStyle: {
                color: "#fff",
                fontSize: 10,
                fontFamily: "Arial",
              },
            },
            emphasis: {
              // 高亮状态下的样式
              //动态展示的样式
              color: "#fff",
            },
          },
          itemStyle: {
            // 地图区域的多边形 图形样式。
            normal: {
              borderColor: "#fff", // 边框颜色
              areaColor: "#1c2f59", //  区域颜色
              // areaColor: { // 使用背景图片
              //   type: "pattern",
              //   image: require("@/assets/texture.jpeg"), // 使用自己本地图片路径
              //   repeat: "repeat", //可选值repeat、no-repeat、repeat-x、repeat-y
              // },
              textStyle: {
                // 文字颜色
                color: "#fff",
              },
              // shadowBlur: 10, // 图形阴影的模糊大小
              // shadowOffsetX: 10, // 阴影水平方向上的偏移距离。
            },
            emphasis: {
              areaColor: "#1c2f59",
              color: "#fff",
            },
          },
          regions: [
            //对不同的区块进行着色
            // {
            //   name: "河南省", //区块名称
            //   itemStyle: {
            //     normal: {
            //       areaColor: "#281fe1",
            //     },
            //   },
            // },
            // {
            //   name: "浙江省", //区块名称
            //   itemStyle: {
            //     normal: {
            //       areaColor: "#193094",
            //     },
            //   },
            // },
          ],
        },
      };
    },
  },
};
</script>
2.4 点击地图省市区展示省市区地图
  • 大概就是点击省市区时根据名称与编码文件去匹配,把匹配到的编码通过外部接口去获取想要的省市区JSON地图数据。再次渲染echarts即可。
  • 注意:如果没匹配到需跳主地图/获取不到此区域的JSON地图数据。
<template>
  <div>
    <div id="echatsMap" style="width: 100%; height: 800px"></div>
  </div>
</template>

<script>
import * as echarts from "echarts";
import axios from "axios";
import { cityCode } from "@/components/cityCode.js";
export default {
  name: "echatsMap",
  components: {},
  data() {
    return {
      cityCode: cityCode,
      myChart: "",
      distributionOptions: "",
    };
  },
  mounted() {
    this.$nextTick(() => {
      this.init();
    });
  },
  methods: {
    // 初始化地图数据
    init() {
      // 主地图的JSON文件下载
      let path = `https://geo.datav.aliyun.com/areas_v3/bound/100000_full.json`;
      axios.get(path).then((res) => {
        echarts.registerMap("china", res.data);
        this.changeOptions("china");
        this.myChart = echarts.init(document.querySelector("#echatsMap"));
        this.myChart.setOption(this.distributionOptions);
        // 点击省份子区域的时候可以切换到省份地图
        this.myChart.on("click", (chinaParam) => {
          // 如果没有下层则展示主地图
          if (!this.cityCode) {
            this.cityCode = cityCode;
            // 100000 主地图
            this.getProvinceMapOpt(100000, "")
            return;
          }
          // 根据点击位置地图名字去跟编码数据匹配
          let code = this.cityCode.find(
            (x) => chinaParam.name.indexOf(x ? x.name : "") !== -1
          );
          // 找到正确的编码   去获取对应的地图数据
          // 将该省市区的下级放入 -- 如果接口支持根据编码查询省市区所有下级子级就不需要这么写
          if (code) {
            this.cityCode = code.city;
            this.getProvinceMapOpt(Number(code.adcode), chinaParam.name);
          } else {
            // 没有对应的编码跳主地图
            this.cityCode = cityCode;
            // 100000 主地图
            this.getProvinceMapOpt(100000, "");
          }
        });
      });
      window.onresize = function () {
        if (this.myChart) this.myChart.resize();
      };
    },
    // 下载/显示各省地图
    getProvinceMapOpt(provinceAlphabet, name) {
      // 根据地区编码获取所在地区的JSON地图
      let path = `https://geo.datav.aliyun.com/areas_v3/bound/${provinceAlphabet}_full.json`;
      if (provinceAlphabet === 100000) {
        path = "/mapJson/china.json";
      }
      axios.get(path).then((res) => {
        // 获取完最新的JSON地图数据后,重新渲染
        echarts.registerMap(name, res.data);
        this.changeOptions(name);
        this.myChart.setOption(this.distributionOptions, true);
      });
    },
    // echarts 配置项
    changeOptions(name) {
      // 经纬度数据  --- 不存在的经纬度不会展示出来
      const seriesList = [
        {
          data: [{ value: [106.9, 27.7] }, { value: [105.29, 27.32] }],
        },
      ];
      // 图标
      const series = seriesList.map((v) => {
        return {
          type: "scatter", //配置显示方式为用户自定义
          coordinateSystem: "geo",
          data: v.data,
          // 自定义图标的样式  支持svg与bse64
          symbol: function (params, key) {
            return "image://" + require("@/assets/logo.png");
          },
          symbolSize: 16,
        };
      });

      // options
      this.distributionOptions = {
        tooltip: {
          // 提示框组件
          show: true, // 显示提示框组件
          trigger: "item", // 触发类型
          triggerOn: "mousemove", // 触发条件
          formatter: "名称:{b}<br/>坐标:{c}",
        },
        series, // 数据
        geo: {
          map: name || "china", // 引入地图 省份或者 国家
          layoutCenter: ["50%", "50%"], //设置后left/right/top/bottom等属性无效
          layoutSize: "45%",
          roam: true, //开启鼠标缩放
          zoom: 2,
          label: {
            normal: {
              //静态的时候展示样式
              show: true, //是否显示地图省份得名称
              textStyle: {
                color: "#fff",
                fontSize: 10,
                fontFamily: "Arial",
              },
            },
            emphasis: {
              // 高亮状态下的样式
              //动态展示的样式
              color: "#fff",
            },
          },
          itemStyle: {
            // 地图区域的多边形 图形样式。
            normal: {
              borderColor: "#fff", // 边框颜色
              areaColor: "#1c2f59", //  区域颜色
              textStyle: {
                // 文字颜色
                color: "#fff",
              },
              // shadowBlur: 10, // 图形阴影的模糊大小
              // shadowOffsetX: 10, // 阴影水平方向上的偏移距离。
            },
            emphasis: {
              areaColor: "#1c2f59",
              color: "#fff",
            },
          },
          regions: [
            //对不同的区块进行着色
            // {
            //   name: "河南省", //区块名称
            //   itemStyle: {
            //     normal: {
            //       areaColor: "#281fe1",
            //     },
            //   },
            // },
            // {
            //   name: "浙江省", //区块名称
            //   itemStyle: {
            //     normal: {
            //       areaColor: "#193094",
            //     },
            //   },
            // },
          ],
        },
      };
    },
  },
};
</script>

3 完整代码

<template>
  <div>
    <div id="echatsMap" style="width: 100%; height: 800px"></div>
  </div>
</template>

<script>
import * as echarts from "echarts";
import axios from "axios";
import { cityCode } from "@/components/cityCode.js";
export default {
  name: "echatsMap",
  components: {},
  data() {
    return {
      cityCode: cityCode,
      myChart: "",
      distributionOptions: "",
    };
  },
  mounted() {
    this.$nextTick(() => {
      this.init();
    });
  },
  methods: {
    // 初始化地图数据
    init() {
      // 主地图的JSON文件下载
      let path = `https://geo.datav.aliyun.com/areas_v3/bound/100000_full.json`;
      axios.get(path).then((res) => {
        echarts.registerMap("china", res.data);
        this.changeOptions("china");
        this.myChart = echarts.init(document.querySelector("#echatsMap"));
        this.myChart.setOption(this.distributionOptions);
        // 点击省份子区域的时候可以切换到省份地图
        this.myChart.on("click", (chinaParam) => {
          // 如果没有下层则展示主地图
          if (!this.cityCode) {
            this.cityCode = cityCode;
            // 100000 主地图
            this.getProvinceMapOpt(100000, "")
            return;
          }
          // 根据点击位置地图名字去跟编码数据匹配
          let code = this.cityCode.find(
            (x) => chinaParam.name.indexOf(x ? x.name : "") !== -1
          );
          // 找到正确的编码   去获取对应的地图数据
          // 将该省市区的下级放入 -- 如果接口支持根据编码查询省市区所有下级子级就不需要这么写
          if (code) {
            this.cityCode = code.city;
            this.getProvinceMapOpt(Number(code.adcode), chinaParam.name);
          } else {
            // 没有对应的编码跳主地图
            this.cityCode = cityCode;
            // 100000 主地图
            this.getProvinceMapOpt(100000, "");
          }
        });
      });
      window.onresize = function () {
        if (this.myChart) this.myChart.resize();
      };
    },
    // 下载/显示各省地图
    getProvinceMapOpt(provinceAlphabet, name) {
      // 根据地区编码获取所在地区的JSON地图
      let path = `https://geo.datav.aliyun.com/areas_v3/bound/${provinceAlphabet}_full.json`;
      if (provinceAlphabet === 100000) {
        path = "/mapJson/china.json";
      }
      axios.get(path).then((res) => {
        // 获取完最新的JSON地图数据后,重新渲染
        echarts.registerMap(name, res.data);
        this.changeOptions(name);
        this.myChart.setOption(this.distributionOptions, true);
      });
    },
    // echarts 配置项
    changeOptions(name) {
      // 经纬度数据  --- 不存在的经纬度不会展示出来
      const seriesList = [
        {
          data: [{ value: [106.9, 27.7] }, { value: [105.29, 27.32] }],
        },
      ];
      // 图标
      const series = seriesList.map((v) => {
        return {
          type: "scatter", //配置显示方式为用户自定义
          coordinateSystem: "geo",
          data: v.data,
          // 自定义图标的样式  支持svg与bse64
          symbol: function (params, key) {
            return "image://" + require("@/assets/logo.png");
          },
          symbolSize: 16,
        };
      });

      // options
      this.distributionOptions = {
        tooltip: {
          // 提示框组件
          show: true, // 显示提示框组件
          trigger: "item", // 触发类型
          triggerOn: "mousemove", // 触发条件
          formatter: "名称:{b}<br/>坐标:{c}",
        },
        series, // 数据
        geo: {
          map: name || "china", // 引入地图 省份或者 国家
          layoutCenter: ["50%", "50%"], //设置后left/right/top/bottom等属性无效
          layoutSize: "45%",
          roam: true, //开启鼠标缩放
          zoom: 2,
          label: {
            normal: {
              //静态的时候展示样式
              show: true, //是否显示地图省份得名称
              textStyle: {
                color: "#fff",
                fontSize: 10,
                fontFamily: "Arial",
              },
            },
            emphasis: {
              // 高亮状态下的样式
              //动态展示的样式
              color: "#fff",
            },
          },
          itemStyle: {
            // 地图区域的多边形 图形样式。
            normal: {
              borderColor: "#fff", // 边框颜色
              areaColor: "#1c2f59", //  区域颜色
              textStyle: {
                // 文字颜色
                color: "#fff",
              },
              // shadowBlur: 10, // 图形阴影的模糊大小
              // shadowOffsetX: 10, // 阴影水平方向上的偏移距离。
            },
            emphasis: {
              areaColor: "#1c2f59",
              color: "#fff",
            },
          },
          regions: [
            //对不同的区块进行着色
            // {
            //   name: "河南省", //区块名称
            //   itemStyle: {
            //     normal: {
            //       areaColor: "#281fe1",
            //     },
            //   },
            // },
            // {
            //   name: "浙江省", //区块名称
            //   itemStyle: {
            //     normal: {
            //       areaColor: "#193094",
            //     },
            //   },
            // },
          ],
        },
      };
    },
  },
};
</script>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值