refactor
This commit is contained in:
parent
477bf6f6bd
commit
3429e19c6c
@ -1,6 +1,8 @@
|
|||||||
import { Routes, Route, Navigate } from "react-router-dom";
|
import { Routes, Route, Navigate } from "react-router-dom";
|
||||||
import HomeLayout from "@/components/home/Layout";
|
import HomeLayout from "@/components/home/Layout";
|
||||||
import DomainOne from "./components/domain/One";
|
import DomainOne from "@/components/domain/One";
|
||||||
|
import DomainTwo from "@/components/domain/Two";
|
||||||
|
import DomainThree from "@/components/domain/Three";
|
||||||
import "./App.less";
|
import "./App.less";
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
@ -8,6 +10,8 @@ function App() {
|
|||||||
<Routes>
|
<Routes>
|
||||||
<Route path="/" element={<HomeLayout />} />
|
<Route path="/" element={<HomeLayout />} />
|
||||||
<Route path="map/1" element={<DomainOne />}></Route>
|
<Route path="map/1" element={<DomainOne />}></Route>
|
||||||
|
<Route path="map/2" element={<DomainTwo />}></Route>
|
||||||
|
<Route path="map/3" element={<DomainThree />}></Route>
|
||||||
<Route path="*" element={<Navigate to={"/"} replace={true} />} />
|
<Route path="*" element={<Navigate to={"/"} replace={true} />} />
|
||||||
</Routes>
|
</Routes>
|
||||||
);
|
);
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import MapLayout from "@/components/map/Layout";
|
import MapLayout from "@/components/map/Layout";
|
||||||
import CustomClock from "./CustomClock";
|
import CustomToolbar from "@/components/common/CustomToolbar";
|
||||||
|
import CustomClock from "@/components/common/CustomClock";
|
||||||
|
import TextInfoPanel from "@/components/common/TextInfoPanel";
|
||||||
import CustomFlyTo from "./CustomFlyTo";
|
import CustomFlyTo from "./CustomFlyTo";
|
||||||
import CustomToolbar from "./CustomToolbar";
|
|
||||||
import Point from "./Point";
|
import Point from "./Point";
|
||||||
import PlateauPolygon from "./PlateauPolygon";
|
import PlateauPolygon from "./PlateauPolygon";
|
||||||
import TextInfoPanel from "./TextInfoPanel";
|
|
||||||
import Cyclone from "./Cyclone";
|
import Cyclone from "./Cyclone";
|
||||||
import Barotropic from "./Barotorpic";
|
import Barotropic from "./Barotorpic";
|
||||||
import WavePoints from "./WavePoints";
|
import WavePoints from "./WavePoints";
|
||||||
@ -25,17 +25,11 @@ export default function DomainOne() {
|
|||||||
<CustomFlyTo />
|
<CustomFlyTo />
|
||||||
<Point />
|
<Point />
|
||||||
<PlateauPolygon />
|
<PlateauPolygon />
|
||||||
<div className="left-panel">
|
<div className="left-panel one">
|
||||||
<div className="top-panel"></div>
|
<TextInfoPanel content="基于再分析资料JRA55和线性斜压模式LBM的试验结果,在年代际尺度上,拉布拉多海海温偏暖会引起北大西洋至欧洲地区大气环流异常,导致青藏高原夏季出现年代际增温。" />
|
||||||
<div className="bottom-panel">
|
|
||||||
<TextInfoPanel content="基于再分析资料JRA55和线性斜压模式LBM的试验结果,在年代际尺度上,拉布拉多海海温偏暖会引起北大西洋至欧洲地区大气环流异常,导致青藏高原夏季出现年代际增温。" />
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div className="right-panel">
|
<div className="right-panel one">
|
||||||
<div className="top-panel"></div>
|
<ChartPanel />
|
||||||
<div className="bottom-panel">
|
|
||||||
<ChartPanel />
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<Cyclone />
|
<Cyclone />
|
||||||
<Barotropic />
|
<Barotropic />
|
||||||
|
184
src/components/domain/Three/ChartPanel.jsx
Normal file
184
src/components/domain/Three/ChartPanel.jsx
Normal file
@ -0,0 +1,184 @@
|
|||||||
|
import ReactECharts from "echarts-for-react";
|
||||||
|
|
||||||
|
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 ChartPanel() {
|
||||||
|
const option = {
|
||||||
|
title: {
|
||||||
|
// text: "Stacked Line",
|
||||||
|
},
|
||||||
|
tooltip: {
|
||||||
|
trigger: "axis",
|
||||||
|
},
|
||||||
|
legend: {
|
||||||
|
data: ["南极", "北极", "青藏高原"],
|
||||||
|
textStyle: { color: "#04fbfd", cursor: "point" },
|
||||||
|
},
|
||||||
|
animationDuration: years.length * 500,
|
||||||
|
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],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
yAxis: {
|
||||||
|
type: "value",
|
||||||
|
min: -1,
|
||||||
|
max: 1,
|
||||||
|
interval: 0.5,
|
||||||
|
splitNumber: 5,
|
||||||
|
splitLine: { show: false },
|
||||||
|
axisLine: {
|
||||||
|
onZero: false,
|
||||||
|
show: true,
|
||||||
|
symbol: ["none", "arrow"],
|
||||||
|
symbolOffset: [0, 10],
|
||||||
|
},
|
||||||
|
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 (
|
||||||
|
<div className="chart-info-panel">
|
||||||
|
<ReactECharts
|
||||||
|
option={option}
|
||||||
|
lazyUpdate={true}
|
||||||
|
style={{
|
||||||
|
height: "100%",
|
||||||
|
width: "100%",
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ChartPanel;
|
11
src/components/domain/Three/CustomFlyTo.jsx
Normal file
11
src/components/domain/Three/CustomFlyTo.jsx
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
import { Cartesian3 } from "cesium";
|
||||||
|
import { CameraFlyTo } from "resium";
|
||||||
|
|
||||||
|
export default function CustomFlyTo() {
|
||||||
|
return (
|
||||||
|
<CameraFlyTo
|
||||||
|
duration={5}
|
||||||
|
destination={Cartesian3.fromDegrees(-38.0, 27, 16000000)}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
33
src/components/domain/Three/LandImageLayer.jsx
Normal file
33
src/components/domain/Three/LandImageLayer.jsx
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
import { useEffect, useMemo, useState } from "react";
|
||||||
|
import { ImageryLayer, useCesium } from "resium";
|
||||||
|
import { WebMapServiceImageryProvider } from "cesium";
|
||||||
|
|
||||||
|
const url = "http://analysis.tpdc.ac.cn/gs/geoserver/phitrellis/wms";
|
||||||
|
const name = "phitrellis:4_3_t2m_era_1024";
|
||||||
|
|
||||||
|
function LandImageLayer() {
|
||||||
|
const { viewer } = useCesium();
|
||||||
|
|
||||||
|
const tempProvider = useMemo(
|
||||||
|
() =>
|
||||||
|
new WebMapServiceImageryProvider({
|
||||||
|
url: url,
|
||||||
|
layers: name,
|
||||||
|
parameters: {
|
||||||
|
service: "WMS",
|
||||||
|
format: "image/png",
|
||||||
|
transparent: true,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
[name, url]
|
||||||
|
);
|
||||||
|
return (
|
||||||
|
<ImageryLayer
|
||||||
|
key={`ImageryLayer-${name}`}
|
||||||
|
imageryProvider={tempProvider}
|
||||||
|
show={true}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default LandImageLayer;
|
34
src/components/domain/Three/OceanImageLayer.jsx
Normal file
34
src/components/domain/Three/OceanImageLayer.jsx
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
import { useEffect, useMemo, useState } from "react";
|
||||||
|
import { ImageryLayer, useCesium } from "resium";
|
||||||
|
import { WebMapServiceImageryProvider } from "cesium";
|
||||||
|
import { useInterval } from "ahooks";
|
||||||
|
import { useSelector } from "react-redux";
|
||||||
|
|
||||||
|
const url = "http://analysis.tpdc.ac.cn/gs/geoserver/phitrellis/wms";
|
||||||
|
const name = "phitrellis:4_3_hadisst_1822";
|
||||||
|
|
||||||
|
function OceanImageLayer() {
|
||||||
|
const tempProvider = useMemo(
|
||||||
|
() =>
|
||||||
|
new WebMapServiceImageryProvider({
|
||||||
|
url: url,
|
||||||
|
layers: name,
|
||||||
|
parameters: {
|
||||||
|
service: "WMS",
|
||||||
|
format: "image/png",
|
||||||
|
transparent: true,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
[name, url]
|
||||||
|
);
|
||||||
|
return (
|
||||||
|
<ImageryLayer
|
||||||
|
key={`ImageryLayer-${name}`}
|
||||||
|
imageryProvider={tempProvider}
|
||||||
|
show={true}
|
||||||
|
opacity={0.5}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default OceanImageLayer;
|
11
src/components/domain/Three/WavePoints.jsx
Normal file
11
src/components/domain/Three/WavePoints.jsx
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
import { Fragment } from "react";
|
||||||
|
import WavePoint from "@/components/common/WavePoint";
|
||||||
|
|
||||||
|
export default function WavePoints() {
|
||||||
|
return (
|
||||||
|
<Fragment>
|
||||||
|
<WavePoint stationLon={88} stationLat={-85} />
|
||||||
|
<WavePoint stationLon={88} stationLat={32.5} />
|
||||||
|
</Fragment>
|
||||||
|
);
|
||||||
|
}
|
31
src/components/domain/Three/index.jsx
Normal file
31
src/components/domain/Three/index.jsx
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
import MapLayout from "@/components/map/Layout";
|
||||||
|
import CustomToolbar from "@/components/common/CustomToolbar";
|
||||||
|
import CustomClock from "@/components/common/CustomClock";
|
||||||
|
import TextInfoPanel from "@/components/common/TextInfoPanel";
|
||||||
|
import CustomFlyTo from "./CustomFlyTo";
|
||||||
|
import WavePoints from "./WavePoints";
|
||||||
|
import ChartPanel from "./ChartPanel";
|
||||||
|
import LandImageLayer from "./LandImageLayer";
|
||||||
|
import OceanImageLayer from "./OceanImageLayer";
|
||||||
|
|
||||||
|
export default function DomainOne() {
|
||||||
|
return (
|
||||||
|
<MapLayout>
|
||||||
|
<div className="title">
|
||||||
|
两极协同—连接南极和北极的热带大西洋经向模的媒介作用
|
||||||
|
</div>
|
||||||
|
<CustomToolbar />
|
||||||
|
<CustomClock />
|
||||||
|
<CustomFlyTo />
|
||||||
|
<div className="left-panel one">
|
||||||
|
<TextInfoPanel content="利用GISTEMP资料,通过EEMD分解方法提取两极温度多年代际变化序列,发现南北极温度变化的跷跷板现象与大西洋多年代际振荡AMO紧密相关。而AMO与热带大西洋经向模AMM在年代际尺度上显著相关。ERA5再分析资料显示AMM可以通过Rossby波影响西南极的气温与海冰偶极子。因此,AMM可能在联系南北极气候变化的中起到了重要的媒介作用。" />
|
||||||
|
</div>
|
||||||
|
<div className="right-panel one">
|
||||||
|
<ChartPanel />
|
||||||
|
</div>
|
||||||
|
<WavePoints />
|
||||||
|
<LandImageLayer />
|
||||||
|
<OceanImageLayer />
|
||||||
|
</MapLayout>
|
||||||
|
);
|
||||||
|
}
|
115
src/components/domain/Two/CustomFlyTo.jsx
Normal file
115
src/components/domain/Two/CustomFlyTo.jsx
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
import { useDispatch } from "react-redux";
|
||||||
|
import { useCesium } from "resium";
|
||||||
|
|
||||||
|
function CustomFlyTo() {
|
||||||
|
const dispatch = useDispatch();
|
||||||
|
const { viewer } = useCesium();
|
||||||
|
const { camera } = viewer;
|
||||||
|
|
||||||
|
function cameraFlyToLine(adjustPitch) {
|
||||||
|
// 南极
|
||||||
|
const antarcticalOptions = {
|
||||||
|
destination: Cesium.Cartesian3.fromDegrees(88, -89, 1600000),
|
||||||
|
orientation: {
|
||||||
|
heading: Cesium.Math.toRadians(15.0),
|
||||||
|
pitch: Cesium.Math.toRadians(-60),
|
||||||
|
roll: 0.0,
|
||||||
|
},
|
||||||
|
duration: 10,
|
||||||
|
complete: function () {
|
||||||
|
setTimeout(() => {
|
||||||
|
camera.flyTo(plateauOptions);
|
||||||
|
}, 1000);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const area1Options = {
|
||||||
|
destination: Cesium.Cartesian3.fromDegrees(-110, -60, 6000000),
|
||||||
|
duration: 5,
|
||||||
|
complete: function () {
|
||||||
|
setTimeout(function () {
|
||||||
|
camera.flyTo(area2Options);
|
||||||
|
}, 1000);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const area2Options = {
|
||||||
|
destination: Cesium.Cartesian3.fromDegrees(-30, -55, 6000000),
|
||||||
|
duration: 5,
|
||||||
|
complete: function () {
|
||||||
|
setTimeout(function () {
|
||||||
|
camera.flyTo(area3Options);
|
||||||
|
}, 1000);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const area3Options = {
|
||||||
|
destination: Cesium.Cartesian3.fromDegrees(30, -40, 6000000),
|
||||||
|
duration: 5,
|
||||||
|
complete: function () {
|
||||||
|
setTimeout(function () {
|
||||||
|
camera.flyTo(area4Options);
|
||||||
|
}, 1000);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const area4Options = {
|
||||||
|
destination: Cesium.Cartesian3.fromDegrees(65, -35, 6000000),
|
||||||
|
duration: 5,
|
||||||
|
complete: function () {
|
||||||
|
setTimeout(function () {
|
||||||
|
camera.flyTo(sideViewOptions);
|
||||||
|
}, 1000);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
// 青藏高原
|
||||||
|
const plateauOptions = {
|
||||||
|
destination: Cesium.Cartesian3.fromDegrees(90, 20, 1600000),
|
||||||
|
duration: 5,
|
||||||
|
orientation: {
|
||||||
|
heading: Cesium.Math.toRadians(-15.0),
|
||||||
|
pitch: -Cesium.Math.PI_OVER_FOUR,
|
||||||
|
roll: 0.0,
|
||||||
|
},
|
||||||
|
complete: function () {
|
||||||
|
setTimeout(function () {
|
||||||
|
camera.flyTo(sideViewOptions);
|
||||||
|
}, 1000);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
// 侧边
|
||||||
|
const sideViewOptions = {
|
||||||
|
destination: Cesium.Cartesian3.fromDegrees(80, -60, 16000000),
|
||||||
|
// destination: Cesium.Cartesian3.fromDegrees(130, -10.5, 20000000),
|
||||||
|
duration: 5,
|
||||||
|
orientation: {
|
||||||
|
heading: Cesium.Math.toRadians(-10.0),
|
||||||
|
pitch: Cesium.Math.toRadians(-92),
|
||||||
|
roll: 6.0,
|
||||||
|
},
|
||||||
|
complete: () => {
|
||||||
|
viewer.clock.shouldAnimate = true;
|
||||||
|
dispatch.data.updateToolbar({ showPanel: true });
|
||||||
|
setTimeout(() => {
|
||||||
|
camera.flyTo({
|
||||||
|
duration: 5,
|
||||||
|
destination: Cesium.Cartesian3.fromDegrees(90, -12, 14000000),
|
||||||
|
});
|
||||||
|
}, 40 * 1000);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
if (adjustPitch) {
|
||||||
|
antarcticalOptions.pitchAdjustHeight = 1000;
|
||||||
|
plateauOptions.pitchAdjustHeight = 1000;
|
||||||
|
sideViewOptions.pitchAdjustHeight = 1000;
|
||||||
|
}
|
||||||
|
camera.flyTo(antarcticalOptions);
|
||||||
|
}
|
||||||
|
cameraFlyToLine();
|
||||||
|
return <></>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default CustomFlyTo;
|
34
src/components/domain/Two/IndiaOceanSST.jsx
Normal file
34
src/components/domain/Two/IndiaOceanSST.jsx
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
import { useEffect, useMemo, useState } from "react";
|
||||||
|
import { ImageryLayer, useCesium } from "resium";
|
||||||
|
import { WebMapServiceImageryProvider } from "cesium";
|
||||||
|
import { useInterval } from "ahooks";
|
||||||
|
import { useSelector } from "react-redux";
|
||||||
|
|
||||||
|
const url = "http://analysis.tpdc.ac.cn/gs/geoserver/phitrellis/wms";
|
||||||
|
|
||||||
|
function IndianOceanSST() {
|
||||||
|
const { imageLayer } = useSelector((state) => state.data);
|
||||||
|
|
||||||
|
const tempProvider = useMemo(
|
||||||
|
() =>
|
||||||
|
new WebMapServiceImageryProvider({
|
||||||
|
url: url,
|
||||||
|
layers: "phitrellis:india_ocean_sst",
|
||||||
|
parameters: {
|
||||||
|
service: "WMS",
|
||||||
|
format: "image/png",
|
||||||
|
transparent: true,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
[url]
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ImageryLayer
|
||||||
|
key={`ImageryLayer-india-ocean`}
|
||||||
|
imageryProvider={tempProvider}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default IndianOceanSST;
|
104
src/components/domain/Two/Legend.jsx
Normal file
104
src/components/domain/Two/Legend.jsx
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
import { Fragment } from "react";
|
||||||
|
|
||||||
|
const colorBar = [
|
||||||
|
"#ffc53d",
|
||||||
|
"#ffd666",
|
||||||
|
"#ffe58f",
|
||||||
|
"#fff1b8",
|
||||||
|
"#fffbe6",
|
||||||
|
"#e6f7ff",
|
||||||
|
"#bae7ff",
|
||||||
|
"#91d5ff",
|
||||||
|
"#69c0ff",
|
||||||
|
"#40a9ff",
|
||||||
|
];
|
||||||
|
|
||||||
|
const colorBar2 = [
|
||||||
|
"#73d13d",
|
||||||
|
"#95de64",
|
||||||
|
"#b7eb8f",
|
||||||
|
"#d9f7be",
|
||||||
|
"#f6ffed",
|
||||||
|
"#fff1f0",
|
||||||
|
"#ffccc7",
|
||||||
|
"#ffa39e",
|
||||||
|
"#ff7875",
|
||||||
|
"#ff4d4f",
|
||||||
|
];
|
||||||
|
|
||||||
|
function Legend() {
|
||||||
|
return (
|
||||||
|
<Fragment>
|
||||||
|
<div className="vertical-legend" style={{ right: 12 }}>
|
||||||
|
<div className="legend-title">青藏高原感热通量</div>
|
||||||
|
<div style={{ flex: 1, width: "100%", display: "flex", gap: 8 }}>
|
||||||
|
<div className="legend-text">
|
||||||
|
{[-0.5, -0.4, -0.3, -0.2, -0.1, 0, 0.1, 0.2, 0.3, 0.4, 0.5].map(
|
||||||
|
(item, index) => {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
key={`legend-text-item-${index}`}
|
||||||
|
className="legend-text-item"
|
||||||
|
>
|
||||||
|
{item}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<div className="colorbar">
|
||||||
|
{colorBar2.map((color, index) => {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
key={`colorbar-item-${index}`}
|
||||||
|
className="colorbar-item"
|
||||||
|
style={{ backgroundColor: color }}
|
||||||
|
title={`${(-0.5 + index * 0.1).toFixed(1)}~${(
|
||||||
|
-0.5 +
|
||||||
|
(index + 1) * 0.1
|
||||||
|
).toFixed(1)}`}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="vertical-legend" style={{ right: 154 }}>
|
||||||
|
<div className="legend-title">青藏高原降水量</div>
|
||||||
|
<div style={{ flex: 1, width: "100%", display: "flex", gap: 8 }}>
|
||||||
|
<div className="legend-text">
|
||||||
|
{[-0.5, -0.4, -0.3, -0.2, -0.1, 0, 0.1, 0.2, 0.3, 0.4, 0.5].map(
|
||||||
|
(item, index) => {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
key={`legend-text-item-${index}`}
|
||||||
|
className="legend-text-item"
|
||||||
|
>
|
||||||
|
{item}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<div className="colorbar">
|
||||||
|
{colorBar.map((color, index) => {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
key={`colorbar-item-${index}`}
|
||||||
|
className="colorbar-item"
|
||||||
|
style={{ backgroundColor: color }}
|
||||||
|
title={`${(-0.5 + index * 0.1).toFixed(1)}~${(
|
||||||
|
-0.5 +
|
||||||
|
(index + 1) * 0.1
|
||||||
|
).toFixed(1)}`}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Fragment>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Legend;
|
37
src/components/domain/Two/PlateauPolygon.jsx
Normal file
37
src/components/domain/Two/PlateauPolygon.jsx
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
import { useCallback, useState } from "react";
|
||||||
|
import { useParams } from "react-router-dom";
|
||||||
|
import { Entity, PolygonGraphics, useCesium } from "resium";
|
||||||
|
import { useInterval } from "ahooks";
|
||||||
|
|
||||||
|
function PlateauPolygon() {
|
||||||
|
const { type } = useParams();
|
||||||
|
const { viewer } = useCesium();
|
||||||
|
const [show, setShow] = useState(false);
|
||||||
|
|
||||||
|
const showAnimate = useCallback(() => {
|
||||||
|
const { currentTime, stopTime } = viewer.clock;
|
||||||
|
const leftTime = Math.floor(
|
||||||
|
stopTime.secondsOfDay - currentTime.secondsOfDay
|
||||||
|
);
|
||||||
|
|
||||||
|
if (leftTime < 20) {
|
||||||
|
setShow(true);
|
||||||
|
} else if (show) setShow(false);
|
||||||
|
}, [show, type]);
|
||||||
|
|
||||||
|
useInterval(showAnimate, 100);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Entity id="plateau" show={show}>
|
||||||
|
<PolygonGraphics
|
||||||
|
hierarchy={Cesium.Cartesian3.fromDegreesArray([
|
||||||
|
// 85, 30, 91, 30, 91, 35, 85, 35,
|
||||||
|
80, 31, 84, 29.5, 87.4, 28, 91, 28, 98, 29, 94, 35, 79, 34.4, 80, 31,
|
||||||
|
])}
|
||||||
|
material={new Cesium.Color(1, 0, 0, 0.1)}
|
||||||
|
/>
|
||||||
|
</Entity>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default PlateauPolygon;
|
93
src/components/domain/Two/Point.jsx
Normal file
93
src/components/domain/Two/Point.jsx
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
import { useState } from "react";
|
||||||
|
import { Entity, PointGraphics, useCesium } from "resium";
|
||||||
|
import { useInterval } from "ahooks";
|
||||||
|
|
||||||
|
// 从南极到青藏高原
|
||||||
|
const dataAntarcticaToQTP = [
|
||||||
|
{ longitude: -110, latitude: -60, height: 0, time: 0 },
|
||||||
|
{ longitude: -110, latitude: -60, height: 1000000, time: 10 },
|
||||||
|
{ longitude: -30, latitude: -55, height: 1000000, time: 20 },
|
||||||
|
{ longitude: 30, latitude: -40, height: 1000000, time: 30 },
|
||||||
|
{ longitude: 65, latitude: -35, height: 1000000, time: 40 },
|
||||||
|
{ longitude: 95, latitude: -30, height: 1000000, time: 50 },
|
||||||
|
{ longitude: 95, latitude: -30, height: 0, time: 60 },
|
||||||
|
];
|
||||||
|
|
||||||
|
function Point() {
|
||||||
|
const { viewer } = useCesium();
|
||||||
|
|
||||||
|
const [delay, setDelay] = useState(1000);
|
||||||
|
|
||||||
|
const start = viewer.clock.startTime;
|
||||||
|
const stop = viewer.clock.stopTime;
|
||||||
|
|
||||||
|
const pathMaterial = new Cesium.Color(4 / 255, 251 / 255, 253 / 255);
|
||||||
|
|
||||||
|
useInterval(() => {
|
||||||
|
if (viewer.clock?.shouldAnimate) setDelay(undefined);
|
||||||
|
}, delay);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 计算飞行路径
|
||||||
|
* 数据坐标
|
||||||
|
* {SampledPositionProperty|*}
|
||||||
|
*/
|
||||||
|
function createProperty(source) {
|
||||||
|
let property = new Cesium.SampledPositionProperty();
|
||||||
|
for (let i = 0; i < source.length; i++) {
|
||||||
|
let time = Cesium.JulianDate.addSeconds(
|
||||||
|
start,
|
||||||
|
source[i].time,
|
||||||
|
new Cesium.JulianDate()
|
||||||
|
);
|
||||||
|
let position = Cesium.Cartesian3.fromDegrees(
|
||||||
|
source[i].longitude,
|
||||||
|
source[i].latitude,
|
||||||
|
source[i].height
|
||||||
|
);
|
||||||
|
// 添加位置,和时间对应
|
||||||
|
property.addSample(time, position);
|
||||||
|
}
|
||||||
|
property.setInterpolationOptions({
|
||||||
|
interpolationDegree: 1,
|
||||||
|
interpolationAlgorithm: Cesium.LinearApproximation,
|
||||||
|
});
|
||||||
|
return property;
|
||||||
|
}
|
||||||
|
|
||||||
|
const property = createProperty(dataAntarcticaToQTP);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Entity
|
||||||
|
id={"point"}
|
||||||
|
position={property}
|
||||||
|
availability={
|
||||||
|
new Cesium.TimeIntervalCollection([
|
||||||
|
new Cesium.TimeInterval({
|
||||||
|
start,
|
||||||
|
stop,
|
||||||
|
}),
|
||||||
|
])
|
||||||
|
}
|
||||||
|
orientation={new Cesium.VelocityOrientationProperty(property)}
|
||||||
|
path={{
|
||||||
|
resolution: 1,
|
||||||
|
material: pathMaterial,
|
||||||
|
// leadTime、trailTime 不设置 path全显示
|
||||||
|
leadTime: 0, // 设置为0时 模型通过后显示path
|
||||||
|
// trailTime: 0, // 设置为0时 模型通过后隐藏path
|
||||||
|
width: 2,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<PointGraphics
|
||||||
|
show={true}
|
||||||
|
color={Cesium.Color.SKYBLUE}
|
||||||
|
pixelSize={10}
|
||||||
|
outlineColor={Cesium.Color.YELLOW}
|
||||||
|
outlineWidth={3}
|
||||||
|
/>
|
||||||
|
</Entity>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Point;
|
11
src/components/domain/Two/WavePoints.jsx
Normal file
11
src/components/domain/Two/WavePoints.jsx
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
import { Fragment } from "react";
|
||||||
|
import WavePoint from "@/components/common/WavePoint";
|
||||||
|
|
||||||
|
export default function WavePoints() {
|
||||||
|
return (
|
||||||
|
<Fragment>
|
||||||
|
<WavePoint stationLon={88} stationLat={-85} />
|
||||||
|
<WavePoint stationLon={88} stationLat={32.5} />
|
||||||
|
</Fragment>
|
||||||
|
);
|
||||||
|
}
|
29
src/components/domain/Two/index.jsx
Normal file
29
src/components/domain/Two/index.jsx
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
import MapLayout from "@/components/map/Layout";
|
||||||
|
import CustomToolbar from "@/components/common/CustomToolbar";
|
||||||
|
import CustomClock from "@/components/common/CustomClock";
|
||||||
|
import TextInfoPanel from "@/components/common/TextInfoPanel";
|
||||||
|
import CustomFlyTo from "./CustomFlyTo";
|
||||||
|
import Point from "./Point";
|
||||||
|
import PlateauPolygon from "./PlateauPolygon";
|
||||||
|
import WavePoints from "./WavePoints";
|
||||||
|
import Legend from "./Legend";
|
||||||
|
import IndianOceanSST from "./IndiaOceanSST";
|
||||||
|
|
||||||
|
export default function DomainTwo() {
|
||||||
|
return (
|
||||||
|
<MapLayout>
|
||||||
|
<div className="title">两极协同—南极涛动有效调节青藏高原降水和加热</div>
|
||||||
|
<CustomToolbar />
|
||||||
|
<CustomClock />
|
||||||
|
<CustomFlyTo />
|
||||||
|
<Point />
|
||||||
|
<PlateauPolygon />
|
||||||
|
<div className="left-panel one">
|
||||||
|
<TextInfoPanel content="利用ERA5再分析数据诊断和CESM印度洋海温强迫数值实验,发现5月的南极涛动正位相(AAO)激发原子阿蒙森海的纬向波列异常。该异常造成印度洋海温降低进而激发环流异常造成高原上空降水增加、感热通量降低。这一结果有助于提高青藏高原热源的预测技巧,改进亚洲夏季风的预测。" />
|
||||||
|
</div>
|
||||||
|
<WavePoints />
|
||||||
|
<Legend />
|
||||||
|
<IndianOceanSST />
|
||||||
|
</MapLayout>
|
||||||
|
);
|
||||||
|
}
|
@ -152,6 +152,10 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.one {
|
||||||
|
top: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
.legend {
|
.legend {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: 40px;
|
bottom: 40px;
|
||||||
@ -206,4 +210,59 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.vertical-legend {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 12px;
|
||||||
|
right: 474px;
|
||||||
|
height: 300px;
|
||||||
|
width: 130px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
background-color: #1f485690;
|
||||||
|
border: 1px solid #04fbfd;
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 8px;
|
||||||
|
|
||||||
|
.legend-title {
|
||||||
|
color: #04fbfd;
|
||||||
|
}
|
||||||
|
|
||||||
|
.colorbar {
|
||||||
|
width: 100px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: space-between;
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
.colorbar-item {
|
||||||
|
flex: 1;
|
||||||
|
border: 2px black solid;
|
||||||
|
border-left: none;
|
||||||
|
border-right: none;
|
||||||
|
height: 25px;
|
||||||
|
width: 25px;
|
||||||
|
|
||||||
|
&:not(:nth-child(1)) {
|
||||||
|
border-top: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.legend-text {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: space-between;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
.legend-text-item {
|
||||||
|
flex: 1;
|
||||||
|
text-align: right;
|
||||||
|
font-weight: 600;
|
||||||
|
color: white;
|
||||||
|
-webkit-text-stroke: #04fbfd 1px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user