wangyongping

echarts中国及省份合并地图以及阴影的显示

一、写在前面

因为百度echarts不在提供地图,所以需要在一些网站上找一些地图的json数据,所以总结了一些站点;

1:http://datav.aliyun.com/portal/school/atlas/area_selector -------  阿里云地图数据下载

2:https://api.map.baidu.com/lbsapi/getpoint/index.html ------------ 百度坐标拾取系统定位

3:https://pan.baidu.com/s/16A-WG_bufpW3RsWCcMv1VQ ------ 百度网盘下载,是接下来当前项目所用的依赖文件,提取码:d6pw,内容如图

 

二、开发

1.成果图:

       

 

2.业务需求是首先展示中国地图,根据不一样的省份名称,来显示不一样的省份合并地图,如北京、天津,河北三个省市合并的地图,这里需要根据这三个名称生成这个地图。

a.所以首先整理出地图json和对应的名称数组:(引入文件百度网盘下载)

/***
@文件名:provinceMap.js
@来源:Winford.Wang|2021-12-30,17:51
@描述:地图绑定数据数据来源
***/
import beijing from \'@/modules/datacenter/assets/json/geometryProvince/11.json\';
import tianjin from \'@/modules/datacenter/assets/json/geometryProvince/12.json\';
import hebei from \'@/modules/datacenter/assets/json/geometryProvince/13.json\';
import shanxi from \'@/modules/datacenter/assets/json/geometryProvince/14.json\';
import neimenggu from \'@/modules/datacenter/assets/json/geometryProvince/15.json\';
import liaoning from \'@/modules/datacenter/assets/json/geometryProvince/21.json\';
import jilin from \'@/modules/datacenter/assets/json/geometryProvince/22.json\';
import heilongjiang from \'@/modules/datacenter/assets/json/geometryProvince/23.json\';
import shanghai from \'@/modules/datacenter/assets/json/geometryProvince/31.json\';
import jiangsu from \'@/modules/datacenter/assets/json/geometryProvince/32.json\';
import zhejiang from \'@/modules/datacenter/assets/json/geometryProvince/33.json\';
import anhui from \'@/modules/datacenter/assets/json/geometryProvince/34.json\';
import fujian from \'@/modules/datacenter/assets/json/geometryProvince/35.json\';
import jiangxi from \'@/modules/datacenter/assets/json/geometryProvince/36.json\';
import shandong from \'@/modules/datacenter/assets/json/geometryProvince/37.json\';
import henan from \'@/modules/datacenter/assets/json/geometryProvince/41.json\';
import hubei from \'@/modules/datacenter/assets/json/geometryProvince/42.json\';
import hunan from \'@/modules/datacenter/assets/json/geometryProvince/43.json\';
import guangdong from \'@/modules/datacenter/assets/json/geometryProvince/44.json\';
import guangxi from \'@/modules/datacenter/assets/json/geometryProvince/45.json\';
import hainan from \'@/modules/datacenter/assets/json/geometryProvince/46.json\';
import chongqing from \'@/modules/datacenter/assets/json/geometryProvince/50.json\';
import sichuan from \'@/modules/datacenter/assets/json/geometryProvince/51.json\';
import guizhou from \'@/modules/datacenter/assets/json/geometryProvince/52.json\';
import yunnan from \'@/modules/datacenter/assets/json/geometryProvince/53.json\';
import xizang from \'@/modules/datacenter/assets/json/geometryProvince/54.json\';
import shanxisheng from \'@/modules/datacenter/assets/json/geometryProvince/61.json\';
import gansu from \'@/modules/datacenter/assets/json/geometryProvince/62.json\';
import qinghai from \'@/modules/datacenter/assets/json/geometryProvince/63.json\';
import ningxia from \'@/modules/datacenter/assets/json/geometryProvince/64.json\';
import xinjiang from \'@/modules/datacenter/assets/json/geometryProvince/65.json\';
import taiwan from \'@/modules/datacenter/assets/json/geometryProvince/71.json\';
import xianggang from \'@/modules/datacenter/assets/json/geometryProvince/81.json\';
import aomen from \'@/modules/datacenter/assets/json/geometryProvince/82.json\';
// get地图名称
const mapdata = [
  {
    name: \'北京\',
    data: beijing
  },
  {
    name: \'天津\',
    data: tianjin
  },
  {
    name: \'河北\',
    data: hebei
  },
  {
    name: \'山西\',
    data: shanxi
  },
  {
    name: \'内蒙古\',
    data: neimenggu
  },
  {
    name: \'辽宁\',
    data: liaoning
  },
  {
    name: \'吉林\',
    data: jilin
  },
  {
    name: \'黑龙江\',
    data: heilongjiang
  },
  {
    name: \'上海\',
    data: shanghai
  },
  {
    name: \'江苏\',
    data: jiangsu
  },
  {
    name: \'浙江\',
    data: zhejiang
  },
  {
    name: \'安徽\',
    data: anhui
  },
  {
    name: \'福建\',
    data: fujian
  },
  {
    name: \'江西\',
    data: jiangxi
  },
  {
    name: \'山东\',
    data: shandong
  },
  {
    name: \'河南\',
    data: henan
  },
  {
    name: \'湖北\',
    data: hubei
  },
  {
    name: \'湖南\',
    data: hunan
  },
  {
    name: \'广东\',
    data: guangdong
  },
  {
    name: \'广西\',
    data: guangxi
  },
  {
    name: \'海南\',
    data: hainan
  },
  {
    name: \'重庆\',
    data: chongqing
  },
  {
    name: \'四川\',
    data: sichuan
  },
  {
    name: \'贵州\',
    data: guizhou
  },
  {
    name: \'云南\',
    data: yunnan
  },
  {
    name: \'西藏\',
    data: xizang
  },
  {
    name: \'陕西\',
    data: shanxisheng
  },
  {
    name: \'甘肃\',
    data: gansu
  },
  {
    name: \'青海\',
    data: qinghai
  },
  {
    name: \'宁夏\',
    data: ningxia
  },
  {
    name: \'新疆\',
    data: xinjiang
  },
  {
    name: \'台湾\',
    data: taiwan
  },
  {
    name: \'香港\',
    data: xianggang
  },
  {
    name: \'澳门\',
    data: aomen
  }
];

export default mapdata;

 

 

 b.仔细研究这个json数据,不难发现,坐标数据大概结构就是最外层包裹很多子类,最终渲染子类,所以,只要将子类合并,即可出现合并地图。因为业务需求的原因,合成地图的最外层要显示阴影,当我把地图阴影效果加上的时候地图就像长斑了一样,并不是在最外层显示阴影,并且使地图不好看,所以为了解决这个问题,经过测试,是因为地图渲染顺序造成的,地图内的json数组数据,会优先渲染开头的,后面的会覆盖上一层数据,利用这个数据渲染方式,可以优先对数据内的省份进行排序,但不是最佳解决方式。根据数据显示全国的显示各省,各省显示市区,所以当我显示中国地图时候在最上层加上中国地图轮廓,显示省的时时候,在最上层加省的轮廓,得以解决。合并代码如下:

/***
@文件名:mergeProvince.js
@来源:Winford.Wang|2021-12-30,17:52
@描述:返回根据省份名称获取相应的地图数据合并数据
***/

import provinceMap from \'./provinceMap\';
import chinaMapData from \'@/modules/datacenter/assets/json/groupPortal/chinaEchart.json\';

export function getMaoPrivince(names = []) {
  // 容器映射
  let resultMap = {
    type: \'FeatureCollection\',
    features: []
  };
  let oldMapData = [];
  // 非空
  if (names.length === 0) return resultMap;
  // 名字和地图排序添加,
  for (let j = 0; j < names.length; j++) {
    // 将阴影层放在头处,显示时候将在地图最下层
    for (let i = 0; i < chinaMapData.features.length; i++) {
      let item = chinaMapData.features[i];
      if (item.properties.name === names[j]) {
        oldMapData.unshift(item);
        break;
      }
    }
    // 获取相应名字的地图
    for (let i = 0; i < provinceMap.length; i++) {
      if (provinceMap[i].name === names[j]) {
        let objdata = provinceMap[i].data
          ? provinceMap[i].data.features
            ? provinceMap[i].data.features
            : []
          : [];
        oldMapData = oldMapData.concat(objdata);
        break;
      }
    }
  }
  // 新地图
  resultMap.features = oldMapData;
  // 返回
  return resultMap;
}

 

 

c.辅助组件编写完成后,开始写调用方法,就是echarts的option,数据及方法都存在了,那么就是样式了,注意看引用组件的路径

/***
 @文件名:chinaMap.js
 @来源:Winford.Wang|2021-10-20,13:37
 @描述:地图组件应用,设置地图显示等
 ***/
import chinaMapData from \'@/modules/datacenter/assets/json/groupPortal/chinaEchart.json\';
import { getMaoPrivince } from \'@/modules/datacenter/views/groupPortal/gatewayPage/mergeProvince\';
import chinaMapYin from \'@/modules/datacenter/assets/json/groupPortal/china-contour.json\';
// 组件加载
const echarts = require(\'echarts\');
// 样式集合 基础
const styleS = {
  // 基础样式,地图平面样式
  itemRootStyle: {
    normal: {
      borderColor: \'#c1c1c1\',
      borderType: \'dotted\',
      borderWidth: 0.5,
      areaColor: \'#fff\'
    },
    emphasis: {
      areaColor: \'#eceaea\', // 鼠标放上去  省份颜色
      borderWidth: 0.1
    }
  },
  // 阴影样式,立体感添加
  itemStyleQ: {
    normal: {
      shadowBlur: 0,
      shadowColor: \'#f0f0f0\',
      shadowOffsetX: 0,
      shadowOffsetY: 10,
      borderWidth: 0
    }
  },
  // 鼠标放到阴影上的去样式
  itemStyleEmphasis: {
    itemStyle: {
      opacity: 0
    },
    label: {
      color: \'rgba(255,255,255,0)\'
    }
  },
  // china 文字样式
  labelStyle: {
    normal: {
      fontSize: 8,
      show: true,
      textStyle: {
        color: \'#6e6e6e\'
      }
    },
    emphasis: {
      textStyle: {
        color: \'#333333\'
      }
    }
  },
  // 各个区域文字样式
  labelStyleHide: {
    normal: {
      fontSize: 8,
      show: false
    },
    emphasis: {
      show: true,
      textStyle: {
        color: \'#333333\'
      }
    }
  },
  // 点坐标样式
  markPointLabelStyle: {
    show: false,
    emphasis: {
      show: false
    }
  },
  // 弹窗样式
  tooltipStyle: {
    color: \'#333333\',
    fontSize: 10,
    fontWeight: 600
  },
  // 地图最大最小缩放级别
  scaleLimit: {
    min: 0.7,
    max: 3
  }
};
// 弹窗配置
const tooltip = function(mapdata) {
  return {
    backgroundColor: \'rgba(236,236,236,0.85)\',
    textStyle: styleS.tooltipStyle
  };
};
// 中国大地图设置
const chinaMapOption = function(data, mapdata = \'china\') {
  let provinceShodawData;
  // 查找注册地图区域组件
  if (mapdata === \'china\') {
    chinaMapData.features.unshift(chinaMapYin.features[0]);
    // 注册中国地图
    echarts.registerMap(mapdata, chinaMapData);
  } else {
    let names = mapdata.split(\',\');
    // 获取地图数据
    let map = getMaoPrivince(names);
    // 注册省份地图
    echarts.registerMap(mapdata, map);
  }
  // 设置阴影显示,伪立体感觉
  if (mapdata === \'china\') {
    // 阴影 最外围显示阴影
    provinceShodawData = [\'中华人民共和国\'];
  } else {
    // 阴影 最外围显示阴影
    provinceShodawData = mapdata ? mapdata.split(\',\') : [];
  }
  // 阴影和样式结合
  provinceShodawData = provinceShodawData.map(item => {
    return {
      itemStyle: styleS.itemStyleQ,
      emphasis: styleS.itemStyleEmphasis,
      label: {
        show: false
      },
      name: item
    };
  });
  // 引用点
  let markPointData = data ? data : [];
  // 返回设置
  return {
    tooltip: tooltip(mapdata),
    series: [
      {
        type: \'map\',
        map: mapdata,
        zoom: 1.2, //当前视角的缩放比例。
        roam: true, //是否开启鼠标缩放和平移漫游
        scaleLimit: styleS.scaleLimit,
        label: mapdata == \'china\' ? styleS.labelStyle : styleS.labelStyleHide,
        itemStyle: styleS.itemRootStyle,
        markPoint: {
          symbolSize: 18,
          label: styleS.markPointLabelStyle,
          data: markPointData
        },
        data: provinceShodawData
      }
    ]
  };
};

export { chinaMapOption };

 

 

d.接下来直接引用这个方法,传入要生成的地图名字,和点数据,映射到dom上即可,一个地图基本就出现了。

// 中国地图获取方式
let markPointDatas = [
{name:\'dian1\',coord: [longitude, latitude]}
{name:\'dian2\',coord: [经度, 纬度]}
] 
this.chinaData = chinaMapOption(markPointDatas, \'china\');


// 各省地图获取方式
let markPointDatas = [
{name:\'dian1\',coord: [longitude, latitude]}
{name:\'dian2\',coord: [经度, 纬度]}
] 
this.chinaData = chinaMapOption(markPointDatas, \'北京,天津,河北\');

// 基于准备好的dom,初始化echarts实例
this.chartInstance = echarts.init(document.getElementById(this.chartId));
this.chartInstance.setOption(this.chinaData);

 

 

3.根据不一样的需求,最终需要的地图样式也不一样,可根据自己的需要来变更采纳。

三、其它

这里后来又对3d echarts地图进行了一点研究,引入和echarts版本相匹配的echarts-gl,代码如下,仅供参考:

/***
 @文件名:china3DMap.js
 @来源:Winford.Wang|2021-10-20,13:37
 @描述:3d地图组件应用,设置地图显示等
 ***/
import \'echarts-gl\';
import chinaMapData from \'@/modules/datacenter/assets/json/groupPortal/chinaEchart.json\';
import { getMaoPrivince } from \'@/modules/datacenter/views/groupPortal/gatewayPage/mergeProvince\';
// 组件加载
const echarts = require(\'echarts\');
// 弹窗配置
const tooltip = function(data, mapdata) {
  return {
    backgroundColor: \'rgba(236,236,236,0.85)\',
    textStyle: {
      color: \'#333333\',
      fontSize: 10,
      fontWeight: 600
    }
  };
};
// 地图样式显示
const styleMap = {
  label: {
    show: true,
    distance: [0, 0, 0],
    textStyle: {
      fontSize: 8,
      color: \'#6e6e6e\',
      backgroundColor: \'rgba(255,255,255,0)\'
    }
  },
  itemStyle: {
    color: [255, 255, 255, 0.9],
    borderWidth: 0.5,
    borderColor: \'#c1c1c1\'
  },
  emphasis: {
    itemStyle: {
      show: true,
      color: \'rgba(245,245,245,1)\'
    },
    label: {
      show: true,
      distance: 0,
      textStyle: {
        color: \'#333\'
      }
    }
  }
};
// 地图样式显示2
const styleMap2 = {
  label: {
    show: false,
    distance: 0,
    textStyle: {
      fontSize: 8,
      color: \'#6e6e6e\',
      backgroundColor: \'rgba(255,255,255,0)\'
    }
  },
  itemStyle: {
    color: [255, 255, 255, 0.9],
    borderWidth: 0.5,
    borderColor: \'#c1c1c1\'
  },
  emphasis: {
    itemStyle: {
      show: true,
      color: \'#fafafa\'
    },
    label: {
      show: true,
      distance: 0,
      textStyle: {
        color: \'#333\'
      }
    }
  }
};
// 点样式显示
const styleScatter = {
  label: {
    show: false
  },
  emphasis: {
    itemStyle: {
      opacity: 0.9
    },
    label: {
      show: false
    }
  }
};
// 中国大地图设置
const chinaMapOption = function(data, mapdata = \'china\') {
  // 查找注册地图区域组件
  if (mapdata === \'china\') {
    // 注册中国地图
    echarts.registerMap(mapdata, chinaMapData);
  } else {
    let names = mapdata.split(\',\');
    // 获取地图数据
    let map = getMaoPrivince(names);
    // 注册省份地图
    echarts.registerMap(mapdata, map);
  }
  // 返回设置
  return {
    color: [\'#fff\'],
    tooltip: tooltip(data, mapdata),
    geo3D: {
      show: true,
      map: mapdata,
      label: mapdata === \'china\' ? styleMap.label : styleMap2.label,
      itemStyle: styleMap.itemStyle,
      emphasis: styleMap.emphasis,
      shading: \'color\',
      viewControl: {
        rotateSensitivity: 2, // 旋转操作的灵敏度
        zoomSensitivity: 2, // 缩放操作的灵敏度
        // distance: 80, //视角距离主体
        minDistance: 50,
        maxDistance: 300
        // alpha: 30, // 倾斜角度
        // beta: 10 // 旋转角度
      }
    },
    series: []
  };
};

export { chinaMapOption };

 

 

希望对你有帮助

 

分类:

技术点:

相关文章: