惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

T
Threat Research - Cisco Blogs
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
月光博客
月光博客
V
Vulnerabilities – Threatpost
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
S
Secure Thoughts
Microsoft Azure Blog
Microsoft Azure Blog
Blog — PlanetScale
Blog — PlanetScale
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
T
Tailwind CSS Blog
S
SegmentFault 最新的问题
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
云风的 BLOG
云风的 BLOG
The Last Watchdog
The Last Watchdog
L
LINUX DO - 热门话题
酷 壳 – CoolShell
酷 壳 – CoolShell
WordPress大学
WordPress大学
AWS News Blog
AWS News Blog
美团技术团队
G
Google Developers Blog
宝玉的分享
宝玉的分享
www.infosecurity-magazine.com
www.infosecurity-magazine.com
C
CXSECURITY Database RSS Feed - CXSecurity.com
Recent Commits to openclaw:main
Recent Commits to openclaw:main
I
InfoQ
小众软件
小众软件
Google DeepMind News
Google DeepMind News
P
Privacy & Cybersecurity Law Blog
Stack Overflow Blog
Stack Overflow Blog
Webroot Blog
Webroot Blog
D
DataBreaches.Net
IT之家
IT之家
PCI Perspectives
PCI Perspectives
人人都是产品经理
人人都是产品经理
Hacker News: Ask HN
Hacker News: Ask HN
L
LangChain Blog
SecWiki News
SecWiki News
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
C
Cisco Blogs
T
Threatpost
P
Proofpoint News Feed
Y
Y Combinator Blog
Cloudbric
Cloudbric
T
Tor Project blog
量子位
博客园_首页
B
Blog
Hugging Face - Blog
Hugging Face - Blog
GbyAI
GbyAI
D
Darknet – Hacking Tools, Hacker News & Cyber Security

博客园 - weipt

终于!我造了个「AI代驾」级别的AutoBuilder,一键干掉80%的重复CRUD工作 OpenClaw 配置飞书机器人完整指南:从零到每天定时推送天气 国产数据库私有化部署实战:PolarDB for PostgreSQL 免费容器版踩坑记 发票打印还在花钱?这款免费小工具,A4纸一半大小、自动排版,真香! 🔥 自己写的FBX转3D Tiles工具,免费!还能当模型浏览器用 相同代码在360浏览器能显示,在edge提示webgl不支持,edge下都最新的内核。 什么是技术架构、数据架构、业务架构、应用架构和代码架构? 使用pyinstaller打包的exe文件太大,怎么办 2026无人机新规正式施行!各位飞手赶紧收藏 谈谈EF的两种模式 谈谈EF Core 微软官方的 ORM(对象关系映射)框架 Next.js和blazor server比较开发网站哪个好 Blazor Server和 Blazor WebAssembly区别 关于顺丰退出抖音电商退货业务事件的分析 在WINDOWS上创建NTP授时服务器,并验证是否可用 这样的算作“全栈技术”吗? 大疆上云APIdemo打包配置 用nssm将minio和srs注册成服务 LoRa定位技术和蓝牙AoA定位技术的关系 Mysql查询工具,你还用navcat吗? jar注册为服务的方式 nginx怎么样配置rtmp推流服务器 时间戳和时间格式互转
关于vue项目中cesium的地图显示问题
weipt · 2026-01-12 · via 博客园 - weipt

vite.config.js文件如下

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import cesium from 'vite-plugin-cesium'
// https://vite.dev/config/
export default defineConfig({
  plugins: [
    vue(),
  cesium()],
})

 app.vue文件如下

<template>
  <div id="app">
    <div id="cesium-container"></div>
    <div class="control-panel">
      <div>
        <label>经度: </label>
        <input v-model="longitude" type="number" step="0.000001">
      </div>
      <div>
        <label>纬度: </label>
        <input v-model="latitude" type="number" step="0.000001">
      </div>
      <div>
        <label>高度(米): </label>
        <input v-model="height" type="number">
      </div>
      <div>
        <label>偏航角(度): </label>
        <input v-model="headingAngle" type="number">
      </div>
      <div>
        <label>俯仰角(度): </label>
        <input v-model="pitchAngle" type="number">
      </div>
      <button @click="flyTo">飞入</button>
    </div>
  </div>
</template>

<script>
import { onMounted, ref } from 'vue';
import * as Cesium from 'cesium';

export default {
  setup() {
    // 默认参数
    const longitude = ref(108.94859);
    const latitude = ref(34.18970);
    const height = ref(230);
    const headingAngle = ref(255.01);
    const pitchAngle = ref(-77.64);

    let viewer = null;

    Cesium.Ion.defaultAccessToken ="WeyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiI1NDYwYTU4Ny01OGQzLTQ1YjItYmM0OS1lMTg0NzQ4Y2E5ZjQiLCJpZCI6NDQ4OTksImlhdCI6MTYxNDU3MDc5OX0.Wx5h51PEYxUM_ORJ6gGbyew1nhzTX2wEN01P7BU38cE";

    // 初始化Cesium
    const initCesium = async () => {
      //知识重点////////////////
      //创建 Cesium.Viewer 时没有指定 imageryProvider 和 terrainProvider,则Cesium 会自动使用默认的 Bing Maps 作为影像源(通过您提供的 Ion Token)
      
      // 检查Cesium版本
      console.log('Cesium版本:', Cesium.VERSION);
     
      viewer = new Cesium.Viewer('cesium-container', {
       // terrainProvider: new Cesium.EllipsoidTerrainProvider(),    //EllipsoidTerrainProvider加载默认的地形。效果是有bing地图但是无起伏dem数据。
        timeline: false,
        animation: false,
        baseLayerPicker: false,
        sceneModePicker: false,
        navigationHelpButton: false,
        homeButton: false,
        geocoder: false,
        infoBox: false,
        selectionIndicator: false
      });

      // // 添加基本影像图层(使用OpenStreetMap)
      // viewer.imageryLayers.addImageryProvider(
      //   new Cesium.UrlTemplateImageryProvider({
      //     url: 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
      //     subdomains: ['a', 'b', 'c'],
      //     maximumLevel: 19
      //   })
      // );

      // 或者方法2:使用ArcGIS World Imagery(免费卫星影像)国内不能访问!!!
      // viewer.imageryLayers.addImageryProvider(
      //   new Cesium.ArcGisMapServerImageryProvider({
      //     url: 'https://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer'
      //   })
      // );

      // // 高德地图影像
      // const amapProvider = new Cesium.UrlTemplateImageryProvider({
      //   url: 'https://webst0{1-4}.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}',
      //   subdomains: ['1', '2', '3', '4'],
      //   maximumLevel: 18
      // });
       
   
      //加载自定义地形服务
      viewer.terrainProvider = Cesium.CesiumTerrainProvider.fromUrl(
        'http://192.168.10.23:42225/service/bydzy2lf9bkl/terrain', 
        {
          requestWaterMask: true,
        }
      );

      //移除水印
      viewer.cesiumWidget.creditContainer.style.display = "none";

      // flyTo();
    };
    onMounted(initCesium);

    const flyTo = () => {
      if (viewer) {
        const destination = Cesium.Cartesian3.fromDegrees(
          parseFloat(longitude.value),
          parseFloat(latitude.value),
          parseFloat(height.value)
        );
        
        const heading = Cesium.Math.toRadians(parseFloat(headingAngle.value));
        const pitch = Cesium.Math.toRadians(parseFloat(pitchAngle.value));
        
        viewer.camera.flyTo({
          destination,
          orientation: {
            heading,
            pitch,
            roll: 0.0
          },
          duration: 3 // 飞行时间(秒)
        });
      }
    };



    return {
      longitude, latitude, height,
      headingAngle, pitchAngle,flyTo   
    };
  }
};
</script>


<style>
/* 样式保持不变 */
#app {
  width: 100%;
  height: 100vh;
  margin: 0;
  padding: 0;
  background: rgba(42, 42, 42, 0.8);

}

#cesium-container {
  position: absolute;
  width: 100%;
  height: 100vh;
  margin: 0;
  padding: 0;
  overflow: hidden;
}

.control-panel {
  position: absolute;
  top: 10px;
  left: 10px;
  background: rgba(42, 42, 42, 0.8);
  padding: 10px;
  border-radius: 5px;
  z-index: 999;
  color: white;
}

.control-panel div {
  margin-bottom: 8px;
}

.control-panel label {
  display: inline-block;
  width: 100px;
}

.control-panel input {
  width: 80px;
}

.control-panel button {
  margin-top: 10px;
  padding: 5px 10px;
  cursor: pointer;
}
</style>

  下面是加载第三方底图并且加载自定义地形

<template>
  <div id="app">
    <div id="cesium-container"></div>
    <div class="control-panel">
      <div>
        <label>经度: </label>
        <input v-model="longitude" type="number" step="0.000001">
      </div>
      <div>
        <label>纬度: </label>
        <input v-model="latitude" type="number" step="0.000001">
      </div>
      <div>
        <label>高度(米): </label>
        <input v-model="height" type="number">
      </div>
      <div>
        <label>偏航角(度): </label>
        <input v-model="headingAngle" type="number">
      </div>
      <div>
        <label>俯仰角(度): </label>
        <input v-model="pitchAngle" type="number">
      </div>
      <button @click="flyTo">飞入</button>
    </div>
  </div>
</template>

<script>
import { onMounted, ref } from 'vue';
import * as Cesium from 'cesium';

export default {
  setup() {
    // 默认参数 (西安大雁塔附近坐标)
    const longitude = ref(108.94859);
    const latitude = ref(34.18970);
    const height = ref(500); // 建议高度设置高一点,方便观察地形起伏
    const headingAngle = ref(255.01);
    const pitchAngle = ref(-77.64);

    let viewer = null;

    // 1. 配置 Cesium Token
    Cesium.Ion.defaultAccessToken = "WeyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiI1NDYwYTU4Ny01OGQzLTQ1YjItYmM0OS1lMTg0NzQ4Y2E5ZjQiLCJpZCI6NDQ4OTksImlhdCI6MTYxNDU3MDc5OX0.Wx5h51PEYxUM_ORJ6gGbyew1nhzTX2wEN01P7BU38cE";

    const initCesium = async () => {
      console.log('Cesium版本:', Cesium.VERSION);
     
      // 2. 创建 Viewer 实例
      viewer = new Cesium.Viewer('cesium-container', {
        terrainProvider: new Cesium.EllipsoidTerrainProvider(), // 先使用默认地形兜底
        timeline: false,
        animation: false,
        baseLayerPicker: false,
        sceneModePicker: false,
        navigationHelpButton: false,
        homeButton: false,
        geocoder: false,
        infoBox: false,
        selectionIndicator: false,
        // 配置高德地图影像 (修复了 {s} 占位符问题)
        imageryProvider: new Cesium.UrlTemplateImageryProvider({
          url: 'https://webst0{s}.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}',
          subdomains: ['1', '2', '3', '4'],
          maximumLevel: 18,
          credit: new Cesium.Credit('高德地图')
        })
      });

      // 3. 移除默认图层并确保高德地图在最底层
      viewer.imageryLayers.removeAll();
      viewer.imageryLayers.addImageryProvider(new Cesium.UrlTemplateImageryProvider({
        url: 'https://webst0{s}.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}',
        subdomains: ['1', '2', '3', '4'],
        maximumLevel: 18
      }));

      // 4. 加载自定义地形服务 (使用 Promise 链式调用避免 undefined 错误)
      const terrainUrl = 'http://192.168.10.23:42225/service/bydzy2lf9bkl/terrain';
      console.log('正在连接地形服务:', terrainUrl);

      try {
        if (Cesium.CesiumTerrainProvider.fromUrl) {
          Cesium.CesiumTerrainProvider.fromUrl(terrainUrl, {
            requestWaterMask: true,
            requestVertexNormals: true
          }).then(provider => {
            if (provider) {
              provider.readyPromise.then(() => {
                console.log('✅ 地形加载成功!');
                viewer.terrainProvider = provider;
                viewer.scene.globe.dirty = true; // 强制刷新
                flyTo(); // 地形加载好后再定位
              }).catch(err => {
                console.error('❌ 地形准备失败:', err);
              });
            }
          }).catch(err => {
            console.error('❌ 地形Provider创建失败:', err);
          });
        }
      } catch (error) {
        console.error('❌ 地形加载异常:', error);
        alert('地形服务连接失败,请检查网络或服务端配置。');
      }

      // 5. 场景优化配置
      viewer.scene.globe.depthTestAgainstTerrain = true; // 开启深度测试,防止模型穿模
      viewer.scene.globe.enableLighting = true; // 开启光照,让地形阴影更明显
      
      // 移除 Cesium 水印
      viewer.cesiumWidget.creditContainer.style.display = "none";
    };

    onMounted(initCesium);

    // 6. 视角控制方法
    const flyTo = () => {
      if (viewer) {
        const destination = Cesium.Cartesian3.fromDegrees(
          parseFloat(longitude.value),
          parseFloat(latitude.value),
          parseFloat(height.value)
        );
        
        const heading = Cesium.Math.toRadians(parseFloat(headingAngle.value));
        const pitch = Cesium.Math.toRadians(parseFloat(pitchAngle.value));
        
        viewer.camera.flyTo({
          destination,
          orientation: {
            heading,
            pitch,
            roll: 0.0
          },
          duration: 2
        });
      }
    };

    return {
      longitude, latitude, height,
      headingAngle, pitchAngle, flyTo   
    };
  }
};
</script>

<style>
#app {
  width: 100%;
  height: 100vh;
  margin: 0;
  padding: 0;
  background: rgba(42, 42, 42, 0.8);
}

#cesium-container {
  position: absolute;
  width: 100%;
  height: 100vh;
  margin: 0;
  padding: 0;
  overflow: hidden;
}

.control-panel {
  position: absolute;
  top: 10px;
  left: 10px;
  background: rgba(42, 42, 42, 0.8);
  padding: 10px;
  border-radius: 5px;
  z-index: 999;
  color: white;
}

.control-panel div {
  margin-bottom: 8px;
}

.control-panel label {
  display: inline-block;
  width: 100px;
}

.control-panel input {
  width: 120px;
}

.control-panel button {
  margin-top: 10px;
  padding: 5px 10px;
  cursor: pointer;
  width: 100%;
}
</style>