前言
做了一版基于高德地图的3D效果的大屏,由于高德API
地图主题就那么几种,无法按需调整色调以及更换背景图(理论上应该是可行的,通过图层等相关控制),继续换方案,换成使用 ECharts
相关技术栈实现3D地图效果
本文主要整理面向AI和搜索引擎开发过程遇到的一些情况和处理方案,文章中主要提供关键代码和思路介绍,完整代码运行在文末有 GitHub
源码地址
方案实现
引入关键包
3D效果实现主要是加了 echarts-gl
这个包,其他的配置和普通图表类似
js
import * as echarts from "echarts";
import "echarts-gl"; //3D地图插件
引入GeoJSON 文件
这个文件是地图轮廓坐标点,例如我这里用的是北京市朝阳区的街道地图数据
js
import geoJson from "./json/chaoyang_street.json"; //该文件路径改成自己项目中的文件路径即可
提示
高德和一些地图平台提供的一般只到区,例如北京市朝阳区,街道以及更深层的数据需要付费购买,可以通过购买高德的服务,调用接口获得街道数据,或者通过第三方平台购买相关数据
如果只是做一小块区域的效果,想获取相关坐标点,可以访问 geojson.io ,这个里面可以创建
验证数据
关于购买的 GeoJSON 数据或者通过别的格式转换过来的数据,在 geojson.io 里面验证数据是否正常
提示
如果数据格式不正确,会导致渲染异常或失败
构建地图
创建html元素
html
<div class="map" id="mapEchart" style="width:100%;height:calc(100vh - 100px) ;"></div>
地图初始化
使用echarts.registerMap
注册地图,这是地图效果的关键
js
var myChart = echarts.init(document.getElementById("mapEchart"));
// 重点:不要遗漏这句代码!!
echarts.registerMap("chaoyang", geoJson);
其他配置在 option
中进行即可,和 echarts
图表配置几乎一样
3D地图配置
3D地图的配置在 option
中添加 geo3D
配置,在 viewControl
中控制地图的角度,旋转 等动画效果,emphasis
中配置元素块移入的效果,完整配置如下
js
//3D地图配置项
geo3D: {
map: "chaoyang",
roam: true,
itemStyle: {
color: "#007aff",
opacity: 0.8,
borderWidth: 0.4,
borderColor: "#000",
// areaColor: '#fff'
},
viewControl: {
// autoRotate: true,
autoRotate: false, // 关闭自动旋转
autoRotateAfterStill: 3,
distance: 190,// 增加距离值来缩小视图 (原值: 120)
minAlpha: 5, // 上下旋转的最小 alpha 值。即视角能旋转到达最上面的角度。[ default: 5 ]
maxAlpha: 90, // 上下旋转的最大 alpha 值。即视角能旋转到达最下面的角度。[ default: 90 ]
minBeta: -360, // 左右旋转的最小 beta 值。即视角能旋转到达最左的角度。[ default: -80 ]
maxBeta: 360, // 左右旋转的最大 beta 值。即视角能旋转到达最右的角度。[ default: 80 ]
animation: true, // 是否开启动画。[ default: true ]
animationDurationUpdate: 1000, // 过渡动画的时长。[ default: 1000 ]
animationEasingUpdate: "cubicInOut", // 过渡动画的缓动效果。[ default: cubicInOut ]
// alpha: 45, // 调整上下角度,让地图更往上一点 (新增)
// beta: 10, // 左右角度 (新增)
},
emphasis: {
disabled: true, //是否可以被选中
label: {
//移入时的高亮文本
show: true,
color: "#333", //显示字体颜色变淡
// fontSize: 18, //显示字体变大
formatter: function (params) {
// 可以返回任意自定义内容
// return params.name; // 显示区域名称
// 或者
return `${params.name}`; // 自定义格式
}
},
itemStyle: {
color: "#ff7aff", //显示移入的区块变粉色
},
},
label: {
show: false,
position: "top",
color: "#111", //地图初始化区域字体颜色
fontSize: 14,
lineHeight: 16,
},
shading: "lambert",
light: {
//光照阴影
main: {
// color: "#fff", //光照颜色
intensity: 1, //光照强度
//shadowQuality: 'high', //阴影亮度
shadow: true, //是否显示阴影
shadowQuality: "medium", //阴影质量 ultra //阴影亮度
alpha: 55,
beta: 10,
},
ambient: {
intensity: 0.7,
},
},
},
注意!
绑定 map
参数为 echarts.registerMap("chaoyang", geoJson);
中注册的地图
绑定热力图数据块
在具体的业务中,移入街道需要显示对应的数据,这里使用3D柱状图效果显示数值,数据绑定在 series
中,注意 type
类型为 bar3D
js
series: [
//3D柱状图配置项
{
name: "",
type: "bar3D",
coordinateSystem: "geo3D",
barSize: 2,
shading: "lambert",
opacity: 0.1,
bevelSize: 0.2,
label: {
show: false,
formatter: "{a}",
},
data: [
{
name: '和平街街道', value: [116.408795, 39.971735, 100],
}
]
},
],
设置热力图的数据区间色块效果,添加 visualMap
设置
js
//热力图配置项
visualMap: [
{
type: "continuous",
text: ["高", "低"],
show: false, // 隐藏视觉映射组件,但仍然应用其配置
calculable: true,
max: 250,
inRange: {
color: ["#87aa66", "#eba438", "#d94d4c"],
},
},
],
例如,这里添加了一个 和平街街道
的数据,注意 value
中的值,前两个为经纬度坐标,第三个为具体的数据,此时,地图效果就出来了,鼠标移入对应的柱子显示对应的街道数据

初版效果预览

此时3D效果有了,鼠标移入对应区域会变色,并且能显示对应的数据,但是在旋转时会有明显的渲染异常的效果,阴影闪来闪去的,需要优化优化
优化参数,提升流畅度
在初始化 echarts 时添加配置
js
var myChart = echarts.init(document.getElementById("mapEchart"), null, {
devicePixelRatio: window.devicePixelRatio * 0.8, // 降低渲染精度
useDirtyRect: true, // 使用脏矩形渲染优化
});
优化光照设置
调整光照参数以减少渲染复杂度
js
light: {
main: {
intensity: 0.8, // 降低光照强度
shadow: false, // 关闭阴影以提高性能
alpha: 45,
beta: 10,
},
ambient: {
intensity: 0.5, // 调整环境光
},
},
调整 viewControl 设置
优化控制参数,减少渲染压力
js
viewControl: {
animationDurationUpdate: 500, // 减少动画时长
animationEasingUpdate: "linear", // 使用线性动画
damping: 0.8, // 阻尼系数
rotateSensitivity: 1, // 旋转灵敏度
zoomSensitivity: 1, // 缩放灵敏度
panSensitivity: 1, // 平移灵敏度
},
注意!!!
上面的参数优化,我本地测试的这个例子里,在解决鼠标移入或鼠标控制地图旋转时颜色渲染闪烁问题上并不明显,而且调整光影等参数时还会出现把原本设置的地图的颜色效果给影响了,效果变暗,整体感觉更差了 尴尬+1
优化GeoJSON
3D效果渲染,还有一种情况是数据量太大了,导致的效果每次重新渲染时内容太多出现闪烁问题,先看原始数据坐标点

例如某个街道的坐标点行数 1000+, 整个 GeoJSON 文件 2174KB
,明显也太大了, 可以在https://mapshaper.org/
中的 simplfy
简化格式
根据需要简化格式,例如这里设置简化到了 10.8%
,边界的轮廓有细微的变化,相对原始数据效果颗粒度没那么明显了

这是原数据的效果

在简化到 10.8%
后保持基本的轮廓,GeoJSON
文件缩小到了 619KB
,相对原来的 2174KB
的文件体积缩小了两倍多,chaoyang_street.json
是简化后的数据文件, chaoyang_street_origin.json
是原始数据文件

这样缩小后,3D地图的效果明显流畅了很多,鼠标移入和通过鼠标旋转地图不同的街道区域的多边形的颜色也不会那么卡了
优化后效果

代码仓库地址
3D地图代码地址
如果本地运行测试效果,将 Front-end-function-examples
仓库克隆到本地,然后进入 my-project-vue3
项目中,在根目录运行 vue3
项目即可
技术栈版本
- "echarts": "5.5.0",
- "echarts-gl": "^2.0.9",
- "vue": "^3.4.29",
写在最后
关于ECharts 3D Map 可能也有其他的实现方案, 也有其他可优化的空间,欢迎大家评论区讨论交流,一起学习共同进步
如果喜欢本文章或感觉文章有用,动动你那发财的小手点赞、收藏、关注再走呗
^_^
微信公众号:草帽Lufei
