vue+cesium示例:3D热力图(附源码下载)

接到一位知识星友的邀请,随机模拟三维数据点,结合heatmap.js实现基于cesium+vue的3D热力图需求,适合学习Cesium与前端框架结合开发3D可视化项目。

demo源码运行环境以及配置

运行环境:依赖Node安装环境,demo本地Node版本:推荐v18+。

运行工具:vscode或者其他工具。

配置方式:下载demo源码,vscode打开,然后顺序执行以下命令:

(1)下载demo环境依赖包命令:npm install

(2)启动demo命令:npm run dev

(3)打包demo命令: npm run build

技术栈

Vue 3.5.13

Vite 6.2.0

Cesium 1.128.0

示例效果

核心源码

javascript 复制代码
<template>
  <div id="cesiumContainer" class="cesium-container">
  </div>
</template>
<script setup>
import { onMounted, onUnmounted, ref } from 'vue';
import * as Cesium from 'cesium';
Cesium.Ion.defaultAccessToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiIxZjhjYjhkYS1jMzA1LTQ1MTEtYWE1Mi0zODc5NDljOGVkMDYiLCJpZCI6MTAzNjEsInNjb3BlcyI6WyJhc2wiLCJhc3IiLCJhc3ciLCJnYyJdLCJpYXQiOjE1NzA2MDY5ODV9.X7tj92tunUvx6PkDpj3LFsMVBs_SBYyKbIL_G9xKESA';
// 声明Cesium Viewer实例
let viewer = null;
// 组件挂载后初始化Cesium
onMounted(async () => {
  const files = [
    "./heatmap/heatmap.js"
  ];
  loadScripts(files, function () {
    console.log("All scripts loaded");
    initMap();
  });
});
const loadScripts = (files, callback) => {
  // Make Cesium available globally for the scripts
  // window.Cesium = Cesium;
  if (files.length === 0) {
    callback();
    return;
  }
  const file = files.shift();
  const script = document.createElement("script");
  script.onload = function () {
    loadScripts(files, callback);
  };
  script.src = file;
  document.head.appendChild(script);
};
const initMap = async () => {
  // 初始化Cesium Viewer
  viewer = new Cesium.Viewer('cesiumContainer', {
    // 基础配置
    animation: false, // 动画小部件
    baseLayerPicker: false, // 底图选择器
    fullscreenButton: false, // 全屏按钮
    vrButton: false, // VR按钮
    geocoder: false, // 地理编码搜索框
    homeButton: false, // 主页按钮
    infoBox: false, // 信息框 - 禁用点击弹窗
    sceneModePicker: false, // 场景模式选择器
    selectionIndicator: false, // 选择指示器
    timeline: false, // 时间轴
    navigationHelpButton: false, // 导航帮助按钮
    navigationInstructionsInitiallyVisible: false, // 导航说明初始可见性
    scene3DOnly: false, // 仅3D场景
    terrain: Cesium.Terrain.fromWorldTerrain(), // 使用世界地形
  });
  // 隐藏logo
  viewer.cesiumWidget.creditContainer.style.display = "none";
  viewer.scene.globe.enableLighting = true;
  // 禁用大气层和太阳
  viewer.scene.skyAtmosphere.show = false;
  //前提先把场景上的图层全部移除或者隐藏 
  // viewer.scene.globe.baseColor = Cesium.Color.BLACK; //修改地图蓝色背景
  viewer.scene.globe.baseColor = new Cesium.Color(0.0, 0.1, 0.2, 1.0); //修改地图为暗蓝色背景
  // 设置抗锯齿
  viewer.scene.postProcessStages.fxaa.enabled = true;
  // 清除默认底图
  viewer.imageryLayers.remove(viewer.imageryLayers.get(0));
  // 加载底图 - 使用更暗的地图服务
  const imageryProvider = await Cesium.ArcGisMapServerImageryProvider.fromUrl("https://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer");
  viewer.imageryLayers.addImageryProvider(imageryProvider);
  // 设置默认视图位置 - 默认显示全球视图
  // viewer.camera.setView({
  //   destination: Cesium.Cartesian3.fromDegrees(104.0, 30.0, 10000000.0), // 中国中部上空
  //   orientation: {
  //     heading: 0.0,
  //     pitch: -Cesium.Math.PI_OVER_TWO,
  //     roll: 0.0
  //   }
  // });
  // 启用地形深度测试,确保地形正确渲染
  viewer.scene.globe.depthTestAgainstTerrain = true;
  // 模拟数值
  const points = new Array(50).fill("").map(() => {
    return {
      lnglat: [
        116.46 + Math.random() * 0.1 * (Math.random() > 0.5 ? 1 : -1),
        39.92 + Math.random() * 0.1 * (Math.random() > 0.5 ? 1 : -1),
      ],
      value: 1000 * Math.random(),
    };
  });
  // 创建热力图
  create3DHeatmap(viewer, {
    dataPoints: points,
    radius: 15,
    baseElevation: 0,
    primitiveType: "TRIANGLES",
    colorGradient: {
      ".3": "blue",
      ".5": "green",
      ".7": "yellow",
      ".95": "red",
    },
  });
  viewer.camera.flyTo({
    destination: Cesium.Cartesian3.fromDegrees(116.46, 39.92, 100000),
    orientation: {},
    duration: 3,
  });
}
// 组件卸载前清理资源
onUnmounted(() => {
  if (viewer) {
    viewer.destroy();
    viewer = null;
  }
});
/**
 * 创建三维热力图
 * @param {Cesium.Viewer} viewer 地图viewer对象
 * @param {Object} options 基础参数
 * @param {Array} options.dataPoints 热力值数组
 * @param {Array} options.radius 热力点半径
 * @param {Array} options.baseElevation 最低高度
 * @param {Array} options.colorGradient 颜色配置
 */
function create3DHeatmap(viewer, options = {}) {
  const heatmapState = {
    viewer,
    options,
    dataPoints: options.dataPoints || [],
    containerElement: undefined,
    instanceId: Number(
      `${new Date().getTime()}${Number(Math.random() * 1000).toFixed(0)}`
    ),
    canvasWidth: 200,
    boundingBox: undefined, // 四角坐标
    boundingRect: {}, // 经纬度范围
    xAxis: undefined, // x 轴
    yAxis: undefined, // y 轴
    xAxisLength: 0, // x轴长度
    yAxisLength: 0, // y轴长度
    baseElevation: options.baseElevation || 0,
    heatmapPrimitive: undefined,
    positionHierarchy: [],
    heatmapInstance: null,
  };
  if (!heatmapState.dataPoints || heatmapState.dataPoints.length < 2) {
    console.log("热力图点位不得少于3个!");
    return;
  }
  createHeatmapContainer(heatmapState);
  const heatmapConfig = {
    container: document.getElementById(`heatmap-${heatmapState.instanceId}`),
    radius: options.radius || 20,
    maxOpacity: 0.7,
    minOpacity: 0,
    blur: 0.75,
    gradient: options.colorGradient || {
      ".1": "blue",
      ".5": "yellow",
      ".7": "red",
      ".99": "white",
    },
  };
  heatmapState.primitiveType = options.primitiveType || "TRIANGLES";
  heatmapState.heatmapInstance = h337.create(heatmapConfig);
  initializeHeatmap(heatmapState);
  return {
    destroy: () => destroyHeatmap(heatmapState),
    heatmapState,
  };
}
......
相关推荐
花间相见7 分钟前
【终端效率工具01】—— Yazi:Rust 编写的现代化终端文件管理器,告别繁琐操作
前端·ide·git·rust·极限编程
|晴 天|16 分钟前
我如何用Vue 3打造一个现代化个人博客系统(性能提升52%)
前端·javascript·vue.js
风止何安啊24 分钟前
网页都知道要双向握手才加载!从 URL 到页面渲染,单向喜欢连 DNS 都解析不通
前端·javascript·面试
太极OS30 分钟前
给 AI Skill 做 CI/CD:GitHub + ClawHub + Xiaping 同步发布实战
前端
你_好30 分钟前
Chrome 内置了 AI 工具协议?WebMCP 抢先体验 + 开源 DevTools 全解析
前端·mcp
GISer_Jing31 分钟前
LangChain.js + LangGraph.js 前端AI开发实战指南
前端·javascript·langchain
正在发育ing__34 分钟前
从源码看vue的key和状态错乱的patch
前端
yuqifang1 小时前
vue3+typescript+vite封装自己的UI组件库并上传至npm
vue.js·arkui
黄林晴1 小时前
第一次听到 Tauri 这个词,去学习一下
前端
丷丩1 小时前
第 2 篇:入门实操|3dtubetilecreater 环境搭建全教程(零踩坑版)
3d·gis·postgis·管线·自动建模·管网