| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373 |
- <template>
- <div class="mapBox">
- <div id="cesiumContainer" style="width: 100%; height: 100vh"></div>
- <div class="menuBox" :class="allyShow ? '' : 'switch'">
- <el-button type="primary" @click="resetViewport()">初始化视角</el-button>
- <el-button
- :type="windLayer ? 'danger' : 'primary'"
- @click="switchWindLayer"
- >{{ windLayer ? "关闭" : "显示" }}风场图</el-button
- >
- <el-button
- :type="cloudLayer ? 'danger' : 'primary'"
- @click="switchCloudLayer"
- >{{ cloudLayer ? "关闭" : "显示" }}云图</el-button
- >
- <el-button
- :type="rainLayer ? 'danger' : 'primary'"
- @click="switchRainLayer"
- >{{ rainLayer ? "关闭" : "显示" }}降雨图</el-button
- >
- <el-tooltip
- class="box-item"
- effect="dark"
- :content="`点击${allyShow ? '隐藏' : '常显'}菜单栏`"
- placement="bottom-end"
- >
- <el-icon
- style="margin-left: 20px"
- size="20px"
- :color="allyShow ? '#1890ff' : '#f25656'"
- @click="allyShow = !allyShow"
- >
- <House
- :style="`transform: rotate(${
- allyShow ? -45 : 45
- }deg); transition: 0.2s; cursor: pointer;`"
- />
- </el-icon>
- </el-tooltip>
- </div>
- </div>
- </template>
- <script>
- import * as Cesium from "../Cesium";
- import "../Cesium/Widgets/widgets.css";
- import Windy from "../assets/wind/Windy_source.js";
- import SingleImageProvider from "../assets/wind/SingleImageProvider";
- import basicGeoJson from "../assets/geoJson/basic.json";
- import windLineJson from "../assets/geoJson/windLine_2017121300.json";
- import axios from "axios";
- export default {
- name: "CesiumMap",
- data() {
- return {
- allyShow: false,
- viewer: null,
- windLayer: null, // 风场图
- windLayerTimmer: null, // 风场图计时器
- cloudLayer: null, // 卫星云图
- rainLayer: null, //
- };
- },
- mounted() {
- this.initCesium();
- },
- unmounted() {
- if (this.windLayer !== null) {
- clearInterval(this.windLayerTimmer);
- this.windLayer.removeLines();
- this.windLayer = null;
- }
- },
- methods: {
- initCesium() {
- // 需要从 https://cesium.com/ion/signup 获取
- Cesium.Ion.defaultAccessToken =
- "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiIwYTQwNDk3MC05YTZkLTQ2ZTEtODc0MS1lZTFkYjFlOTFmNmQiLCJpZCI6MTcyNDQ1LCJpYXQiOjE3NTQ4ODA4MzF9.KnhENYiHxNwTkhTWRA-lHqG59coLVT2FsIyOru2TV3E";
- const viewer = new Cesium.Viewer("cesiumContainer", {
- baseLayerPicker: false,
- animation: false,
- vrButton: false,
- geocoder: false,
- homeButton: false,
- infoBox: false,
- sceneModePicker: false,
- selectionIndicator: false,
- timeline: false,
- fullscreenButton: false,
- navigationHelpButton: false,
- shouldAnimate: true,
- });
- // 隐藏logo
- // this.$nextTick(() => {
- // document.querySelector(".cesium-viewer-bottom")?.remove();
- // });
- // 隐藏logo
- viewer.cesiumWidget.creditContainer.style.display = "none";
- // 添加中文底图
- const imageryProvider = new Cesium.UrlTemplateImageryProvider({
- url: "https://webst02.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}",
- credit: "高德地图",
- });
- viewer.imageryLayers.addImageryProvider(imageryProvider);
- // 添加一些3D模型
- // const addModel = (name, lon, lat, height) => {
- // viewer.entities.add({
- // name: name,
- // position: Cesium.Cartesian3.fromDegrees(lon, lat, height),
- // model: {
- // uri: "/sample-data/models/CesiumAir/Cesium_Air.glb",
- // scale: 50000.0,
- // },
- // });
- // };
- // addModel("模型1", 116.4, 39.9, 1000);
- // addModel("模型2", 121.47, 31.23, 1000);
- // 添加点击事件显示坐标
- viewer.screenSpaceEventHandler.setInputAction((movement) => {
- const cartesian = viewer.camera.pickEllipsoid(
- movement.position,
- viewer.scene.globe.ellipsoid
- );
- if (cartesian) {
- const cartographic = Cesium.Cartographic.fromCartesian(cartesian);
- const lon = Cesium.Math.toDegrees(cartographic.longitude).toFixed(5);
- const lat = Cesium.Math.toDegrees(cartographic.latitude).toFixed(5);
- viewer.entities.removeAll();
- viewer.entities.add({
- position: cartesian,
- point: {
- pixelSize: 10,
- color: Cesium.Color.RED,
- },
- label: {
- text: `经度: ${lon}°, 纬度: ${lat}°`,
- font: '16px "Microsoft YaHei"',
- fillColor: Cesium.Color.WHITE,
- outlineColor: Cesium.Color.BLACK,
- outlineWidth: 2,
- style: Cesium.LabelStyle.FILL_AND_OUTLINE,
- pixelOffset: new Cesium.Cartesian2(0, -30),
- },
- });
- }
- }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
- this.viewer = viewer;
- this.initGeoJsonData();
- },
- // 初始化 geoJson 数据
- async initGeoJsonData() {
- // 创建GeoJSON数据源
- await new Cesium.GeoJsonDataSource.load(basicGeoJson, {
- stroke: Cesium.Color.WHITE, // 边界线颜色
- fill: Cesium.Color.BLACK.withAlpha(0.1), // 填充颜色
- strokeWidth: 1, // 边界线宽度
- markerSymbol: "?", // 点要素的符号
- }).then((dataSource) => {
- // 添加到视图
- this.viewer.dataSources.add(dataSource);
- var entities = dataSource.entities.values;
- for (let i = 0; i < entities.length; i++) {
- let entity = entities[i];
- let polyPositions = entity.polygon.hierarchy.getValue(
- Cesium.JulianDate.now()
- ).positions;
- //单独设置线条样式
- var positions = entity.polygon.hierarchy._value.positions;
- entity.polyline = {
- positions: positions,
- width: 1,
- outline: false,
- };
- }
- // 添加中文标签图层
- const labelLayer = new Cesium.LabelCollection();
- this.viewer.scene.primitives.add(labelLayer);
- const cities = [];
- basicGeoJson?.features?.forEach((ele) => {
- if (Array.isArray(ele.properties.centroid)) {
- const name = ele.properties.name;
- const lon = ele.properties.centroid[0];
- const lat = ele.properties.centroid[1];
- cities.push({ name, lon, lat });
- }
- });
- cities.forEach((city) => {
- labelLayer.add({
- position: Cesium.Cartesian3.fromDegrees(city.lon, city.lat),
- text: city.name,
- font: 'bold 16px "Microsoft YaHei", sans-serif',
- fillColor: Cesium.Color.YELLOW,
- outlineColor: Cesium.Color.BLACK,
- outlineWidth: 2,
- style: Cesium.LabelStyle.FILL_AND_OUTLINE,
- pixelOffset: new Cesium.Cartesian2(0, 0), // 设置为0
- horizontalOrigin: Cesium.HorizontalOrigin.CENTER, // 水平居中
- verticalOrigin: Cesium.VerticalOrigin.CENTER, // 垂直居中
- });
- });
- this.resetViewport();
- });
- },
- // 重置视角
- resetViewport(height = 0) {
- // 设置初始视图为宁夏
- this.viewer.camera.flyTo({
- destination: Cesium.Cartesian3.fromDegrees(
- 106.169866,
- 38.46637,
- height || 8000000
- ),
- orientation: {
- heading: Cesium.Math.toRadians(0),
- pitch: Cesium.Math.toRadians(-90),
- roll: 0.0,
- },
- duration: 1.0,
- });
- },
- // 添加风场图
- showWindLayer() {
- if (!this.windLayer) {
- this.resetViewport(20000000);
- this.windLayer = new Windy(windLineJson, this.viewer);
- this.windLayerTimmer = setInterval(() => {
- this.windLayer.animate();
- }, 200);
- }
- },
- // 将风向角度数据转换为矢量坐标
- windToVector(speed, direction) {
- // 转换为弧度(气象角度:0°=北风,90°=东风)
- const rad = Cesium.Math.toRadians(direction);
- // 计算UV分量(U: 东西方向,V: 南北方向)
- return {
- u: -speed * Math.sin(rad), // 东正西负
- v: -speed * Math.cos(rad), // 北正南负
- };
- },
- // 显示云图
- showCloudLayer() {
- // 设置云图位置(示例:覆盖中国区域)
- // const rectangle = Cesium.Rectangle.fromDegrees(
- // 73.66, // 西经
- // 18.16, // 南纬
- // 135.05, // 东经
- // 53.55 // 北纬
- // );
- const now = new Date();
- const year = now.getFullYear();
- const month = String(now.getMonth() + 1).padStart(2, "0");
- const day = String(now.getDate()).padStart(2, "0");
- const hour = String(Math.floor(now.getHours() / 3) * 3).padStart(2, "0"); // 每3小时更新
- // 创建云图图层
- const cloudLayer = this.viewer.imageryLayers.addImageryProvider(
- new Cesium.UrlTemplateImageryProvider({
- url: `https://data.ventusky.com/${year}/${month}/${day}/icon/whole_world/hour_${hour}/icon_oblacnost_${year}${month}${day}_${hour}.jpg`,
- rectangle: Cesium.Rectangle.fromDegrees(-180, -90, 180, 90),
- credit: "实时卫星云图",
- })
- );
- // 设置蓝色调效果
- cloudLayer.alpha = 0.75; // 透明度
- cloudLayer.brightness = 1; // 亮度
- cloudLayer.contrast = 1; // 对比度
- this.cloudLayer = cloudLayer;
- },
- // 移除风场图
- removeWindLayer() {
- if (this.windLayer) {
- clearInterval(this.windLayerTimmer);
- this.windLayer.removeLines();
- this.viewer.imageryLayers.remove(this.windLayer);
- this.windLayer = null;
- }
- },
- // 移除卫星云图
- removeCloudLayer() {
- if (this.cloudLayer) {
- this.viewer.imageryLayers.remove(this.cloudLayer);
- this.cloudLayer = null;
- }
- },
- // 切换风场图显隐
- switchWindLayer() {
- if (this.windLayer) {
- this.removeWindLayer();
- } else {
- this.showWindLayer();
- }
- },
- // 切换微星图显隐
- switchCloudLayer() {
- if (this.cloudLayer) {
- this.removeCloudLayer();
- } else {
- this.showCloudLayer();
- }
- },
- switchRainLayer() {
- this.$router.push({
- path: "/satellitecloudchart",
- });
- },
- },
- };
- </script>
- <style lang="less" scoped>
- .mapBox {
- width: 100%;
- height: 100%;
- position: relative;
- box-sizing: content-box;
- .menuBox {
- position: absolute;
- left: 0;
- top: 0;
- width: 100%;
- background: #fff;
- display: flex;
- justify-content: flex-end;
- align-items: center;
- padding: 10px;
- &.switch {
- opacity: 0;
- transition: 0.2s;
- &:hover {
- opacity: 1;
- transition: 0.2s;
- }
- }
- }
- }
- </style>
|