| | |
| | | import dayjs from "dayjs"; |
| | | import { getRainfall } from "@/api"; |
| | | |
| | | let dataIntervalId = null; // 定时器 ID |
| | | let dataIntervalId = null; // 表格定时器 ID |
| | | const jsonData = ref([]); // JSON 数据 |
| | | const tableData = ref([]); // 表格数据 |
| | | const currentIndex = ref(0); // 当前加载索引 |
| | | const isPaused = ref(false); // 是否暂停标志 |
| | | const chart1Data = ref(null); |
| | | const chart2Data = ref(null); |
| | | let intervalId1 = null; |
| | | let intervalId2 = null; |
| | | const chart1Data = ref(null); //降雨数据 |
| | | const chart2Data = ref(null); //断面数据 |
| | | let intervalId1 = null; //降雨数据定时器 |
| | | let intervalId2 = null; //断面数据定时器 |
| | | |
| | | // 根据时间轴匹配的x轴的时间显示 |
| | | const nowTime = ref(null); |
| | | |
| | | const isFinished = ref(true); |
| | | |
| | | const props = defineProps({ |
| | | isDynamicMode: { |
| | |
| | | watch( |
| | | () => props.isFinish, |
| | | (newVal) => { |
| | | isFinished.value = newVal; |
| | | if (!newVal) { |
| | | resetTable(); |
| | | chart1Data.value.resetLoading(); |
| | |
| | | EventBus.on("reset-table", () => { |
| | | resetTable(); // 调用重置表格的函数 |
| | | }); |
| | | |
| | | // 清除echarts图表 |
| | | EventBus.on("clear-echart", () => { |
| | | clearEchartData(); // 调用清除函数 |
| | | chart1Data.value.resetLoading(); |
| | | chart2Data.value.resetLoading(); |
| | | }); |
| | | |
| | | |
| | | // 清除 echart1/2数据的函数 |
| | | const clearEchartData = () => { |
| | | if (myChart1) { |
| | | const currentOption = myChart1.getOption(); // 获取当前图表配置 |
| | | currentOption.series.forEach((series) => { |
| | | series.data = []; // 清空每个系列的数据 |
| | | }); |
| | | currentOption.xAxis[0].data = []; |
| | | myChart1.setOption(currentOption); |
| | | } |
| | | if (myChart2) { |
| | | const currentOption = myChart2.getOption(); |
| | | currentOption.series.forEach((series) => { |
| | | series.data = []; |
| | | }); |
| | | currentOption.xAxis[0].data = []; |
| | | myChart2.setOption(currentOption); |
| | | } |
| | | }; |
| | | // 清除威胁对象中的数据 |
| | | const resetTable = () => { |
| | | currentIndex.value = 0; |
| | |
| | | if (intervalId1) { |
| | | clearInterval(intervalId1); |
| | | chart1Data.value.stopUpdating(); // 每隔 1 秒更新一次 |
| | | |
| | | intervalId1 = null; |
| | | } |
| | | if (intervalId2) { |
| | | console.log(intervalId2, "暂停"); |
| | | clearInterval(intervalId2); |
| | | chart2Data.value.stopUpdating(); // 每隔 1 秒更新一次 |
| | | intervalId2 = null; |
| | |
| | | dataIntervalId = null; |
| | | } |
| | | }; |
| | | |
| | | // 监听时间轴结束模拟 |
| | | EventBus.on("hide-schemeInfo", handleHideSchemeInfo); |
| | | |
| | | // 监听父组件传递的数据变化 |
| | |
| | | let myChart1 = null; |
| | | let myChart2 = null; |
| | | |
| | | const getRandomInt = (min = 0, max = 100) => { |
| | | const minCeiled = Math.ceil(min); |
| | | const maxFloored = Math.floor(max); |
| | | return Math.floor(Math.random() * (maxFloored - minCeiled) + minCeiled); |
| | | }; |
| | | // 威胁对象数据 |
| | | const getDangerInfo = async () => { |
| | | try { |
| | | const response = await fetch( |
| | |
| | | }); |
| | | }; |
| | | |
| | | const getRainfallData = async () => { |
| | | try { |
| | | const res = await getRainfall(); |
| | | rainfallData.value = res.data; |
| | | } catch (error) { |
| | | console.error("Error fetching rainfall data:", error); |
| | | } |
| | | }; |
| | | |
| | | const rainClick = () => { |
| | | rainChangeShow.value = !rainChangeShow.value; |
| | | let desc = { func_name: "RainChange", visibility: rainChangeShow.value }; |
| | |
| | | charts.style.height = style.height; |
| | | }; |
| | | |
| | | // 时间轴时间截取处理 |
| | | const syncTimeWithTimeline = () => { |
| | | // 2025-05-24 00:25 |
| | | // // 将时间字符串转换为分钟数 (格式: "YYYY-MM-DD mm:ss") |
| | |
| | | return timeOnly; |
| | | }; |
| | | |
| | | //初始化并配置第一个ECharts图表(降雨数据图表) |
| | | const setEcharts1 = () => { |
| | | // 获取DOM元素并初始化ECharts实例 |
| | | const chartDom = document.getElementById("echarts1"); |
| | | myChart1 = echarts.init(chartDom); |
| | | |
| | | let rainfallData = ref([]); // 存储从 JSON 文件中加载的数据 |
| | | let data1 = ref([]); // 降雨数据数据 |
| | | let data2 = ref([]); // 累计雨量数据 |
| | | let xAxisData = ref([]); // 动态时间轴 |
| | | let updateInterval = null; // 定时器变量 |
| | | let dataIndex = ref(0); // 当前数据索引,用于按顺序更新 |
| | | // 响应式数据定义 |
| | | let rainfallData = ref([]); // 存储从JSON加载的原始降雨数据 |
| | | let data1 = ref([]); // 存储降雨数据(mm/min) |
| | | let data2 = ref([]); // 存储累计雨量数据(mm) |
| | | let xAxisData = ref([]); // 存储x轴时间数据 |
| | | let updateInterval = null; // 定时器ID |
| | | let dataIndex = ref(0); // 当前数据索引 |
| | | |
| | | // 加载 JSON 数据 |
| | | // 从JSON文件加载降雨数据 |
| | | const loadJsonData = async () => { |
| | | try { |
| | | // 发起网络请求获取数据 |
| | | const response = await fetch("/json/rainfall.json"); |
| | | const result = await response.json(); |
| | | |
| | | // 验证数据格式 |
| | | if (result && result.data && Array.isArray(result.data)) { |
| | | rainfallData.value = result.data; |
| | | |
| | | // 计算 value 和 total 的最大值 |
| | | // 计算数据的最大值用于y轴刻度 |
| | | const maxValue = Math.max( |
| | | ...rainfallData.value.map((item) => item.value) |
| | | ); |
| | |
| | | ...rainfallData.value.map((item) => item.total) |
| | | ); |
| | | |
| | | // 初始化时间轴(从00:00开始) |
| | | xAxisData.value = ["00:00"]; // 初始时间点 |
| | | |
| | | // 初始化图表(仅加载第一个数据点) |
| | | // 初始化时间轴和第一个数据点 |
| | | xAxisData.value = ["00:00"]; // 起始时间 |
| | | if (rainfallData.value.length > 0) { |
| | | data1.value.push(rainfallData.value[0].value); // 降雨数据 |
| | | data2.value.push(rainfallData.value[0].total); // 累计雨量 |
| | | data1.value.push(rainfallData.value[0].value); // 添加第一个降雨数据 |
| | | data2.value.push(rainfallData.value[0].total); // 添加第一个累计雨量 |
| | | } |
| | | |
| | | // 根据最大值设置 y 轴参数并初始化图表 |
| | | const yAxis1Params = calculateYAxisParams(maxValue); |
| | | const yAxis2Params = calculateYAxisParams(maxTotal); |
| | | // 计算y轴参数并更新图表 |
| | | const yAxis1Params = calculateYAxisParams(maxValue); // 左侧y轴(降雨数据) |
| | | const yAxis2Params = calculateYAxisParams(maxTotal); // 右侧y轴(累计雨量) |
| | | updateChart(yAxis1Params, yAxis2Params); |
| | | } else { |
| | | console.error( |
| | |
| | | } |
| | | }; |
| | | |
| | | // 计算 y 轴参数(最多有 4 个点) |
| | | /** |
| | | * 计算y轴参数(生成均匀分布的刻度) |
| | | * @param {number} max - 数据最大值 |
| | | * @returns {Object} 包含max和interval的对象 |
| | | */ |
| | | const calculateYAxisParams = (max) => { |
| | | const step = Math.ceil(max / 3); // 最多有 4 个点(包括 0),所以分成 3 份 |
| | | const step = Math.ceil(max / 3); // 将范围分成3等份(产生4个刻度点) |
| | | return { |
| | | max: step * 3, // 确保最大值是步长的整数倍 |
| | | interval: step, |
| | | interval: step, // 刻度间隔 |
| | | }; |
| | | }; |
| | | |
| | | // 更新图表配置 |
| | | /** |
| | | * 更新图表配置 |
| | | * @param {Object} yAxis1Params - 左侧y轴参数 |
| | | * @param {Object} yAxis2Params - 右侧y轴参数 |
| | | */ |
| | | const updateChart = (yAxis1Params, yAxis2Params) => { |
| | | const option = { |
| | | animation: false, // 禁用动画 |
| | | animation: false, // 禁用动画提高性能 |
| | | |
| | | // 提示框配置 |
| | | tooltip: { |
| | | trigger: "axis", |
| | | trigger: "axis", // 坐标轴触发 |
| | | axisPointer: { |
| | | type: "cross", |
| | | crossStyle: { |
| | | color: "#fff", |
| | | }, |
| | | // 指示器样式 |
| | | type: "cross", // 十字准星指示器 |
| | | crossStyle: { color: "#fff" }, // 白色线条 |
| | | }, |
| | | }, |
| | | |
| | | // 图表布局 |
| | | grid: { |
| | | left: "1%", |
| | | right: "1%", |
| | | bottom: "1%", |
| | | containLabel: true, |
| | | bottom: "1%", // 边距 |
| | | containLabel: true, // 包含坐标轴标签 |
| | | }, |
| | | |
| | | // 图例配置 |
| | | legend: { |
| | | data: ["降雨数据", "累计雨量"], |
| | | textStyle: { |
| | | color: "#fff", |
| | | }, |
| | | right: "10px", // 将图例靠右贴边 |
| | | data: ["降雨数据", "累计雨量"], // 系列名称 |
| | | textStyle: { color: "#fff" }, // 白色文字 |
| | | right: "10px", // 靠右对齐 |
| | | }, |
| | | |
| | | // x轴配置(时间轴) |
| | | xAxis: [ |
| | | { |
| | | type: "category", |
| | | data: xAxisData.value, // 使用动态时间轴 |
| | | axisPointer: { |
| | | type: "shadow", |
| | | }, |
| | | type: "category", // 类目轴 |
| | | data: xAxisData.value, // 时间数据 |
| | | axisPointer: { type: "shadow" }, // 阴影指示器 |
| | | axisLabel: { |
| | | color: "#fff", |
| | | rotate: 0, // 将旋转角度设置为0,取消倾斜 |
| | | color: "#fff", // 白色标签 |
| | | rotate: 0, // 不旋转 |
| | | }, |
| | | }, |
| | | ], |
| | | |
| | | // y轴配置(双y轴) |
| | | yAxis: [ |
| | | // 左侧y轴(降雨数据) |
| | | { |
| | | type: "value", |
| | | name: "单位:mm", |
| | | min: 0, |
| | | max: yAxis1Params.max, |
| | | interval: yAxis1Params.interval, |
| | | min: 0, // 最小值为0 |
| | | max: yAxis1Params.max, // 动态计算的最大值 |
| | | interval: yAxis1Params.interval, // 动态计算的间隔 |
| | | axisLabel: { |
| | | formatter: "{value}", |
| | | color: "#fff", |
| | | align: "right", // 将标签右对齐 |
| | | align: "right", // 标签右对齐 |
| | | }, |
| | | nameTextStyle: { |
| | | padding: [0, 0, 0, 30], // 在右侧添加一些内边距 |
| | | padding: [0, 0, 0, 30], // 名称右侧内边距 |
| | | color: "#fff", |
| | | }, |
| | | splitLine: { |
| | | show: false, // 关闭左侧 y 轴的横线 |
| | | }, |
| | | splitLine: { show: false }, // 不显示网格线 |
| | | }, |
| | | // 右侧y轴(累计雨量) |
| | | { |
| | | type: "value", |
| | | name: "单位:mm", |
| | |
| | | axisLabel: { |
| | | formatter: "{value}", |
| | | color: "#fff", |
| | | align: "left", // 将标签右对齐 |
| | | align: "left", // 标签左对齐 |
| | | }, |
| | | nameTextStyle: { |
| | | padding: [0, 10, 0, 0], // 在右侧添加一些内边距 |
| | | padding: [0, 10, 0, 0], // 名称左侧内边距 |
| | | color: "#fff", |
| | | }, |
| | | splitLine: { |
| | | show: true, // 保留右侧 y 轴的横线 |
| | | }, |
| | | splitLine: { show: true }, // 显示网格线 |
| | | }, |
| | | ], |
| | | |
| | | // 数据系列配置 |
| | | series: [ |
| | | // 柱状图(降雨数据) |
| | | { |
| | | name: "降雨数据", |
| | | type: "bar", |
| | | type: "bar", // 柱状图 |
| | | tooltip: { |
| | | valueFormatter: function (value) { |
| | | return value + " mm/min"; |
| | | }, |
| | | valueFormatter: (value) => value + " mm/min", // 提示框单位 |
| | | }, |
| | | data: data1.value, |
| | | itemStyle: { |
| | | color: "#3268fe", |
| | | }, |
| | | label: { |
| | | show: false, |
| | | color: "#fff", |
| | | }, |
| | | data: data1.value, // 绑定数据 |
| | | itemStyle: { color: "#3268fe" }, // 蓝色柱状图 |
| | | label: { show: false, color: "#fff" }, // 不显示数据标签 |
| | | }, |
| | | // 折线图(累计雨量) |
| | | { |
| | | name: "累计雨量", |
| | | type: "line", |
| | | yAxisIndex: 1, |
| | | type: "line", // 折线图 |
| | | yAxisIndex: 1, // 使用第二个y轴 |
| | | tooltip: { |
| | | valueFormatter: function (value) { |
| | | return value + " mm"; |
| | | }, |
| | | valueFormatter: (value) => value + " mm", // 提示框单位 |
| | | }, |
| | | data: data2.value, |
| | | lineStyle: { |
| | | color: "#ffb637", |
| | | }, |
| | | label: { |
| | | show: false, // 确保标签不显示 |
| | | color: "#fff", |
| | | }, |
| | | data: data2.value, // 绑定数据 |
| | | lineStyle: { color: "#ffb637" }, // 黄色线条 |
| | | label: { show: false, color: "#fff" }, // 不显示数据标签 |
| | | }, |
| | | ], |
| | | }; |
| | | |
| | | // 应用配置到图表 |
| | | myChart1.setOption(option); |
| | | }; |
| | | |
| | | // 定义按顺序更新数据的方法 |
| | | // 定时更新图表数据 |
| | | const updateData = () => { |
| | | // 检查是否还有数据需要显示 |
| | | if (dataIndex.value < rainfallData.value.length) { |
| | | // 获取当前索引的数据项 |
| | | const newItem = rainfallData.value[dataIndex.value]; |
| | | |
| | | // 添加新数据 |
| | | data1.value.push(newItem.value); // 添加降雨数据 |
| | | data2.value.push(newItem.total); // 添加累计雨量 |
| | | xAxisData.value.push(syncTimeWithTimeline()); // 添加时间点 |
| | | |
| | | const nextTime = syncTimeWithTimeline(); |
| | | xAxisData.value.push(nextTime); |
| | | dataIndex.value++; // 递增索引 |
| | | |
| | | // 更新当前索引 |
| | | dataIndex.value++; |
| | | |
| | | // 更新图表 |
| | | // 更新图表(保持原有y轴范围) |
| | | updateChart( |
| | | { |
| | | max: myChart1.getOption().yAxis[0].max, |
| | | interval: myChart1.getOption().yAxis[0].interval, |
| | | }, // 左侧 y 轴保持不变 |
| | | }, |
| | | { |
| | | max: myChart1.getOption().yAxis[1].max, |
| | | interval: myChart1.getOption().yAxis[1].interval, |
| | | } // 右侧 y 轴保持不变 |
| | | } |
| | | ); |
| | | } else { |
| | | console.log("All data has been displayed."); |
| | | stopUpdating(); // 停止定时更新 |
| | | stopUpdating(); // 数据全部显示完成后停止更新 |
| | | } |
| | | }; |
| | | |
| | | // 启动定时更新 |
| | | //启动定时更新 |
| | | const startUpdating = (interval = 1000) => { |
| | | if (!updateInterval) { |
| | | updateInterval = setInterval(updateData, interval); // 每隔 interval 毫秒更新一次数据 |
| | | updateInterval = setInterval(updateData, interval); |
| | | console.log("Started updating..."); |
| | | } |
| | | }; |
| | | |
| | | // 停止定时更新 |
| | | //停止定时更新 |
| | | const stopUpdating = () => { |
| | | if (updateInterval) { |
| | | clearInterval(updateInterval); |
| | |
| | | } |
| | | }; |
| | | |
| | | // 重置加载 |
| | | //重置图表数据和状态 |
| | | const resetLoading = () => { |
| | | stopUpdating(); // 停止定时器 |
| | | dataIndex.value = 0; // 重置数据索引 |
| | | data1.value = []; // 清空降雨数据数据 |
| | | data2.value = []; // 清空累计雨量数据 |
| | | xAxisData.value = ["00:00"]; // 重置时间轴 |
| | | stopUpdating(); // 停止当前更新 |
| | | |
| | | // 重新加载第一个数据点 |
| | | // 重置状态 |
| | | dataIndex.value = 0; |
| | | data1.value = []; |
| | | data2.value = []; |
| | | xAxisData.value = ["00:00"]; |
| | | |
| | | // 重新加载第一个数据点(如果有数据) |
| | | if (rainfallData.value.length > 0) { |
| | | data1.value.push(rainfallData.value[0].value); // 降雨数据 |
| | | data2.value.push(rainfallData.value[0].total); // 累计雨量 |
| | | data1.value.push(rainfallData.value[0].value); |
| | | data2.value.push(rainfallData.value[0].total); |
| | | } |
| | | |
| | | // 重新绘制图表 |
| | | // 重新绘制图表(保持原有y轴范围) |
| | | updateChart( |
| | | { |
| | | max: myChart1.getOption().yAxis[0].max, |
| | | interval: myChart1.getOption().yAxis[0].interval, |
| | | }, // 左侧 y 轴保持不变 |
| | | }, |
| | | { |
| | | max: myChart1.getOption().yAxis[1].max, |
| | | interval: myChart1.getOption().yAxis[1].interval, |
| | | } // 右侧 y 轴保持不变 |
| | | } |
| | | ); |
| | | |
| | | console.log("Reset loading..."); |
| | | }; |
| | | |
| | | // 初始化加载 JSON 数据 |
| | | // 初始化:加载数据 |
| | | loadJsonData(); |
| | | |
| | | // 返回公共接口 |
| | | return { |
| | | myChart1, |
| | | startUpdating, |
| | | stopUpdating, |
| | | resetLoading, |
| | | myChart1, // 图表实例 |
| | | startUpdating, // 启动更新方法 |
| | | stopUpdating, // 停止更新方法 |
| | | resetLoading, // 重置方法 |
| | | }; |
| | | }; |
| | | |
| | |
| | | }; |
| | | |
| | | onMounted(() => { |
| | | // getRainfallData(); |
| | | // 时间轴时间的变化 |
| | | EventBus.on("time-update", (time) => { |
| | | nowTime.value = time; |
| | | }); |
| | |
| | | }); |
| | | |
| | | onBeforeUnmount(() => { |
| | | EventBus.off("time-update"); // 清理事件监听 |
| | | nowTime.value = null; |
| | | if (intervalId1) clearInterval(intervalId1); |
| | | if (intervalId2) clearInterval(intervalId2); |
| | |
| | | onUnmounted(() => { |
| | | EventBus.off("reset-table"); // 移除事件监听 |
| | | EventBus.off("clear-echart"); |
| | | EventBus.off("time-update"); // 清理事件监听 |
| | | }); |
| | | </script> |
| | | |
| | |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { onMounted, onUnmounted, ref, watch } from "vue" |
| | | import { createPoint, initHandler, initView, addTileset, addTerrain } from "@/utils/map.js" |
| | | import { loadAreaPolygon } from "@/utils/area.js" |
| | | import { loadAreaPolygonAll } from "@/utils/area_all.js" |
| | | import { isVisibleDistance } from "@/utils/customEntity" |
| | | import { getDistrictCount, getDistrictCountByCity } from "@/api/index" |
| | | import { useRoute } from "vue-router" |
| | | const route = useRoute() |
| | | let handler = null |
| | | function initMap () { |
| | | window.Cesium = SmartEarth.Cesium |
| | | window.earthCtrl = new SmartEarth.EarthCtrl("gis-view") |
| | | import { onMounted, onUnmounted, ref, watch } from "vue"; |
| | | import { |
| | | createPoint, |
| | | initHandler, |
| | | initView, |
| | | addTileset, |
| | | addTerrain, |
| | | } from "@/utils/map.js"; |
| | | import { loadAreaPolygon } from "@/utils/area.js"; |
| | | import { loadAreaPolygonAll } from "@/utils/area_all.js"; |
| | | import { isVisibleDistance } from "@/utils/customEntity"; |
| | | import { getDistrictCount, getDistrictCountByCity } from "@/api/index"; |
| | | import { useRoute } from "vue-router"; |
| | | const route = useRoute(); |
| | | let handler = null; |
| | | function initMap() { |
| | | window.Cesium = SmartEarth.Cesium; |
| | | window.earthCtrl = new SmartEarth.EarthCtrl("gis-view"); |
| | | window.viewer = earthCtrl.viewer; |
| | | const date = new Date(2025, 3, 11, 12, 0, 0, 0); |
| | | |
| | | // 1. 设置初始时间 |
| | | const date = new Date(2025, 3, 11, 16, 0, 0, 0); |
| | | const julianDate = SmartEarth.Cesium.JulianDate.fromDate(date); |
| | | // earthCtrl.viewer.clock.currentTime = julianDate; |
| | | |
| | | // 2. 配置时钟选项,禁止自动推进时间 |
| | | earthCtrl.viewer.clockViewModel.shouldAnimate = false; // 禁用动画 |
| | | earthCtrl.viewer.clockViewModel.clockRange = |
| | | SmartEarth.Cesium.ClockRange.CLAMPED; // 限制时间范围 |
| | | earthCtrl.viewer.clockViewModel.multiplier = 0; // 设置时间推进速度为0 |
| | | |
| | | // 3. 设置当前时间并锁定 |
| | | earthCtrl.viewer.clock.currentTime = julianDate; |
| | | |
| | | |
| | | //显示fps |
| | | earthCtrl.showFPS = true |
| | | earthCtrl.showFPS = true; |
| | | earthCtrl.factory.createImageryLayer({ |
| | | sourceType: "mapworld", |
| | | url: "http://t0.tianditu.com/img_w/wmts?service=wmts&request=GetTile&version=1.0.0&LAYER=img&tileMatrixSet=w&TileMatrix={TileMatrix}&TileRow={TileRow}&TileCol={TileCol}&style=default&format=tiles&tk=7eb11c0c503429878691ac917238f87f", |
| | |
| | | maximumLevel: 18, |
| | | layer: "", |
| | | tileMatrixSetID: "", |
| | | }) |
| | | }); |
| | | // 关闭地形深度检测 |
| | | // viewer.scene.globe.depthTestAgainstTerrain = false; |
| | | } |
| | | |
| | | function addCityPolygon () { |
| | | const url = `/json/110000.geo.json` |
| | | function addCityPolygon() { |
| | | const url = `/json/110000.geo.json`; |
| | | let wallLayer = earthCtrl.factory.createTrailWallLayer({ |
| | | url: "/json/110000.geojson", |
| | | color: "LIGHTSTEELBLUE", //颜色 |
| | | height: 2000, //高度 |
| | | speed: 3, |
| | | }) |
| | | }); |
| | | const dataSourcePromise = Cesium.GeoJsonDataSource.load(url, { |
| | | clampToGround: true, |
| | | }) |
| | | }); |
| | | return dataSourcePromise.then(function (dataSource) { |
| | | viewer.dataSources.add(dataSource) |
| | | const polygonEntity = dataSource.entities.values |
| | | viewer.dataSources.add(dataSource); |
| | | const polygonEntity = dataSource.entities.values; |
| | | // console.log("polygonEntity", polygonEntity) |
| | | const distanceDisplayCondition = new Cesium.DistanceDisplayCondition(1000, 50000000) |
| | | polygonEntity.forEach(entity => { |
| | | const distanceDisplayCondition = new Cesium.DistanceDisplayCondition( |
| | | 1000, |
| | | 50000000 |
| | | ); |
| | | polygonEntity.forEach((entity) => { |
| | | // console.log("entity", entity) |
| | | |
| | | entity.polygon.material = new Cesium.ColorMaterialProperty( |
| | |
| | | // minimumAlpha: 0.2, |
| | | // maximumAlpha: 0.9, |
| | | // }) |
| | | ) |
| | | ); |
| | | |
| | | entity.polygon.distanceDisplayCondition = distanceDisplayCondition |
| | | entity.polygon.distanceDisplayCondition = distanceDisplayCondition; |
| | | |
| | | const properties = entity.properties |
| | | const center = properties.centroid.getValue() |
| | | const fullname = properties.fullname.getValue() |
| | | const districtCount = properties.districtCount.getValue() || 0 |
| | | const properties = entity.properties; |
| | | const center = properties.centroid.getValue(); |
| | | const fullname = properties.fullname.getValue(); |
| | | const districtCount = properties.districtCount.getValue() || 0; |
| | | |
| | | const position = Cesium.Cartesian3.fromDegrees(center[0], center[1]) |
| | | const positions = entity.polygon.hierarchy._value.positions |
| | | const position = Cesium.Cartesian3.fromDegrees(center[0], center[1]); |
| | | const positions = entity.polygon.hierarchy._value.positions; |
| | | |
| | | entity.position = position |
| | | entity.position = position; |
| | | // 判断是否为东城区或西城区 |
| | | let labelText = fullname || "默认标签" |
| | | let labelText = fullname || "默认标签"; |
| | | if (fullname === "东城区" || fullname === "西城区") { |
| | | // 将文本拆分为竖列 |
| | | labelText = fullname.split("").join("\n") |
| | | labelText = fullname.split("").join("\n"); |
| | | } |
| | | entity.label = { |
| | | // 文本。支持显式换行符“ \ n” |
| | |
| | | disableDepthTestDistance: Number.POSITIVE_INFINITY, |
| | | // 是否显示 |
| | | show: true, |
| | | } |
| | | }; |
| | | entity.polyline = { |
| | | positions: positions, |
| | | width: 5, |
| | |
| | | ), |
| | | clampToGround: true, |
| | | distanceDisplayCondition: distanceDisplayCondition, |
| | | } |
| | | }; |
| | | |
| | | viewer.entities.add(entity) |
| | | }) |
| | | viewer.entities.add(entity); |
| | | }); |
| | | |
| | | // 获取 GeoJSON 中的第一个 Polygon feature |
| | | }) |
| | | }); |
| | | } |
| | | |
| | | function flyToHomeView () { |
| | | function flyToHomeView() { |
| | | const view = { |
| | | destination: { |
| | | x: -2355432.569004413, |
| | |
| | | roll: 0.00031421159527500464, |
| | | heading: 6.140424766644804, |
| | | }, |
| | | } |
| | | viewer.scene.camera.flyTo(view) |
| | | }; |
| | | viewer.scene.camera.flyTo(view); |
| | | } |
| | | |
| | | let htmlEntityList = [] |
| | | function initDistrictCount () { |
| | | getDistrictCount().then(res => { |
| | | res.data.forEach(item => { |
| | | const { districtName, count, lat, lon } = item |
| | | item.name = `${item.districtName}\n${item.count}` |
| | | item.longitude = item.lon |
| | | item.latitude = item.lat |
| | | item.showBillboard = false |
| | | item.showLabel = true |
| | | let htmlEntityList = []; |
| | | function initDistrictCount() { |
| | | getDistrictCount().then((res) => { |
| | | res.data.forEach((item) => { |
| | | const { districtName, count, lat, lon } = item; |
| | | item.name = `${item.districtName}\n${item.count}`; |
| | | item.longitude = item.lon; |
| | | item.latitude = item.lat; |
| | | item.showBillboard = false; |
| | | item.showLabel = true; |
| | | item.label = { |
| | | text: item.name, |
| | | backgroundColor: SmartEarth.Cesium.Color.SKYBLUE.withAlpha(0.8), |
| | | font: "14pt Source Han Sans CN", |
| | | fillColor: SmartEarth.Cesium.Color.WHITE, |
| | | showBackground: true, |
| | | } |
| | | }; |
| | | // createPoint(item) |
| | | const html = earthCtrl.view.createScreenDialog({ |
| | | html: ` |
| | |
| | | lon: item.lon, |
| | | lat: item.lat, |
| | | height: 0, |
| | | }) |
| | | html.maxVisibleDistance = 69000 |
| | | html.minVisibleDistance = 20000 |
| | | }); |
| | | html.maxVisibleDistance = 69000; |
| | | html.minVisibleDistance = 20000; |
| | | html.element.addEventListener("click", () => { |
| | | viewer.camera.flyTo({ |
| | | destination: Cesium.Cartesian3.fromDegrees(item.longitude, item.latitude, 12000), |
| | | destination: Cesium.Cartesian3.fromDegrees( |
| | | item.longitude, |
| | | item.latitude, |
| | | 12000 |
| | | ), |
| | | orientation: { |
| | | pitch: Cesium.Math.toRadians(-90), |
| | | heading: Cesium.Math.toRadians(0), |
| | | roll: 0, |
| | | }, |
| | | duration: 2, |
| | | }) |
| | | }) |
| | | }); |
| | | }); |
| | | |
| | | htmlEntityList.push(html) |
| | | }) |
| | | }) |
| | | htmlEntityList.push(html); |
| | | }); |
| | | }); |
| | | } |
| | | function initDistrictCountByCity () { |
| | | getDistrictCountByCity().then(res => { |
| | | res.data.forEach(item => { |
| | | const { districtName, count, lat, lon } = item |
| | | item.name = `${item.districtName}\n${item.count}` |
| | | item.longitude = item.lon |
| | | item.latitude = item.lat |
| | | item.showBillboard = false |
| | | item.showLabel = true |
| | | function initDistrictCountByCity() { |
| | | getDistrictCountByCity().then((res) => { |
| | | res.data.forEach((item) => { |
| | | const { districtName, count, lat, lon } = item; |
| | | item.name = `${item.districtName}\n${item.count}`; |
| | | item.longitude = item.lon; |
| | | item.latitude = item.lat; |
| | | item.showBillboard = false; |
| | | item.showLabel = true; |
| | | item.label = { |
| | | text: item.name, |
| | | backgroundColor: SmartEarth.Cesium.Color.SKYBLUE.withAlpha(0.8), |
| | | font: "14pt Source Han Sans CN", |
| | | fillColor: SmartEarth.Cesium.Color.WHITE, |
| | | showBackground: true, |
| | | } |
| | | }; |
| | | // createPoint(item) |
| | | const html = earthCtrl.view.createScreenDialog({ |
| | | html: ` |
| | |
| | | lon: item.lon, |
| | | lat: item.lat, |
| | | height: 0, |
| | | }) |
| | | html.maxVisibleDistance = 50000000 |
| | | html.minVisibleDistance = 70000 |
| | | }); |
| | | html.maxVisibleDistance = 50000000; |
| | | html.minVisibleDistance = 70000; |
| | | html.element.addEventListener("click", () => { |
| | | viewer.camera.flyTo({ |
| | | destination: Cesium.Cartesian3.fromDegrees(item.longitude, item.latitude, 45000), |
| | | destination: Cesium.Cartesian3.fromDegrees( |
| | | item.longitude, |
| | | item.latitude, |
| | | 45000 |
| | | ), |
| | | orientation: { |
| | | pitch: Cesium.Math.toRadians(-90), |
| | | heading: Cesium.Math.toRadians(0), |
| | | roll: 0, |
| | | }, |
| | | duration: 2, |
| | | }) |
| | | }) |
| | | }); |
| | | }); |
| | | |
| | | htmlEntityList.push(html) |
| | | }) |
| | | }) |
| | | htmlEntityList.push(html); |
| | | }); |
| | | }); |
| | | } |
| | | watch( |
| | | () => route.fullPath, |
| | | val => { |
| | | (val) => { |
| | | if (val != "/") { |
| | | // clusterLayer.dataSource.show = false |
| | | htmlEntityList.forEach(item => { |
| | | item.show = false |
| | | }) |
| | | removeCameraChange() |
| | | htmlEntityList.forEach((item) => { |
| | | item.show = false; |
| | | }); |
| | | removeCameraChange(); |
| | | } else { |
| | | handleCameraChange() |
| | | handleCameraChange(); |
| | | // clusterLayer.dataSource.show = true |
| | | htmlEntityList.forEach(item => { |
| | | item.show = isVisibleDistance(item.minVisibleDistance, item.maxVisibleDistance) |
| | | }) |
| | | htmlEntityList.forEach((item) => { |
| | | item.show = isVisibleDistance( |
| | | item.minVisibleDistance, |
| | | item.maxVisibleDistance |
| | | ); |
| | | }); |
| | | } |
| | | } |
| | | ) |
| | | function handleCameraChange () { |
| | | viewer.camera.changed.addEventListener(toggleHtmlLayerByVisibleDistance) |
| | | ); |
| | | function handleCameraChange() { |
| | | viewer.camera.changed.addEventListener(toggleHtmlLayerByVisibleDistance); |
| | | } |
| | | function removeCameraChange () { |
| | | viewer.camera.changed.removeEventListener(toggleHtmlLayerByVisibleDistance) |
| | | function removeCameraChange() { |
| | | viewer.camera.changed.removeEventListener(toggleHtmlLayerByVisibleDistance); |
| | | } |
| | | let cameraChangeTimer = null |
| | | let cameraChangeTimer = null; |
| | | |
| | | function toggleHtmlLayerByVisibleDistance () { |
| | | function toggleHtmlLayerByVisibleDistance() { |
| | | if (cameraChangeTimer) { |
| | | clearTimeout(cameraChangeTimer) |
| | | cameraChangeTimer = null |
| | | return |
| | | clearTimeout(cameraChangeTimer); |
| | | cameraChangeTimer = null; |
| | | return; |
| | | } |
| | | cameraChangeTimer = setTimeout(() => { |
| | | htmlEntityList.forEach(item => { |
| | | item.show = isVisibleDistance(item.minVisibleDistance, item.maxVisibleDistance) |
| | | }) |
| | | }, 100) |
| | | htmlEntityList.forEach((item) => { |
| | | item.show = isVisibleDistance( |
| | | item.minVisibleDistance, |
| | | item.maxVisibleDistance |
| | | ); |
| | | }); |
| | | }, 100); |
| | | } |
| | | |
| | | onMounted(() => { |
| | | initMap() |
| | | addCityPolygon() |
| | | initHandler() |
| | | initMap(); |
| | | addCityPolygon(); |
| | | initHandler(); |
| | | // initView() |
| | | loadAreaPolygon("/json/nsl_area.geojson") |
| | | loadAreaPolygonAll("/json/geometry.json", true) |
| | | flyToHomeView() |
| | | initDistrictCount() |
| | | initDistrictCountByCity() |
| | | handleCameraChange() |
| | | loadAreaPolygon("/json/nsl_area.geojson"); |
| | | loadAreaPolygonAll("/json/geometry.json", true); |
| | | flyToHomeView(); |
| | | initDistrictCount(); |
| | | initDistrictCountByCity(); |
| | | handleCameraChange(); |
| | | // 设置 billboard 点击事件 |
| | | }) |
| | | }); |
| | | onUnmounted(() => { |
| | | removeCameraChange() |
| | | }) |
| | | removeCameraChange(); |
| | | }); |
| | | </script> |
| | | |
| | | <style lang="less" scoped> |