| | |
| | | // éè¿æ¥å£å»è¯·æ±jsonï¼å°è¯·æ±çjsonè§£æè·åæ³¥ç³æµåæ° |
| | | export async function fetchWaterSimulationData() { |
| | | try { |
| | | const response = await fetch("/simu/c2h1dc/layer.json"); // åèµ·è¯·æ± |
| | | const response = await fetch("/simu/20250515111549/layer.json"); // åèµ·è¯·æ± |
| | | if (!response.ok) { |
| | | throw new Error(`HTTP error! status: ${response.status}`); |
| | | } |
| | |
| | | <div v-for="(date, index) in visibleDates" :key="index" class="date-label"> |
| | | <!-- {{ formatDate(date) }} --> |
| | | </div> |
| | | <!-- ä¸é¢æ¸²æ: |
| | | <el-switch v-model="isColorRenderEnabled" @change="handleColorRenderChange" style="margin-top:-3px" |
| | | :disabled="!isPlaying || !isWaterPrimitiveCreated" /> --> |
| | | <!-- active-text="å¼" inactive-text="å
³" --> |
| | | </div> |
| | | <div class="timeline-track" ref="timelineTrack" @click="seekToPosition"> |
| | | <div class="timeline-progress" :style="{ width: progressPercentage + '%' }"></div> |
| | |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <el-button @click="handleBack" style="margin-top: 26px; margin-left: 30px; margin-right: 10px">ç»ææ¨¡æ</el-button> |
| | | <div> |
| | | <ratelevel ref="ratelevelRef" :playing-time="sendCurrentPlayingTime" @finish-calculation="handleFinishCalculation" |
| | | style="margin-top: 8px; margin-left: 28px; margin-right: 10px;justify-content: flex-end;"></ratelevel> |
| | | <el-button @click="handleBack" style="margin-top: 3px; margin-left: 30px; margin-right: 10px">ç»ææ¨¡æ</el-button> |
| | | </div> |
| | | |
| | | </div> |
| | | </template> |
| | | |
| | |
| | | inject, |
| | | reactive |
| | | } from "vue"; |
| | | import ratelevel from "@/components/menu/flowRate_waterLevel.vue"; |
| | | |
| | | import dayjs from "dayjs"; |
| | | import { getRainfall } from "@/api/index"; |
| | | import { |
| | | createWaterPrimitive, |
| | | destoryWaterPrimitive, |
| | | pauseWaterSimulation, |
| | | resumeWaterSimulation, |
| | | setTimeForWaterSimulation, |
| | | toggleWaterColorRender, |
| | | } from "@/utils/water"; |
| | | import mapUtils from "@/utils/tools.js"; |
| | | import { fetchWaterSimulationData } from "@/api/trApi.js"; |
| | |
| | | import { storeToRefs } from "pinia"; |
| | | const simStore = useSimStore(); |
| | | const { selectedScheme } = storeToRefs(simStore); |
| | | |
| | | const emit = defineEmits(["timeUpdate", "isPlaying", "playbackFinished"]); |
| | | |
| | | const emit = defineEmits(["timeUpdate", "isPlaying", "playbackFinished", "isColorRender"]); |
| | | // å®ä¹props |
| | | const props = defineProps({ |
| | | waterSimulateParams: { |
| | |
| | | }), |
| | | }, |
| | | }); |
| | | |
| | | // ååºå¼ç¶æ |
| | | const ratelevelRef = ref(null); // è·ååç»ä»¶å®ä¾çå¼ç¨ |
| | | const currentPlayingTime = ref(""); // å½åææ¾æ¶é´ |
| | | const sendCurrentPlayingTime = ref(""); // å½åææ¾æ¶é´ |
| | | const isPlaying = ref(false); |
| | | const playbackFinished = ref(true); |
| | | const currentTime = ref(0); |
| | |
| | | const waterTimestamps = ref([]); // å卿¶é´è½´æ°æ® |
| | | const timeMarkers = ref([]); |
| | | const timelineTrack = ref(null); |
| | | // æ°å¢æ è¯åé |
| | | const isColorRenderEnabled = ref(false); // åè®¾è¿æ¯ä½ çé¢è²æ¸²æå¼å
³ç¶æ |
| | | const isWaterPrimitiveCreated = ref(false); |
| | | let playInterval = null; |
| | | const isRainEnabled = ref(false); |
| | |
| | | rainDensity: 30 // é¨çå¯åº¦ |
| | | }); |
| | | // 计ç®å±æ§ |
| | | const startDate = computed(() => dayjs(props.waterSimulateParams.date[0])); |
| | | const endDate = computed(() => dayjs(props.waterSimulateParams.date[1])); |
| | | const progressPercentage = computed( |
| | | () => (currentTime.value / duration.value) * 100 |
| | | ); |
| | |
| | | new Set(waterTimestamps.value.map((ts) => dayjs(ts).format("YYYY-MM-DD"))) |
| | | ).map((date) => dayjs(date).toDate()) |
| | | ); |
| | | const currentTimeFormatted = computed(() => formatTime(currentTime.value)); |
| | | // ææ¾æ§å¶ |
| | | const togglePlay = () => { |
| | | if (!isPlaying.value && currentTime.value >= duration.value) |
| | | currentTime.value = 0; // å¦æå·²ç»ææ¾å®æ¯ï¼éç½®æ¶é´ |
| | | currentTime.value = 0; |
| | | |
| | | isPlaying.value = !isPlaying.value; |
| | | emit("isPlaying", isPlaying.value); |
| | | |
| | | if (isPlaying.value) { |
| | | startPlayback(); |
| | | |
| | | if (!isWaterPrimitiveCreated.value) { |
| | | // ç¬¬ä¸æ¬¡ææ¾æ¶åå»ºæ°´ä½æ¨¡æå± |
| | | console.log(selectedScheme.value, 'è¿éæ¯å½åæ¹æ¡çå
¨é¨ä¿¡æ¯'); |
| | | createWaterPrimitive({ interval: intervalMap[playbackRate.value], baseUrl: "/simu/c2h1dc" }); |
| | | isWaterPrimitiveCreated.value = true; // æ 记为已å建 |
| | | // è¿ééè¿water.jsä¸å»åé请æ±è·åæ°´é¢æ¨¡æ |
| | | createWaterPrimitive({ |
| | | baseUrl: "/simu/20250515111549", |
| | | interval: intervalMap[playbackRate.value], |
| | | colorRender: isColorRenderEnabled.value |
| | | }); |
| | | isWaterPrimitiveCreated.value = true; |
| | | } else { |
| | | // åç»ææ¾æ¶è°ç¨æ¢å¤æ¥å£ |
| | | resumeWaterSimulation(); |
| | | toggleWaterColorRender(isColorRenderEnabled.value); // æ´æ°é¢è²æ¸²æ |
| | | } |
| | | |
| | | if (currentTime.value === 0) emit("playbackFinished", false); |
| | | // æ¢å¤ä¸é¨ææ |
| | | |
| | | if (isRainEnabled.value) { |
| | | mapUtils.toggleRain(rainParams, true); |
| | | } |
| | | } else { |
| | | stopPlayback(); |
| | | pauseWaterSimulation(); // è°ç¨æåæ¥å£ |
| | | // 忢ä¸é¨ææ |
| | | isRainEnabled.value = true; // ä¿åå½åéè¦ä¸é¨çç¶æ |
| | | pauseWaterSimulation(); |
| | | |
| | | isRainEnabled.value = true; |
| | | setTimeout(() => { |
| | | mapUtils.delRain(); |
| | | }, 3000); |
| | | } |
| | | }; |
| | | |
| | | // é¢è²æ¸²æåæ¢äºä»¶ |
| | | const handleColorRenderChange = (enabled) => { |
| | | if (!isPlaying.value) { |
| | | ElMessage({ |
| | | message: "请å
å¯å¨æ°´ä½æ¨¡æååè¿è¡ä¸é¢ææåæ¢ã", |
| | | type: "warning", |
| | | }); |
| | | return; // 黿¢åç»é»è¾æ§è¡ |
| | | } |
| | | if (isWaterPrimitiveCreated.value) { |
| | | console.log('å½åæ¯å¦å¼å¯ä¸é¢æ¸²æï¼', enabled); |
| | | emit("isColorRender", enabled) |
| | | toggleWaterColorRender(enabled); |
| | | } |
| | | }; |
| | | const intervalMap = { |
| | | 1: 1000, // 1åé |
| | | 2: 500, // 2åé |
| | |
| | | }; |
| | | // ææ¾é»è¾ |
| | | const startPlayback = () => { |
| | | const interval = intervalMap[playbackRate.value] || 1000; // é»è®¤ä¸º1000 |
| | | // const interval = intervalMap[playbackRate.value] || 1000; // é»è®¤ä¸º1000 |
| | | clearInterval(playInterval); // æ¸
é¤ä¹åç宿¶å¨ |
| | | playInterval = setInterval(() => { |
| | | const timeIncrement = playbackRate.value; // åéä½ä¸ºå¢é |
| | |
| | | () => currentTime.value, |
| | | () => { |
| | | if (waterTimestamps.value.length > 0) { |
| | | currentPlayingTime.value = dayjs(waterTimestamps.value[0]) |
| | | sendCurrentPlayingTime.value = dayjs(waterTimestamps.value[0]) |
| | | .add(currentTime.value, "second") |
| | | .format("YYYY-MM-DD mm:ss"); |
| | | .valueOf(); // ä½¿ç¨ valueOf() è·ååå§æ¶é´æ³ |
| | | |
| | | // æ´æ° currentPlayingTime æ ¼å¼ååçæ¶é´å符串 |
| | | currentPlayingTime.value = dayjs(sendCurrentPlayingTime.value).format("YYYY-MM-DD HH:mm:ss"); |
| | | EventBus.emit("time-update", currentPlayingTime.value); |
| | | } |
| | | } |
| | |
| | | if (!timestamps || timestamps.length === 0) return []; |
| | | const sorted = [...timestamps].sort((a, b) => dayjs(a).diff(dayjs(b))); |
| | | const interval = Math.floor( |
| | | dayjs(sorted.at(-1)).diff(dayjs(sorted[0]), "second") / 7 |
| | | dayjs(sorted.at(-1)).diff(dayjs(sorted[0]), "second") / 5 |
| | | ); |
| | | return Array.from({ length: 8 }, (_, i) => |
| | | return Array.from({ length: 6 }, (_, i) => |
| | | dayjs(sorted[0]) |
| | | .add(i * interval, "second") |
| | | .format("mm:ss") |
| | | .format("HH:mm:ss") |
| | | ); |
| | | } |
| | | |
| | |
| | | onMounted(async () => { |
| | | try { |
| | | getRainfallData() |
| | | // æ ¹æ®layer.jsonå»è·åæ¶é´è½´ä¿¡æ¯ |
| | | const { waterTimestamps: timestamps } = await fetchWaterSimulationData(); |
| | | if (timestamps) { |
| | | waterTimestamps.value = timestamps; |
| | | updateTimelineRange(); |
| | | timeMarkers.value = generateTimeMarkers(timestamps); |
| | | sendCurrentPlayingTime.value = timestamps[0] |
| | | currentPlayingTime.value = dayjs(timestamps[0]).format( |
| | | "YYYY-MM-DD HH:mm:ss" |
| | | ); |
| | |
| | | |
| | | const { endSimulate } = inject("simulateActions"); |
| | | function handleBack() { |
| | | if (ratelevelRef.value) { |
| | | ratelevelRef.value.endCalculation(); |
| | | } |
| | | emit("isColorRender", false); |
| | | setTimeout(() => { |
| | | mapUtils.delRain(); |
| | | }, 3000); |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div style="display: flex;justify-content: space-between;"> |
| | | <!-- éç¹æé® --> |
| | | <div @click="togglePick" :class="['pick-button', { active: isPickingActive }]"> |
| | | <img src="@/assets/img/timeline/åæ .png" style="width: 26px;height: 26px;" /> |
| | | <!-- <span v-if="isPickingActive">忢æ¾å</span> |
| | | <span v-else>å¼å§æ¾å</span> --> |
| | | </div> |
| | | <!-- å¼å§è®¡ç®æé® --> |
| | | <!-- <div @click="startCalculation"> |
| | | <img src="@/assets/img/timeline/æ°´ä½.png" style="margin-top: -4px;width: 34px;height: 34px;" /> |
| | | </div> --> |
| | | <!-- ç»æè®¡ç®æé® --> |
| | | <div @click="endCalculation"> |
| | | <img src="@/assets/img/timeline/æ¸
é¤.png" style="width: 26px;height: 26px;" /> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { defineProps, watch, ref, onMounted, defineExpose } from "vue"; |
| | | import { ElMessage } from 'element-plus'; |
| | | |
| | | const pickedPoints = ref([]); |
| | | const handler = ref(null); |
| | | const isPickingActive = ref(false); |
| | | const currentTime = ref(0); |
| | | |
| | | const props = defineProps({ |
| | | playingTime: { |
| | | type: String, |
| | | required: true |
| | | } |
| | | }); |
| | | |
| | | watch( |
| | | () => props.playingTime, |
| | | (newVal) => { |
| | | currentTime.value = newVal; |
| | | }, |
| | | { immediate: true } |
| | | ); |
| | | // Cesium viewer åå§åç¸å
³é»è¾ |
| | | const viewer = window.viewer; |
| | | |
| | | function getPickPosition(windowPosition) { |
| | | if (!viewer) return null; |
| | | viewer.scene.globe.depthTestAgainstTerrain = true; |
| | | const cartesian = viewer.scene.pickPosition(windowPosition); |
| | | if (!cartesian) return null; |
| | | const cartographic = Cesium.Cartographic.fromCartesian(cartesian); |
| | | cartographic.height += 200.0; |
| | | return { |
| | | cartesian: Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, cartographic.height), |
| | | longitude: Cesium.Math.toDegrees(cartographic.longitude), |
| | | latitude: Cesium.Math.toDegrees(cartographic.latitude), |
| | | height: cartographic.height |
| | | }; |
| | | } |
| | | function addPointToViewer(point, index) { |
| | | // ç¡®ä¿ currentTime æåçå¼ |
| | | const displayTime = currentTime.value || "æªè®¾ç½®æ¶é´"; |
| | | |
| | | // æ·»å æ ç¾ï¼ç¡®ä¿å®ä½å建æ¶å
å«label屿§ï¼ |
| | | const entity = viewer.entities.add({ |
| | | position: point.cartesian, |
| | | label: { |
| | | text: `æµéç¹ ${index + 1}\nç»åº¦: ${point.longitude.toFixed(6)}\n纬度: ${point.latitude.toFixed(6)}\næ¶é´: ${displayTime}`, |
| | | font: '14pt monospace', // åå°åä½å¤§å° |
| | | style: Cesium.LabelStyle.FILL_AND_OUTLINE, |
| | | fillColor: Cesium.Color.YELLOW, |
| | | outlineColor: Cesium.Color.BLACK, |
| | | outlineWidth: 2, // åå°è½®å»å®½åº¦ |
| | | verticalOrigin: Cesium.VerticalOrigin.CENTER, |
| | | horizontalOrigin: Cesium.HorizontalOrigin.CENTER, |
| | | backgroundColor: Cesium.Color.fromCssColorString('rgba(0,0,0,0.7)'), |
| | | backgroundPadding: new Cesium.Cartesian2(10, 10), // åå°èæ¯å¡«å
|
| | | showBackground: true, |
| | | scale: 1, // è®¾ç½®ç¼©æ¾æ¯ä¾ |
| | | maximumScale: 1.5, // 设置æå¤§ç¼©æ¾æ¯ä¾ |
| | | } |
| | | }); |
| | | |
| | | // æ·»å åç´çº¿ |
| | | viewer.entities.add({ |
| | | polyline: { |
| | | positions: [point.cartesian, Cesium.Cartesian3.fromRadians(point.longitude * Math.PI / 180, point.latitude * Math.PI / 180, 0)], |
| | | width: 2, |
| | | material: new Cesium.PolylineOutlineMaterialProperty({ |
| | | outlineWidth: 4, |
| | | outlineColor: Cesium.Color.WHITE |
| | | }) |
| | | } |
| | | }); |
| | | |
| | | // åå¨ç¹çä¿¡æ¯ï¼å
å«å®æ´çentityå¼ç¨ï¼ |
| | | pickedPoints.value.push({ |
| | | entity: entity, |
| | | longitude: point.longitude, |
| | | latitude: point.latitude, |
| | | }); |
| | | } |
| | | |
| | | function initPickHandler() { |
| | | if (!viewer?.scene?.canvas) return; |
| | | |
| | | if (handler.value) { |
| | | handler.value.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK); |
| | | handler.value.destroy(); |
| | | handler.value = null; |
| | | } |
| | | |
| | | handler.value = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas); |
| | | |
| | | handler.value.setInputAction((movement) => { |
| | | const position = getPickPosition(movement.position); |
| | | if (position) { |
| | | const index = pickedPoints.value.length; |
| | | addPointToViewer(position, index); |
| | | } |
| | | }, Cesium.ScreenSpaceEventType.LEFT_CLICK); |
| | | } |
| | | |
| | | function startPicking() { |
| | | // pickedPoints.value = []; |
| | | // viewer.entities.removeAll(); |
| | | if (!handler.value) { |
| | | initPickHandler(); // åªæç¬¬ä¸æ¬¡æåå§å |
| | | } |
| | | |
| | | isPickingActive.value = true; |
| | | ElMessage.success('å¼å§æ¾ååæ ï¼è¯·ç¹å»å°å¾éæ©ç¹ä½ï¼'); |
| | | } |
| | | |
| | | function stopPicking() { |
| | | if (handler.value) { |
| | | handler.value.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK); |
| | | handler.value.destroy(); |
| | | handler.value = null; |
| | | } |
| | | isPickingActive.value = false; |
| | | } |
| | | |
| | | function togglePick() { |
| | | if (isPickingActive.value) { |
| | | stopPicking(); // è°ç¨ stopPicking æ¥æ£ç¡®å°åæ¢éåè¿ç¨ |
| | | isPickingActive.value = false; // ç¡®ä¿ isPickingActive 设置为 false |
| | | ElMessage.success('å½ååæ å·²éåå®æï¼æ°´ä½æµéæµéåå¤å®æ¯ï¼'); |
| | | console.log(pickedPoints.value, 'æç»éåçç¹'); |
| | | } else { |
| | | startPicking(); |
| | | isPickingActive.value = true; // å¨å¼å§éåå设置为 true |
| | | } |
| | | } |
| | | // å½ currentTime æ¹åæ¶æ´æ°ææç¹ç label ä¸çæ¶é´æ³ |
| | | // ä¿®æ¹watché»è¾ |
| | | watch( |
| | | () => props.playingTime, |
| | | (newVal) => { |
| | | currentTime.value = newVal || "æªè®¾ç½®æ¶é´"; |
| | | updateAllLabels(); |
| | | }, |
| | | { immediate: true } |
| | | ); |
| | | |
| | | function updateAllLabels() { |
| | | pickedPoints.value.forEach((pointInfo, index) => { |
| | | if (pointInfo.entity && pointInfo.entity.label) { |
| | | pointInfo.entity.label.text = |
| | | `æµéç¹ ${index + 1}\nç»åº¦: ${pointInfo.longitude.toFixed(6)}\n纬度: ${pointInfo.latitude.toFixed(6)}\næ¶é´: ${currentTime.value}`; |
| | | } |
| | | }); |
| | | } |
| | | |
| | | function startCalculation() { |
| | | console.log('éåçåæ ç¹ï¼', pickedPoints.value); |
| | | console.log(`å½åæ¶é´ï¼${currentTime.value}`); |
| | | } |
| | | |
| | | function endCalculation() { |
| | | ElMessage.success('æ¸
é¤æææµéç¹ï¼'); |
| | | pickedPoints.value = []; |
| | | viewer.entities.removeAll(); |
| | | // currentTime.value = 0; |
| | | } |
| | | defineExpose({ |
| | | endCalculation |
| | | }); |
| | | |
| | | </script> |
| | | |
| | | <style lang="less" scoped></style> |
| | |
| | | <template> |
| | | <div class="listCard"> |
| | | <div class="top"><span>æ¹æ¡è¯¦æ
</span> |
| | | <div @click="togglePick" :class="['pick-button', { active: isPickingActive }]"> |
| | | <!-- <div @click="togglePick" :class="['pick-button', { active: isPickingActive }]"> |
| | | {{ isPickingActive ? 'è¿è¡è®¡ç®' : 'å¼å§æ¾å' }} |
| | | </div> |
| | | </div> --> |
| | | </div> |
| | | <div class="details"> |
| | | <div v-if="formattedData.length" class="input-group"> |
| | |
| | | |
| | | // ç¶æç®¡ç |
| | | const formattedData = ref([]); |
| | | const pickedPoints = ref([]); |
| | | const handler = ref(null); |
| | | const isPickingActive = ref(false); |
| | | |
| | | |
| | | // æ å°è¡¨ |
| | | const areaTypeMap = { |
| | |
| | | }, |
| | | { immediate: true } |
| | | ); |
| | | // const pickedPoints = ref([]); |
| | | // const handler = ref(null); |
| | | // const isPickingActive = ref(false); |
| | | // // æ¾åç¸å
³é»è¾ |
| | | // const viewer = window.viewer; |
| | | |
| | | // æ¾åç¸å
³é»è¾ |
| | | const viewer = window.viewer; |
| | | // function getPickPosition(windowPosition) { |
| | | // if (!viewer) return null; |
| | | // viewer.scene.globe.depthTestAgainstTerrain = true; |
| | | // const cartesian = viewer.scene.pickPosition(windowPosition); |
| | | // if (!cartesian) return null; |
| | | |
| | | function getPickPosition(windowPosition) { |
| | | if (!viewer) return null; |
| | | viewer.scene.globe.depthTestAgainstTerrain = true; |
| | | const cartesian = viewer.scene.pickPosition(windowPosition); |
| | | if (!cartesian) return null; |
| | | |
| | | const cartographic = Cesium.Cartographic.fromCartesian(cartesian); |
| | | // const cartographic = Cesium.Cartographic.fromCartesian(cartesian); |
| | | |
| | | // å¨åæé«åº¦ä¸å¢å 300ç±³ |
| | | cartographic.height += 80.0; |
| | | // // å¨åæé«åº¦ä¸å¢å 300ç±³ |
| | | // cartographic.height += 80.0; |
| | | |
| | | return { |
| | | cartesian: Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, cartographic.height), |
| | | longitude: Cesium.Math.toDegrees(cartographic.longitude), |
| | | latitude: Cesium.Math.toDegrees(cartographic.latitude), |
| | | height: cartographic.height |
| | | }; |
| | | } |
| | | // return { |
| | | // cartesian: Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, cartographic.height), |
| | | // longitude: Cesium.Math.toDegrees(cartographic.longitude), |
| | | // latitude: Cesium.Math.toDegrees(cartographic.latitude), |
| | | // height: cartographic.height |
| | | // }; |
| | | // } |
| | | |
| | | function addPointToViewer(point, index) { |
| | | const entity = viewer.entities.add({ |
| | | position: point.cartesian, |
| | | billboard: { |
| | | // image: '../path/to/your/icon.png', // æ¿æ¢ä¸ºä½ ç徿 è·¯å¾ |
| | | width: 32, // 徿 宽度 |
| | | height: 32, // 徿 é«åº¦ |
| | | verticalOrigin: Cesium.VerticalOrigin.BOTTOM |
| | | }, |
| | | label: { |
| | | text: `Point ${index + 1}\nç»åº¦: ${point.longitude.toFixed(6)}\n纬度: ${point.latitude.toFixed(6)}`, |
| | | font: '14pt monospace', |
| | | style: Cesium.LabelStyle.FILL_AND_OUTLINE, |
| | | outlineWidth: 2, |
| | | verticalOrigin: Cesium.VerticalOrigin.TOP, |
| | | pixelOffset: new Cesium.Cartesian2(0, -40), // è°æ´æ ç¾ç¸å¯¹äºå¾æ çåç§»é |
| | | fillColor: Cesium.Color.WHITE, |
| | | outlineColor: Cesium.Color.BLACK |
| | | } |
| | | }); |
| | | // function addPointToViewer(point, index) { |
| | | // const entity = viewer.entities.add({ |
| | | // position: point.cartesian, |
| | | // billboard: { |
| | | // // image: '../path/to/your/icon.png', // æ¿æ¢ä¸ºä½ ç徿 è·¯å¾ |
| | | // width: 32, // 徿 宽度 |
| | | // height: 32, // 徿 é«åº¦ |
| | | // verticalOrigin: Cesium.VerticalOrigin.BOTTOM |
| | | // }, |
| | | // label: { |
| | | // text: `Point ${index + 1}\nç»åº¦: ${point.longitude.toFixed(6)}\n纬度: ${point.latitude.toFixed(6)}`, |
| | | // font: '14pt monospace', |
| | | // style: Cesium.LabelStyle.FILL_AND_OUTLINE, |
| | | // outlineWidth: 2, |
| | | // verticalOrigin: Cesium.VerticalOrigin.TOP, |
| | | // pixelOffset: new Cesium.Cartesian2(0, -40), // è°æ´æ ç¾ç¸å¯¹äºå¾æ çåç§»é |
| | | // fillColor: Cesium.Color.WHITE, |
| | | // outlineColor: Cesium.Color.BLACK |
| | | // } |
| | | // }); |
| | | |
| | | // å¯éï¼åå¨å®ä½å¼ç¨ä»¥ä¾¿åç»æä½ |
| | | pickedPoints.value.push(entity); |
| | | } |
| | | // // å¯éï¼åå¨å®ä½å¼ç¨ä»¥ä¾¿åç»æä½ |
| | | // pickedPoints.value.push(entity); |
| | | // } |
| | | |
| | | function initPickHandler() { |
| | | if (!viewer?.scene?.canvas) return; |
| | | handler.value = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas); |
| | | // function initPickHandler() { |
| | | // if (!viewer?.scene?.canvas) return; |
| | | // handler.value = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas); |
| | | |
| | | handler.value.setInputAction((movement) => { |
| | | const position = getPickPosition(movement.position); |
| | | if (position) { |
| | | const index = pickedPoints.value.length; |
| | | pickedPoints.value.push(position); |
| | | addPointToViewer(position, index); |
| | | } |
| | | }, Cesium.ScreenSpaceEventType.LEFT_CLICK); |
| | | } |
| | | // handler.value.setInputAction((movement) => { |
| | | // const position = getPickPosition(movement.position); |
| | | // if (position) { |
| | | // const index = pickedPoints.value.length; |
| | | // pickedPoints.value.push(position); |
| | | // addPointToViewer(position, index); |
| | | // } |
| | | // }, Cesium.ScreenSpaceEventType.LEFT_CLICK); |
| | | // } |
| | | |
| | | function togglePick() { |
| | | isPickingActive.value ? stopPicking() : startPicking(); |
| | | } |
| | | // function togglePick() { |
| | | // isPickingActive.value ? stopPicking() : startPicking(); |
| | | // } |
| | | |
| | | function startPicking() { |
| | | pickedPoints.value = []; |
| | | viewer.entities.removeAll(); |
| | | !handler.value && initPickHandler(); |
| | | isPickingActive.value = true; |
| | | } |
| | | // function startPicking() { |
| | | // pickedPoints.value = []; |
| | | // viewer.entities.removeAll(); |
| | | // !handler.value && initPickHandler(); |
| | | // isPickingActive.value = true; |
| | | // } |
| | | |
| | | function stopPicking() { |
| | | if (handler.value) { |
| | | handler.value.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK); |
| | | handler.value.destroy(); |
| | | handler.value = null; |
| | | } |
| | | // function stopPicking() { |
| | | // if (handler.value) { |
| | | // handler.value.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK); |
| | | // handler.value.destroy(); |
| | | // handler.value = null; |
| | | // } |
| | | |
| | | isPickingActive.value = false; |
| | | } |
| | | // isPickingActive.value = false; |
| | | // } |
| | | </script> |
| | | |
| | | <style lang="less" scoped> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div class="legend-container"> |
| | | <div class="legend-title">æ°´ä½é«åº¦å¾ä¾</div> |
| | | <ul class="legend-list"> |
| | | <li v-for="(item, index) in waterHeightLevels" :key="index" class="legend-item"> |
| | | <span class="legend-color-box" :style="{ 'background-color': item.color }"></span> |
| | | <span class="legend-label">{{ item.height }} ç±³</span> |
| | | </li> |
| | | </ul> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { onMounted, ref } from "vue"; |
| | | |
| | | // å®ä¹æ°´ä½é«åº¦æ°æ® |
| | | const waterHeightLevels = ref([ |
| | | { height: 0.5, color: "#09a2dc" }, |
| | | { height: 1.0, color: "#58c196" }, |
| | | { height: 1.5, color: "#bedf74" }, |
| | | { height: 2.0, color: "#d7f06e" }, |
| | | { height: 2.5, color: "#ffe930" }, |
| | | { height: 3.0, color: "#fdd10a" }, |
| | | { height: 4.0, color: "#feb652" }, |
| | | { height: 5.0, color: "#fd7f06" }, |
| | | { height: 10.0, color: "#fe2b07" }, |
| | | ]); |
| | | onMounted(()=>{ |
| | | }) |
| | | </script> |
| | | |
| | | <style lang="less" scoped> |
| | | .legend-container { |
| | | padding: 1rem; |
| | | border: 1px solid #ddd; |
| | | border-radius: 8px; |
| | | max-width: 100%; |
| | | width: auto; |
| | | font-size: clamp(10px, 1vw, 14px); |
| | | } |
| | | |
| | | .legend-title { |
| | | width: 100%; |
| | | text-align: center; |
| | | letter-spacing: 2px; |
| | | font-weight: 600; |
| | | font-size: clamp(16px, 1vw, 20px); |
| | | } |
| | | |
| | | .legend-list { |
| | | list-style: none; |
| | | padding: 0; |
| | | display: flex; |
| | | flex-direction: column; |
| | | gap: 0.5rem; |
| | | } |
| | | |
| | | .legend-item { |
| | | display: flex; |
| | | align-items: center; |
| | | } |
| | | |
| | | .legend-color-box { |
| | | width: 60px; |
| | | height: 10px; |
| | | margin-right: 0.5rem; |
| | | display: inline-block; |
| | | } |
| | | |
| | | .legend-label { |
| | | font-size: inherit; |
| | | } |
| | | </style> |
| | |
| | | <template> |
| | | <div class="legend-container"> |
| | | <div class="legend-title">å¾ä¾è¯´æ</div> |
| | | <div class="legend-title">çæµä½ç½®å¾ä¾</div> |
| | | <ul class="legend-list"> |
| | | <li v-for="(item, index) in legendItems" :key="index" class="legend-item"> |
| | | <img :src="getImageUrl(item.icon)" :alt="item.label" class="legend-icon" /> |
| | |
| | | <template> |
| | | <div class="legend-container"> |
| | | <div class="legend-title">å¾ä¾è¯´æ</div> |
| | | <div class="legend-title">çæµè®¾å¤å¾ä¾</div> |
| | | <ul class="legend-list"> |
| | | <li v-for="(item, index) in legendItems" :key="index" class="legend-item"> |
| | | <img :src="getImageUrl(item.icon)" :alt="item.label" class="legend-icon" /> |
| | |
| | | * åå»ºæ°´ä½æ¨¡æå± |
| | | * @param {Object} options - å¯éåæ° |
| | | * @param {number} options.interval - æ°´ä½æ¨¡æçæ¶é´é´éï¼åä½ï¼æ¯«ç§ï¼ |
| | | * @param {string} options.baseUrl - 仿çæå¡å°å |
| | | * @param {boolean} options.colorRender - æ¯å¦å¯ç¨é¢è²æ¸²æ |
| | | */ |
| | | export function createWaterPrimitive(options = {}) { |
| | | const { baseUrl = "/simu/c2h1dc", interval = 1000 } = options; // é»è®¤ baseUrl å interval |
| | | |
| | | water = earthCtrl.simulate.createWaterSimulateLayer({ |
| | | baseUrl, // 仿çæå¡ URL |
| | | interval, // å¨æè®¾ç½® interval |
| | | color: new SmartEarth.Cesium.Color.fromCssColorString("#D4F2E7"), |
| | | loop: false, // æ¯å¦å¾ªç¯ææ¾ |
| | | callback: timeCallback, // åè°å½æ° |
| | | }); |
| | | console.log(`Water simulation started with baseUrl: ${baseUrl}, interval: ${interval}ms`); |
| | | } |
| | | const { baseUrl = "/simu/c2h1dc", interval = 1000, colorRender = true } = options; |
| | | |
| | | water = earthCtrl.simulate.createWaterSimulateLayer({ |
| | | baseUrl, |
| | | interval, |
| | | color: new SmartEarth.Cesium.Color.fromCssColorString("#D4F2E7"), |
| | | loop: false, |
| | | callback: timeCallback, |
| | | waterHeightLevels: [ |
| | | { height: 0.5, color: "#09a2dc" }, |
| | | { height: 1.0, color: "#58c196" }, |
| | | { height: 1.5, color: "#bedf74" }, |
| | | { height: 2.0, color: "#d7f06e" }, |
| | | { height: 2.5, color: "#ffe930" }, |
| | | { height: 3.0, color: "#fdd10a" }, |
| | | { height: 4.0, color: "#feb652" }, |
| | | { height: 5.0, color: "#fd7f06" }, |
| | | { height: 10.0, color: "#fe2b07" }, |
| | | ], |
| | | colorRender, // æ§å¶æ¯å¦å¯ç¨é¢è²æ¸²æ |
| | | }); |
| | | |
| | | console.log(`Water simulation started with baseUrl: ${baseUrl}, interval: ${interval}ms, colorRender: ${colorRender}`); |
| | | } |
| | | /** |
| | | * åå§åæ°´ä½æ¨¡æè§å¾ |
| | | */ |
| | |
| | | |
| | | /** |
| | | * è·³è½¬å°æä¸ªæ¶é´ç¹çæ°´é¢ç¶æ |
| | | * @param {number} closestIndex - ç®æ æ¶é´æ³ç´¢å¼ |
| | | */ |
| | | export function setTimeForWaterSimulation(closestIndex) { |
| | | console.log(closestIndex,'index'); |
| | | |
| | | if (water) { |
| | | const imageList = water.getTimeList(); // è·åææå¯ç¨æ¶é´æ³ |
| | | if (imageList.length === 0) { |
| | | const imageList = water.getTimeList(); |
| | | |
| | | if (!imageList.length) { |
| | | console.warn("No timestamps available for water simulation."); |
| | | return; |
| | | } |
| | | const idx = Math.floor(Math.random() * imageList.length); // éæºéæ©ä¸ä¸ªæ¶é´æ³ |
| | | console.log( |
| | | `Jumping to timestamp: count:[${imageList.length}], index:[${idx}]` |
| | | ); |
| | | |
| | | water.setTime(imageList[closestIndex]); // 设置æ¶é´æ³ï¼è·³è½¬å°å¯¹åºæ¶å» |
| | | |
| | | const idx = Math.floor(Math.random() * imageList.length); |
| | | console.log(`Jumping to timestamp: count:[${imageList.length}], index:[${closestIndex}]`); |
| | | water.setTime(imageList[closestIndex]); |
| | | } else { |
| | | console.warn("No water simulation to set time for."); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 设置æå
³éé¢è²æ¸²æ |
| | | * @param {boolean} enabled |
| | | */ |
| | | export function toggleWaterColorRender(enabled) { |
| | | if (water) { |
| | | water.colorRender = enabled; |
| | | console.log(`Water color render set to: ${enabled}`); |
| | | } else { |
| | | console.warn("No water simulation to toggle color rendering."); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * æ¶é´æ³åè°å½æ° |
| | | * @param {number} timeStamp - å½åæ¶é´æ³ |
| | | */ |
| | |
| | | initMap(); |
| | | // å¨ä½ çåå§å代ç ä¸è°ç¨è¿ä¸ªå½æ° |
| | | addCityPolygon(); |
| | | initHandler(); |
| | | // initHandler(); |
| | | // initView() |
| | | loadAreaPolygon("/json/nsl_area.geojson"); |
| | | loadAreaPolygonAll("/json/geometry.json", true); |
| | |
| | | :waterSimulateParams="waterSimulateParams" |
| | | @playbackFinished="playbackFinished" |
| | | @end="endSimulate" |
| | | @isColorRender="isColorRender" |
| | | /> |
| | | <LegendMNFZ class="legend" v-if="isShowLegend"></LegendMNFZ> |
| | | <DebuffDetail |
| | | v-if="showDebuffDetail" |
| | | @open="openDetail" |
| | |
| | | import { EventBus } from "@/eventBus"; // å¼å
¥äºä»¶æ»çº¿ |
| | | import { ref, onMounted, onUnmounted, provide } from "vue"; |
| | | import TimeLine from "@/components/menu/TimeLine.vue"; |
| | | import LegendMNFZ from "@/components/tools/Legend_mnfz.vue"; |
| | | import Left from "./left/Left.vue"; |
| | | import echartInfo from "@/components/monifangzhen/echartInfo.vue"; |
| | | import DebuffDetail from "@/components/tools/DebuffDetail.vue"; |
| | |
| | | const showDebuffTable = ref(false); |
| | | const isDynamicMode = ref(false); |
| | | const isFinish = ref(true); |
| | | const isShowLegend = ref(false); |
| | | |
| | | const treeMap = new Map(); |
| | | |
| | |
| | | function playbackFinished(val) { |
| | | isFinish.value = val; |
| | | } |
| | | function isColorRender(val){ |
| | | console.log('è¿éæå°æ¯å¦æ¾ç¤ºæ°´ä½å¾ä¾çå¼ï¼',val); |
| | | isShowLegend.value = val |
| | | } |
| | | // å®ä¹å
¨å±åéåå¨å½åæ£å¨éªå¨çé¢ç |
| | | let flashingPolygon = null; |
| | | |
| | |
| | | </script> |
| | | <style lang="less" scoped> |
| | | @import url("../assets/css/home.css"); |
| | | .legend { |
| | | // background: url("@/assets/img/right/rightbg.png"); |
| | | color: white; |
| | | position: fixed; |
| | | bottom: 6%; |
| | | right: 20%; |
| | | z-index: 3333; |
| | | } |
| | | </style> |