diff --git a/src/components/domain/One/Point.jsx b/src/components/domain/One/Point.jsx index 165df93..d8a57ef 100644 --- a/src/components/domain/One/Point.jsx +++ b/src/components/domain/One/Point.jsx @@ -15,12 +15,6 @@ import { // 从拉布拉多海到青藏高原 const dataLabToQTP = [ - // { longitude: -59, latitude: 60, height: 1000000, time: 5 }, - // { longitude: -25, latitude: 46, height: 1000000, time: 10 }, - // { longitude: 0, latitude: 42, height: 1000000, time: 15 }, - // // { longitude: 30, latitude: 45, height: 1000000, time: 17 }, - // { longitude: 47, latitude: 38, height: 1000000, time: 20 }, - // { longitude: 95, latitude: 36, height: 1000000, time: 25 }, { longitude: -59, latitude: 60, height: 1000000, time: 5 }, { longitude: -38, latitude: 55, height: 1000000, time: 7.5 }, { longitude: -20, latitude: 50, height: 1000000, time: 10 }, diff --git a/src/components/domain/Three/SceneTwo/Circles.jsx b/src/components/domain/Three/SceneTwo/Circles.jsx new file mode 100644 index 0000000..047a91e --- /dev/null +++ b/src/components/domain/Three/SceneTwo/Circles.jsx @@ -0,0 +1,148 @@ +import { Fragment, useState } from "react"; +import { + Entity, + useCesium, + PolylineGraphics, + LabelGraphics, + ModelGraphics, +} from "resium"; +import { useInterval } from "ahooks"; +import { + Cartesian3, + Color, + Math as CesiumMath, + LabelStyle, + PolylineDashMaterialProperty, + Cartesian2, + ColorBlendMode, +} from "cesium"; +import arrowRound from "@/assets/arrow_round.glb"; +import arrowRoundReverse from "@/assets/arrow_round_reverse.glb"; + +const anticycloneColor = Color.fromCssColorString("#f70000"); +const cycloneColor = Color.fromCssColorString("#0000ff"); + +function Circles() { + const { viewer } = useCesium(); + + const Circle = ({ id, lon, lat, isLow, showTime }) => { + const [show, setShow] = useState(false); + const arrow = !isLow ? arrowRound : arrowRoundReverse; + const color = !isLow ? anticycloneColor : cycloneColor; + const minimumPixelSize = !isLow ? 128 : 98; + + const circle = ( + + ); + + useInterval(() => { + const { startTime, currentTime, shouldAnimate } = viewer.clock; + const _time = (currentTime.secondsOfDay - startTime.secondsOfDay).toFixed( + 1 + ); + if (!shouldAnimate) return; + if (_time >= showTime) { + setShow(true); + } else { + if (!show) return; + setShow(false); + } + }, 300); + + if (!show) return <>; + + return ( + + + {circle} + + + + + + {circle} + + + + + + ); + }; + + return ( + + + + + + + + ); +} + +export default Circles; diff --git a/src/components/domain/Three/SceneTwo/CustomChartPanel.jsx b/src/components/domain/Three/SceneTwo/CustomChartPanel.jsx new file mode 100644 index 0000000..fb5d691 --- /dev/null +++ b/src/components/domain/Three/SceneTwo/CustomChartPanel.jsx @@ -0,0 +1,188 @@ +import ChartPanel from "@/components/common/ChartPanel"; + +const years = []; + +for (let year = 1900; year <= 2000; year++) { + years.push(year); +} + +// 北极 +const AntarcticaData = [ + 0.101942611, 0.121527548, 0.139042908, 0.153372484, 0.163348844, 0.16781324, + 0.165740405, 0.156668394, 0.140792524, 0.118786901, 0.091903343, 0.062313072, + 0.032977812, 0.00716395, -0.012074836, -0.022308346, -0.021755523, + -0.00911355, 0.016196573, 0.053416993, 0.100564819, 0.155328769, 0.215351821, + 0.278252395, 0.341745714, 0.40383823, 0.463006888, 0.518309403, 0.569408932, + 0.616333481, 0.65915749, 0.697835067, 0.732192543, 0.761939745, 0.78659761, + 0.805314271, 0.81708585, 0.820876623, 0.815679973, 0.800851314, 0.776409401, + 0.742721875, 0.700509783, 0.651004076, 0.595858743, 0.536937172, 0.476075479, + 0.414725656, 0.353864772, 0.294239451, 0.236327526, 0.18015056, 0.125260938, + 0.070978964, 0.016363941, -0.039809019, -0.09861786, -0.160770418, + -0.226238681, -0.294159838, -0.363174145, -0.431703208, -0.497831469, + -0.559188985, -0.613384987, -0.658281488, -0.692634725, -0.716904761, + -0.73222222, -0.739942379, -0.741611283, -0.73898482, -0.733815531, + -0.727389051, -0.720449369, -0.713466528, -0.706847385, -0.700922099, + -0.695911133, -0.691920829, -0.688978939, -0.687022002, -0.685739611, + -0.684476492, -0.682376879, -0.678508387, -0.672015068, -0.662330127, + -0.649157058, -0.632405431, -0.612100964, -0.588400678, -0.56151658, + -0.531629308, -0.498751783, -0.462720586, -0.423305188, -0.380187818, + -0.332990445, -0.281392986, -0.225240753, +]; + +// 南极 +const ArcticData = [ + 0.280477536, 0.259957371, 0.238217659, 0.215366218, 0.191558571, 0.167050728, + 0.142221385, 0.117514405, 0.093353739, 0.070136018, 0.048165337, 0.027449274, + 0.007551689, -0.012191879, -0.032557296, -0.054358257, -0.078483167, + -0.105781444, -0.137208672, -0.174049223, -0.217858518, -0.26986764, + -0.329886107, -0.395653113, -0.463819615, -0.530529991, -0.591308473, + -0.641252419, -0.675396192, -0.689099366, -0.679883827, -0.649742172, + -0.602149752, -0.540699996, -0.469155442, -0.39235518, -0.317187358, + -0.251641431, -0.203124483, -0.175400473, -0.167133512, -0.174805821, + -0.194600911, -0.222664488, -0.254875954, -0.286753396, -0.31384639, + -0.331733387, -0.335992097, -0.322259345, -0.28761534, -0.234372353, + -0.167389335, -0.091870697, -0.013026713, 0.063931601, 0.133955753, + 0.193415777, 0.241940543, 0.280019233, 0.308168154, 0.326938643, 0.337234614, + 0.34096367, 0.340608802, 0.338547054, 0.336593745, 0.335321866, 0.334127457, + 0.331817533, 0.327341923, 0.320216724, 0.310432332, 0.298228465, 0.284102612, + 0.268784935, 0.253114795, 0.237954629, 0.224151962, 0.212536008, 0.203736355, + 0.198010458, 0.195233614, 0.194960735, 0.196490857, 0.19901247, 0.201666439, + 0.203617401, 0.204129573, 0.202630823, 0.19873752, 0.192336315, 0.183625216, + 0.173000981, 0.16106866, 0.148653001, 0.136669759, 0.12600632, 0.117368896, + 0.111065474, 0.107060448, +]; + +// 青藏高原 +const TibetanData = [ + -0.054774324, -0.072074468, -0.088166217, -0.102150868, -0.113128752, + -0.12021764, -0.122708696, -0.12041877, -0.113696453, -0.103130771, + -0.089455408, -0.073531475, -0.056259257, -0.03854918, -0.021352917, + -0.005665395, 0.007550856, 0.01747264, 0.023473197, 0.025172256, 0.022567986, + 0.01612004, 0.006575074, -0.005110343, -0.017780686, -0.030203073, + -0.041154273, -0.04937311, -0.053563998, -0.052516092, -0.045257867, + -0.031279225, -0.010592879, 0.016344502, 0.048680379, 0.085233754, + 0.124518788, 0.164767706, 0.204092074, 0.240587798, 0.272353213, 0.297512938, + 0.314395917, 0.321976324, 0.320031404, 0.309041322, 0.289958303, 0.26397781, + 0.232447596, 0.196815201, 0.15858192, 0.119195224, 0.079906512, 0.041729979, + 0.005377081, -0.028807517, -0.060676589, -0.09016857, -0.11718843, + -0.141549386, -0.163019079, -0.181382947, -0.196521195, -0.208451503, + -0.21726015, -0.223065102, -0.226003897, -0.226234158, -0.223991288, + -0.219766729, -0.214261928, -0.208224121, -0.202386774, -0.197405298, + -0.193729514, -0.191661726, -0.191394367, -0.192960556, -0.196177765, + -0.20070803, -0.206145455, -0.212083352, -0.218149914, -0.223985256, + -0.229195822, -0.233329665, -0.235927137, -0.236550243, -0.234784989, + -0.230241493, -0.222529731, -0.211284994, -0.196192431, -0.177010405, + -0.153629275, -0.126243447, -0.095383816, -0.061763417, -0.026131148, + 0.010750252, 0.048064799, +]; + +function CustomChartPanel() { + const option = { + title: { + // text: "Stacked Line", + }, + tooltip: { + trigger: "axis", + }, + legend: { + data: ["南极", "北极", "青藏高原"], + textStyle: { color: "#04fbfd", cursor: "point", fontSize: 20 }, + }, + animationDuration: 10 * 1000, + animationEasing: "cubicInOut", + grid: { + left: "3%", + right: "4%", + bottom: "3%", + containLabel: true, + }, + // toolbox: { + // feature: { + // // 下载 + // saveAsImage: {}, + // }, + // }, + xAxis: { + type: "category", + boundaryGap: false, + data: years, + axisLine: { + onZero: false, + symbol: ["none", "arrow"], + symbolOffser: [0, 10], + lineStyle: { + color: "#04fbfd", + }, + }, + axisLabel: { + interval: 9, + }, + }, + yAxis: { + type: "value", + name: "℃", + min: -1, + max: 1, + interval: 0.25, + splitNumber: 5, + splitLine: { show: false }, + axisLine: { + onZero: false, + show: true, + symbol: ["none", "arrow"], + symbolOffset: [0, 10], + lineStyle: { + color: "#04fbfd", + }, + }, + axisLabel: { + show: true, + }, + axisTick: { show: true }, + scale: true, + }, + dataZoom: { type: "inside", start: 0, end: 100 }, + series: [ + { + name: "北极", + type: "line", + stack: "Total", + data: AntarcticaData, + smooth: true, + color: "red", + symbol: "none", + itemStyle: { + color: "red", + }, + }, + { + name: "南极", + type: "line", + // stack: "Total", + data: ArcticData, + smooth: true, + color: "blue", + symbol: "none", + itemStyle: { + color: "blue", + }, + }, + { + name: "青藏高原", + type: "line", + // stack: "Total", + data: TibetanData, + smooth: true, + color: "green", + symbol: "none", + itemStyle: { + color: "green", + }, + }, + ], + }; + + return ; +} + +export default CustomChartPanel; diff --git a/src/components/domain/Three/SceneTwo/CustomFlyTo.jsx b/src/components/domain/Three/SceneTwo/CustomFlyTo.jsx index 667b363..0aabccc 100644 --- a/src/components/domain/Three/SceneTwo/CustomFlyTo.jsx +++ b/src/components/domain/Three/SceneTwo/CustomFlyTo.jsx @@ -1,11 +1,81 @@ -import { Cartesian3 } from "cesium"; -import { CameraFlyTo } from "resium"; +import { Cartesian3, EasingFunction } from "cesium"; +import { useCesium } from "resium"; export default function CustomFlyTo() { - return ( - - ); + const { viewer } = useCesium(); + const { camera } = viewer; + + function cameraFlyToLine() { + const step1 = { + destination: Cartesian3.fromDegrees(18, -75, 10000000), + duration: 3, + orientation: { + heading: 6.283, + pitch: -1.3, + roll: 0, + }, + complete: () => { + viewer.clock.shouldAnimate = true; + setTimeout(() => { + camera.flyTo(step2); + }, 2000); + }, + easingFunction: EasingFunction.LINEAR_NONE, + }; + + const step2 = { + destination: Cartesian3.fromDegrees(80, -75, 10000000), + duration: 5, + orientation: { + heading: 6.283, + pitch: -1.3, + roll: 0, + }, + complete: () => { + camera.flyTo(step3); + }, + easingFunction: EasingFunction.LINEAR_NONE, + }; + const step3 = { + destination: Cartesian3.fromDegrees(130, -55, 10000000), + duration: 5, + orientation: { + heading: 6.283, + pitch: -1.3, + roll: 0, + }, + complete: () => { + camera.flyTo(step4); + }, + easingFunction: EasingFunction.LINEAR_NONE, + }; + const step4 = { + destination: Cartesian3.fromDegrees(180, -75, 10000000), + duration: 5, + orientation: { + heading: 6.283, + pitch: -1.3, + roll: 0, + }, + complete: () => { + camera.flyTo(step5); + }, + easingFunction: EasingFunction.LINEAR_NONE, + }; + const step5 = { + destination: Cartesian3.fromDegrees(-130, -85, 10000000), + duration: 5, + orientation: { + heading: 6.283, + pitch: -1.3, + roll: 0, + }, + easingFunction: EasingFunction.LINEAR_NONE, + }; + + camera.flyTo(step1); + } + cameraFlyToLine(); + + return <>; } diff --git a/src/components/domain/Three/SceneTwo/Legend.jsx b/src/components/domain/Three/SceneTwo/Legend.jsx index d2f2d1c..d520da6 100644 --- a/src/components/domain/Three/SceneTwo/Legend.jsx +++ b/src/components/domain/Three/SceneTwo/Legend.jsx @@ -42,7 +42,7 @@ const colorBar2 = [ function Legend({ style }) { return ( -
+ {/*
南半球冬季南极半岛区域地表气温年代际分量(单位:K)
@@ -105,8 +105,8 @@ function Legend({ style }) { ); })}
-
-
+
*/} +
南半球冬季200hPa涡动位势高度异常(单位:gpm)
diff --git a/src/components/domain/Three/SceneTwo/Point.jsx b/src/components/domain/Three/SceneTwo/Point.jsx new file mode 100644 index 0000000..3f28670 --- /dev/null +++ b/src/components/domain/Three/SceneTwo/Point.jsx @@ -0,0 +1,101 @@ +import { useState } from "react"; +import { Entity, PointGraphics, useCesium } from "resium"; +import { useInterval } from "ahooks"; +import { + Cartesian3, + Color, + JulianDate, + LagrangePolynomialApproximation, + PolylineDashMaterialProperty, + SampledPositionProperty, + TimeInterval, + TimeIntervalCollection, + VelocityOrientationProperty, +} from "cesium"; + +const data = [ + { longitude: 18, latitude: -50, height: 0, time: 0 }, + { longitude: 18, latitude: -50, height: 1000000, time: 2 }, + { longitude: 80, latitude: -50, height: 1000000, time: 7 }, + { longitude: 130, latitude: -40, height: 1000000, time: 12 }, + { longitude: 166, latitude: -55, height: 1000000, time: 17 }, + { longitude: -130, latitude: -65, height: 1000000, time: 22 }, +]; + +function Point() { + const { viewer } = useCesium(); + const [delay, setDelay] = useState(1000); + + const start = viewer.clock.startTime; + const stop = viewer.clock.stopTime; + + const pathMaterial = new PolylineDashMaterialProperty({ + dashLength: 20, + color: new Color(4 / 255, 251 / 255, 253 / 255), + }); + + useInterval(() => { + if (viewer.clock?.shouldAnimate) setDelay(undefined); + }, delay); + + /** + * 计算飞行路径 + * 数据坐标 + * {SampledPositionProperty|*} + */ + function createProperty(source) { + let property = new SampledPositionProperty(); + for (let i = 0; i < source.length; i++) { + let time = JulianDate.addSeconds(start, source[i].time, new JulianDate()); + let position = Cartesian3.fromDegrees( + source[i].longitude, + source[i].latitude, + source[i].height + ); + // 添加位置,和时间对应 + property.addSample(time, position); + } + // property.setInterpolationOptions({ + // interpolationDegree: 2, + // interpolationAlgorithm: LagrangePolynomialApproximation, + // }); + + return property; + } + + const property = createProperty(data); + + return ( + + + + ); +} + +export default Point; diff --git a/src/components/domain/Three/SceneTwo/SceneChartPanel.jsx b/src/components/domain/Three/SceneTwo/SceneChartPanel.jsx deleted file mode 100644 index cf8dbbd..0000000 --- a/src/components/domain/Three/SceneTwo/SceneChartPanel.jsx +++ /dev/null @@ -1,128 +0,0 @@ -import ChartPanel from "@/components/common/ChartPanel"; - -const years = []; - -for (let year = 1950; year <= 2020; year++) { - years.push(year); -} - -const SATData = [ - 0.429685116, 0.689356685, 0.873310268, 0.967009068, 1.003803611, 1.036836505, - 1.102791905, 1.167440891, 1.17760396, 1.124955773, 1.01085484, 0.859563529, - 0.71795398, 0.621988237, 0.597750485, 0.598902822, 0.532728314, 0.342583299, - -0.024368536, -0.493425161, -0.9331339, -1.273939967, -1.476933718, - -1.554893732, -1.475591898, -1.279159307, -1.064661622, -0.922379196, - -0.918932199, -1.11133039, -1.43390727, -1.801198602, -2.015464544, - -2.0192132, -1.855630398, -1.571777582, -1.243658185, -1.025858879, - -0.930935264, -0.869536936, -0.719216347, -0.443715662, -0.130082458, - 0.151266798, 0.290564477, 0.236905336, 0.056489315, -0.14797987, -0.240299582, - -0.17908895, 0.034180526, 0.390409917, 0.806362808, 1.218396306, 1.526551723, - 1.709755898, 1.74579525, 1.635397196, 1.387297392, 1.11059618, 0.822289705, - 0.581417382, 0.404003143, 0.258351594, 0.119950205, 0.01043385, -0.079203822, - -0.124122731, -0.129883319, -0.031686373, 0.16967541, -]; - -const SSTData = [ - 1.212813735, 1.429750562, 1.521738529, 1.469550729, 1.316006422, 1.125649571, - 0.986746848, 0.915246606, 0.915339172, 0.951494932, 0.970494628, 0.926436901, - 0.79472959, 0.602078795, 0.395833611, 0.238499194, 0.111982882, -0.020530188, - -0.205848336, -0.508775234, -0.927411437, -1.398505688, -1.82903564, - -2.119443178, -2.199231863, -2.063818693, -1.770155549, -1.401496291, - -1.074879527, -0.84980756, -0.789860964, -0.888945699, -1.096244812, - -1.2922014, -1.367582083, -1.272272468, -1.035024524, -0.74733454, - -0.570655763, -0.564872324, -0.715999901, -0.92039144, -1.045125961, - -0.965325236, -0.686810315, -0.263357043, 0.127493069, 0.37617141, - 0.430310369, 0.350464702, 0.266462713, 0.269338131, 0.410024047, 0.642185688, - 0.879462898, 1.070014119, 1.173520446, 1.198034406, 1.178782582, 1.129892349, - 1.029724956, 0.902248025, 0.708711326, 0.465828151, 0.227744579, 0.055393901, - 0.002014907, 0.076390825, 0.281141222, 0.559546649, 0.895649433, -]; - -function SceneChartPanel() { - const option = { - title: { - // text: "Stacked Line", - }, - tooltip: { - trigger: "axis", - }, - legend: { - data: ["南极半岛", "热带大西洋"], - textStyle: { color: "#04fbfd", cursor: "point", fontSize: 20 }, - }, - animationDuration: 10 * 1000, - animationEasing: "cubicInOut", - grid: { - left: "3%", - right: "4%", - bottom: "3%", - containLabel: true, - }, - xAxis: { - type: "category", - boundaryGap: false, - data: years, - axisLine: { - onZero: false, - symbol: ["none", "arrow"], - symbolOffser: [0, 10], - lineStyle: { - color: "#04fbfd", - }, - }, - }, - yAxis: { - type: "value", - min: -3.0, - max: 2.0, - interval: 1.0, - splitNumber: 5, - splitLine: { show: false }, - axisLine: { - onZero: false, - show: true, - symbol: ["none", "arrow"], - symbolOffset: [0, 10], - lineStyle: { - color: "#04fbfd", - }, - }, - axisLabel: { - show: true, - }, - axisTick: { show: true }, - scale: true, - }, - dataZoom: { type: "inside", start: 0, end: 100 }, - series: [ - { - name: "南极半岛", - type: "line", - // stack: "Total", - data: SATData, - smooth: true, - color: "blue", - symbol: "none", - itemStyle: { - color: "blue", - }, - }, - { - name: "热带大西洋", - type: "line", - // stack: "Total", - data: SSTData, - smooth: true, - color: "red", - symbol: "none", - itemStyle: { - color: "red", - }, - }, - ], - }; - - return ; -} - -export default SceneChartPanel; diff --git a/src/components/domain/Three/SceneTwo/index.jsx b/src/components/domain/Three/SceneTwo/index.jsx index 694a29b..7c03b3b 100644 --- a/src/components/domain/Three/SceneTwo/index.jsx +++ b/src/components/domain/Three/SceneTwo/index.jsx @@ -1,11 +1,13 @@ import MapLayout from "@/components/map/Layout"; import Legend from "./Legend"; import ViewerOne from "../SceneOne/ViewerOne"; -import SceneChartPanel from "./SceneChartPanel"; import CustomFlyTo from "./CustomFlyTo"; import SSTImageLayer from "./SSTImageLayer"; import TSImageLayer from "./TSImageLayer"; import HGTImageLayer from "./HGTImageLayer"; +import Point from "./Point"; +import Circles from "./Circles"; +import CustomChartPanel from "./CustomChartPanel"; function SceneTwo() { return ( @@ -16,18 +18,17 @@ function SceneTwo() {
- +
+ {/* */} {/* */} + - {/* - - */} ); } diff --git a/src/components/domain/Three/index.jsx b/src/components/domain/Three/index.jsx index dcfd669..632006b 100644 --- a/src/components/domain/Three/index.jsx +++ b/src/components/domain/Three/index.jsx @@ -9,8 +9,9 @@ export default function DomainThree() { return (
- {scene === 1 ? : } - + {/* {scene === 1 ? : } */} + + {/* */}
); }