三维可视化:使用 ECharts-GL 实现世界级、国家级、省市级 3D 地图

一. 前言

在数据可视化领域,二维地图早已司空见惯,它以直观的方式呈现数据关系,帮助我们理解复杂的信息。然而,在追求更优(高大上)用户体验的今天,传统的二维展示方式已经不满足客户的体验需求,同时平面图表也难以充分展现地理信息的丰富维度和空间关系。于是,三维数据可视化越来越受到广大用户的青睐。

ECharts-GL ,作为 ECharts 家族的一员,更是专为三维数据可视化而生,它不仅继承了 ECharts 的易用性和高性能,还引入了 WebGL 技术,为用户提供了一个强大且直观的工具,用于创建令人惊叹的 3D 地图和数据可视化作品。

本篇文章,你将学习到如何利用 ECharts-GL 构建沉浸式的 3D 地图体验。并学习如何配置和定制地图的部分细节,包括地形、光照、视角 以及纹理的三维表示。

通过本篇文章,你将学习到以下内容:

  • 基础 3D 地图的实现逻辑
  • 丰富 3D 地图的配置项
  • 世界级、国家级、省市区级别 3D 地图展示

本篇文章既是 3D 地图的扫盲篇章,也是开启你从二维地图迈向三维世界的开端,让你从零到一,循序渐进的完整实现各种 3D 地图的渲染!

预览效果图如下图所示:

二. 准备 geoJson 数据

首先,我们需要准备多层级的地图数据,比如世界、国家、省份、城市等各级别的地理数据,以及每个区域对应的数据指标,这些数据通常是以 JSON 格式提供的地理信息数据。同时,确保数据格式符合 ECharts 的要求,可以参考官方文档了解各种地图类型的数据格式。

我们可以在一些其他网站获取最新的 geoJson,比如:我是通过阿里云 DataV 数据可视化平台下载最新的 json 数据文件,以保证目前所有市区的数据都是最新的。

如下图所示,选择数据版本后,点击页面上的下载按钮后即可以下载 json 文件:

也可以使用在线的 JSON API 接口获取数据,API 地址:geo.datav.aliyun.com/areas_v3/bo...

注意:如遇 403 Forbidden 错误,请参考文章巧用 meta 标签,设置 referrer 解决 403 Forbidden 问题

因为后面我会逐步实现世界级、国家级、城市级的 3D 地图,所以在这里我准备了这几个 json 文件,可以通过在线 API 获取:

准备好以上地图数据,接下来我们继续进行,最终实现世界地图,中国地图,山东省地图,青岛市地图等 3D 地图展示。

三. 初步实现 3D 地图

以中国地图 - 3D 地图的实现为例,接下来我们一步一步进行从零到一逐步丰富地图的显示

1. 加载 geoJson 数据

js 复制代码
const geoJson = "获取的的中国地图json";
const myChart = echarts.init(document.getElementById("main"));
// 注册地图名字(china)和数据(geoJson)
echarts.registerMap("china", geoJson);
// 图表配置项
const option = {
  series: [
    {
      type: "map3D",
      map: "china",
    },
  ],
};
// 设置图表实例的配置项以及数据
myChart.setOption(option);

通过以上最基础的代码,就可以渲染出最基础的 3D 中国地图,如下图所示:

2. 设置地图的颜色

itemStyle 主要用来设置三维地图中三维图形的视觉属性,包括颜色,透明度,描边等。

js 复制代码
const option = {
  series: [
    {
      type: "map3D",
      map: "china",
      // 地图的颜色
      itemStyle: {
        color: "#286ECA", // 地图板块的颜色
        opacity: 1, // 图形的不透明度 [ default: 1 ]
        borderWidth: 0.5, // (地图板块间的分隔线)图形描边的宽度。加上描边后可以更清晰的区分每个区域
        borderColor: "#286ECA", // 图形描边的颜色。[ default: #333 ]
      },
    },
  ],
};

3. 设置标签显示

label 主要用来配置地图上的城市名称是否显示标签,同时对标签的显示格式、显示样式进行配置

js 复制代码
const option = {
  series: [
    {
      type: "map3D",
      map: "china",
      // 标签的相关设置
      label: {
        show: true, // (地图上的城市名称)是否显示标签
        distance: 5,
        formatter: function (params) {
          return params.name ? params.name : " ";
        },
        textStyle: {
          // 标签的字体样式
          color: "#fff", // 地图初始化区域字体颜色
          fontSize: 8, // 字体大小
        },
      },
    },
  ],
};

4. 设置鼠标 hover 高亮效果

emphasis 主要用来设置鼠标 hover 高亮时图形和标签的样式 (当鼠标放上去时 label 和 itemStyle 的样式)

js 复制代码
const option = {
  series: [
    {
      type: "map3D",
      map: "china",
      // 鼠标 hover 高亮时图形和标签的样式
      emphasis: {
        label: {
          // label 高亮时的配置
          show: true,
          textStyle: {
            color: "#fff", // 高亮时标签颜色变为 白色
            fontSize: 15, // 高亮时标签字体 变大
          },
        },
        itemStyle: {
          // itemStyle 高亮时的配置
          color: "#66ffff", // 高亮时地图板块颜色改变
        },
      },
    },
  ],
};

5. 设置 tootip

tooltip 为提示框组件,它的设置属于 ECharts 的基础配置项,提示框组件可以设置在多种地方,主要作用为当鼠标鼠标悬浮到地图上时,提示框浮层的显示效果,详细配置参考文档:ECharts tooltip

js 复制代码
const option = {
  tooltip: {
    trigger: "item",
    position: "inside",
    formatter: "{b}",
    backgroundColor: "rgba(50, 50, 50, 0.7)",
    textStyle: {
      color: "#FFFFFF",
      textalign: "center",
      fontSize: "12px",
    },
  },
  series: [
    {
      type: "map3D",
      map: "china",
    },
  ],
};

四. 丰富 3D 地图的配置

1. 环境贴图

环境贴图 environment 主要支持 3 种配置方式,支持纯颜色值,渐变色,全景贴图的 url。默认为 'auto'

简单说:环境贴图可以看作是地图的底层背景。

  • 配置为全景贴图
    • environment: 'asset/environment.png'
  • 配置为纯黑色的背景
    • environment: '#000'
  • 配置为垂直渐变的背景
    • 通过 new echarts.graphic.LinearGradient 来配置

注意:在配置有 light.ambientCubemap.texture 的时候会使用该纹理作为环境贴图。否则不显示环境贴图。

在这里,我们使用垂直渐变的背景色来配置

js 复制代码
const option = {
  series: [
    {
      type: "map3D",
      map: "china",
      // 环境贴图,支持純颜色值,渐变色,全景贴图的 url。默认为 'auto'
      environment: new echarts.graphic.LinearGradient(
        0,
        0,
        0,
        1,
        [
          {
            // 配置为垂直渐变的背景
            offset: 0,
            color: "#183890", // 天空颜色
          },
          {
            offset: 0.7,
            color: "#040829", // 地面颜色
          },
          {
            offset: 1,
            color: "#040829", // 地面颜色
          },
        ],
        false
      ),
    },
  ],
};

2. 设置地面

groundPlane 主要用来配置地面,可以让整个组件有个"摆放"的地方,从而使整个场景看起来更真实,更有模型感。

js 复制代码
const option = {
  series: [
    {
      type: "map3D",
      map: "china",
      // 地面可以使整个场景看起来更真实,更有模型感。
      groundPlane: {
        show: true, // 是否显示地面
        color: "#aaa", // 地面颜色
      },
    },
  ],
};

3. 设置光照

light 主要用来配置关照,主要有:场景主光源、全局环境光等,合理的光照设置能够让整个场景的明暗变得更丰富,更有层次。

js 复制代码
const option = {
  series: [
    {
      type: "map3D",
      map: "china",
      // 光照相关的设置
      light: {
        main: {
          // 场景主光源的设置,在 globe 组件中就是太阳光。
          color: "#3D94CE", // 主光源的颜色。
          intensity: 1.2, // 主光源的强度。
          shadow: false, // 主光源是否投射阴影。默认关闭。开启阴影可以给场景带来更真实和有层次的光照效果。会增加程序的运行开销。
          shadowQuality: "high", // 阴影的质量。可选'low', 'medium', 'high', 'ultra'
          alpha: 55, // 主光源绕 x 轴,即上下旋转的角度。配合 beta 控制光源的方向。
          beta: 10, // 主光源绕 y 轴,即左右旋转的角度。
        },
        ambient: {
          // 全局的环境光设置。
          color: "red", // 环境光的颜色。[ default: #fff ]
          intensity: 0.5, // 环境光的强度。[ default: 0.2 ]
        },
      },
    },
  ],
};

注意:在 shading 为 'color' 的时候无效。 光照的设置会影响到组件以及组件所在坐标系上的所有图表。

4. 设置视角控制

viewControl 的配置主要用于鼠标的旋转,缩放等视角控制。

js 复制代码
const option = {
  series: [
    {
      type: "map3D",
      map: "china",
      viewControl: {
        projection: "perspective", // 投影方式
        autoRotate: true, // 是否开启视角绕物体的自动旋转查看
        autoRotateDirection: "cw", // 物体自传的方向。默认是 'cw',也可以取 'ccw'
        autoRotateSpeed: 10, // 物体自传的速度。角度 / 秒
        autoRotateAfterStill: 3, // 在鼠标静止操作后恢复自动旋转的时间间隔
        damping: 0, // 鼠标进行旋转,缩放等操作时的迟滞因子
        distance: 120, // 默认视角距离主体的距离
        alpha: 40, // 视角绕 x 轴,即上下旋转的角度
        beta: 0, // 视角绕 y 轴,即左右旋转的角度
        center: [0, 0, 0], // 视角中心点
        animation: true, // 是否开启动画
        animationDurationUpdate: 1000, // 过渡动画的时长
        animationEasingUpdate: "cubicInOut", // 过渡动画的缓动效果
      },
    },
  ],
};

以上代码设置了开启了自动旋转,如下图所示:

5. 设置纹理

在使用 echarts-gl 绘制 3D 地图时,为了增强地图的真实感,你可以设置纹理和光照效果。同时配合 lightpostEffect 使用可以让展示的画面效果和质感有质的提升。

下面我们具体来看一下简单示例:

js 复制代码
const option = {
  series: [
    {
      type: "map3D",
      map: "china",
      // 三维图形的着色效果
      shading: "realistic",
      // 真实感材质相关的配置项
      realisticMaterial: {
        detailTexture: "./img/texture.png", // 纹理图片
        textureTiling: 1,
      },
      // 后处理特效
      postEffect: {
        enable: true,
        SSAO: {
          enable: true,
          radius: 1,
          intensity: 1,
          quality: "high",
        },
        bloom: {
          enable: true,
          strength: 0.5,
          radius: 0,
          threshold: 0,
        },
        FXAA: {
          enable: true,
          alpha: 0.5,
        },
      },
      // 光照设置
      light: {
        main: {
          color: "#3D94CE",
          intensity: 1.2,
          shadow: false,
          shadowQuality: "high",
          alpha: 55,
          beta: 10,
        },
        ambient: {
          color: "#fff",
          intensity: 0.5,
        },
      },
    },
  ],
};

五. 显示不同级别的 3D 地图

通过上面的配置,地图的渲染效果已经逐渐有了效果还算不错的 3D 雏形,如果后续我们想要更好的视觉效果,可以参考官方文档配置项,一步步开发更加震撼的 3D 效果。

有了以上的配置项之后,接下来我们看一下如何进行渲染不同级别的地图,主要原理在于:根据不同的 geoJson 渲染不同的地图模型即可。

1. 世界级别

加载世界级的 geoJson 即可展示 3D 世界地图

2. 国家级别

加载国家级的 geoJson 即可展示 3D 国家版地图,例如:中国地图

3. 省份级别

加载省份级的 geoJson 即可展示 3D 省份地图,例如:山东省地图

4. 市区级别

加载市区级的 geoJson 即可展示 3D 市区地图,例如:青岛市地图

省级和城市级地图可能需要额外的处理,例如缩放和定位,以确保地图在 3D 视图中正确显示。此外,由于 echarts-gl 的设计,一些地图数据可能需要额外的调整才能在 3D 模式下正确渲染。

请注意:每个地图的 map 属性应该匹配你注册的地图数据的名称,如果你自己创建了地图数据并注册到 ECharts,那么 map 的值应该是你注册时所使用的名称。

最终预览效果图如下图所示:

六. 总结

通过本篇文章的介绍,相信我们大家都掌握了如何使用 ECharts 和 ECharts-GL 来构建世界级、国家级以及省市级的 3D 地图,更重要的是,本篇文章也是开启你从二维地图迈向三维世界的开端,让你从零到一,循序渐进的完整实现各种 3D 地图的渲染!

ECharts-GL 不仅提供了强大的 3D 渲染引擎,还支持高度定制化的地图样式和动态交互,使得数据可视化不再局限于图表和表格,因此在接下来的文章中,我将继续探索 ECharts-GL 在 3D 可视化大屏中的的应用,敬请关注!

七. 参考文档

八. 系列文章

关于 ECharts 的系列文章,感兴趣的朋友们可以查看以下文章进行了解:

本文正在参加金石计划征文活动,如果本文对您有帮助,麻烦点点收藏,点点赞!感谢

相关推荐
Envyᥫᩣ2 分钟前
《ASP.NET Web Forms 实现视频点赞功能的完整示例》
前端·asp.net·音视频·视频点赞
bin91534 小时前
【EXCEL数据处理】000010 案列 EXCEL文本型和常规型转换。使用的软件是微软的Excel操作的。处理数据的目的是让数据更直观的显示出来,方便查看。
大数据·数据库·信息可视化·数据挖掘·数据分析·excel·数据可视化
Мартин.4 小时前
[Meachines] [Easy] Sea WonderCMS-XSS-RCE+System Monitor 命令注入
前端·xss
昨天;明天。今天。5 小时前
案例-表白墙简单实现
前端·javascript·css
数云界5 小时前
如何在 DAX 中计算多个周期的移动平均线
java·服务器·前端
风清扬_jd5 小时前
Chromium 如何定义一个chrome.settingsPrivate接口给前端调用c++
前端·c++·chrome
安冬的码畜日常5 小时前
【玩转 JS 函数式编程_006】2.2 小试牛刀:用函数式编程(FP)实现事件只触发一次
开发语言·前端·javascript·函数式编程·tdd·fp·jasmine
ChinaDragonDreamer5 小时前
Vite:为什么选 Vite
前端
小御姐@stella6 小时前
Vue 之组件插槽Slot用法(组件间通信一种方式)
前端·javascript·vue.js
GISer_Jing6 小时前
【React】增量传输与渲染
前端·javascript·面试