cesium中.entities.add.label无法转换thml

时间: 2025-02-10 13:13:16 AIGC 浏览: 61
在Cesium.js中,`cesium.entities.add.label` 是用于添加标签(Label)到场景中的API,它通常处理的是GeoJSON格式的数据,而不是HTML。当你试图将HTML直接传递给这个方法时,可能会遇到问题,因为Cesium期望的是结构化的几何信息和文本内容。 Cesium更倾向于使用GeoJSON来创建Label,因为它包含了经纬度、图标、样式等必要信息,并且可以直接渲染到三维空间中。如果你需要显示富文本,可以考虑将HTML内容转换为GeoJSON格式,其中包含经纬度以及一个特殊的`text`属性,例如: ```javascript const text = { text: '<b>Hello, World!</b>', // HTML内容 position: Cesium.Cartesian3.fromDegrees(-75.59777, 40.03883), // 经纬度 style: { font: '16pt sans-serif', verticalOrigin: Cesium.VerticalOrigin.BOTTOM } }; cesium.entities.add({ name: 'My Label', label: { text: text.text, font: text.style.font, backgroundColor: Cesium.Color.WHITE, scale: 1.0, verticalOrigin: text.style.verticalOrigin }, position: text.position }); ``` 如果想要在Cesium中显示HTML,你可能需要借助第三方库,如`cesium-ion-labels`这样的插件,它们提供了额外的支持。
阅读全文

相关推荐

// 1. 优化点位(Entity)配置,强制置顶 var point = window.viewer.entities.add({ name: data.ghName ? data.ghName : data.type == 0 && data.numData == 1 ? '顶点' : '点', position: data.position3, description: { position: data.position }, label: { // ... 其他配置不变 ... // 关键:禁用深度测试,确保标签不被任何物体遮挡 disableDepthTestDistance: Number.POSITIVE_INFINITY }, billboard: { // ... 其他配置不变 ... // 关键:禁用深度测试,确保图标不被任何物体遮挡 disableDepthTestDistance: Number.POSITIVE_INFINITY, // 额外添加:提升渲染优先级(Entity 内部生效) zIndex: 100 // 确保在其他 Entity 之上 } }); // 2. 优化圆形(Primitive)配置,确保不遮挡 Entity var primitives = new Cesium.Primitive({ geometryInstances: instance, appearance: new Cesium.MaterialAppearance({ material: new Cesium.Material({ fabric: { type: "Color", uniforms: { color: Cesium.Color.fromCssColorString("#2963C3").withAlpha(0.1) } } }), translucent: true, renderState: { depthTest: { enabled: false }, depthMask: false, // 关键:配置混合模式,让圆形正确与下层融合 blending: { enabled: true, equationRgb: Cesium.BlendingEquation.ADD, equationAlpha: Cesium.BlendingEquation.ADD, functionSourceRgb: Cesium.BlendingFunction.SOURCE_ALPHA, functionSourceAlpha: Cesium.BlendingFunction.SOURCE_ALPHA, functionDestinationRgb: Cesium.BlendingFunction.ONE_MINUS_SOURCE_ALPHA, functionDestinationAlpha: Cesium.BlendingFunction.ONE_MINUS_SOURCE_ALPHA } } }), show: true, allowPicking: false, zIndex: 1 }); // 3. 优化轮廓线(Primitive)配置 var primitivesLine = new Cesium.Primitive({ geometryInstances: polylineInstance, appearance: new Cesium.PolylineMaterialAppearance({ material: Cesium.Material.fromType("Color", { color: Cesium.Color.fromCssColorString("#2963C3").withAlpha(1) }), translucent: true, renderState: { depthTest: { enabled: false }, depthMask: false, // 同样添加混合模式 blending: { enabled: true, equationRgb: Cesium.BlendingEquation.ADD, equationAlpha: Cesium.BlendingEquation.ADD, functionSourceRgb: Cesium.BlendingFunction.SOURCE_ALPHA, functionSourceAlpha: Cesium.BlendingFunction.SOURCE_ALPHA, functionDestinationRgb: Cesium.BlendingFunction.ONE_MINUS_SOURCE_ALPHA, functionDestinationAlpha: Cesium.BlendingFunction.ONE_MINUS_SOURCE_ALPHA } } }), asynchronous: false, show: true, allowPicking: false, zIndex: 1 }); // 4. 确保圆形在点位之后添加到场景 // 先添加点位(Entity 会立即处理) routeArr.push(point); // 后添加圆形(Primitive 后添加,避免覆盖已添加的 Entity) this.circleEntity = window.viewer.scene.primitives.add(primitives); this.circleEntityOutline = window.viewer.scene.primitives.add(primitivesLine); 怎么确保的创建的点位在圆的上面呢

function createAirplane(positions, id, finalTime, props) { const len = positions.length; if (len < 2) return; const position = positions[len - 2]; const secondPosition = positions[len - 1]; const color = Cesium.Color.BLUE; const item = airflyCollection.entities.getById("air" + id); // 倒数第二个点 const ps = Cesium.Cartesian3.fromDegrees( position[0], position[1], position[2] ); // 倒数第一个 const ps1 = Cesium.Cartesian3.fromDegrees( secondPosition[0], secondPosition[1], secondPosition[2] ); // 创建采样位置属性 const positionProperty = new Cesium.SampledPositionProperty(); positionProperty.extrapolationType = Cesium.ExtrapolationType.HOLD; viewer.clock.clockRange = Cesium.ClockRange.CLAMPED; // 计算飞行总时间 const totalSeconds = 5; const startTime = Cesium.JulianDate.now(); const stopTime = Cesium.JulianDate.addSeconds( startTime, totalSeconds, new Cesium.JulianDate() ); const route = [ps, ps1]; // 添加航点采样 route.forEach((point, index) => { // 计算当前点对应时间 const time = Cesium.JulianDate.addSeconds( startTime, index * (totalSeconds / (route.length - 1)), new Cesium.JulianDate() ); // 添加位置样本 positionProperty.addSample(time, point); }); if (item) { // 位置不更新 if (item.finalTime == finalTime) return; item.position = positionProperty; item.orientation = new Cesium.VelocityOrientationProperty(positionProperty); return; } const airplaneEntity = airflyCollection.entities.add({ name: "Aircraft", position: positionProperty, flightnumber: props.flightnumber, station: props.station, icao: props.icao, id: "air" + id, endPosition:ps1, finalTime: finalTime, model: { uri: "/static/model/Cesium_Air.glb", // Cesium默认飞机模型 scale: 1.0, minimumPixelSize:32, color, runAnimations: false, clampAnimations:false }, orientation: new Cesium.VelocityOrientationProperty(positionProperty), // path: { // resolution: 1, // material: Cesium.Color.CYAN, // width: 2, // leadTime: 0, // }, label: { text: props.flightnumber, // 直接使用航班号属性 font: "14px sans-serif", fillColor: Cesium.Color.BLUE, // outlineColor: Cesium.Color.BLACK, // outlineWidth: 2, style: Cesium.LabelStyle.FILL_AND_OUTLINE, verticalOrigin: Cesium.VerticalOrigin.BOTTOM, // 标签在模型上方 pixelOffset: new Cesium.Cartesian2(0, -20), // 上移20像素 }, }); } arr.forEach((v) => { // const item = viewer.entities.getById("air" + v.key); const lineItem = viewer.entities.getById("airLine" + v.key); if (item) { // item.show = true; lineItem.show = true; return; } if (!drawIdCollection.includes(v.key)) { createAirplane(v.points, v.key, v.finalTime, v); drawIdCollection.push(v.key); } }); 没有用啊,还是会回到原点

<template> </template> <script> import * as Cesium from 'cesium'; import 'cesium/Build/Cesium/Widgets/widgets.css'; import CircleRippleMaterialProperty from './CircleRippleMaterialProperty'; export default { name: 'CesiumRippleEffect', data() { return { viewer: null, rippleEntity: null }; }, mounted() { this.initCesium(); }, beforeDestroy() { if (this.viewer) { // 安全销毁Viewer this.viewer.destroy(); this.viewer = null; } }, methods: { async initCesium() { try { // 安全初始化Cesium Viewer this.viewer = new Cesium.Viewer('cesium-container', { animation: false, timeline: false, baseLayerPicker: false, geocoder: false, homeButton: false, sceneModePicker: false, navigationHelpButton: false, fullscreenButton: true, // 添加安全沙箱配置 contextOptions: { webgl: { preserveDrawingBuffer: true }, allowTextureFilterAnisotropic: true } }); // 添加波纹圆效果 this.addRippleEffect(); // 安全调整相机位置(使用??替代弃用的defaultValue) const defaultPosition = Cesium.Cartesian3.fromDegrees(113.194006, 27.399411, 2000); const destination = defaultPosition; await this.viewer.camera.flyTo({ destination, orientation: { heading: Cesium.Math.toRadians(0), pitch: Cesium.Math.toRadians(-60), roll: 0 }, duration: 2.0 }); // 添加安全的事件监听器 this.viewer.scene.postRender.addEventListener(this.handlePostRender, this); } catch (error) { console.error('Cesium初始化错误:', error); } }, addRippleEffect() { try { // 指定坐标 (113.194006, 27.399411) const position = Cesium.Cartesian3.fromDegrees(113.194006, 27.399411); // 创建波纹圆实体(使用??替代弃用的defaultValue) const rippleOptions = { color: Cesium.Color.fromCssColorString("#00FFFF").withAlpha(0.6), speed: 3.0, count: 6, gradient: 0.1 }; this.rippleEntity = this.viewer.entities.add({ name: '动态波纹圆', position: position, ellipse: { semiMinorAxis: 500.0, semiMajorAxis: 500.0, height: 0, material: new CircleRippleMaterialProperty(rippleOptions) } }); // 添加参考点 this.viewer.entities.add({ position: position, point: { pixelSize: 10, color: Cesium.Color.RED } }); } catch (error) { console.error('添加波纹效果错误:', error); } }, // 安全的后渲染处理 handlePostRender() { // 这里可以添加每帧执行的逻辑 }, // 可选:动态更新波纹参数 updateRippleParams() { if (this.rippleEntity && this.rippleEntity.ellipse.material) { // 使用安全访问 this.rippleEntity.ellipse.material.speed = 4.0; this.rippleEntity.ellipse.material.count = 8; } } } }; // 加载株洲矢量数据 const loadZhuzhouVector = async (viewer) => { try { // 1. 加载株洲市整体边界(绿色填充) const cityDataSource = await Cesium.GeoJsonDataSource.load( "https://geo.datav.aliyun.com/areas_v3/bound/geojson?code=430200", { clampToGround: true, stroke: Cesium.Color.GREEN.withAlpha(0.8), strokeWidth: 2, fill: Cesium.Color.GREEN.withAlpha(0.3) } ); viewer.dataSources.add(cityDataSource); // 2. 加载株洲各区县边界(白色边框) const countyDataSource = await Cesium.GeoJsonDataSource.load( "https://geo.datav.aliyun.com/areas_v3/bound/geojson?code=430200_full", { clampToGround: true, stroke: Cesium.Color.WHITE, strokeWidth: 1, fill: Cesium.Color.TRANSPARENT } ); viewer.dataSources.add(countyDataSource); // 添加区县标签 countyDataSource.entities.values.forEach(entity => { if (entity.polygon && entity.properties && entity.properties.name) { const hierarchy = entity.polygon.hierarchy.getValue(Cesium.JulianDate.now()); const center = Cesium.BoundingSphere.fromPoints(hierarchy.positions).center; entity.label = { text: entity.properties.name, font: '18px 黑体', fillColor: Cesium.Color.WHITE, outlineColor: Cesium.Color.BLACK, outlineWidth: 3, style: Cesium.LabelStyle.FILL_AND_OUTLINE, verticalOrigin: Cesium.VerticalOrigin.CENTER, horizontalOrigin: Cesium.HorizontalOrigin.CENTER, pixelOffset: new Cesium.Cartesian2(0, 0), disableDepthTestDistance: Number.POSITIVE_INFINITY, scaleByDistance: new Cesium.NearFarScalar(1e3, 1.0, 1e6, 0.5) }; entity.position = center; } }); // 3. 定位到株洲范围 const rectangle = Cesium.Rectangle.fromDegrees(113.50, 24.94, 113.60, 26.84); viewer.camera.flyTo({ destination: rectangle, orientation: { heading: Cesium.Math.toRadians(0), pitch: Cesium.Math.toRadians(-70), roll: 0 }, duration: 2 }); } catch (error) { console.error("加载株洲数据失败:", error); const chinaRectangle = Cesium.Rectangle.fromDegrees(73.0, 3.0, 136.0, 59.0); viewer.camera.flyTo({ destination: chinaRectangle }); } }; </script> <style scoped> .cesium-container { width: 100%; height: 100vh; position: relative; /* 确保Cesium容器有正确的层级 */ z-index: 0; } /* 添加安全边界 */ #cesium-container ::v-deep .cesium-widget { border: none; overflow: hidden; } #cesium-container ::v-deep .cesium-widget canvas { display: block; } </style> 修改完善,实现加载株洲地区影像并在指定区域加载动态波纹圆功能,将视野定位在株洲

var circle = new Cesium.CircleGeometry({ center: Cesium.Cartesian3.fromDegrees(val.longitude, val.latitude), radius: 8000, segments: 32, extrudedHeight: 0, perPositionHeight: true }); var geometry = Cesium.CircleGeometry.createGeometry(circle); const instance = new Cesium.GeometryInstance({ geometry: geometry, }); const pline = this.getCircleLine(val.longitude,val.latitude,8000) const polylineGeometry = new Cesium.PolylineGeometry({ positions: pline, width: 4.0, vertexFormat: Cesium.PolylineMaterialAppearance.VERTEX_FORMAT }); const polylineInstance = new Cesium.GeometryInstance({ geometry: Cesium.PolylineGeometry.createGeometry(polylineGeometry) }); var primitives = new Cesium.Primitive({ geometryInstances: instance, appearance: new Cesium.MaterialAppearance({ material: new Cesium.Material({ fabric: { type: "Color", uniforms: { color: Cesium.Color.fromCssColorString("#2963C3").withAlpha(0.1) } }, }), translucent: true, // 设置renderState来控制深度测试 renderState: { depthTest: { enabled:true, // 是否启用深度测试 }, depthMask: false, } }), asynchronous: false, show:true, allowPicking: false, zIndex: 0 }) var primitivesLine = new Cesium.Primitive({ geometryInstances: polylineInstance, appearance: new Cesium.PolylineMaterialAppearance({ material: Cesium.Material.fromType("Color", { color: Cesium.Color.fromCssColorString("#2963C3").withAlpha(1) }), translucent: true, // 设置renderState来控制深度测试 renderState: { depthTest: { enabled:true, // 是否启用深度测试 }, depthMask: false, } }), asynchronous: false, show:true, allowPicking: false, zIndex: 1 }) this.circleEntityMap.set(val,primitives) this.circleEntityLineMap.set(val,primitivesLine) this.circleEntity = window.viewer.scene.primitives.add(primitives); this.circleEntityOutline = window.viewer.scene.primitives.add(primitivesLine);开启了深度监测。会有部分在地下怎么能贴地呢

// src/utils/circleRippleMaterialProperty.js class CircleRippleMaterialProperty { constructor(options = {}) { this._definitionChanged = new Cesium.Event(); this._color = Cesium.defaultValue(options.color, Cesium.Color.BLUE); this._speed = Cesium.defaultValue(options.speed, 3.0); this._count = Cesium.defaultValue(options.count, 6); this._gradient = Cesium.defaultValue(options.gradient, 0.1); // GLSL着色器源码 this._source = uniform vec4 color; uniform float speed; uniform float count; uniform float gradient; czm_material czm_getMaterial(czm_materialInput materialInput) { czm_material material = czm_getDefaultMaterial(materialInput); vec2 st = materialInput.st; float time = czm_frameNumber * speed / 1000.0; float d = distance(st, vec2(0.5, 0.5)); // 多圈波纹效果 float alpha = 0.0; for(float i = 0.0; i < count; i++) { // 波纹方程:sin(波纹密度 * d - 时间 * 角频率 - 相位偏移) float ripple = sin(d * 20.0 - time * 2.0 - i * 0.5); // 边缘平滑过渡 float fade = smoothstep(0.0, 0.3, d) * (1.0 - smoothstep(0.3, 0.5, d)); // 边缘渐变效果 alpha += abs(ripple) * fade * pow(1.0 - d, gradient * 10.0); } material.alpha = alpha * color.a; // 颜色混合:中心到边缘渐变 material.diffuse = mix(color.rgb, vec3(1.0), d * 0.5); return material; }; } get isConstant() { return false; } get definitionChanged() { return this._definitionChanged; } get color() { return this._color; } set color(value) { this._color = value; } get speed() { return this._speed; } set speed(value) { this._speed = value; } get count() { return this._count; } set count(value) { this._count = value; } get gradient() { return this._gradient; } set gradient(value) { this._gradient = value; } getType() { return 'CircleRipple'; } getValue(time, result) { if (!result) result = {}; result.color = this._color; result.speed = this._speed; result.count = this._count; result.gradient = this._gradient; return result; } equals(other) { return this === other || (other instanceof CircleRippleMaterialProperty && Cesium.Color.equals(this._color, other._color) && this._speed === other._speed && this._count === other._count && this._gradient === other._gradient); } } // 注册材质类型到Cesium Cesium.Material.CircleRippleType = 'CircleRipple'; Cesium.Material._materialCache.addMaterial(Cesium.Material.CircleRippleType, { fabric: { type: Cesium.Material.CircleRippleType, uniforms: { color: new Cesium.Color(0.0, 0.8, 1.0, 0.6), speed: 3.0, count: 6.0, gradient: 0.1 }, source: new CircleRippleMaterialProperty()._source }, translucent: function() { return true; } }); export default CircleRippleMaterialProperty; 这个为circleRippleMaterialProperty.js文件,CesiumViewer.vue文件代码如下所示: <template> Cesium动态波纹效果 - 科技蓝 波纹参数控制 <label>波纹速度 {{ rippleSpeed.toFixed(1) }}</label> <input type="range" v-model="rippleSpeed" min="0.1" max="10" step="0.1"> <label>波纹数量 {{ rippleCount }}</label> <input type="range" v-model="rippleCount" min="1" max="12" step="1"> <label>波纹大小 {{ rippleSize }}米</label> <input type="range" v-model="rippleSize" min="100" max="2000" step="50"> <label>边缘渐变 {{ rippleGradient.toFixed(2) }}</label> <input type="range" v-model="rippleGradient" min="0" max="1" step="0.05"> 定位坐标:
经度: {{ position.longitude }}
纬度: {{ position.latitude }}
</template> <script> import 'cesium/Build/Cesium/Widgets/widgets.css'; import CircleRippleMaterialProperty from '@/utils/circleRippleMaterialProperty'; export default { name: 'CesiumViewer', data() { return { viewer: null, rippleEntity: null, position: { longitude: 113.194006, latitude: 27.399411 }, rippleSpeed: 3.0, rippleCount: 6, rippleSize: 500, rippleGradient: 0.1 }; }, watch: { rippleSpeed(newVal) { if (this.rippleEntity) { this.rippleEntity.ellipse.material.speed = newVal; } }, rippleCount(newVal) { if (this.rippleEntity) { this.rippleEntity.ellipse.material.count = newVal; } }, rippleSize(newVal) { if (this.rippleEntity) { this.rippleEntity.ellipse.semiMinorAxis = newVal; this.rippleEntity.ellipse.semiMajorAxis = newVal; } }, rippleGradient(newVal) { if (this.rippleEntity) { this.rippleEntity.ellipse.material.gradient = newVal; } } }, mounted() { this.initCesium(); }, beforeDestroy() { if (this.viewer && !this.viewer.isDestroyed()) { this.viewer.destroy(); } }, methods: { initCesium() { // 初始化Cesium Viewer this.viewer = new Cesium.Viewer('cesium-container', { animation: false, timeline: false, baseLayerPicker: true, geocoder: true, homeButton: true, sceneModePicker: true, navigationHelpButton: false, fullscreenButton: true, infoBox: false, terrainProvider: Cesium.createWorldTerrain() }); // 添加科技蓝波纹效果 const position = Cesium.Cartesian3.fromDegrees( this.position.longitude, this.position.latitude ); this.rippleEntity = this.viewer.entities.add({ name: '科技蓝动态波纹', position: position, ellipse: { semiMinorAxis: this.rippleSize, semiMajorAxis: this.rippleSize, height: 0, material: new CircleRippleMaterialProperty({ color: Cesium.Color.fromCssColorString("#00FFFF").withAlpha(0.6), speed: this.rippleSpeed, count: this.rippleCount, gradient: this.rippleGradient }) } }); // 添加中心点标记 this.viewer.entities.add({ position: position, point: { pixelSize: 12, color: Cesium.Color.fromCssColorString("#FF00FF"), outlineColor: Cesium.Color.WHITE, outlineWidth: 2 }, label: { text: '波纹中心', font: '14px sans-serif', fillColor: Cesium.Color.WHITE, style: Cesium.LabelStyle.FILL_AND_OUTLINE, outlineWidth: 2, verticalOrigin: Cesium.VerticalOrigin.TOP, pixelOffset: new Cesium.Cartesian2(0, -20) } }); // 添加坐标点标记 this.viewer.entities.add({ position: position, label: { text: 经度: ${this.position.longitude}\n纬度: ${this.position.latitude}, font: '12px monospace', fillColor: Cesium.Color.CYAN, style: Cesium.LabelStyle.FILL_AND_OUTLINE, outlineWidth: 1, verticalOrigin: Cesium.VerticalOrigin.BOTTOM, pixelOffset: new Cesium.Cartesian2(0, -50), backgroundColor: new Cesium.Color(0.1, 0.1, 0.1, 0.7), padding: new Cesium.Cartesian2(8, 8) } }); // 调整相机位置 this.viewer.camera.flyTo({ destination: Cesium.Cartesian3.fromDegrees( this.position.longitude, this.position.latitude, 2000 ), orientation: { heading: Cesium.Math.toRadians(0), pitch: Cesium.Math.toRadians(-60), roll: 0 }, duration: 2.0 }); // 添加科技感背景 this.viewer.scene.backgroundColor = Cesium.Color.fromBytes(10, 20, 40); this.viewer.scene.globe.baseColor = Cesium.Color.fromBytes(30, 40, 70); this.viewer.scene.globe.enableLighting = true; this.viewer.scene.fog.enabled = true; this.viewer.scene.fog.density = 0.0001; this.viewer.scene.fog.minimumBrightness = 0.01; } } }; </script> <style scoped> .cesium-container { position: relative; width: 100%; height: 100vh; overflow: hidden; } #cesium-container { width: 100%; height: 100%; } .title { position: absolute; top: 20px; left: 20px; color: #00ffff; background: rgba(0, 20, 40, 0.7); padding: 10px 15px; border-radius: 5px; z-index: 1000; font-size: 18px; text-shadow: 0 0 10px rgba(0, 200, 255, 0.8); } .control-panel { position: absolute; top: 20px; right: 20px; background: rgba(40, 44, 52, 0.8); padding: 15px; border-radius: 8px; color: #61dafb; z-index: 1000; box-shadow: 0 0 15px rgba(0, 200, 255, 0.5); max-width: 280px; } .control-panel h3 { margin-top: 0; color: #00ffff; text-align: center; border-bottom: 1px solid #00aaff; padding-bottom: 8px; } .slider-container { margin: 12px 0; } label { display: block; margin-bottom: 5px; font-size: 14px; } input[type="range"] { width: 100%; margin: 5px 0; background: linear-gradient(to right, #0088ff, #00ffff); height: 6px; border-radius: 3px; outline: none; } .value-display { display: inline-block; width: 40px; text-align: right; font-size: 14px; } .coordinates { background: rgba(0, 40, 80, 0.7); padding: 8px; border-radius: 4px; margin-top: 10px; font-size: 13px; } </style> 基于此修改好两个的代码发我

<template> 晴 31℃/西北风 株洲市"天空地水"动态监测平台 {{ currentTime }} {{ currentWeek }} <select v-model="projectionType" @change="switchProjectionType"> <option value="c">经纬度投影</option> <option value="w">球面墨卡托投影</option> </select> <select v-model="selectedMapType" @change="switchMapType"> <option v-for="option in mapOptions" :value="option.value" :key="option.value"> {{ option.label }} </option> </select> <select v-model="networkType" @change="switchNetworkType"> <option value="internal">内网地图</option> <option value="external">外网地图</option> </select> </template> <script setup> import { ref, onMounted } from 'vue'; import * as Cesium from 'cesium'; import "cesium/Build/Cesium/Widgets/widgets.css"; // 天地图服务密钥 const TIANDITU_TOKEN = '72d487f15710ca558987b9baaba13736'; // 当前时间和星期 const currentTime = ref(""); const currentWeek = ref(""); const weekMap = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六']; const updateTime = () => { const now = new Date(); currentTime.value = now.toLocaleString('zh-CN', { year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', second: '2-digit', hour12: false }).replace(/\//g, '-').replace(/(\d{4})-(\d{2})-(\d{2})/, '$ 1年$ 2月$ 3日'); currentWeek.value = weekMap[now.getDay()]; }; setInterval(updateTime, 1000); updateTime(); // 网络类型选择 const networkType = ref('external'); // 默认外网 // 地图类型选择 const selectedMapType = ref('img_c'); // 默认显示影像+注记 // 投影类型选择 const projectionType = ref('c'); // 默认经纬度投影 // 地图选项配置 const mapOptions = ref([ { value: 'img_c', label: '影像+注记' }, { value: 'vec_c', label: '矢量+注记' } ]); // Cesium相关变量 let viewer = null; let tiandituLayers = { baseLayer: null, annotationLayer: null }; // 网络类型切换 const switchNetworkType = () => { // 重置投影类型为默认值 projectionType.value = 'c'; // 根据网络类型更新地图选项 if (networkType.value === 'internal') { mapOptions.value = [ { value: 'img_c', label: '内网影像地图' }, { value: 'vec_c', label: '内网矢量地图' } ]; // 设置内网默认地图类型 selectedMapType.value = 'img_c'; } else { mapOptions.value = [ { value: 'img', label: '天地图影像' }, { value: 'img_c', label: '影像+注记' }, { value: 'vec', label: '矢量地图' }, { value: 'vec_c', label: '矢量+注记' }, { value: 'ter', label: '地形图' } ]; // 设置外网默认地图类型 selectedMapType.value = 'img_c'; } // 重新加载地图 loadMapService(selectedMapType.value); // 重新加载石河子数据并定位 loadShiheziVector(viewer, projectionType.value); setTimeout(flyToShihezi, 500); }; // 地图类型切换 const switchMapType = () => { if (viewer) { loadMapService(selectedMapType.value); } }; // // 投影类型切换 // const switchProjectionType = () => { // if (viewer && networkType.value === 'external') { // loadMapService(selectedMapType.value); // } // }; // 加载地图服务 const loadMapService = (type) => { if (!viewer || !viewer.imageryLayers) return; // 清除现有图层 if (tiandituLayers.baseLayer) viewer.imageryLayers.remove(tiandituLayers.baseLayer); if (tiandituLayers.annotationLayer) viewer.imageryLayers.remove(tiandituLayers.annotationLayer); if (networkType.value === 'internal') { // 内网地图服务 - 只支持c投影 const baseUrl = "http://59.255.48.160:81"; if (type === 'img_c') { // 内网影像地图 tiandituLayers.baseLayer = viewer.imageryLayers.addImageryProvider( new Cesium.WebMapTileServiceImageryProvider({ url: ${baseUrl}/img_c/wmts, layer: "img", style: "default", tileMatrixSetID: "c", format: "tiles", credit: new Cesium.Credit("内网影像地图"), maximumLevel: 18 }) ); } else if (type === 'vec_c') { // 内网矢量地图 tiandituLayers.baseLayer = viewer.imageryLayers.addImageryProvider( new Cesium.WebMapTileServiceImageryProvider({ url: ${baseUrl}/vec_c/wmts, layer: "vec", style: "default", tileMatrixSetID: "c", format: "tiles", credit: new Cesium.Credit("内网矢量地图"), maximumLevel: 18 }) ); } } else { // 外网天地图服务 - 支持c和w投影 // 根据投影类型动态构建URL const baseUrlTemplate = https://t{s}.tianditu.gov.cn/{layer}_${projectionType.value}/wmts?tk=${TIANDITU_TOKEN}; // 图层配置映射表 - 根据投影类型调整图层名称 const layerConfigs = { img: { layer: "img", credit: "天地图影像" }, img_c: { baseLayer: { layer: "img", credit: "天地图影像" }, annotationLayer: { layer: projectionType.value === 'c' ? "cia" : "cia_w", credit: "天地图注记" } }, vec: { layer: "vec", credit: "天地图矢量" }, vec_c: { baseLayer: { layer: "vec", credit: "天地图矢量" }, annotationLayer: { layer: projectionType.value === 'c' ? "cva" : "cva_w", credit: "天地图注记" } }, ter: { layer: "ter", credit: "天地图地形" } }; const config = layerConfigs[type]; if (!config) return; // 添加基础图层 tiandituLayers.baseLayer = viewer.imageryLayers.addImageryProvider( new Cesium.WebMapTileServiceImageryProvider({ url: baseUrlTemplate.replace('{layer}', config.layer || config.baseLayer.layer), layer: config.layer || config.baseLayer.layer, style: "default", tileMatrixSetID: projectionType.value, // 使用选择的投影类型 format: "tiles", credit: new Cesium.Credit(config.credit || config.baseLayer.credit), subdomains: ['0', '1', '2', '3', '4', '5', '6', '7'], maximumLevel: 18 }) ); // 添加注记图层(如果需要) if (config.annotationLayer) { tiandituLayers.annotationLayer = viewer.imageryLayers.addImageryProvider( new Cesium.WebMapTileServiceImageryProvider({ url: baseUrlTemplate.replace('{layer}', config.annotationLayer.layer), layer: config.annotationLayer.layer, style: "default", tileMatrixSetID: projectionType.value, // 使用选择的投影类型 format: "tiles", credit: new Cesium.Credit(config.annotationLayer.credit), subdomains: ['0', '1', '2', '3', '4', '5', '6', '7'], maximumLevel: 18 }) ); } } }; // // 加载株洲矢量数据 // const loadZhuzhouVector = async (viewer) => { // try { // // 加载株洲市整体边界 // const cityDataSource = await Cesium.GeoJsonDataSource.load( // "https://geo.datav.aliyun.com/areas_v3/bound/geojson?code=430200", // { // clampToGround: true, // stroke: Cesium.Color.GREEN.withAlpha(0.8), // strokeWidth: 2, // fill: Cesium.Color.WHITE.withAlpha(0.3) // } // ); // viewer.dataSources.add(cityDataSource); // // 加载株洲各区县边界 // const countyDataSource = await Cesium.GeoJsonDataSource.load( // "https://geo.datav.aliyun.com/areas_v3/bound/geojson?code=430200_full", // { // clampToGround: true, // stroke: Cesium.Color.WHITE, // strokeWidth: 1, // fill: Cesium.Color.TRANSPARENT // } // ); // viewer.dataSources.add(countyDataSource); // // 添加区县标签 // countyDataSource.entities.values.forEach(entity => { // if (entity.polygon && entity.properties && entity.properties.name) { // const hierarchy = entity.polygon.hierarchy.getValue(Cesium.JulianDate.now()); // const center = Cesium.BoundingSphere.fromPoints(hierarchy.positions).center; // entity.label = { // text: entity.properties.name, // font: '18px 黑体', // fillColor: Cesium.Color.WHITE, // outlineColor: Cesium.Color.BLACK, // outlineWidth: 3, // style: Cesium.LabelStyle.FILL_AND_OUTLINE, // verticalOrigin: Cesium.VerticalOrigin.CENTER, // horizontalOrigin: Cesium.HorizontalOrigin.CENTER, // pixelOffset: new Cesium.Cartesian2(0, 0), // disableDepthTestDistance: Number.POSITIVE_INFINITY, // scaleByDistance: new Cesium.NearFarScalar(1e3, 1.0, 1e6, 0.5) // }; // entity.position = center; // } // }); // // 定位到株洲范围 // const rectangle = Cesium.Rectangle.fromDegrees(113.50, 24.94, 113.60, 26.84); // viewer.camera.flyTo({ // destination: rectangle, // orientation: { // heading: Cesium.Math.toRadians(0), // pitch: Cesium.Math.toRadians(-70), // roll: 0 // }, // duration: 2 // }); // } catch (error) { // console.error("加载株洲数据失败:", error); // const chinaRectangle = Cesium.Rectangle.fromDegrees(73.0, 3.0, 136.0, 59.0); // viewer.camera.flyTo({ // destination: chinaRectangle // }); // } // }; // 修改加载石河子矢量数据 // 保存石河子范围矩形 const shiheziRectangle = ref(null); // 加载石河子矢量数据(修复版) const loadShiheziVector = async (viewer) => { try { // 清除现有石河子数据 const dataSources = viewer.dataSources; for (let i = dataSources.length - 1; i >= 0; i--) { if (dataSources.get(i).name === 'shihezi') { dataSources.remove(dataSources.get(i)); } } // 加载石河子市整体边界 const cityDataSource = await Cesium.GeoJsonDataSource.load( "https://geo.datav.aliyun.com/areas_v3/bound/geojson?code=659001", { clampToGround: true, stroke: Cesium.Color.GREEN.withAlpha(0.8), strokeWidth: 2, fill: Cesium.Color.WHITE.withAlpha(0.3), name: 'shihezi' // 添加标识 } ); viewer.dataSources.add(cityDataSource); // 添加石河子市标签 cityDataSource.entities.values.forEach(entity => { if (entity.polygon && entity.properties && entity.properties.name) { const hierarchy = entity.polygon.hierarchy.getValue(Cesium.JulianDate.now()); const positions = hierarchy.positions; // 计算地理中心 const center = Cesium.BoundingSphere.fromPoints(positions).center; entity.label = { text: "石河子市", font: '18px 黑体', fillColor: Cesium.Color.WHITE, outlineColor: Cesium.Color.BLACK, outlineWidth: 3, style: Cesium.LabelStyle.FILL_AND_OUTLINE, verticalOrigin: Cesium.VerticalOrigin.CENTER, horizontalOrigin: Cesium.HorizontalOrigin.CENTER, pixelOffset: new Cesium.Cartesian2(0, 0), disableDepthTestDistance: Number.POSITIVE_INFINITY, scaleByDistance: new Cesium.NearFarScalar(1e3, 1.0, 1e6, 0.5) }; entity.position = center; } }); // 保存石河子范围(地理坐标) const positions = cityDataSource.entities.values[0].polygon.hierarchy.getValue().positions; const cartographicPositions = positions.map(pos => Cesium.Cartographic.fromCartesian(pos) ); const minLon = Math.min(...cartographicPositions.map(p => p.longitude)); const maxLon = Math.max(...cartographicPositions.map(p => p.longitude)); const minLat = Math.min(...cartographicPositions.map(p => p.latitude)); const maxLat = Math.max(...cartographicPositions.map(p => p.latitude)); shiheziRectangle.value = new Cesium.Rectangle( minLon, minLat, maxLon, maxLat ); } catch (error) { console.error("加载石河子数据失败:", error); } }; // 定位到石河子(修复版) const flyToShihezi = () => { if (viewer && shiheziRectangle.value) { // 根据当前投影类型转换坐标 let destination; if (projectionType.value === 'c') { // 经纬度投影直接使用地理坐标 destination = shiheziRectangle.value; } else { // 墨卡托投影需要转换坐标 const west = Cesium.Math.toDegrees(shiheziRectangle.value.west); const south = Cesium.Math.toDegrees(shiheziRectangle.value.south); const east = Cesium.Math.toDegrees(shiheziRectangle.value.east); const north = Cesium.Math.toDegrees(shiheziRectangle.value.north); // 计算墨卡托坐标 const sw = Cesium.WebMercatorProjection.geodeticToWebMercator( new Cesium.Cartographic(shiheziRectangle.value.west, shiheziRectangle.value.south) ); const ne = Cesium.WebMercatorProjection.geodeticToWebMercator( new Cesium.Cartographic(shiheziRectangle.value.east, shiheziRectangle.value.north) ); destination = new Cesium.Rectangle( sw.x, sw.y, ne.x, ne.y ); } viewer.camera.flyTo({ destination: destination, orientation: { heading: Cesium.Math.toRadians(0), pitch: Cesium.Math.toRadians(-70), roll: 0 }, duration: 1 }); } }; // 投影类型切换(修复版) const switchProjectionType = () => { if (viewer && networkType.value === 'external') { // 重新加载地图 loadMapService(selectedMapType.value); // 重新定位到石河子 setTimeout(flyToShihezi, 500); } }; onMounted(async () => { try { // 设置Cesium Ion访问令牌 Cesium.Ion.defaultAccessToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiI0ZTdiZDBhZS0xNzBhLTRjZGUtOTY4NC1kYzA5ZDEyNGEyNjUiLCJpZCI6MzE2OTI5LCJpYXQiOjE3NTEzMzg2Mzh9.9QHGIwaWkUOX0NOSre5369rrf1k6bGhZu7xUQia4JmE'; // 初始化Cesium Viewer viewer = new Cesium.Viewer('cesiumContainer', { baseLayerPicker: false, timeline: false, animation: false, geocoder: false, sceneModePicker: false, navigationHelpButton: false, homeButton: false, selectionIndicator: false, infoBox: false, navigationInstructionsInitiallyVisible: false, scene3DOnly: true, terrainProvider: new Cesium.EllipsoidTerrainProvider(), imageryProvider: new Cesium.WebMapTileServiceImageryProvider({ url: https://t{s}.tianditu.gov.cn/img_w/wmts?tk=${TIANDITU_TOKEN}, layer: "img", style: "default", tileMatrixSetID: "w", subdomains: ['0', '1', '2', '3', '4', '5', '6', '7'], maximumLevel: 18 }) }); // 强制设置中国视角 viewer.camera.setView({ destination: Cesium.Rectangle.fromDegrees(73.0, 3.0, 136.0, 59.0) }); // // 加载株洲数据 // loadZhuzhouVector(viewer); // 加载石河子数据(修改为调用新函数) // 加载石河子数据 await loadShiheziVector(viewer); flyToShihezi(); // 加载地图服务 loadMapService(selectedMapType.value); } catch (error) { console.error("初始化失败:", error); } }); </script> <style scoped> /* 基础样式 */ * { margin: 0; padding: 0; box-sizing: border-box; font-family: "Microsoft YaHei", sans-serif; } .monitor-container { width: 100vw; height: 100vh; background: radial-gradient(circle at center, #0c2a50 0%, #0a1a35 100%); overflow: hidden; position: fixed; top: 0; left: 0; display: flex; flex-direction: column; } /* 顶部导航栏样式 - 重新布局 */ .top-bar { height: 70px; background: linear-gradient(90deg, #0a1a35 0%, #1a3a6e 50%, #0a1a35 100%); display: flex; align-items: center; justify-content: space-between; padding: 0 15px; position: relative; z-index: 100; border-bottom: 1px solid rgba(0, 150, 255, 0.3); } /* 左侧区域 */ .left-section { display: flex; align-items: center; flex: 0 0 auto; } /* 中间区域 */ .center-section { flex: 1 1 auto; display: flex; justify-content: center; } /* 右侧区域 */ .right-section { display: flex; align-items: center; flex: 0 0 auto; gap: 10px; } /* 控件组 */ .controls-group { display: flex; gap: 10px; } /* 天气模块 */ .weather-module { display: flex; align-items: center; color: white; font-size: 14px; min-width: 120px; justify-content: center; } .weather-icon { color: #ffcc00; margin-right: 8px; font-size: 16px; } /* 梯形标题样式 */ .platform-title { position: relative; z-index: 10; max-width: 500px; /* 限制最大宽度 */ } .trapezoid-bg { position: relative; padding: 0 40px; height: 70px; display: flex; align-items: center; } .trapezoid-bg::before { content: ''; position: absolute; top: 0; left: 0; right: 0; bottom: 0; background: rgba(0, 60, 113, 0.6); clip-path: polygon(0% 0%, 100% 0%, 90% 100%, 10% 100%); z-index: -1; } .platform-title h1 { font-size: 24px; font-weight: bold; background: linear-gradient(to bottom, #a2e7eb, #00f2fe); -webkit-background-clip: text; background-clip: text; color: transparent; text-shadow: 0 0 8px rgba(0, 242, 254, 0.3); white-space: nowrap; text-overflow: ellipsis; overflow: hidden; max-width: 100%; } /* 时间模块 */ .time-module { color: white; font-size: 14px; min-width: 220px; text-align: center; white-space: nowrap; } /* 所有控件统一样式 */ .network-switcher select, .map-switcher select, .projection-switcher select { background: rgba(10, 26, 53, 0.8); color: #66ffff; border: 1px solid rgba(0, 150, 255, 0.5); border-radius: 4px; padding: 6px 12px; font-size: 14px; outline: none; cursor: pointer; box-shadow: 0 0 8px rgba(0, 150, 255, 0.3); transition: all 0.3s ease; min-width: 120px; } .network-switcher select:hover, .map-switcher select:hover, .projection-switcher select:hover { background: rgba(26, 58, 110, 0.8); border-color: #00f2fe; box-shadow: 0 0 12px rgba(0, 242, 254, 0.5); } .network-switcher select:focus, .map-switcher select:focus, .projection-switcher select:focus { border-color: #00f2fe; } /* Cesium容器 */ #cesiumContainer { width: 100%; height: calc(100vh - 70px); background-color: #000; position: relative; } /* 响应式调整 */ @media (max-width: 1600px) { .platform-title h1 { font-size: 20px; } .weather-module, .time-module { font-size: 13px; } .network-switcher select, .map-switcher select, .projection-switcher select { padding: 5px 10px; font-size: 13px; min-width: 110px; } } @media (max-width: 1400px) { .platform-title h1 { font-size: 18px; } .trapezoid-bg { padding: 0 30px; } .time-module { min-width: 180px; } .controls-group { gap: 8px; } } @media (max-width: 1200px) { .platform-title h1 { font-size: 16px; } .trapezoid-bg { padding: 0 20px; } .time-module { min-width: 160px; font-size: 12px; } .network-switcher select, .map-switcher select, .projection-switcher select { padding: 4px 8px; font-size: 12px; min-width: 100px; } } @media (max-width: 992px) { .time-module { display: none; } .platform-title h1 { font-size: 14px; } .trapezoid-bg { padding: 0 15px; } .weather-module { min-width: auto; } .network-switcher select, .map-switcher select, .projection-switcher select { padding: 4px 6px; font-size: 11px; min-width: 90px; } } @media (max-width: 768px) { .weather-module { display: none; } .platform-title h1 { font-size: 12px; } .trapezoid-bg { padding: 0 10px; } .controls-group { gap: 5px; } .network-switcher select, .map-switcher select, .projection-switcher select { min-width: 80px; } } </style> 再检查一下,默认设置为墨卡托投影,然后切换到经纬度时这个位置还是没有变化

<template> 晴 31℃/西北风 株洲市"天空地水"动态监测平台 {{ currentTime }} {{ currentWeek }} <select v-model="projectionType" @change="switchProjectionType"> <option value="c">经纬度投影</option> <option value="w">球面墨卡托投影</option> </select> <select v-model="selectedMapType" @change="switchMapType"> <option v-for="option in mapOptions" :value="option.value" :key="option.value"> {{ option.label }} </option> </select> <select v-model="networkType" @change="switchNetworkType"> <option value="internal">内网地图</option> <option value="external">外网地图</option> </select> </template> <script setup> import { ref, onMounted } from 'vue'; import * as Cesium from 'cesium'; import "cesium/Build/Cesium/Widgets/widgets.css"; // 天地图服务密钥 const TIANDITU_TOKEN = '72d487f15710ca558987b9baaba13736'; // 当前时间和星期 const currentTime = ref(""); const currentWeek = ref(""); const weekMap = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六']; const updateTime = () => { const now = new Date(); currentTime.value = now.toLocaleString('zh-CN', { year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', second: '2-digit', hour12: false }).replace(/\//g, '-').replace(/(\d{4})-(\d{2})-(\d{2})/, '$ 1年$ 2月$ 3日'); currentWeek.value = weekMap[now.getDay()]; }; setInterval(updateTime, 1000); updateTime(); // 网络类型选择 const networkType = ref('external'); // 默认外网 // 地图类型选择 const selectedMapType = ref('img_c'); // 默认显示影像+注记 // 投影类型选择 const projectionType = ref('c'); // 默认经纬度投影 // 地图选项配置 const mapOptions = ref([ { value: 'img_c', label: '影像+注记' }, { value: 'vec_c', label: '矢量+注记' } ]); // Cesium相关变量 let viewer = null; let tiandituLayers = { baseLayer: null, annotationLayer: null }; // 网络类型切换 const switchNetworkType = () => { // 重置投影类型为默认值 projectionType.value = 'c'; // 根据网络类型更新地图选项 if (networkType.value === 'internal') { mapOptions.value = [ { value: 'img_c', label: '内网影像地图' }, { value: 'vec_c', label: '内网矢量地图' } ]; // 设置内网默认地图类型 selectedMapType.value = 'img_c'; } else { mapOptions.value = [ { value: 'img', label: '天地图影像' }, { value: 'img_c', label: '影像+注记' }, { value: 'vec', label: '矢量地图' }, { value: 'vec_c', label: '矢量+注记' }, { value: 'ter', label: '地形图' } ]; // 设置外网默认地图类型 selectedMapType.value = 'img_c'; } // 重新加载地图 loadMapService(selectedMapType.value); // 重新加载石河子数据并定位 loadShiheziVector(viewer, projectionType.value); setTimeout(flyToShihezi, 500); }; // 地图类型切换 const switchMapType = () => { if (viewer) { loadMapService(selectedMapType.value); } }; // // 投影类型切换 // const switchProjectionType = () => { // if (viewer && networkType.value === 'external') { // loadMapService(selectedMapType.value); // } // }; // 加载地图服务 const loadMapService = (type) => { if (!viewer || !viewer.imageryLayers) return; // 清除现有图层 if (tiandituLayers.baseLayer) viewer.imageryLayers.remove(tiandituLayers.baseLayer); if (tiandituLayers.annotationLayer) viewer.imageryLayers.remove(tiandituLayers.annotationLayer); if (networkType.value === 'internal') { // 内网地图服务 - 只支持c投影 const baseUrl = "http://59.255.48.160:81"; if (type === 'img_c') { // 内网影像地图 tiandituLayers.baseLayer = viewer.imageryLayers.addImageryProvider( new Cesium.WebMapTileServiceImageryProvider({ url: ${baseUrl}/img_c/wmts, layer: "img", style: "default", tileMatrixSetID: "c", format: "tiles", credit: new Cesium.Credit("内网影像地图"), maximumLevel: 18 }) ); } else if (type === 'vec_c') { // 内网矢量地图 tiandituLayers.baseLayer = viewer.imageryLayers.addImageryProvider( new Cesium.WebMapTileServiceImageryProvider({ url: ${baseUrl}/vec_c/wmts, layer: "vec", style: "default", tileMatrixSetID: "c", format: "tiles", credit: new Cesium.Credit("内网矢量地图"), maximumLevel: 18 }) ); } } else { // 外网天地图服务 - 支持c和w投影 // 根据投影类型动态构建URL const baseUrlTemplate = https://t{s}.tianditu.gov.cn/{layer}_${projectionType.value}/wmts?tk=${TIANDITU_TOKEN}; // 图层配置映射表 - 根据投影类型调整图层名称 const layerConfigs = { img: { layer: "img", credit: "天地图影像" }, img_c: { baseLayer: { layer: "img", credit: "天地图影像" }, annotationLayer: { layer: projectionType.value === 'c' ? "cia" : "cia_w", credit: "天地图注记" } }, vec: { layer: "vec", credit: "天地图矢量" }, vec_c: { baseLayer: { layer: "vec", credit: "天地图矢量" }, annotationLayer: { layer: projectionType.value === 'c' ? "cva" : "cva_w", credit: "天地图注记" } }, ter: { layer: "ter", credit: "天地图地形" } }; const config = layerConfigs[type]; if (!config) return; // 添加基础图层 tiandituLayers.baseLayer = viewer.imageryLayers.addImageryProvider( new Cesium.WebMapTileServiceImageryProvider({ url: baseUrlTemplate.replace('{layer}', config.layer || config.baseLayer.layer), layer: config.layer || config.baseLayer.layer, style: "default", tileMatrixSetID: projectionType.value, // 使用选择的投影类型 format: "tiles", credit: new Cesium.Credit(config.credit || config.baseLayer.credit), subdomains: ['0', '1', '2', '3', '4', '5', '6', '7'], maximumLevel: 18 }) ); // 添加注记图层(如果需要) if (config.annotationLayer) { tiandituLayers.annotationLayer = viewer.imageryLayers.addImageryProvider( new Cesium.WebMapTileServiceImageryProvider({ url: baseUrlTemplate.replace('{layer}', config.annotationLayer.layer), layer: config.annotationLayer.layer, style: "default", tileMatrixSetID: projectionType.value, // 使用选择的投影类型 format: "tiles", credit: new Cesium.Credit(config.annotationLayer.credit), subdomains: ['0', '1', '2', '3', '4', '5', '6', '7'], maximumLevel: 18 }) ); } } }; // // 加载株洲矢量数据 // const loadZhuzhouVector = async (viewer) => { // try { // // 加载株洲市整体边界 // const cityDataSource = await Cesium.GeoJsonDataSource.load( // "https://geo.datav.aliyun.com/areas_v3/bound/geojson?code=430200", // { // clampToGround: true, // stroke: Cesium.Color.GREEN.withAlpha(0.8), // strokeWidth: 2, // fill: Cesium.Color.WHITE.withAlpha(0.3) // } // ); // viewer.dataSources.add(cityDataSource); // // 加载株洲各区县边界 // const countyDataSource = await Cesium.GeoJsonDataSource.load( // "https://geo.datav.aliyun.com/areas_v3/bound/geojson?code=430200_full", // { // clampToGround: true, // stroke: Cesium.Color.WHITE, // strokeWidth: 1, // fill: Cesium.Color.TRANSPARENT // } // ); // viewer.dataSources.add(countyDataSource); // // 添加区县标签 // countyDataSource.entities.values.forEach(entity => { // if (entity.polygon && entity.properties && entity.properties.name) { // const hierarchy = entity.polygon.hierarchy.getValue(Cesium.JulianDate.now()); // const center = Cesium.BoundingSphere.fromPoints(hierarchy.positions).center; // entity.label = { // text: entity.properties.name, // font: '18px 黑体', // fillColor: Cesium.Color.WHITE, // outlineColor: Cesium.Color.BLACK, // outlineWidth: 3, // style: Cesium.LabelStyle.FILL_AND_OUTLINE, // verticalOrigin: Cesium.VerticalOrigin.CENTER, // horizontalOrigin: Cesium.HorizontalOrigin.CENTER, // pixelOffset: new Cesium.Cartesian2(0, 0), // disableDepthTestDistance: Number.POSITIVE_INFINITY, // scaleByDistance: new Cesium.NearFarScalar(1e3, 1.0, 1e6, 0.5) // }; // entity.position = center; // } // }); // // 定位到株洲范围 // const rectangle = Cesium.Rectangle.fromDegrees(113.50, 24.94, 113.60, 26.84); // viewer.camera.flyTo({ // destination: rectangle, // orientation: { // heading: Cesium.Math.toRadians(0), // pitch: Cesium.Math.toRadians(-70), // roll: 0 // }, // duration: 2 // }); // } catch (error) { // console.error("加载株洲数据失败:", error); // const chinaRectangle = Cesium.Rectangle.fromDegrees(73.0, 3.0, 136.0, 59.0); // viewer.camera.flyTo({ // destination: chinaRectangle // }); // } // }; // 修改加载石河子矢量数据 // 保存石河子范围矩形 const shiheziRectangle = ref(null); // 加载石河子矢量数据(新增函数) const loadShiheziVector = async (viewer, projectionType = 'c') => { try { // 清除现有石河子数据 const dataSources = viewer.dataSources; for (let i = dataSources.length - 1; i >= 0; i--) { if (dataSources.get(i).name === 'shihezi') { dataSources.remove(dataSources.get(i)); } } // 加载石河子市整体边界 const cityDataSource = await Cesium.GeoJsonDataSource.load( "https://geo.datav.aliyun.com/areas_v3/bound/geojson?code=659001", { clampToGround: true, stroke: Cesium.Color.GREEN.withAlpha(0.8), strokeWidth: 2, fill: Cesium.Color.WHITE.withAlpha(0.3), name: 'shihezi' // 添加标识 } ); viewer.dataSources.add(cityDataSource); // 添加石河子市标签 cityDataSource.entities.values.forEach(entity => { if (entity.polygon && entity.properties && entity.properties.name) { const hierarchy = entity.polygon.hierarchy.getValue(Cesium.JulianDate.now()); const positions = hierarchy.positions; // 根据投影类型转换坐标 let center; if (projectionType === 'c') { // 经纬度投影直接使用地理中心 center = Cesium.BoundingSphere.fromPoints(positions).center; } else { // 墨卡托投影需要转换坐标 const cartographicPositions = positions.map(pos => Cesium.Cartographic.fromCartesian(pos) ); // 计算平均经纬度 const avgLon = cartographicPositions.reduce((sum, pos) => sum + pos.longitude, 0) / cartographicPositions.length; const avgLat = cartographicPositions.reduce((sum, pos) => sum + pos.latitude, 0) / cartographicPositions.length; // 转换为墨卡托坐标 center = Cesium.Cartesian3.fromDegrees( Cesium.Math.toDegrees(avgLon), Cesium.Math.toDegrees(avgLat) ); } entity.label = { text: "石河子市", font: '18px 黑体', fillColor: Cesium.Color.WHITE, outlineColor: Cesium.Color.BLACK, outlineWidth: 3, style: Cesium.LabelStyle.FILL_AND_OUTLINE, verticalOrigin: Cesium.VerticalOrigin.CENTER, horizontalOrigin: Cesium.HorizontalOrigin.CENTER, pixelOffset: new Cesium.Cartesian2(0, 0), disableDepthTestDistance: Number.POSITIVE_INFINITY, scaleByDistance: new Cesium.NearFarScalar(1e3, 1.0, 1e6, 0.5) }; entity.position = center; } }); // 保存石河子范围 const positions = cityDataSource.entities.values[0].polygon.hierarchy.getValue().positions; const cartographicPositions = positions.map(pos => Cesium.Cartographic.fromCartesian(pos) ); const minLon = Math.min(...cartographicPositions.map(p => p.longitude)); const maxLon = Math.max(...cartographicPositions.map(p => p.longitude)); const minLat = Math.min(...cartographicPositions.map(p => p.latitude)); const maxLat = Math.max(...cartographicPositions.map(p => p.latitude)); shiheziRectangle.value = new Cesium.Rectangle( minLon, minLat, maxLon, maxLat ); } catch (error) { console.error("加载石河子数据失败:", error); } }; // 定位到石河子(新增函数) const flyToShihezi = () => { if (viewer && shiheziRectangle.value) { viewer.camera.flyTo({ destination: shiheziRectangle.value, orientation: { heading: Cesium.Math.toRadians(0), pitch: Cesium.Math.toRadians(-70), roll: 0 }, duration: 1 }); } }; // 投影类型切换 const switchProjectionType = () => { if (viewer && networkType.value === 'external') { loadMapService(selectedMapType.value); // 重新加载石河子数据并定位 loadShiheziVector(viewer, projectionType.value); setTimeout(flyToShihezi, 500); } }; onMounted(async () => { try { // 设置Cesium Ion访问令牌 Cesium.Ion.defaultAccessToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiI0ZTdiZDBhZS0xNzBhLTRjZGUtOTY4NC1kYzA5ZDEyNGEyNjUiLCJpZCI6MzE2OTI5LCJpYXQiOjE3NTEzMzg2Mzh9.9QHGIwaWkUOX0NOSre5369rrf1k6bGhZu7xUQia4JmE'; // 初始化Cesium Viewer viewer = new Cesium.Viewer('cesiumContainer', { baseLayerPicker: false, timeline: false, animation: false, geocoder: false, sceneModePicker: false, navigationHelpButton: false, homeButton: false, selectionIndicator: false, infoBox: false, navigationInstructionsInitiallyVisible: false, scene3DOnly: true, terrainProvider: new Cesium.EllipsoidTerrainProvider(), imageryProvider: new Cesium.WebMapTileServiceImageryProvider({ url: https://t{s}.tianditu.gov.cn/img_w/wmts?tk=${TIANDITU_TOKEN}, layer: "img", style: "default", tileMatrixSetID: "w", subdomains: ['0', '1', '2', '3', '4', '5', '6', '7'], maximumLevel: 18 }) }); // 强制设置中国视角 viewer.camera.setView({ destination: Cesium.Rectangle.fromDegrees(73.0, 3.0, 136.0, 59.0) }); // // 加载株洲数据 // loadZhuzhouVector(viewer); // 加载石河子数据(修改为调用新函数) await loadShiheziVector(viewer); flyToShihezi(); // 加载地图服务 loadMapService(selectedMapType.value); } catch (error) { console.error("初始化失败:", error); } }); </script> <style scoped> /* 基础样式 */ * { margin: 0; padding: 0; box-sizing: border-box; font-family: "Microsoft YaHei", sans-serif; } .monitor-container { width: 100vw; height: 100vh; background: radial-gradient(circle at center, #0c2a50 0%, #0a1a35 100%); overflow: hidden; position: fixed; top: 0; left: 0; display: flex; flex-direction: column; } /* 顶部导航栏样式 - 重新布局 */ .top-bar { height: 70px; background: linear-gradient(90deg, #0a1a35 0%, #1a3a6e 50%, #0a1a35 100%); display: flex; align-items: center; justify-content: space-between; padding: 0 15px; position: relative; z-index: 100; border-bottom: 1px solid rgba(0, 150, 255, 0.3); } /* 左侧区域 */ .left-section { display: flex; align-items: center; flex: 0 0 auto; } /* 中间区域 */ .center-section { flex: 1 1 auto; display: flex; justify-content: center; } /* 右侧区域 */ .right-section { display: flex; align-items: center; flex: 0 0 auto; gap: 10px; } /* 控件组 */ .controls-group { display: flex; gap: 10px; } /* 天气模块 */ .weather-module { display: flex; align-items: center; color: white; font-size: 14px; min-width: 120px; justify-content: center; } .weather-icon { color: #ffcc00; margin-right: 8px; font-size: 16px; } /* 梯形标题样式 */ .platform-title { position: relative; z-index: 10; max-width: 500px; /* 限制最大宽度 */ } .trapezoid-bg { position: relative; padding: 0 40px; height: 70px; display: flex; align-items: center; } .trapezoid-bg::before { content: ''; position: absolute; top: 0; left: 0; right: 0; bottom: 0; background: rgba(0, 60, 113, 0.6); clip-path: polygon(0% 0%, 100% 0%, 90% 100%, 10% 100%); z-index: -1; } .platform-title h1 { font-size: 24px; font-weight: bold; background: linear-gradient(to bottom, #a2e7eb, #00f2fe); -webkit-background-clip: text; background-clip: text; color: transparent; text-shadow: 0 0 8px rgba(0, 242, 254, 0.3); white-space: nowrap; text-overflow: ellipsis; overflow: hidden; max-width: 100%; } /* 时间模块 */ .time-module { color: white; font-size: 14px; min-width: 220px; text-align: center; white-space: nowrap; } /* 所有控件统一样式 */ .network-switcher select, .map-switcher select, .projection-switcher select { background: rgba(10, 26, 53, 0.8); color: #66ffff; border: 1px solid rgba(0, 150, 255, 0.5); border-radius: 4px; padding: 6px 12px; font-size: 14px; outline: none; cursor: pointer; box-shadow: 0 0 8px rgba(0, 150, 255, 0.3); transition: all 0.3s ease; min-width: 120px; } .network-switcher select:hover, .map-switcher select:hover, .projection-switcher select:hover { background: rgba(26, 58, 110, 0.8); border-color: #00f2fe; box-shadow: 0 0 12px rgba(0, 242, 254, 0.5); } .network-switcher select:focus, .map-switcher select:focus, .projection-switcher select:focus { border-color: #00f2fe; } /* Cesium容器 */ #cesiumContainer { width: 100%; height: calc(100vh - 70px); background-color: #000; position: relative; } /* 响应式调整 */ @media (max-width: 1600px) { .platform-title h1 { font-size: 20px; } .weather-module, .time-module { font-size: 13px; } .network-switcher select, .map-switcher select, .projection-switcher select { padding: 5px 10px; font-size: 13px; min-width: 110px; } } @media (max-width: 1400px) { .platform-title h1 { font-size: 18px; } .trapezoid-bg { padding: 0 30px; } .time-module { min-width: 180px; } .controls-group { gap: 8px; } } @media (max-width: 1200px) { .platform-title h1 { font-size: 16px; } .trapezoid-bg { padding: 0 20px; } .time-module { min-width: 160px; font-size: 12px; } .network-switcher select, .map-switcher select, .projection-switcher select { padding: 4px 8px; font-size: 12px; min-width: 100px; } } @media (max-width: 992px) { .time-module { display: none; } .platform-title h1 { font-size: 14px; } .trapezoid-bg { padding: 0 15px; } .weather-module { min-width: auto; } .network-switcher select, .map-switcher select, .projection-switcher select { padding: 4px 6px; font-size: 11px; min-width: 90px; } } @media (max-width: 768px) { .weather-module { display: none; } .platform-title h1 { font-size: 12px; } .trapezoid-bg { padding: 0 10px; } .controls-group { gap: 5px; } .network-switcher select, .map-switcher select, .projection-switcher select { min-width: 80px; } } </style> 检查代码,还是有问题,切换到经纬度投影时石河子位置还是不对,没有切换

<template> <Search @location-selected="handleLocationSelected" /> <LocationBar v-if="loaded" :update-interval="100" :use-dms-format="useDmsFormat" /> </template> <style> /* @import "/temp/css/divGraphic.css"; */ </style> <script setup lang="ts"> import { computed, onUnmounted, onMounted, reactive } from "vue"; import LocationBar from "./location-bar.vue"; import Search from "./search.vue"; import initMap from "./init"; import { ref } from "vue"; import { throttle } from 'lodash'; import { loadRipplePoints, createMultipleRippleCircles } from './circle.js'; import { $prototype } from "../../main.ts"; const miniMapContainer = ref<HTMLElement>(); let viewIndicator: Rectangle; // 视图指示器样式 const currentPosition = reactive({ longitude: 113.361538, latitude: 27.339318, }); // 株洲市范围常量 const ZHUZHOU_EXTENT = { west: 112.5, // 株洲市西边界 east: 114.5, // 株洲市东边界 south: 26.0, // 株洲市南边界 north: 28.0 // 株洲市北边界 }; const rippleEntities = ref<any[]>([]); // 存储波纹圆实体 const heightThreshold = 80000; // 高度阈值(米),高于此值隐藏波纹圆 // 修复1:重新定义 indicatorStyle 为 ref const indicatorStyle = ref({ left: '50%', top: '50%', display: "block" }); const updateRippleVisibility = throttle(() => { if (!$prototype.$map || rippleEntities.value.length === 0) return; // 修复1:将 shouldShow 提取到块级作用域外部 let shouldShow = false; // 获取相机高度 const cartographic = $prototype.$map.camera.positionCartographic; // 修复2:添加空值检查 if (cartographic) { const cameraHeight = cartographic.height; shouldShow = cameraHeight > heightThreshold; } // 修复3:确保 shouldShow 已定义 rippleEntities.value.forEach(entity => { entity.show = shouldShow; }); }, 200); // 更新指示器位置 const updateIndicatorPosition = () => { if (!$prototype.$map) return; const camera = $prototype.$map.camera; const rect = camera.computeViewRectangle(); if (!rect) return; // 计算在株洲市范围内的相对位置 const center = Cesium.Rectangle.center(rect); const lon = Cesium.Math.toDegrees(center.longitude); const lat = Cesium.Math.toDegrees(center.latitude); // 确保位置在株洲市范围内 const constrainedLon = Math.max(ZHUZHOU_EXTENT.west, Math.min(ZHUZHOU_EXTENT.east, lon)); const constrainedLat = Math.max(ZHUZHOU_EXTENT.south, Math.min(ZHUZHOU_EXTENT.north, lat)); const lonPercent = ((constrainedLon - ZHUZHOU_EXTENT.west) / (ZHUZHOU_EXTENT.east - ZHUZHOU_EXTENT.west)) * 100; const latPercent = 100 - ((constrainedLat - ZHUZHOU_EXTENT.south) / (ZHUZHOU_EXTENT.north - ZHUZHOU_EXTENT.south)) * 100; // 更新CSS指示器 indicatorStyle.value = { left: ${lonPercent}%, top: ${latPercent}%, display: "block" }; }; // 更新鹰眼地图 - 只更新指示器位置 const updateOverview = () => { if (!$prototype.$map || !overviewViewer.value) return; // 获取主地图的当前视图中心 const rectangle = $prototype.$map.camera.computeViewRectangle(); if (!rectangle) return; // 更新指示器位置 updateIndicatorPosition(); }; const overviewViewer = ref(null); // 初始化鹰眼地图 - 使用全球底图+株洲市叠加层 const initMiniMap = () => { Cesium.Ion.defaultAccessToken = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiIxMDhlNDdmYy03NzFhLTQ1ZTQtOWQ3NS1lZDAzNDc3YjE4NDYiLCJpZCI6MzAxNzQyLCJpYXQiOjE3NDcwNTMyMDN9.eaez8rQxVbPv2LKEU0sMDclPWyHKhh1tR27Vg-_rQSM"; if (!miniMapContainer.value) return; // 创建全球底图提供器 const worldProvider = new Cesium.UrlTemplateImageryProvider({ url: "https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}", minimumLevel: 0, maximumLevel: 19, tilingScheme: new Cesium.WebMercatorTilingScheme(), }); // 创建株洲市专用影像提供器 const zhuzhouProvider = new Cesium.UrlTemplateImageryProvider({ url: "http://124.232.190.30:9000/proxy/pk1725866655224/map/zzzsyx_18/{z}/{x}/{y}.png", minimumLevel: 1, maximumLevel: 17, tilingScheme: new Cesium.WebMercatorTilingScheme(), }); // 鹰眼地图初始化 - 使用全球底图 overviewViewer.value = new Cesium.Viewer(miniMapContainer.value, { sceneMode: Cesium.SceneMode.SCENE2D, baseLayerPicker: false, homeButton: false, timeline: false, navigationHelpButton: false, animation: false, scene3DOnly: true, selectionIndicator: false, infoBox: false, imageryProvider: worldProvider, // 使用全球底图 terrainProvider: undefined, mapProjection: new Cesium.WebMercatorProjection(), skyBox: false, skyAtmosphere: false }); // 添加株洲市影像作为叠加层 const zhuzhouLayer = overviewViewer.value.imageryLayers.addImageryProvider(zhuzhouProvider); // 设置固定视野为株洲市范围 overviewViewer.value.camera.setView({ destination: Cesium.Rectangle.fromDegrees( ZHUZHOU_EXTENT.west, ZHUZHOU_EXTENT.south, ZHUZHOU_EXTENT.east, ZHUZHOU_EXTENT.north ) }); // 隐藏控件 const toolbar = overviewViewer.value.container.getElementsByClassName("cesium-viewer-toolbar")[0]; if (toolbar) toolbar.style.display = "none"; // 隐藏版权信息 overviewViewer.value.cesiumWidget.creditContainer.style.display = "none"; // 初始化视图指示器 initRectangle(); // 新增:添加白色边界到鹰眼地图 const addBoundaryToMiniMap = () => { overviewViewer.value.dataSources.add( Cesium.GeoJsonDataSource.load("/shp_zz.geojson", { stroke: Cesium.Color.WHITE, fill: false, clampToGround: true, describe: null, }) ).then((dataSource) => { const entities = dataSource.entities.values; for (let entity of entities) { if (entity.polyline) { entity.polyline.fill = false; // 设置线宽和样式 entity.polyline.width = 2; entity.polyline.material = new Cesium.PolylineOutlineMaterialProperty({ color: Cesium.Color.WHITE, outlineWidth: 1, outlineColor: Cesium.Color.BLACK }); } } }).catch((error) => { console.error("加载鹰眼地图边界失败:", error); }); }; // 调用添加边界函数 addBoundaryToMiniMap(); }; // 初始化视图指示器 function initRectangle() { // 创建视图指示器(株洲市范围框) viewIndicator = overviewViewer.value.entities.add({ rectangle: { coordinates: Cesium.Rectangle.fromDegrees( ZHUZHOU_EXTENT.west, ZHUZHOU_EXTENT.south, ZHUZHOU_EXTENT.east, ZHUZHOU_EXTENT.north ), material: Cesium.Color.RED.withAlpha(0.3), outline: true, outlineColor: Cesium.Color.RED, outlineWidth: 2, }, }); } const loaded = ref(false); const useDmsFormat = ref(false); function addDemoGraphics() { const chinaBoundary = $prototype.$map.dataSources.add( Cesium.GeoJsonDataSource.load("/shp_zz.geojson", { stroke: Cesium.Color.WHITE, fill: false, clampToGround: true, describe: null, }) ); chinaBoundary.then((dataSource) => { const entities = dataSource.entities.values; for (let entity of entities) { if (entity.polyline) { entity.polyline.fill = false; } } }); } function flyToDes() { const center = Cesium.Cartesian3.fromDegrees(-98.0, 40.0); $prototype.$map.camera.flyTo({ destination: new Cesium.Cartesian3( -2432812.6687511606, 5559483.804371395, 2832009.419525571 ), orientation: { heading: 6.283185307179421, pitch: -1.0472145569408116, roll: 6.2831853071795205, }, complete: function () {}, }); } // 监听主地图相机变化 const setupCameraListener = () => { $prototype.$map.camera.changed.addEventListener(updateOverview); }; // 鹰眼地图点击处理 const handleMiniMapClick = (event: MouseEvent) => { if (!miniMapContainer.value || !overviewViewer.value) return; const rect = miniMapContainer.value.getBoundingClientRect(); const x = event.clientX - rect.left; const y = event.clientY - rect.top; // 计算在固定范围内的相对位置 const xPercent = (x / rect.width) * 100; const yPercent = (y / rect.height) * 100; // 转换为株洲市范围内的经纬度 const lon = ZHUZHOU_EXTENT.west + (xPercent / 100) * (ZHUZHOU_EXTENT.east - ZHUZHOU_EXTENT.west); const lat = ZHUZHOU_EXTENT.north - (yPercent / 100) * (ZHUZHOU_EXTENT.north - ZHUZHOU_EXTENT.south); // 主地图飞向点击位置 $prototype.$map.camera.flyTo({ destination: Cesium.Cartesian3.fromDegrees(lon, lat, 1000000), }); }; function addImage() { var rightImageProvider = new Cesium.UrlTemplateImageryProvider({ name: "影像图", type: "xyz", layer: "vec_d", url: "http://124.232.190.30:9000/proxy/pk1725866655224/map/zzzsyx_18/{z}/{x}/{y}.png", minimumLevel: 1, maximumLevel: 17, crs: "EPSG:3857", }); $prototype.$map.imageryLayers.addImageryProvider(rightImageProvider); rightImageProvider.splitDirection = Cesium.SplitDirection.right; } onMounted(() => { initMap(); addImage(); loaded.value = true; addDemoGraphics(); flyToDes(); // 修复6:确保正确的初始化顺序 setTimeout(() => { initMiniMap(); setupCameraListener(); // 初始更新 updateOverview(); }, 1000); (async () => { try { const ripplePoints = await loadRipplePoints(); rippleEntities.value = createMultipleRippleCircles( $prototype.$map, ripplePoints ); $prototype.$map.camera.changed.addEventListener(updateRippleVisibility); updateRippleVisibility(); } catch (error) { console.error('加载波纹圆失败:', error); } })(); }); let currentMarker: any = null; const createMarker = (location: { lng: number; lat: number; name: string }) => { if (currentMarker) { $prototype.$map.entities.remove(currentMarker); } currentMarker = $prototype.$map.entities.add({ position: Cesium.Cartesian3.fromDegrees( location.lng, location.lat, 50 ), point: { pixelSize: 200, color: Cesium.Color.RED, outlineColor: Cesium.Color.WHITE, outlineWidth: 2, heightReference: Cesium.HeightReference.RELATIVE_TO_GROUND, }, label: { text: location.name, font: "40px sans-serif", fillColor: Cesium.Color.WHITE, outlineColor: Cesium.Color.BLACK, outlineWidth: 1, verticalOrigin: Cesium.VerticalOrigin.BOTTOM, pixelOffset: new Cesium.Cartesian2(0, -20), heightReference: Cesium.HeightReference.RELATIVE_TO_GROUND, distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 10000), }, description: ${location.name} 经度:${location.lng.toFixed(6)} 纬度:${location.lat.toFixed(6)} , }); return currentMarker; }; const handleLocationSelected = (location: { lng: number; lat: number; name: string; }) => { if (!$prototype.$map) return; const destination = Cesium.Cartesian3.fromDegrees( location.lng, location.lat, 200 ); $prototype.$map.camera.flyTo({ destination, orientation: { heading: Cesium.Math.toRadians(0), pitch: Cesium.Math.toRadians(-45), roll: 0, }, duration: 2, complete: () => { createMarker(location); }, }); }; onUnmounted(() => { if ($prototype.$map) { $prototype.$map.destroy(); $prototype.$map = null; } if ($prototype.$map) { $prototype.$map.camera.changed.removeEventListener(updateRippleVisibility); } console.log("组件销毁"); }); const emit = defineEmits(["onload", "onclick"]); const initMars3d = async (option: any) => { emit("onclick", true); emit("onload", $prototype.$map); }; </script> <style lang="less"> /**cesium 工具按钮栏*/ .cesium-viewer-toolbar { top: auto !important; bottom: 35px !important; left: 12px !important; right: auto !important; } .cesium-toolbar-button img { height: 100%; } .cesium-viewer-toolbar > .cesium-toolbar-button, .cesium-navigationHelpButton-wrapper, .cesium-viewer-geocoderContainer { margin-bottom: 5px; float: left; clear: both; text-align: center; } .cesium-button { background-color: rgba(23, 49, 71, 0.8); color: #e6e6e6; fill: #e6e6e6; box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3); line-height: 32px; } .cesium-button:hover { background: #3ea6ff; } /**cesium 底图切换面板*/ .cesium-baseLayerPicker-dropDown { bottom: 0; left: 40px; max-height: 700px; margin-bottom: 5px; background-color: rgba(23, 49, 71, 0.8); } /**cesium 帮助面板*/ .cesium-navigation-help { top: auto; bottom: 0; left: 40px; transform-origin: left bottom; background: none; background-color: rgba(23, 49, 71, 0.8); .cesium-navigation-help-instructions { background: none; } .cesium-navigation-button { background: none; } .cesium-navigation-button-selected, .cesium-navigation-button-unselected:hover { background: rgba(0, 138, 255, 0.2); } } /**cesium 二维三维切换*/ .cesium-sceneModePicker-wrapper { width: auto; } .cesium-sceneModePicker-wrapper .cesium-sceneModePicker-dropDown-icon { float: right; margin: 0 3px; } /**cesium POI查询输入框*/ .cesium-viewer-geocoderContainer .search-results { left: 0; right: 40px; width: auto; z-index: 9999; } .cesium-geocoder-searchButton { background-color: rgba(23, 49, 71, 0.8); } .cesium-viewer-geocoderContainer .cesium-geocoder-input { background-color: rgba(63, 72, 84, 0.7); } .cesium-viewer-geocoderContainer .cesium-geocoder-input:focus { background-color: rgba(63, 72, 84, 0.9); } .cesium-viewer-geocoderContainer .search-results { background-color: rgba(23, 49, 71, 0.8); } /**cesium info信息框*/ .cesium-infoBox { top: 50px; background-color: rgba(23, 49, 71, 0.8); } .cesium-infoBox-title { background-color: rgba(23, 49, 71, 0.8); } /**cesium 任务栏的FPS信息*/ .cesium-performanceDisplay-defaultContainer { top: auto; bottom: 35px; right: 50px; } .cesium-performanceDisplay-ms, .cesium-performanceDisplay-fps { color: #fff; } /**cesium tileset调试信息面板*/ .cesium-viewer-cesiumInspectorContainer { top: 10px; left: 10px; right: auto; } .cesium-cesiumInspector { background-color: rgba(23, 49, 71, 0.8); } /**覆盖mars3d内部控件的颜色等样式*/ .mars3d-compass .mars3d-compass-outer { fill: rgba(23, 49, 71, 0.8); } .mars3d-contextmenu-ul, .mars3d-sub-menu { background-color: rgba(23, 49, 71, 0.8); > li > a:hover, > li > a:focus, > li > .active { background-color: #3ea6ff; } > .active > a, > .active > a:hover, > .active > a:focus { background-color: #3ea6ff; } } /* Popup样式*/ .mars3d-popup-color { color: #ffffff; } .mars3d-popup-background { background: rgba(23, 49, 71, 0.8); } .mars3d-popup-content { margin: 15px; } .mars3d-template-content label { padding-right: 6px; } .mars3d-template-titile { border-bottom: 1px solid #3ea6ff; } .mars3d-template-titile a { font-size: 16px; } .mars3d-tooltip { background: rgba(23, 49, 71, 0.8); border: 1px solid rgba(23, 49, 71, 0.8); } .mars3d-popup-btn-custom { padding: 3px 10px; border: 1px solid #209ffd; background: #209ffd1c; } .mars-dialog .mars-dialog__content { height: 100%; width: 100%; overflow: auto; padding: 5px; } .image { border: solid 2px #fff; } .content { height: 90%; padding-top: 10px; overflow-x: auto; overflow-y: auto; } .content-text { padding: 0 10px; text-indent: 30px; font-size: 17px; } .details-video { width: 100%; height: 760px; background-color: #000; } :where(.css-lt97qq9).ant-space { display: inline-flex; } :where(.css-lt97qq9).ant-space-align-center { align-items: center; } :where(.css-lt97qq9).ant-image .ant-image-mask { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; color: #fff; background: rgba(0, 0, 0, 0.5); cursor: pointer; opacity: 0; transition: opacity 0.3s; } :where(.css-lt97qq9).ant-image .ant-image-mask .ant-image-mask-info { overflow: hidden; white-space: nowrap; text-overflow: ellipsis; padding: 0 4px; } :where(.css-1t97qq9)[class^="ant-image"] [class^="ant-image"], :where(.css-1t97qq9)[class*=" ant-image"] [class^="ant-image"], :where(.css-1t97qq9)[class^="ant-image"] [class*=" ant-image"], :where(.css-1t97qq9)[class*=" ant-image"] [class*=" ant-image"] { box-sizing: border-box; } :where(.css-lt97qq9).ant-image .ant-image-img { width: 100%; height: auto; vertical-align: middle; } </style> <style scoped> .mini-map-container { position: relative; width: 100%; height: 100%; } .main-viewer { width: 100%; height: 100%; } .mini-map { position: absolute; right: 3vw; bottom: 6vh; width: 12vw; height: 17vh; border: 2px solid #fff; box-shadow: 0 0 10px rgba(0, 0, 0, 0.5); z-index: 999; cursor: pointer; overflow: hidden; } .location-indicator { position: absolute; width: 14px; height: 14px; background: #ff3e3e; border: 2px solid white; border-radius: 50%; transform: translate(-50%, -50%); box-shadow: 0 0 15px rgba(255, 62, 62, 1); z-index: 100; } .view-rectangle { position: absolute; border: 2px solid #00f2fe; z-index: 99; pointer-events: none; box-shadow: 0 0 20px rgba(0, 242, 254, 0.7); } /* 相机聚焦样式 - 四个角折角 */ .corner { position: absolute; width: 25px; height: 25px; z-index: 100; pointer-events: none; } .corner::before, .corner::after { content: ""; position: absolute; background: #00f2fe; box-shadow: 0 0 10px rgba(0, 242, 254, 0.8); } .corner-top-left { top: -2px; left: -2px; } .corner-top-left::before { top: 0; left: 0; width: 15px; height: 3px; } .corner-top-left::after { top: 0; left: 0; width: 3px; height: 15px; } .corner-top-right { top: -2px; right: -2px; } .corner-top-right::before { top: 0; right: 0; width: 15px; height: 3px; } .corner-top-right::after { top: 0; right: 0; width: 3px; height: 15px; } .corner-bottom-left { bottom: -2px; left: -2px; } .corner-bottom-left::before { bottom: 0; left: 0; width: 15px; height: 3px; } .corner-bottom-left::after { bottom: 0; left: 0; width: 3px; height: 15px; } .corner-bottom-right { bottom: -2px; right: -2px; } .corner-bottom-right::before { bottom: 0; right: 0; width: 15px; height: 3px; } .corner-bottom-right::after { bottom: 0; right: 0; width: 3px; height: 15px; } .camera-icon { position: absolute; top: 10px; right: 10px; color: #00f2fe; font-size: 24px; z-index: 100; text-shadow: 0 0 10px rgba(0, 242, 254, 0.8); } .focus-effect { position: absolute; top: 0; left: 0; width: 100%; height: 100%; pointer-events: none; z-index: 98; border: 2px solid rgba(0, 242, 254, 0.2); border-radius: 5px; box-shadow: inset 0 0 30px rgba(0, 242, 254, 0.1); } .pulse { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 10px; height: 10px; border-radius: 50%; background: rgba(0, 242, 254, 0.7); box-shadow: 0 0 0 0 rgba(0, 242, 254, 0.7); animation: pulse 2s infinite; } ::v-deep.cesium-viewer-toolbar { display: none; } </style> 如上所示代码,还是没有显示白色边界

import CircleRippleMaterialProperty from “./CircleRippleMaterialProperty”; // 从 public/circle.json 加载坐标数据 export async function loadRipplePoints() { const response = await fetch(“/circle.json”); // 注意路径是相对于 public 目录 return await response.json(); } // 创建多个波纹圆 export function createMultipleRippleCircles( viewer, ripplePoints, options = {} ) { const zIndex = options.zIndex || 1000; // 可选传入 zIndex ripplePoints.forEach((point) => { const position = Cesium.Cartesian3.fromDegrees( point.longitude, point.latitude ); viewer.entities.add({ name: point.name, position: position, ellipse: { semiMinorAxis: 5000.0, semiMajorAxis: 8000.0, height: 0, zIndex: zIndex, // 设置 zIndex 提升层级 material: new CircleRippleMaterialProperty({ color: Cesium.Color.fromCssColorString("#00FFFF").withAlpha(0.8), speed: 30.0, count: 2, gradient: 0.2, }), }, }); }); } 如图所示生成动态波纹圆代码,生成是生成了,但是波纹圆一旦放大就变得很模糊,看起来感觉断断续续的,有问题,你结合下面的vue文件找一些原因更改,但是注意最好不要更改vue文件,或者最小量更改: <Search /> <LocationBar v-if="loaded" :update-interval="100" :use-dms-format="useDmsFormat" /> </template> <style> /* @import "/temp/css/divGraphic.css"; */ </style> <script setup lang="ts"> import { computed, onUnmounted, onMounted, reactive } from "vue"; import LocationBar from "./location-bar.vue"; import Search from "./search.vue"; import initMap from "./init"; import { ref } from "vue"; import { loadRipplePoints, createMultipleRippleCircles } from './circle.js'; import { $ prototype } from "../../main.ts"; const miniMapContainer = ref<HTMLElement>(); let viewIndicator: Rectangle; // 视图指示器样式 const currentPosition = reactive({ longitude: 113.361538, latitude: 27.339318, }); // 更新指示器位置 const updateIndicatorPosition = () => { if (!$ prototype.$ map) return; const camera = $ prototype.$ map.camera; const rect = camera.computeViewRectangle(); if (!rect) return; // 计算指示器在鹰眼中的位置 const miniMapWidth = miniMapContainer.value?.clientWidth || 200; const miniMapHeight = miniMapContainer.value?.clientHeight || 150; // 更新CSS指示器(用于点击交互) const westPercent = (((rect.west * 180) / Math.PI + 180) / 360) * 100; const eastPercent = (((rect.east * 180) / Math.PI + 180) / 360) * 100; const southPercent = ((90 - (rect.south * 180) / Math.PI) / 180) * 100; const northPercent = ((90 - (rect.north * 180) / Math.PI) / 180) * 100; indicatorStyle.value = { left: ${westPercent}%, top: ${northPercent}%, width: ${eastPercent - westPercent}%, height: ${southPercent - northPercent}%, }; return rect; }; // 更新鹰眼地图 const updateOverview = () => { if (!$ prototype.$ map || !overviewViewer.value) return; // 获取主地图的当前视图范围 const rectangle = $ prototype.$ map.camera.computeViewRectangle(); if (!rectangle) return; // 更新当前中心位置 const center = Cesium.Rectangle.center(rectangle); currentPosition.longitude = Cesium.Math.toDegrees(center.longitude); currentPosition.latitude = Cesium.Math.toDegrees(center.latitude); // 计算视图矩形在鹰眼地图上的位置 const scene = overviewViewer.value.scene; const canvas = scene.canvas; const southwest = Cesium.Cartesian3.fromRadians( rectangle.west, rectangle.south ); const northeast = Cesium.Cartesian3.fromRadians( rectangle.east, rectangle.north ); const swPixel = Cesium.SceneTransforms.wgs84ToWindowCoordinates( scene, southwest ); const nePixel = Cesium.SceneTransforms.wgs84ToWindowCoordinates( scene, northeast ); if (!swPixel || !nePixel) return; // 更新视图矩形 viewRectangle.width = Math.abs(nePixel.x - swPixel.x); viewRectangle.height = Math.abs(nePixel.y - swPixel.y); viewRectangle.left = Math.min(swPixel.x, nePixel.x); viewRectangle.top = Math.min(swPixel.y, nePixel.y); syncView(); }; const overviewViewer = ref(null); const initMiniMap = () => { Cesium.Ion.defaultAccessToken = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiIxMDhlNDdmYy03NzFhLTQ1ZTQtOWQ3NS1lZDAzNDc3YjE4NDYiLCJpZCI6MzAxNzQyLCJpYXQiOjE3NDcwNTMyMDN9.eaez8rQxVbPv2LKEU0sMDclPWyHKhh1tR27Vg-_rQSM"; if (!miniMapContainer.value) return; // 鹰眼地图初始化 overviewViewer.value = new Cesium.Viewer(miniMapContainer.value, { sceneMode: Cesium.SceneMode.SCENE2D, baseLayerPicker: false, homeButton: false, timeline: false, navigationHelpButton: false, animation: false, scene3DOnly: true, selectionIndicator: false, infoBox: false, imageryProvider: new Cesium.ArcGisMapServerImageryProvider({ url: "https://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer", }), terrainProvider: window.Cesium.createWorldTerrain(), }); var toolbar = overviewViewer.value.container.getElementsByClassName( "cesium-viewer-toolbar" )[0]; if (toolbar) { toolbar.style.display = "none"; } // 隐藏鹰眼控件 overviewViewer.value.cesiumWidget.creditContainer.style.display = "none"; // 设置鹰眼固定视角 // overviewViewer.value.camera.setView({ // destination: new Cesium.Cartesian3( // -2432812.6687511606, // 5559483.804371395, // 2832009.419525571 // ), // }); }; const syncView = () => { if (!$ prototype.$ map || !overviewViewer.value) return; const rectangle = $ prototype.$ map.camera.computeViewRectangle(); if (!rectangle) return; // 鹰眼地图飞往相同范围 overviewViewer.value.camera.flyTo({ destination: Cesium.Rectangle.fromDegrees( Cesium.Math.toDegrees(rectangle.west), Cesium.Math.toDegrees(rectangle.south), Cesium.Math.toDegrees(rectangle.east), Cesium.Math.toDegrees(rectangle.north) ), duration: 1.5, }); }; function initRectangle() { overviewViewer.value.camera.flyTo({ destination: Cesium.Cartesian3.fromDegrees(113.200224, 27.004546, 50000), orientation: { heading: 3.1769448901508976, pitch: -0.2880443992926125, roll: 6.283184370499525, }, duration: 3.0, // 飞行时间(秒) }); // 创建视图指示器 viewIndicator = overviewViewer.value.entities.add({ rectangle: { // coordinates: new window.Cesium.CallbackProperty( // updateIndicatorPosition, // false // ), coordinates: new Cesium.CallbackProperty(function () { // 必须返回 Cesium.Rectangle 对象 return new Cesium.Rectangle( Cesium.Math.toRadians(113.125), // 西经 Cesium.Math.toRadians(26.9541), // 南纬 Cesium.Math.toRadians(113.2542), // 东经 Cesium.Math.toRadians(27.2545225) // 北纬 ); }, false), // false 表示不持续更新(性能优化) material: Cesium.Color.RED.withAlpha(0.3), outline: true, outlineColor: Cesium.Color.RED, outlineWidth: 2, }, }); overviewViewer.value.flyTo(viewIndicator, { duration: 2, // 飞行持续时间(秒) offset: new Cesium.HeadingPitchRange( Cesium.Math.toRadians(0), // 朝向角度(0表示正北) Cesium.Math.toRadians(-45), // 俯仰角度(-45度俯视) 1000000 // 距离目标的距离(米) ), }); console.log(overviewViewer.value.entities); } const viewRectangle = reactive({ width: 0, height: 0, left: 0, top: 0, }); // 指示器样式计算 const indicatorStyle = computed(() => { if (!overviewViewer.value) return {}; // 将经纬度转换为屏幕坐标 const position = Cesium.Cartesian3.fromDegrees( currentPosition.longitude, currentPosition.latitude ); const scene = overviewViewer.value.scene; const canvas = scene.canvas; const pixel = Cesium.SceneTransforms.wgs84ToWindowCoordinates( scene, position ); if (!pixel) return { display: "none" }; return { left: ${pixel.x}px, top: ${pixel.y}px, display: "block", }; }); // 视图矩形样式计算 const rectangleStyle = computed(() => { return { width: ${viewRectangle.width}px, height: ${viewRectangle.height}px, left: ${viewRectangle.left}px, top: ${viewRectangle.top}px, display: viewRectangle.width > 0 ? "block" : "none", }; }); const loaded = ref(false); const useDmsFormat = ref(false); function addDemoGraphics() { const chinaBoundary = $ prototype.$ map.dataSources.add( Cesium.GeoJsonDataSource.load("/shp_zz.geojson", { stroke: Cesium.Color.WHITE, fill: false, clampToGround: true, describe: null, // 禁用默认样式描述 }) ); // 添加标签 chinaBoundary.then((dataSource) => { const entities = dataSource.entities.values; for (let entity of entities) { if (entity.polyline) { entity.polyline.fill = false; // entity.polyline.material.color = Cesium.Color.BLACK; // 彻底移除材质 } } }); } function flyToDes() { const center = Cesium.Cartesian3.fromDegrees(-98.0, 40.0); // map.camera.lookAt(center, new Cesium.Cartesian3(0.0, -4790000.0, 3930000.0)); // 第一视角飞行 84.330408,38.24518 $ prototype.$ map.camera.flyTo({ destination: new Cesium.Cartesian3( -2432812.6687511606, 5559483.804371395, 2832009.419525571 ), orientation: { heading: 6.283185307179421, pitch: -1.0472145569408116, roll: 6.2831853071795205, }, complete: function () { // map.camera.lookAt( // Cesium.Cartesian3.fromDegrees(113.300224, 27.004546, 500), // new Cesium.HeadingPitchRange( // 3.1769448901508976, // -0.2880443992926125, // 500 // ) // ); // map.camera.flyTo({ // destination: Cesium.Cartesian3.fromDegrees(113.300224, 27.004546, 500), // orientation: { // heading: 3.1769448901508976, // pitch: -0.2880443992926125, // roll: 6.283184370499525, // }, // duration: 3.0, // 飞行时间(秒) // }); }, }); } // 监听主地图相机变化 const setupCameraListener = () => { $ prototype.$ map.camera.changed.addEventListener(updateOverview); // viewIndicator.rectangle.coordinates = updateIndicatorPosition(); }; const handleMiniMapClick = (event: MouseEvent) => { if (!miniMapContainer.value) return; const rect = miniMapContainer.value.getBoundingClientRect(); const x = event.clientX - rect.left; const y = event.clientY - rect.top; // 计算点击位置的经纬度 const lon = (x / rect.width) * 360 - 180; const lat = 90 - (y / rect.height) * 180; // 主地图飞向点击位置 $ prototype.$ map.camera.flyTo({ destination: Cesium.Cartesian3.fromDegrees(lon, lat, 1000000), }); }; function addImage() { var rightImageProvider = new Cesium.UrlTemplateImageryProvider({ name: "影像图", type: "xyz", layer: "vec_d", url: "http://124.232.190.30:9000/proxy/pk1725866655224/map/zzzsyx_18/{z}/{x}/{y}.png", minimumLevel: 1, maximumLevel: 17, crs: "EPSG:3857", }); $ prototype.$ map.imageryLayers.addImageryProvider(rightImageProvider); rightImageProvider.splitDirection = Cesium.SplitDirection.right; } onMounted(() => { // console.clear() initMap(); addImage(); loaded.value = true; addDemoGraphics(); flyToDes(); initMiniMap(); setupCameraListener(); setTimeout(function () { initRectangle(); }, 2000); // 新增部分:加载并创建波纹圆(不影响其他逻辑) (async () => { try { const ripplePoints = await loadRipplePoints(); createMultipleRippleCircles($ prototype.$ map, ripplePoints); // 注意这里没有空格 } catch (error) { console.error('加载波纹圆失败:', error); } })(); //测试加载wmts服务的geojson格式 //此处很重要,很重要如果是4326的话就需要,如果不是4326是900913就不需要下面的了 // var options = { // url: "http://localhost:8080/geoserver/zhuzhou/gwc/service/wmts", // layer: "zhuzhou:lukou_farmland", // name: "zhuzhou:lukou_farmland", // show: true, // alpha: 1.0, // serviceType: "wmts", // type: "raster", // // rectangle: layerData.rectangle, // minimumLevel: 1, // maximumLevel: 14, // tileMatrixSetID: "EPSG:4326", // style: "", // format: "application/json;type=geojson", // }; // options.tileMatrixLabels = [...Array(20).keys()].map((level) => // ("EPSG:4326:" + level).toString() // ); // if (options.tileMatrixSetID == "EPSG:4326") { // options.tilingScheme = new Cesium.GeographicTilingScheme({ // numberOfLevelZeroTilesX: 2, // numberOfLevelZeroTilesY: 1, // }); // } // const provider = new Cesium.WebMapTileServiceImageryProvider(options); // // $ prototype.$ map.imageryLayers.remove( // // $ prototype.$ map.imageryLayers._layers[0] // // ); // $ prototype.$ map!.imageryLayers.addImageryProvider(provider); }); onUnmounted(() => { if ($ prototype.$ map) { $ prototype.$ map.destroy(); $ prototype.$ map = null; } console.log("组件销毁"); }); // onload事件将在地图渲染后触发 const emit = defineEmits(["onload", "onclick"]); const initMars3d = async (option: any) => { emit("onclick", true); emit("onload", $ prototype.$ map); }; </script> <style lang="less"> /**cesium 工具按钮栏*/ .cesium-viewer-toolbar { top: auto !important; bottom: 35px !important; left: 12px !important; right: auto !important; } .cesium-toolbar-button img { height: 100%; } .cesium-viewer-toolbar > .cesium-toolbar-button, .cesium-navigationHelpButton-wrapper, .cesium-viewer-geocoderContainer { margin-bottom: 5px; float: left; clear: both; text-align: center; } .cesium-button { background-color: rgba(23, 49, 71, 0.8); color: #e6e6e6; fill: #e6e6e6; box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3); line-height: 32px; } .cesium-button:hover { background: #3ea6ff; } /**cesium 底图切换面板*/ .cesium-baseLayerPicker-dropDown { bottom: 0; left: 40px; max-height: 700px; margin-bottom: 5px; background-color: rgba(23, 49, 71, 0.8); } /**cesium 帮助面板*/ .cesium-navigation-help { top: auto; bottom: 0; left: 40px; transform-origin: left bottom; background: none; background-color: rgba(23, 49, 71, 0.8); .cesium-navigation-help-instructions { background: none; } .cesium-navigation-button { background: none; } .cesium-navigation-button-selected, .cesium-navigation-button-unselected:hover { background: rgba(0, 138, 255, 0.2); } } /**cesium 二维三维切换*/ .cesium-sceneModePicker-wrapper { width: auto; } .cesium-sceneModePicker-wrapper .cesium-sceneModePicker-dropDown-icon { float: right; margin: 0 3px; } /**cesium POI查询输入框*/ .cesium-viewer-geocoderContainer .search-results { left: 0; right: 40px; width: auto; z-index: 9999; } .cesium-geocoder-searchButton { background-color: rgba(23, 49, 71, 0.8); } .cesium-viewer-geocoderContainer .cesium-geocoder-input { background-color: rgba(63, 72, 84, 0.7); } .cesium-viewer-geocoderContainer .cesium-geocoder-input:focus { background-color: rgba(63, 72, 84, 0.9); } .cesium-viewer-geocoderContainer .search-results { background-color: rgba(23, 49, 71, 0.8); } /**cesium info信息框*/ .cesium-infoBox { top: 50px; background-color: rgba(23, 49, 71, 0.8); } .cesium-infoBox-title { background-color: rgba(23, 49, 71, 0.8); } /**cesium 任务栏的FPS信息*/ .cesium-performanceDisplay-defaultContainer { top: auto; bottom: 35px; right: 50px; } .cesium-performanceDisplay-ms, .cesium-performanceDisplay-fps { color: #fff; } /**cesium tileset调试信息面板*/ .cesium-viewer-cesiumInspectorContainer { top: 10px; left: 10px; right: auto; } .cesium-cesiumInspector { background-color: rgba(23, 49, 71, 0.8); } /**覆盖mars3d内部控件的颜色等样式*/ .mars3d-compass .mars3d-compass-outer { fill: rgba(23, 49, 71, 0.8); } .mars3d-contextmenu-ul, .mars3d-sub-menu { background-color: rgba(23, 49, 71, 0.8); > li > a:hover, > li > a:focus, > li > .active { background-color: #3ea6ff; } > .active > a, > .active > a:hover, > .active > a:focus { background-color: #3ea6ff; } } /* Popup样式*/ .mars3d-popup-color { color: #ffffff; } .mars3d-popup-background { background: rgba(23, 49, 71, 0.8); } .mars3d-popup-content { margin: 15px; } .mars3d-template-content label { padding-right: 6px; } .mars3d-template-titile { border-bottom: 1px solid #3ea6ff; } .mars3d-template-titile a { font-size: 16px; } .mars3d-tooltip { background: rgba(23, 49, 71, 0.8); border: 1px solid rgba(23, 49, 71, 0.8); } .mars3d-popup-btn-custom { padding: 3px 10px; border: 1px solid #209ffd; background: #209ffd1c; } .mars-dialog .mars-dialog__content { height: 100%; width: 100%; overflow: auto; padding: 5px; } .image { border: solid 2px #fff; } .content { height: 90%; padding-top: 10px; overflow-x: auto; overflow-y: auto; } .content-text { padding: 0 10px; text-indent: 30px; font-size: 17px; } .details-video { width: 100%; height: 760px; background-color: #000; } :where(.css-lt97qq9).ant-space { display: inline-flex; } :where(.css-lt97qq9).ant-space-align-center { align-items: center; } :where(.css-lt97qq9).ant-image .ant-image-mask { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; color: #fff; background: rgba(0, 0, 0, 0.5); cursor: pointer; opacity: 0; transition: opacity 0.3s; } :where(.css-lt97qq9).ant-image .ant-image-mask .ant-image-mask-info { overflow: hidden; white-space: nowrap; text-overflow: ellipsis; padding: 0 4px; } :where(.css-1t97qq9)[class^="ant-image"] [class^="ant-image"], :where(.css-1t97qq9)[class*=" ant-image"] [class^="ant-image"], :where(.css-1t97qq9)[class^="ant-image"] [class*=" ant-image"], :where(.css-1t97qq9)[class*=" ant-image"] [class*=" ant-image"] { box-sizing: border-box; } :where(.css-lt97qq9).ant-image .ant-image-img { width: 100%; height: auto; vertical-align: middle; } </style> <style scoped> .mini-map-container { position: relative; width: 100%; height: 100%; } .main-viewer { width: 100%; height: 100%; } .mini-map { position: absolute; right: 3vw; bottom: 6vh; width: 12vw; height: 17vh; border: 2px solid #fff; box-shadow: 0 0 10px rgba(0, 0, 0, 0.5); z-index: 999; cursor: pointer; overflow: hidden; } .location-indicator { position: absolute; width: 14px; height: 14px; background: #ff3e3e; border: 2px solid white; border-radius: 50%; transform: translate(-50%, -50%); box-shadow: 0 0 15px rgba(255, 62, 62, 1); z-index: 100; } .view-rectangle { position: absolute; border: 2px solid #00f2fe; z-index: 99; pointer-events: none; box-shadow: 0 0 20px rgba(0, 242, 254, 0.7); } /* 相机聚焦样式 - 四个角折角 */ .corner { position: absolute; width: 25px; height: 25px; z-index: 100; pointer-events: none; } .corner::before, .corner::after { content: ""; position: absolute; background: #00f2fe; box-shadow: 0 0 10px rgba(0, 242, 254, 0.8); } .corner-top-left { top: -2px; left: -2px; } .corner-top-left::before { top: 0; left: 0; width: 15px; height: 3px; } .corner-top-left::after { top: 0; left: 0; width: 3px; height: 15px; } .corner-top-right { top: -2px; right: -2px; } .corner-top-right::before { top: 0; right: 0; width: 15px; height: 3px; } .corner-top-right::after { top: 0; right: 0; width: 3px; height: 15px; } .corner-bottom-left { bottom: -2px; left: -2px; } .corner-bottom-left::before { bottom: 0; left: 0; width: 15px; height: 3px; } .corner-bottom-left::after { bottom: 0; left: 0; width: 3px; height: 15px; } .corner-bottom-right { bottom: -2px; right: -2px; } .corner-bottom-right::before { bottom: 0; right: 0; width: 15px; height: 3px; } .corner-bottom-right::after { bottom: 0; right: 0; width: 3px; height: 15px; } .camera-icon { position: absolute; top: 10px; right: 10px; color: #00f2fe; font-size: 24px; z-index: 100; text-shadow: 0 0 10px rgba(0, 242, 254, 0.8); } .focus-effect { position: absolute; top: 0; left: 0; width: 100%; height: 100%; pointer-events: none; z-index: 98; border: 2px solid rgba(0, 242, 254, 0.2); border-radius: 5px; box-shadow: inset 0 0 30px rgba(0, 242, 254, 0.1); } .pulse { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 10px; height: 10px; border-radius: 50%; background: rgba(0, 242, 254, 0.7); box-shadow: 0 0 0 0 rgba(0, 242, 254, 0.7); animation: pulse 2s infinite; } ::v-deep.cesium-viewer-toolbar { display: none; } </style> 还有同时结合 // CircleRippleMaterialProperty.js // import * as Cesium from 'cesium'; class CircleRippleMaterialProperty { constructor(options = {}) { this._definitionChanged = new Cesium.Event(); this._color = Cesium.defaultValue(options.color, Cesium.Color.BLUE); this._speed = Cesium.defaultValue(options.speed, 5.0); this._count = Cesium.defaultValue(options.count, 4); this._gradient = Cesium.defaultValue(options.gradient, 0.2); } get isConstant() { return false; } get definitionChanged() { return this._definitionChanged; } get color() { return this._color; } set color(value) { this._color = value; } get speed() { return this._speed; } set speed(value) { this._speed = value; } get count() { return this._count; } set count(value) { this._count = value; } get gradient() { return this._gradient; } set gradient(value) { this._gradient = value; } getType() { return 'CircleRipple'; } getValue(time, result) { if (!result) result = {}; result.color = this._color; result.speed = this._speed; result.count = this._count; result.gradient = this._gradient; return result; } equals(other) { return this === other || (other instanceof CircleRippleMaterialProperty && Cesium.Color.equals(this._color, other._color) && this._speed === other._speed && this._count === other._count && this._gradient === other._gradient); } } // 注册材质类型 Cesium.Material.CircleRippleType = 'CircleRipple'; Cesium.Material.CircleRippleSource = uniform vec4 color; uniform float speed; uniform float count; uniform float gradient; czm_material czm_getMaterial(czm_materialInput materialInput) { czm_material material = czm_getDefaultMaterial(materialInput); vec2 st = materialInput.st; float time = czm_frameNumber * speed / 1000.0; float d = distance(st, vec2(0.5, 0.5)); // 多圈波纹效果 float alpha = 0.0; for(float i = 0.0; i < count; i++) { float ripple = sin(d * 20.0 - time * 2.0 - i * 0.5); float fade = smoothstep(0.0, 0.3, d) * (1.0 - smoothstep(0.3, 0.5, d)); alpha += abs(ripple) * fade * pow(1.0 - d, gradient * 10.0); } material.alpha = alpha * color.a; material.diffuse = mix(color.rgb, vec3(1.0), d * 0.5); return material; }; Cesium.Material._materialCache.addMaterial(Cesium.Material.CircleRippleType, { fabric: { type: Cesium.Material.CircleRippleType, uniforms: { color: new Cesium.Color(0.0, 0.8, 1.0, 0.7), speed: 5.0, count: 4.0, gradient: 0.2 }, source: Cesium.Material.CircleRippleSource }, translucent: function() { return true; } }); export default CircleRippleMaterialProperty; 加上这个circleRippleMaterialProperty.js怎么修改

An error occurred while rendering. Rendering has stopped. ReferenceError: shouldShow is not defined ReferenceError: shouldShow is not defined at http://localhost:8001/src/components/common-map/live-map.vue?t=1751774207331:38:23 at Proxy.forEach (<anonymous>) at http://localhost:8001/src/components/common-map/live-map.vue?t=1751774207331:37:28 at invokeFunc (http://localhost:8001/node_modules/.vite/deps/lodash.js?v=6636ce6c:3839:28) at leadingEdge (http://localhost:8001/node_modules/.vite/deps/lodash.js?v=6636ce6c:3845:30) at debounced (http://localhost:8001/node_modules/.vite/deps/lodash.js?v=6636ce6c:3887:24) at tD.raiseEvent (http://localhost:8001/libs/Cesium/Cesium.js:96:1282) at Jt._updateCameraChanged (http://localhost:8001/libs/Cesium/Cesium.js:11295:124016) at Xi.initializeFrame (http://localhost:8001/libs/Cesium/Cesium.js:12477:35438) at uC.render (http://localhost:8001/libs/Cesium/Cesium.js:12479:1576) 如图所示报错为什么 修改以下代码:<template> <Search @location-selected="handleLocationSelected" /> <LocationBar v-if="loaded" :update-interval="100" :use-dms-format="useDmsFormat" /> </template> <style> /* @import "/temp/css/divGraphic.css"; */ </style> <script setup lang="ts"> import { computed, onUnmounted, onMounted, reactive } from "vue"; import LocationBar from "./location-bar.vue"; import Search from "./search.vue"; import initMap from "./init"; import { ref } from "vue"; import { throttle } from 'lodash'; import { loadRipplePoints, createMultipleRippleCircles } from './circle.js'; import { $prototype } from "../../main.ts"; const miniMapContainer = ref<HTMLElement>(); let viewIndicator: Rectangle; // 视图指示器样式 const currentPosition = reactive({ longitude: 113.361538, latitude: 27.339318, }); // 株洲市范围常量 const ZHUZHOU_EXTENT = { west: 112.5, // 株洲市西边界 east: 114.5, // 株洲市东边界 south: 26.0, // 株洲市南边界 north: 28.0 // 株洲市北边界 }; const rippleEntities = ref<any[]>([]); // 存储波纹圆实体 const heightThreshold = 80000; // 高度阈值(米),高于此值隐藏波纹圆 // 高度节流函数 const updateRippleVisibility = throttle(() => { if (!$prototype.$map || rippleEntities.value.length === 0) return; rippleEntities.value.forEach(entity => { entity.show = shouldShow; }); }, 200); // 每200毫秒最多执行一次 // 更新指示器位置 const updateIndicatorPosition = () => { if (!$prototype.$map) return; const camera = $prototype.$map.camera; const rect = camera.computeViewRectangle(); if (!rect) return; // 计算在株洲市范围内的相对位置 const center = Cesium.Rectangle.center(rect); const lon = Cesium.Math.toDegrees(center.longitude); const lat = Cesium.Math.toDegrees(center.latitude); const lonPercent = ((lon - ZHUZHOU_EXTENT.west) / (ZHUZHOU_EXTENT.east - ZHUZHOU_EXTENT.west)) * 100; const latPercent = 100 - ((lat - ZHUZHOU_EXTENT.south) / (ZHUZHOU_EXTENT.north - ZHUZHOU_EXTENT.south)) * 100; // 更新CSS指示器 indicatorStyle.value = { left: ${lonPercent}%, top: ${latPercent}%, display: "block" }; }; // 更新鹰眼地图 - 只更新指示器位置 const updateOverview = () => { if (!$prototype.$map || !overviewViewer.value) return; // 获取主地图的当前视图中心 const rectangle = $prototype.$map.camera.computeViewRectangle(); if (!rectangle) return; const center = Cesium.Rectangle.center(rectangle); currentPosition.longitude = Cesium.Math.toDegrees(center.longitude); currentPosition.latitude = Cesium.Math.toDegrees(center.latitude); // 更新指示器位置 updateIndicatorPosition(); }; const overviewViewer = ref(null); // 初始化鹰眼地图 - 使用株洲市影像 const initMiniMap = () => { Cesium.Ion.defaultAccessToken = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiIxMDhlNDdmYy03NzFhLTQ1ZTQtOWQ3NS1lZDAzNDc3YjE4NDYiLCJpZCI6MzAxNzQyLCJpYXQiOjE3NDcwNTMyMDN9.eaez8rQxVbPv2LKEU0sMDclPWyHKhh1tR27Vg-_rQSM"; if (!miniMapContainer.value) return; // 创建株洲市专用影像提供器 const zhuzhouProvider = new Cesium.UrlTemplateImageryProvider({ url: "http://124.232.190.30:9000/proxy/pk1725866655224/map/zzzsyx_18/{z}/{x}/{y}.png", minimumLevel: 1, maximumLevel: 17, crs: "EPSG:3857", }); // 鹰眼地图初始化 - 使用株洲市影像 overviewViewer.value = new Cesium.Viewer(miniMapContainer.value, { sceneMode: Cesium.SceneMode.SCENE2D, baseLayerPicker: false, homeButton: false, timeline: false, navigationHelpButton: false, animation: false, scene3DOnly: true, selectionIndicator: false, infoBox: false, imageryProvider: zhuzhouProvider, // 使用株洲市影像 terrainProvider: window.Cesium.createWorldTerrain(), }); // 设置固定视野为株洲市范围 overviewViewer.value.camera.setView({ destination: Cesium.Rectangle.fromDegrees( ZHUZHOU_EXTENT.west, ZHUZHOU_EXTENT.south, ZHUZHOU_EXTENT.east, ZHUZHOU_EXTENT.north ) }); // 隐藏控件 var toolbar = overviewViewer.value.container.getElementsByClassName("cesium-viewer-toolbar")[0]; if (toolbar) toolbar.style.display = "none"; overviewViewer.value.cesiumWidget.creditContainer.style.display = "none"; }; // 初始化视图指示器 function initRectangle() { // 创建视图指示器(株洲市范围框) viewIndicator = overviewViewer.value.entities.add({ rectangle: { coordinates: new Cesium.CallbackProperty(() => { return Cesium.Rectangle.fromDegrees( ZHUZHOU_EXTENT.west, ZHUZHOU_EXTENT.south, ZHUZHOU_EXTENT.east, ZHUZHOU_EXTENT.north ); }, false), material: Cesium.Color.RED.withAlpha(0.3), outline: true, outlineColor: Cesium.Color.RED, outlineWidth: 2, }, }); } // 指示器样式计算 const indicatorStyle = computed(() => { return {}; // 由updateIndicatorPosition直接设置 }); const loaded = ref(false); const useDmsFormat = ref(false); function addDemoGraphics() { const chinaBoundary = $prototype.$map.dataSources.add( Cesium.GeoJsonDataSource.load("/shp_zz.geojson", { stroke: Cesium.Color.WHITE, fill: false, clampToGround: true, describe: null, }) ); chinaBoundary.then((dataSource) => { const entities = dataSource.entities.values; for (let entity of entities) { if (entity.polyline) { entity.polyline.fill = false; } } }); } function flyToDes() { const center = Cesium.Cartesian3.fromDegrees(-98.0, 40.0); $prototype.$map.camera.flyTo({ destination: new Cesium.Cartesian3( -2432812.6687511606, 5559483.804371395, 2832009.419525571 ), orientation: { heading: 6.283185307179421, pitch: -1.0472145569408116, roll: 6.2831853071795205, }, complete: function () {}, }); } // 监听主地图相机变化 const setupCameraListener = () => { $prototype.$map.camera.changed.addEventListener(updateOverview); }; // 鹰眼地图点击处理 const handleMiniMapClick = (event: MouseEvent) => { if (!miniMapContainer.value || !overviewViewer.value) return; const rect = miniMapContainer.value.getBoundingClientRect(); const x = event.clientX - rect.left; const y = event.clientY - rect.top; // 计算在固定范围内的相对位置 const xPercent = (x / rect.width) * 100; const yPercent = (y / rect.height) * 100; // 转换为株洲市范围内的经纬度 const lon = ZHUZHOU_EXTENT.west + (xPercent / 100) * (ZHUZHOU_EXTENT.east - ZHUZHOU_EXTENT.west); const lat = ZHUZHOU_EXTENT.north - (yPercent / 100) * (ZHUZHOU_EXTENT.north - ZHUZHOU_EXTENT.south); // 主地图飞向点击位置 $prototype.$map.camera.flyTo({ destination: Cesium.Cartesian3.fromDegrees(lon, lat, 1000000), }); }; function addImage() { var rightImageProvider = new Cesium.UrlTemplateImageryProvider({ name: "影像图", type: "xyz", layer: "vec_d", url: "http://124.232.190.30:9000/proxy/pk1725866655224/map/zzzsyx_18/{z}/{x}/{y}.png", minimumLevel: 1, maximumLevel: 17, crs: "EPSG:3857", }); $prototype.$map.imageryLayers.addImageryProvider(rightImageProvider); rightImageProvider.splitDirection = Cesium.SplitDirection.right; } onMounted(() => { initMap(); addImage(); loaded.value = true; addDemoGraphics(); flyToDes(); initMiniMap(); setupCameraListener(); setTimeout(function () { initRectangle(); }, 2000); (async () => { try { const ripplePoints = await loadRipplePoints(); rippleEntities.value = createMultipleRippleCircles( $prototype.$map, ripplePoints ); $prototype.$map.camera.changed.addEventListener(updateRippleVisibility); updateRippleVisibility(); } catch (error) { console.error('加载波纹圆失败:', error); } })(); }); let currentMarker: any = null; const createMarker = (location: { lng: number; lat: number; name: string }) => { if (currentMarker) { $prototype.$map.entities.remove(currentMarker); } currentMarker = $prototype.$map.entities.add({ position: Cesium.Cartesian3.fromDegrees( location.lng, location.lat, 50 ), point: { pixelSize: 200, color: Cesium.Color.RED, outlineColor: Cesium.Color.WHITE, outlineWidth: 2, heightReference: Cesium.HeightReference.RELATIVE_TO_GROUND, }, label: { text: location.name, font: "40px sans-serif", fillColor: Cesium.Color.WHITE, outlineColor: Cesium.Color.BLACK, outlineWidth: 1, verticalOrigin: Cesium.VerticalOrigin.BOTTOM, pixelOffset: new Cesium.Cartesian2(0, -20), heightReference: Cesium.HeightReference.RELATIVE_TO_GROUND, distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 10000), }, description: ${location.name} 经度:${location.lng.toFixed(6)} 纬度:${location.lat.toFixed(6)} , }); return currentMarker; }; const handleLocationSelected = (location: { lng: number; lat: number; name: string; }) => { if (!$prototype.$map) return; const destination = Cesium.Cartesian3.fromDegrees( location.lng, location.lat, 200 ); $prototype.$map.camera.flyTo({ destination, orientation: { heading: Cesium.Math.toRadians(0), pitch: Cesium.Math.toRadians(-45), roll: 0, }, duration: 2, complete: () => { createMarker(location); }, }); }; onUnmounted(() => { if ($prototype.$map) { $prototype.$map.destroy(); $prototype.$map = null; } if ($prototype.$map) { $prototype.$map.camera.changed.removeEventListener(updateRippleVisibility); } console.log("组件销毁"); }); const emit = defineEmits(["onload", "onclick"]); const initMars3d = async (option: any) => { emit("onclick", true); emit("onload", $prototype.$map); }; </script> <style lang="less"> /**cesium 工具按钮栏*/ .cesium-viewer-toolbar { top: auto !important; bottom: 35px !important; left: 12px !important; right: auto !important; } .cesium-toolbar-button img { height: 100%; } .cesium-viewer-toolbar > .cesium-toolbar-button, .cesium-navigationHelpButton-wrapper, .cesium-viewer-geocoderContainer { margin-bottom: 5px; float: left; clear: both; text-align: center; } .cesium-button { background-color: rgba(23, 49, 71, 0.8); color: #e6e6e6; fill: #e6e6e6; box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3); line-height: 32px; } .cesium-button:hover { background: #3ea6ff; } /**cesium 底图切换面板*/ .cesium-baseLayerPicker-dropDown { bottom: 0; left: 40px; max-height: 700px; margin-bottom: 5px; background-color: rgba(23, 49, 71, 0.8); } /**cesium 帮助面板*/ .cesium-navigation-help { top: auto; bottom: 0; left: 40px; transform-origin: left bottom; background: none; background-color: rgba(23, 49, 71, 0.8); .cesium-navigation-help-instructions { background: none; } .cesium-navigation-button { background: none; } .cesium-navigation-button-selected, .cesium-navigation-button-unselected:hover { background: rgba(0, 138, 255, 0.2); } } /**cesium 二维三维切换*/ .cesium-sceneModePicker-wrapper { width: auto; } .cesium-sceneModePicker-wrapper .cesium-sceneModePicker-dropDown-icon { float: right; margin: 0 3px; } /**cesium POI查询输入框*/ .cesium-viewer-geocoderContainer .search-results { left: 0; right: 40px; width: auto; z-index: 9999; } .cesium-geocoder-searchButton { background-color: rgba(23, 49, 71, 0.8); } .cesium-viewer-geocoderContainer .cesium-geocoder-input { background-color: rgba(63, 72, 84, 0.7); } .cesium-viewer-geocoderContainer .cesium-geocoder-input:focus { background-color: rgba(63, 72, 84, 0.9); } .cesium-viewer-geocoderContainer .search-results { background-color: rgba(23, 49, 71, 0.8); } /**cesium info信息框*/ .cesium-infoBox { top: 50px; background-color: rgba(23, 49, 71, 0.8); } .cesium-infoBox-title { background-color: rgba(23, 49, 71, 0.8); } /**cesium 任务栏的FPS信息*/ .cesium-performanceDisplay-defaultContainer { top: auto; bottom: 35px; right: 50px; } .cesium-performanceDisplay-ms, .cesium-performanceDisplay-fps { color: #fff; } /**cesium tileset调试信息面板*/ .cesium-viewer-cesiumInspectorContainer { top: 10px; left: 10px; right: auto; } .cesium-cesiumInspector { background-color: rgba(23, 49, 71, 0.8); } /**覆盖mars3d内部控件的颜色等样式*/ .mars3d-compass .mars3d-compass-outer { fill: rgba(23, 49, 71, 0.8); } .mars3d-contextmenu-ul, .mars3d-sub-menu { background-color: rgba(23, 49, 71, 0.8); > li > a:hover, > li > a:focus, > li > .active { background-color: #3ea6ff; } > .active > a, > .active > a:hover, > .active > a:focus { background-color: #3ea6ff; } } /* Popup样式*/ .mars3d-popup-color { color: #ffffff; } .mars3d-popup-background { background: rgba(23, 49, 71, 0.8); } .mars3d-popup-content { margin: 15px; } .mars3d-template-content label { padding-right: 6px; } .mars3d-template-titile { border-bottom: 1px solid #3ea6ff; } .mars3d-template-titile a { font-size: 16px; } .mars3d-tooltip { background: rgba(23, 49, 71, 0.8); border: 1px solid rgba(23, 49, 71, 0.8); } .mars3d-popup-btn-custom { padding: 3px 10px; border: 1px solid #209ffd; background: #209ffd1c; } .mars-dialog .mars-dialog__content { height: 100%; width: 100%; overflow: auto; padding: 5px; } .image { border: solid 2px #fff; } .content { height: 90%; padding-top: 10px; overflow-x: auto; overflow-y: auto; } .content-text { padding: 0 10px; text-indent: 30px; font-size: 17px; } .details-video { width: 100%; height: 760px; background-color: #000; } :where(.css-lt97qq9).ant-space { display: inline-flex; } :where(.css-lt97qq9).ant-space-align-center { align-items: center; } :where(.css-lt97qq9).ant-image .ant-image-mask { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; color: #fff; background: rgba(0, 0, 0, 0.5); cursor: pointer; opacity: 0; transition: opacity 0.3s; } :where(.css-lt97qq9).ant-image .ant-image-mask .ant-image-mask-info { overflow: hidden; white-space: nowrap; text-overflow: ellipsis; padding: 0 4px; } :where(.css-1t97qq9)[class^="ant-image"] [class^="ant-image"], :where(.css-1t97qq9)[class*=" ant-image"] [class^="ant-image"], :where(.css-1t97qq9)[class^="ant-image"] [class*=" ant-image"], :where(.css-1t97qq9)[class*=" ant-image"] [class*=" ant-image"] { box-sizing: border-box; } :where(.css-lt97qq9).ant-image .ant-image-img { width: 100%; height: auto; vertical-align: middle; } </style> <style scoped> .mini-map-container { position: relative; width: 100%; height: 100%; } .main-viewer { width: 100%; height: 100%; } .mini-map { position: absolute; right: 3vw; bottom: 6vh; width: 12vw; height: 17vh; border: 2px solid #fff; box-shadow: 0 0 10px rgba(0, 0, 0, 0.5); z-index: 999; cursor: pointer; overflow: hidden; } .location-indicator { position: absolute; width: 14px; height: 14px; background: #ff3e3e; border: 2px solid white; border-radius: 50%; transform: translate(-50%, -50%); box-shadow: 0 0 15px rgba(255, 62, 62, 1); z-index: 100; } .view-rectangle { position: absolute; border: 2px solid #00f2fe; z-index: 99; pointer-events: none; box-shadow: 0 0 20px rgba(0, 242, 254, 0.7); } /* 相机聚焦样式 - 四个角折角 */ .corner { position: absolute; width: 25px; height: 25px; z-index: 100; pointer-events: none; } .corner::before, .corner::after { content: ""; position: absolute; background: #00f2fe; box-shadow: 0 0 10px rgba(0, 242, 254, 0.8); } .corner-top-left { top: -2px; left: -2px; } .corner-top-left::before { top: 0; left: 0; width: 15px; height: 3px; } .corner-top-left::after { top: 0; left: 0; width: 3px; height: 15px; } .corner-top-right { top: -2px; right: -2px; } .corner-top-right::before { top: 0; right: 0; width: 15px; height: 3px; } .corner-top-right::after { top: 0; right: 0; width: 3px; height: 15px; } .corner-bottom-left { bottom: -2px; left: -2px; } .corner-bottom-left::before { bottom: 0; left: 0; width: 15px; height: 3px; } .corner-bottom-left::after { bottom: 0; left: 0; width: 3px; height: 15px; } .corner-bottom-right { bottom: -2px; right: -2px; } .corner-bottom-right::before { bottom: 0; right: 0; width: 15px; height: 3px; } .corner-bottom-right::after { bottom: 0; right: 0; width: 3px; height: 15px; } .camera-icon { position: absolute; top: 10px; right: 10px; color: #00f2fe; font-size: 24px; z-index: 100; text-shadow: 0 0 10px rgba(0, 242, 254, 0.8); } .focus-effect { position: absolute; top: 0; left: 0; width: 100%; height: 100%; pointer-events: none; z-index: 98; border: 2px solid rgba(0, 242, 254, 0.2); border-radius: 5px; box-shadow: inset 0 0 30px rgba(0, 242, 254, 0.1); } .pulse { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 10px; height: 10px; border-radius: 50%; background: rgba(0, 242, 254, 0.7); box-shadow: 0 0 0 0 rgba(0, 242, 254, 0.7); animation: pulse 2s infinite; } ::v-deep.cesium-viewer-toolbar { display: none; } </style>

最新推荐

recommend-type

Java源码-springboot+vue217志同道合交友网站+mysql完整资料.zip

本项目是基于Java源码的springboot+vue217志同道合交友网站,结合mysql数据库实现的一个完整项目。项目主要功能包括用户注册登录、个人资料管理、兴趣标签匹配、在线聊天、活动发布与参与等,旨在为用户提供一个便捷的交友平台,帮助志同道合的人快速找到彼此。项目采用前后端分离架构,前端使用vue217框架实现用户界面,后端基于springboot框架处理业务逻辑,mysql数据库负责数据存储与管理。开发此项目的目的是为了解决现代社会中人们交友难的问题,通过技术手段提升交友效率,促进人与人之间的交流与互动。毕设项目源码常年开发定制更新,希望对需要的同学有帮助。
recommend-type

yolov13权重文件及代码

从github下载的yolov13模型权重文件。从git下载这些文件,速度太慢了,还经常断了又得重新下载。笔者将已下载好的文件整理打包,分享出来,方便大家快捷下载和使用。 https://github.com/iMoonLab/yolov13/releases/tag/yolov13 压缩包内文件列表包括: yolov13l.pt yolov13n.pt yolov13s.pt yolov13x.pt 已经yolov13代码 yolov13-yolov13.zip
recommend-type

个人作品:使用React和Material-UI打造的赛车主题个人网站

### 知识点概述 该部分将围绕提供的文件信息进行展开,包含React框架、Material-UI库、网站性能优化、版本控制、网站部署以及相关的标签解析等详细知识点。 ### React框架 #### React简介 React是由Facebook开发和维护的一个用于构建用户界面的JavaScript库。它采用组件化的方式,使得开发者可以将UI分解为独立、可复用的组件。这些组件可以包含自己的状态,且只有状态发生变更时,才会重新渲染相应的组件,从而提高应用性能。 #### React应用生命周期 在React中,组件从创建到挂载、更新再到卸载,均遵循一套生命周期方法。例如,`componentDidMount`是在组件挂载后立即调用的方法,常用于执行如数据获取这类操作。`componentDidUpdate`则是组件更新后调用,可用于与当前和之前的props进行比较,并基于比较结果执行更新操作。 ### Material-UI #### Material-UI简介 Material-UI是一个React的用户界面框架,它提供了一整套现成的组件,符合Google的Material Design设计语言。Material-UI的核心优势在于其能够快速实现美观且一致的UI界面,同时保持高度的可定制性。该框架包含各种常用的UI元素,如按钮、输入框、卡片等,并拥有丰富的主题配置选项来支持不同品牌和风格的设计需求。 #### Material-UI中的组件使用 Material-UI通过组件化的方式提供各种UI元素,开发者可以根据需要自由组合和构建界面。例如,`Button`组件可以用于创建按钮,`Card`组件用于创建卡片布局等。每个组件的使用都遵循Material-UI的设计规范,确保界面美观和用户友好。 ### 网站性能优化 #### 响应式设计 从描述中提到网站支持移动和桌面端的定制设计,这是响应式设计的核心特点。响应式设计意味着网页能够根据不同的屏幕尺寸和分辨率,自动调整布局,提供最优化的浏览体验。 #### 动画和过渡效果 网站引入了新的过渡和动画,这不仅提升了用户体验,也可能有助于页面元素间转换时的直观性。使用React可以轻松地添加和管理动画,因为状态更新时React会自动处理组件树的更新。 ### 版本控制和分叉仓库 #### 版本控制(Git) 从描述中提到可以分叉此仓库,这涉及到了Git版本控制工具的使用。Git是一个分布式版本控制系统,用于跟踪代码变更,并且支持协作开发。通过分叉仓库,开发者可以从原始项目创建一个副本,可以在副本上进行修改而不影响原项目。 #### 分叉(Fork)和克隆(Clone) 分叉操作会创建一个远程仓库的副本,而克隆操作则会将远程仓库的内容复制到本地计算机。这意味着开发者可以在本地进行更改,然后选择将更改推送到自己的远程副本,或贡献回原始项目。 ### 安装与部署 #### 安装依赖项 在分叉/克隆仓库之后,开发者需要在项目目录中运行`npm install`来安装所有必需的依赖项。这一步骤是启动开发服务器前的必要准备。 #### 开发和生产环境 开发者需要区分开发环境和生产环境。开发环境通常包含调试工具,而生产环境需要优化和压缩资源以提升网站性能。通过运行`npm start`可以启动开发服务器,而使用`npm run build`则可以构建用于生产环境的静态文件。 ### 标签解析 #### React 标签提及了React,这意味着项目是基于React框架开发的,相关开发者和招聘者可能会搜索此标签以找到具有React开发经验的人才。 #### Blog & personal-website 标签还提到了博客和个人网站,这可能意味着项目是一个个人博客或者展示个人技能和经历的网站,通常用于职业发展或个人品牌建设。 #### Resume-website 标签提到了简历网站,这可以是一个在线简历或个人作品集的展示平台,提供了一个展示个人技能和经验的数字平台,便于求职者与潜在雇主之间沟通。 ### 结语 以上是根据提供的文件信息总结的详细知识点,涵盖了React和Material-UI框架的使用、网站性能优化、版本控制和仓库分叉、安装和部署流程以及对相关标签的解释和应用。这些内容不仅有助于理解该项目的技术细节,而且对于了解构建现代Web应用所涉及的技术和流程也是十分有帮助的。
recommend-type

活动图设计技巧大公开:如何在StarUML中构建高逻辑性的业务流程?

# 摘要 活动图作为软件系统建模的重要工具,能够有效表达复杂业务流程的逻辑结构与行为关系。本文围绕StarUML平台,系统探讨了活动图的设计原理、建模方法及其在实际项目中的应用价值。文章从活动图的核心元素与建模逻辑入手,分析了结构化建模方法与语义表达机制,并详细阐述了在StarUML中构建标准活动图的操作流程与优化策略。针对复杂业务场景,
recommend-type

模拟经典运放电路结构

<think>嗯,用户想了解经典运放电路的结构、模拟方法和实现方式。首先,我需要回忆运放的基本结构。运放通常由差分输入级、中间增益级和输出级组成,对吧?然后,模拟方法可能涉及虚短和虚断的概念,这是分析运放电路的关键。用户提到的引用里也强调了这两个概念的重要性,所以必须详细解释。接下来,我得考虑不同的经典电路结构,比如反向放大器、同向放大器、电压跟随器、加法器、微分器和积分器。每个电路的结构和公式需要准确描述,并确保使用正确的LaTeX格式。例如,反向放大器的公式是$V_o= -\frac{R_f}{R_1}V_i$,要检查是否用$$...$$还是$...$,根据用户的要求,行内公式用$,独立公
recommend-type

MATLAB模拟无线传感器网络与区块链技术

根据给定文件信息,我们将详细探讨以下几个关键知识点: 1. 无线传感器网络(Wireless Sensor Network, WSN): 无线传感器网络是由一组具有传感器、处理单元和通信能力的小型设备组成的网络,这些设备能够相互协作,完成对环境的监测任务。无线传感器网络具有部署便捷、自组织、灵活性高等特点。它在智能交通、环境监测、智能家居等领域有着广泛的应用。 2. 区块链技术(Blockchain Technology): 区块链是一种分布式数据库技术,其特点是去中心化、数据不可篡改、信息透明。在无线传感器网络中,区块链可用于提高数据的可信度和安全性。每个节点生成的块(block)将包含一段时期内的交易信息,这些块链式地连接在一起,形成链状结构,即区块链。通过共识机制(如工作量证明PoW、权益证明PoS等),网络中的节点对数据的有效性达成一致,从而保证数据的安全性和可靠性。 3. 随机泛洪路由技术(Random Flooding Routing): 随机泛洪路由技术是一种无需路由表的简单、基于概率的路由方法。在泛洪机制中,消息从源节点发出后,每个接收到消息的节点都会以一定的概率转发给其邻居节点。该技术易于实现,但可能会导致大量重复传输,进而增加网络的负载和能量消耗。因此,随机泛洪路由通常用于对实时性要求较高,但对能量和资源消耗要求不高的场合。 4. MATLAB仿真: MATLAB是一种高级数学计算和仿真软件,它广泛应用于工程计算、控制系统、信号处理、通信系统等领域。在无线传感器网络和区块链技术的研究中,MATLAB提供了强大的仿真环境和工具箱,使得研究人员能够模拟网络行为、验证算法性能和优化系统设计。 5. 能量效率(Energy Efficiency): 在无线传感器网络的设计中,能量效率是一个核心考量因素。由于传感器节点通常由电池供电,并且电池的更换或充电往往不便或不可行,因此降低节点能耗,延长网络的生命周期至关重要。研究者需要在保证网络性能的同时,采用各种策略来减少节点的能量消耗。 6. 静态节点(Static Node): 在无线传感器网络中,静态节点指的是那些位置固定不动的节点。与移动节点相比,静态节点的网络拓扑结构相对稳定,这有助于简化路由策略的设计,并且在一定程度上提高了系统的可预测性。静态节点适用于那些对位置变化不敏感的监测任务。 7. 节点块生成(Block Generation at Nodes): 在区块链技术中,节点块生成是指每个节点按照一定的规则(如PoW、PoS等)打包一段时间内的交易记录,生成新的数据块,并将其加入到区块链中的过程。每个新生成的块都包含前一个块的哈希值,确保了链的连续性和不可篡改性。在无线传感器网络中,节点生成块的过程也是数据交换的一部分,每个节点在完成数据处理和转发后,可能会产生新的块。 综合以上知识点,我们可以了解到,给定文件中的MATLAB仿真代码是专门用于无线传感器网络环境的仿真,其中实现了随机泛洪路由技术来模拟数据传输过程,并通过节点上生成块的方式构建了区块链。该代码特别适用于静态节点环境,其目的在于研究如何降低能量消耗,并保证数据传输的可靠性和安全性。代码的开源性将有助于研究人员和开发者访问、使用、修改和进一步优化该仿真模型。
recommend-type

UML状态图深度剖析:掌握对象生命周期建模的7个关键要点

# 摘要 UML状态图是描述系统动态行为的核心建模工具,广泛应用于软件与系统设计中。本文系统阐述了状态图的基本概念与理论基础,深入分析了状态、转移、复合结构及并发机制等关键建模元素,并详细探讨了状态图的构建流程与设计原则,强调行为建模的逻辑完整性与可维护性。结合嵌入式系统、业务流程和设计模式等实际应用场景,展示了状态图在复杂系统状态管理中的有效性。同时,本文研究了状态图与类图、序列图的协同机制,探讨了其在系统架构设计中的整合作用,并介绍了主流建模工具对状态图的支持与自动化实现方法,为工程实践提供了理论指导和技术路径。 # 关键字 UML状态图;状态转移;复合状态;并发建模;行为建模;
recommend-type

dbeaver缩小编辑页面

<think> 首先,用户的问题是:“我想查找在DBeaver中缩小编辑页面的方法 请问DBeaver缩小编辑页面的方法”。这似乎是用户在寻求如何在DBeaver数据库工具中缩小编辑页面的方法。 回顾系统级指令: - 所有行内数学表达式使用$...$格式。 - 独立公式使用$$...$$格式并单独成段。 - LaTeX语法必须正确。 - 使用中文回答。 - 生成相关问题。 - 引用的段落末尾自然地添加引用标识。 用户提供的引用: - 引用[1]:关于SQL函数和触发器的更新操作,与DBeaver缩小页面无关。 - 引用[2]:提到搜索历史、模糊查询、列编辑模式、自动换行和截图工具snipa
recommend-type

加强Magento管理员密码强度的扩展工具

Magento是一个流行的开源电子商务平台,它允许商家和开发人员构建和管理在线商店。为了确保在线商店的安全性,管理员密码的强度至关重要。Magento默认提供的管理员密码强度规则对于基本安全需求来说已经不错,但往往可以根据不同的安全需求进行增强。 Magento的“magento-admin-password-strength-enforcer”扩展就是用来加强默认密码策略的工具之一。通过这个扩展,网站管理员可以设置一个更高的密码长度阈值,以强制新创建的管理员密码满足一定的安全标准。 知识点说明: 1. Magento平台概述: Magento是一个基于PHP语言和MySQL数据库开发的电子商务解决方案,它具有模块化架构的特点,提供了丰富的扩展性和定制性。平台内置了许多功能,比如目录管理、营销工具、SEO优化等,同时支持多店铺管理和多种支付方式。 2. 管理员密码安全性: 在电子商务平台中,管理面板的访问权限至关重要。管理员账户通常拥有对网站进行设置、配置和维护的权限,因此密码的安全性直接关系到整个网站的安全性。如果密码强度不够,恶意攻击者就可能通过各种手段获取密码,进而对网站进行非法操作。 3. Magento密码强度策略: Magento默认配置中包含了密码强度的验证规则,如要求密码包含一定数量的字符、数字和特殊符号,以及不得包含用户名等。这些规则在一定程度上增强了密码的安全性,但随着网络攻击手段的不断进步,增强密码策略的要求变得越发重要。 4. Magento扩展与增强: Magento社区和开发人员不断提供各种扩展(Extensions)来增加Magento的功能,包括安全增强功能。magento-admin-password-strength-enforcer扩展就是这类工具之一,它允许管理员通过设置来提高密码强度,尤其是通过增加密码长度的要求。 5. 扩展安装和配置: 安装此类Magento扩展通常涉及解压下载的文件到Magento的特定目录,并通过Magento的后台管理系统进行安装配置。该扩展提供了一个简单的配置界面,管理员可以直接在Magento的后台设置界面(System > Configuration > Admin Password Strength)进行操作,输入想要设置的新密码长度阈值。 6. 特征和优势: - 简洁性:该扩展不会修改Magento的核心代码,这意味着它可以更加安全地应用,不会影响Magento平台的其他部分。 - 向后兼容性:扩展设计为向后兼容,因此可以在不影响其他已安装扩展的情况下使用。 - 灵活性:提供了默认密码长度的设置,管理员可以自行定义密码的最小长度要求,以满足自己的安全需求。 - 升级友好:由于不涉及核心代码,该扩展通常能够随着Magento平台的升级而正常工作。 7. 核心代码与扩展开发: Magento的PHP代码库是其架构的重要组成部分,扩展开发通常需要开发者具备良好的PHP开发能力。通过编写代码来增强或修改Magento的功能,是实现特定需求的常用方法。这种开发方式既保留了Magento的核心优势,又能够灵活地根据用户需求进行调整。 8. 安全维护与最佳实践: 在使用和维护电子商务平台时,应该遵循一些最佳实践,如定期更新Magento和扩展,保持软件处于最新版本以避免已知的安全漏洞。此外,还应定期更换密码,不在不同网站使用相同的密码,以减少被攻击的风险。 通过上述详细的知识点阐述,可以看出magento-admin-password-strength-enforcer扩展是如何通过提高管理员密码的最小长度要求来提升Magento平台的安全性的,同时也强调了在实施此类安全措施时需要注意的最佳实践和操作方法。
recommend-type

时序图绘制实战指南:3步提升可读性,精准表达复杂交互流程

# 摘要 时序图作为UML中描述对象间交互行为的核心工具,在软件设计与系统分析中具有重要价值,但其可读性常因结构复杂、信息过载而受限。本文系统阐述时序图的理论基础,解析参与者、生命线、消息序列等核心要素的语义逻辑,提出聚焦主流程、层次化抽象等建模原则,并深入探讨视觉密度与命名规范对认知负荷的影响。针对实际绘制难点,文章构建了“逻辑精炼—布局优化—