fix
This commit is contained in:
parent
abce91fc07
commit
29090b3db8
BIN
src/assets/heatflux.png
Normal file
BIN
src/assets/heatflux.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.0 KiB |
BIN
src/assets/rain.png
Normal file
BIN
src/assets/rain.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 696 B |
@ -18,10 +18,6 @@ function CustomClock() {
|
||||
// onTick={(clock) => {
|
||||
// if (!clock.shouldAnimate) return;
|
||||
// }}
|
||||
// onStop={() => {
|
||||
// if (toolbar.showPanel === undefined)
|
||||
// dispatch.data.updateToolbar({ showPanel: true });
|
||||
// }}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
@ -1,20 +1,20 @@
|
||||
import { useCallback, useEffect, useState } from "react";
|
||||
import { useSelector } from "react-redux";
|
||||
import { Scrollbars } from "react-custom-scrollbars-2";
|
||||
import { useInterval } from "ahooks";
|
||||
import { useLocation } from "react-router-dom";
|
||||
|
||||
let index = 0;
|
||||
|
||||
function TextInfoPanel({ content }) {
|
||||
const location = useLocation();
|
||||
const showNumberPerTimes = 1;
|
||||
const { toolbar } = useSelector((state) => state.data);
|
||||
|
||||
const [delay, setDelay] = useState(80);
|
||||
const [contentText, setContentText] = useState("");
|
||||
|
||||
useEffect(() => {
|
||||
index = 0;
|
||||
}, [toolbar]);
|
||||
}, [location]);
|
||||
|
||||
const showContent = useCallback(() => {
|
||||
const isFinished = contentText.length >= content.length;
|
||||
@ -23,7 +23,10 @@ function TextInfoPanel({ content }) {
|
||||
index += showNumberPerTimes;
|
||||
return text + content[index - 1];
|
||||
});
|
||||
} else setDelay(undefined);
|
||||
} else {
|
||||
index = 0;
|
||||
setDelay(undefined);
|
||||
}
|
||||
}, [contentText]);
|
||||
|
||||
useInterval(showContent, delay);
|
||||
|
@ -24,6 +24,7 @@ function HeatmapImageLayer() {
|
||||
key={`ImageryLayer-${name}`}
|
||||
imageryProvider={tempProvider}
|
||||
show={true}
|
||||
alpha={0.6}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
@ -15,7 +15,9 @@ const colorBar = [
|
||||
function Legend() {
|
||||
return (
|
||||
<div className="legend">
|
||||
<div className="legend-title"></div>
|
||||
<div className="legend-title">
|
||||
对东亚夏季风具有显著影响的信号(表面温度和表面向上感热通量)分布
|
||||
</div>
|
||||
<div className="colorbar">
|
||||
{colorBar.map((color, index) => {
|
||||
return (
|
||||
|
@ -24,10 +24,7 @@ export default function DomainFive() {
|
||||
/>
|
||||
</div>
|
||||
<div className="right-panel">
|
||||
<div className="top-panel">
|
||||
<FormPanel setShow={setShow} />
|
||||
</div>
|
||||
<div className="bottom-panel" />
|
||||
<FormPanel setShow={setShow} />
|
||||
</div>
|
||||
{show && <HeatmapImageLayer />}
|
||||
<Legend />
|
||||
|
@ -5,46 +5,49 @@ import { Entity, LabelGraphics } from "resium";
|
||||
const points = [
|
||||
{
|
||||
position: [13, -70, 30, -67],
|
||||
name: "sic_s",
|
||||
name: "南极附近海冰异常",
|
||||
// name: "sic_s",
|
||||
},
|
||||
{
|
||||
position: [93, 29, 99, 35],
|
||||
name: "sc_tp",
|
||||
name: "青藏高原上空积雪异常",
|
||||
// name: "sc_tp",
|
||||
},
|
||||
{
|
||||
position: [68, 48, 76, 52],
|
||||
name: "sc_ea",
|
||||
name: "欧亚大陆上空积雪异常",
|
||||
// name: "sc_ea",
|
||||
},
|
||||
{
|
||||
position: [150, 60, 160, 70],
|
||||
name: "ts_ac",
|
||||
name: "表面温度异常ts_ac",
|
||||
},
|
||||
{
|
||||
position: [130, 20, 140, 28],
|
||||
name: "ts_wp",
|
||||
name: "表面温度异常ts_wp",
|
||||
},
|
||||
{
|
||||
position: [150, 12, 175, 22],
|
||||
name: "ts_np",
|
||||
name: "表面温度异常ts_np",
|
||||
},
|
||||
{
|
||||
position: [-110, 20, -95, 35],
|
||||
name: "ts_arn",
|
||||
name: "表面温度异常ts_arn",
|
||||
},
|
||||
{
|
||||
position: [10, -12, 45, -2],
|
||||
name: "ts_af",
|
||||
name: "表面温度异常ts_af",
|
||||
},
|
||||
{ position: [80, 10, 110, 20], name: "ts_io" },
|
||||
{ position: [-150, -10, -40, 5], name: "ts_ep" },
|
||||
{ position: [65, -62, 90, -57], name: "ts_aa" },
|
||||
{ position: [80, 10, 110, 20], name: "表面温度异常ts_io" },
|
||||
{ position: [-150, -10, -40, 5], name: "表面温度异常ts_ep" },
|
||||
{ position: [65, -62, 90, -57], name: "表面温度异常ts_aa" },
|
||||
{
|
||||
position: [145, -30, 155, -20],
|
||||
name: "ts_ea",
|
||||
name: "表面温度异常ts_ea",
|
||||
},
|
||||
{ position: [165, -45, 180, -30], name: "ts_nz" },
|
||||
{ position: [-140, -60, -110, -45], name: "ts_sp" },
|
||||
{ position: [-70, -78, -50, -70], name: "ts_wd" },
|
||||
{ position: [165, -45, 180, -30], name: "表面温度异常ts_nz" },
|
||||
{ position: [-140, -60, -110, -45], name: "表面温度异常ts_sp" },
|
||||
{ position: [-70, -78, -50, -70], name: "表面温度异常ts_wd" },
|
||||
];
|
||||
|
||||
function Labels() {
|
||||
|
@ -1,42 +0,0 @@
|
||||
const colorBar = [
|
||||
"#f6df70",
|
||||
"#f4c53a",
|
||||
"#f5aa38",
|
||||
"#f29438",
|
||||
"#ec6b38",
|
||||
"#ea5418",
|
||||
];
|
||||
|
||||
function Legend() {
|
||||
return (
|
||||
<div className="legend">
|
||||
<div className="legend-title">xxx</div>
|
||||
<div className="colorbar">
|
||||
{colorBar.map((color, index) => {
|
||||
return (
|
||||
<div
|
||||
key={`colorbar-item-${index}`}
|
||||
className="colorbar-item"
|
||||
style={{ backgroundColor: color }}
|
||||
title={`${(-3.2 + index * 0.2).toFixed(1)}~${(
|
||||
-3.2 +
|
||||
(index + 1) * 0.2
|
||||
).toFixed(1)}`}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
<div className="legend-text">
|
||||
{[0.2, 0.3, 0.4, 0.5, 0.6, ""].map((item, index) => {
|
||||
return (
|
||||
<div key={`legend-text-item-${index}`} className="legend-text-item">
|
||||
{item}
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default Legend;
|
@ -7,7 +7,6 @@ import FormPanel from "./FormPanel";
|
||||
import ChartPanel from "./ChartPanel";
|
||||
import RectangleLayer from "./RectangleLayer";
|
||||
import { useState } from "react";
|
||||
import Legend from "./Legend";
|
||||
import Labels from "./Labels";
|
||||
|
||||
export default function DomainFour() {
|
||||
@ -25,13 +24,12 @@ export default function DomainFour() {
|
||||
XGBoos是基于梯度提升决策树方法的分类和回归模型。 LightGBM也是一种基于树的梯度提升方法,可以解决高维输入变量问题。这两个机器学习模型由许多简单的弱学习器(也称为小回归模型)组成,最终的预测是所有弱学习器的预测的加权和。 此外,作为Boosting树模型,XGBoost和LightGBM对多重共线性不敏感,这减少了特征的同时交互,提高了预测能力。`}
|
||||
/>
|
||||
</div>
|
||||
<div className="right-panel">
|
||||
<div className="right-panel" style={{ top: 84 }}>
|
||||
<div className="top-panel">
|
||||
<FormPanel setShow={setShow} />
|
||||
</div>
|
||||
<div className="bottom-panel">{show && <ChartPanel />}</div>
|
||||
</div>
|
||||
{/* <Legend /> */}
|
||||
<Labels />
|
||||
<RectangleLayer />
|
||||
</MapLayout>
|
||||
|
@ -35,10 +35,6 @@ function ChartPanel() {
|
||||
|
||||
const { shouldAnimate } = viewer.clock;
|
||||
|
||||
// useInterval(() => {
|
||||
// console.log(currentTime, startTime, stopTime);
|
||||
// }, 100);
|
||||
|
||||
useEffect(() => {
|
||||
if (shouldAnimate) {
|
||||
setIsHighlight(true);
|
||||
@ -67,12 +63,6 @@ function ChartPanel() {
|
||||
bottom: "3%",
|
||||
containLabel: true,
|
||||
},
|
||||
// toolbox: {
|
||||
// feature: {
|
||||
// // 下载
|
||||
// saveAsImage: {},
|
||||
// },
|
||||
// },
|
||||
xAxis: {
|
||||
type: "category",
|
||||
boundaryGap: false,
|
||||
@ -85,6 +75,9 @@ function ChartPanel() {
|
||||
color: "#04fbfd",
|
||||
},
|
||||
},
|
||||
axisLabel: {
|
||||
interval: 4,
|
||||
},
|
||||
},
|
||||
yAxis: {
|
||||
type: "value",
|
||||
|
@ -1,11 +1,9 @@
|
||||
import { Cartesian3, EasingFunction, Math } from "cesium";
|
||||
import { useDispatch } from "react-redux";
|
||||
import { useCesium } from "resium";
|
||||
|
||||
function CustomFlyTo() {
|
||||
const { viewer } = useCesium();
|
||||
const { camera } = viewer;
|
||||
const dispatch = useDispatch();
|
||||
|
||||
function cameraFlyToLine() {
|
||||
const step1 = {
|
||||
@ -53,9 +51,6 @@ function CustomFlyTo() {
|
||||
setTimeout(function () {
|
||||
camera.flyTo(step1);
|
||||
}, 5000);
|
||||
dispatch.data.updateImageLayer({
|
||||
labrador: true,
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -5,7 +5,7 @@ import waterwapor from "@/assets/waterwapor.png";
|
||||
|
||||
function EntityLegend() {
|
||||
return (
|
||||
<div className="entity-legend">
|
||||
<div className="entity-legend" style={{ bottom: 116 }}>
|
||||
<div className="entity-legend-item">
|
||||
<div style={{ fontWeight: 800, color: "#04fafc" }}>- - - -</div>
|
||||
<div className="entity-legend-item-name">Rossby wave path</div>
|
||||
|
@ -6,7 +6,8 @@ import { useInterval } from "ahooks";
|
||||
function Labels() {
|
||||
const { viewer } = useCesium();
|
||||
|
||||
const [show, setShow] = useState(false);
|
||||
const [showOne, setShowOne] = useState(false);
|
||||
const [showTwo, setShowTwo] = useState(false);
|
||||
|
||||
const showAnimate = useCallback(() => {
|
||||
const { currentTime, stopTime } = viewer.clock;
|
||||
@ -14,18 +15,21 @@ function Labels() {
|
||||
stopTime.secondsOfDay - currentTime.secondsOfDay
|
||||
);
|
||||
|
||||
if (leftTime < 20) {
|
||||
setShowOne(true);
|
||||
} else if (showOne) setShowOne(false);
|
||||
if (leftTime < 5) {
|
||||
setShow(true);
|
||||
} else if (show) setShow(false);
|
||||
}, [show]);
|
||||
setShowTwo(true);
|
||||
} else if (showTwo) setShowTwo(false);
|
||||
}, [showOne, showTwo, viewer]);
|
||||
|
||||
useInterval(showAnimate, 100);
|
||||
useInterval(showAnimate, 300);
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<Entity position={Cartesian3.fromDegrees(90, 27, 0)}>
|
||||
<Entity position={Cartesian3.fromDegrees(-60, 65, 0)}>
|
||||
<LabelGraphics
|
||||
text={"青藏高原温度异常"}
|
||||
text={"拉布拉多海海温偏暖"}
|
||||
font="24px Helvetica"
|
||||
fillColor={Color.SKYBLUE}
|
||||
outlineColor={Color.BLACK}
|
||||
@ -34,9 +38,9 @@ function Labels() {
|
||||
eyeOffset={new Cartesian2(0, 200000)}
|
||||
/>
|
||||
</Entity>
|
||||
<Entity position={Cartesian3.fromDegrees(-55, 45, 0)}>
|
||||
<Entity show={showOne} position={Cartesian3.fromDegrees(-20, 55, 0)}>
|
||||
<LabelGraphics
|
||||
text={"拉布拉多海温度异常"}
|
||||
text={"北大西洋至欧洲地区大气环流异常"}
|
||||
font="24px Helvetica"
|
||||
fillColor={Color.SKYBLUE}
|
||||
outlineColor={Color.BLACK}
|
||||
@ -45,7 +49,7 @@ function Labels() {
|
||||
eyeOffset={new Cartesian2(0, 200000)}
|
||||
/>
|
||||
</Entity>
|
||||
<Entity show={show} position={Cartesian3.fromDegrees(98, 48, 0)}>
|
||||
<Entity show={showTwo} position={Cartesian3.fromDegrees(98, 48, 0)}>
|
||||
<LabelGraphics
|
||||
text={"barotropic"}
|
||||
font="24px Helvetica"
|
||||
@ -56,6 +60,17 @@ function Labels() {
|
||||
eyeOffset={new Cartesian2(0, 1200000)}
|
||||
/>
|
||||
</Entity>
|
||||
<Entity show={showTwo} position={Cartesian3.fromDegrees(90, 27, 0)}>
|
||||
<LabelGraphics
|
||||
text={"青藏高原夏季出现年代际增温"}
|
||||
font="24px Helvetica"
|
||||
fillColor={Color.SKYBLUE}
|
||||
outlineColor={Color.BLACK}
|
||||
outlineWidth={2}
|
||||
style={LabelStyle.FILL_AND_OUTLINE}
|
||||
eyeOffset={new Cartesian2(0, 200000)}
|
||||
/>
|
||||
</Entity>
|
||||
</Fragment>
|
||||
);
|
||||
}
|
||||
|
@ -1,36 +0,0 @@
|
||||
import { useCallback, useState } from "react";
|
||||
import { Entity, PolygonGraphics, useCesium } from "resium";
|
||||
import { useInterval } from "ahooks";
|
||||
import { Cartesian3, Color } from "cesium";
|
||||
|
||||
function PlateauPolygon() {
|
||||
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 < 10) {
|
||||
setShow(true);
|
||||
} else if (show) setShow(false);
|
||||
}, [show]);
|
||||
|
||||
useInterval(showAnimate, 100);
|
||||
|
||||
return (
|
||||
<Entity id="plateau" show={show}>
|
||||
<PolygonGraphics
|
||||
hierarchy={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 Color(1, 0, 0, 0.1)}
|
||||
/>
|
||||
</Entity>
|
||||
);
|
||||
}
|
||||
|
||||
export default PlateauPolygon;
|
@ -4,7 +4,6 @@ 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 Cyclone from "./Cyclone";
|
||||
import Barotropic from "./Barotorpic";
|
||||
import WavePoints from "./WavePoints";
|
||||
@ -26,7 +25,6 @@ export default function DomainOne() {
|
||||
<CustomClock />
|
||||
<CustomFlyTo />
|
||||
<Point />
|
||||
<PlateauPolygon />
|
||||
<div className="left-panel one">
|
||||
<TextInfoPanel content="基于再分析资料JRA55和线性斜压模式LBM的试验结果,在年代际尺度上,拉布拉多海海温偏暖会引起北大西洋至欧洲地区大气环流异常,导致青藏高原夏季出现年代际增温。" />
|
||||
</div>
|
||||
|
@ -6,6 +6,7 @@ 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,
|
||||
@ -27,6 +28,8 @@ const AntarcticaData = [
|
||||
-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,
|
||||
@ -48,6 +51,8 @@ const ArcticData = [
|
||||
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,
|
||||
@ -109,6 +114,9 @@ function ChartPanel() {
|
||||
color: "#04fbfd",
|
||||
},
|
||||
},
|
||||
axisLabel: {
|
||||
interval: 4,
|
||||
},
|
||||
},
|
||||
yAxis: {
|
||||
type: "value",
|
||||
|
@ -37,9 +37,16 @@ function Legend({ style }) {
|
||||
})}
|
||||
</div>
|
||||
<div className="legend-text">
|
||||
{[-0.8, -0.4, 0, 0.4, 0.8, ""].map((item, index) => {
|
||||
{[-0.8, -0.4, 0, 0.4, 0.8].map((item, index) => {
|
||||
return (
|
||||
<div key={`legend-text-item-${index}`} className="legend-text-item">
|
||||
<div
|
||||
key={`legend-text-item-${index}`}
|
||||
className="legend-text-item"
|
||||
style={{
|
||||
textAlign:
|
||||
index === 2 ? "center" : index < 2 ? "left" : "right",
|
||||
}}
|
||||
>
|
||||
{item}
|
||||
</div>
|
||||
);
|
||||
|
55
src/components/domain/Three/SceneOne/Legend.jsx
Normal file
55
src/components/domain/Three/SceneOne/Legend.jsx
Normal file
@ -0,0 +1,55 @@
|
||||
import styles from "./index.module.less";
|
||||
|
||||
const colorBar = [
|
||||
"#801FEF",
|
||||
"#050CFB",
|
||||
"#3B6EE6",
|
||||
"#159AFF",
|
||||
"#36C1F8",
|
||||
"#AADBF2",
|
||||
"#FFF479",
|
||||
"#FFC113",
|
||||
"#FF7E00",
|
||||
"#FF7E00",
|
||||
"#CD0000",
|
||||
"#FFB1B1",
|
||||
];
|
||||
|
||||
function Legend() {
|
||||
return (
|
||||
<div className={styles.legend}>
|
||||
<div className="legend-title">全球温度异常空间分布</div>
|
||||
<div className="colorbar">
|
||||
{colorBar.map((color, index) => {
|
||||
return (
|
||||
<div
|
||||
key={`colorbar-item-${index}`}
|
||||
className="colorbar-item"
|
||||
style={{ backgroundColor: color }}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
<div className="legend-text">
|
||||
{["", -1, -0.8, -0.6, -0.4, -0.2, 0, 0.2, 0.4, 0.6, 0.8, 1.0, ""].map(
|
||||
(item, index) => {
|
||||
return (
|
||||
<div
|
||||
key={`legend-text-item-${index}`}
|
||||
className="legend-text-item"
|
||||
style={{
|
||||
textAlign:
|
||||
index === 6 ? "center" : index < 6 ? "left" : "right",
|
||||
}}
|
||||
>
|
||||
{item}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default Legend;
|
@ -1,6 +1,6 @@
|
||||
import TextInfoPanel from "@/components/common/TextInfoPanel";
|
||||
import ChartPanel from "../ChartPanel";
|
||||
import Legend from "../Legend";
|
||||
import Legend from "./Legend";
|
||||
import ViewerOne from "./ViewerOne";
|
||||
import ViewerTwo from "./ViewerTwo";
|
||||
import ViewerThree from "./ViewerThree";
|
||||
@ -14,11 +14,13 @@ function SceneOne() {
|
||||
<ViewerTwo />
|
||||
<ViewerThree />
|
||||
</div>
|
||||
<div className="left-panel">
|
||||
<TextInfoPanel content="利用GISTEMP资料,通过EEMD分解方法提取两极温度多年代际变化序列,发现南北极温度变化的跷跷板现象与大西洋多年代际振荡AMO紧密相关。而AMO与热带大西洋经向模AMM在年代际尺度上显著相关。ERA5再分析资料显示AMM可以通过Rossby波影响西南极的气温与海冰偶极子。因此,AMM可能在联系南北极气候变化的中起到了重要的媒介作用。" />
|
||||
</div>
|
||||
<div className="right-panel">
|
||||
<ChartPanel />
|
||||
<div className="domain-info">
|
||||
<div className="left-panel">
|
||||
<TextInfoPanel content="利用GISTEMP资料,通过EEMD分解方法提取两极温度多年代际变化序列,发现南北极温度变化的跷跷板现象与大西洋多年代际振荡AMO紧密相关。而AMO与热带大西洋经向模AMM在年代际尺度上显著相关。ERA5再分析资料显示AMM可以通过Rossby波影响西南极的气温与海冰偶极子。因此,AMM可能在联系南北极气候变化的中起到了重要的媒介作用。" />
|
||||
</div>
|
||||
<div className="right-panel">
|
||||
<ChartPanel />
|
||||
</div>
|
||||
</div>
|
||||
<Legend />
|
||||
</div>
|
||||
|
@ -1,12 +1,13 @@
|
||||
.sceneOne :global {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: gray;
|
||||
background-color: darkslategray;
|
||||
|
||||
.domain-viewers {
|
||||
width: 100%;
|
||||
height: calc(100% - 250px);
|
||||
flex: 1;
|
||||
display: flex;
|
||||
|
||||
.domain-viewer {
|
||||
@ -18,4 +19,151 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.domain-info {
|
||||
flex: 1;
|
||||
margin: 12px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
gap: 12px;
|
||||
|
||||
.left-panel {
|
||||
width: 450px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
|
||||
.text-info-panel {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 12px;
|
||||
border: 1px solid #04fbfd;
|
||||
color: #02f9ff !important;
|
||||
background-color: #1f485690;
|
||||
pointer-events: auto;
|
||||
font-size: 18px;
|
||||
text-indent: 2em;
|
||||
line-height: 1.5;
|
||||
z-index: 999;
|
||||
border-radius: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
.right-panel {
|
||||
flex: 1;
|
||||
min-width: 450px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
|
||||
.top-panel {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.bottom-panel {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.form-panel {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
pointer-events: auto;
|
||||
padding: 12px;
|
||||
border: 1px solid #04fbfd;
|
||||
color: #02f9ff !important;
|
||||
background-color: #1f485690;
|
||||
border-radius: 8px;
|
||||
|
||||
.ant-form-item-label {
|
||||
label {
|
||||
color: white;
|
||||
}
|
||||
}
|
||||
|
||||
.ant-form-item-control {
|
||||
.ant-select-multiple {
|
||||
max-height: 300px;
|
||||
overflow-y: scroll;
|
||||
|
||||
&::-webkit-scrollbar {
|
||||
width: 6px;
|
||||
height: 1px;
|
||||
}
|
||||
&::-webkit-scrollbar-thumb {
|
||||
border-radius: 6px;
|
||||
background: #00a2a2;
|
||||
}
|
||||
&::-webkit-scrollbar-track {
|
||||
border-radius: 6px;
|
||||
background: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.chart-info-panel {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
pointer-events: auto;
|
||||
padding: 12px;
|
||||
border: 1px solid #04fbfd;
|
||||
color: #02f9ff !important;
|
||||
background-color: #1f485690;
|
||||
transition: all 0.3s ease-in-out;
|
||||
border-radius: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.legend :global {
|
||||
position: absolute;
|
||||
bottom: calc(50% + 14px);
|
||||
width: 50%;
|
||||
left: 25%;
|
||||
z-index: 1000;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
background-color: #1f485690;
|
||||
border: 1px solid #04fbfd;
|
||||
border-radius: 8px;
|
||||
padding: 8px;
|
||||
|
||||
.legend-title {
|
||||
color: #04fbfd;
|
||||
}
|
||||
|
||||
.colorbar {
|
||||
width: 100%;
|
||||
height: 14px;
|
||||
display: flex;
|
||||
margin: 8px 0;
|
||||
|
||||
.colorbar-item {
|
||||
flex: 1;
|
||||
height: 100%;
|
||||
border: 1px black solid;
|
||||
|
||||
&:not(:nth-child(1)) {
|
||||
border-left: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.legend-text {
|
||||
display: flex;
|
||||
justify-content: space-evenly;
|
||||
width: 100%;
|
||||
height: 20px;
|
||||
|
||||
.legend-text-item {
|
||||
flex: 1;
|
||||
text-align: right;
|
||||
font-weight: 600;
|
||||
color: white;
|
||||
-webkit-text-stroke: #04fbfd 1px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
11
src/components/domain/Three/SceneTwo/CustomFlyTo.jsx
Normal file
11
src/components/domain/Three/SceneTwo/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(-40, -30, 16000000)}
|
||||
/>
|
||||
);
|
||||
}
|
32
src/components/domain/Three/SceneTwo/HGTImageLayer.jsx
Normal file
32
src/components/domain/Three/SceneTwo/HGTImageLayer.jsx
Normal file
@ -0,0 +1,32 @@
|
||||
import { useMemo } from "react";
|
||||
import { ImageryLayer } from "resium";
|
||||
import { WebMapServiceImageryProvider } from "cesium";
|
||||
|
||||
const url = "http://analysis.tpdc.ac.cn/gs/geoserver/phitrellis/wms";
|
||||
const name = "phitrellis:4_3_2_c_hgt_Layer1";
|
||||
|
||||
function HGTImageLayer() {
|
||||
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}
|
||||
alpha={0.6}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export default HGTImageLayer;
|
168
src/components/domain/Three/SceneTwo/Legend.jsx
Normal file
168
src/components/domain/Three/SceneTwo/Legend.jsx
Normal file
@ -0,0 +1,168 @@
|
||||
import { Fragment } from "react";
|
||||
import styles from "./index.module.less";
|
||||
|
||||
const colorBar = [
|
||||
"#7F20F0",
|
||||
"#2A09FA",
|
||||
"#1C33F1",
|
||||
"#3B6CE3",
|
||||
"#2388F8",
|
||||
"#0EA5FE",
|
||||
"#23C0FB",
|
||||
"#85CAF1",
|
||||
"#B8E1F3",
|
||||
"#FEF995",
|
||||
"#FEDD30",
|
||||
"#FEB709",
|
||||
"#FF8B00",
|
||||
"#FF5D00",
|
||||
"#FF1001",
|
||||
"#E00000",
|
||||
"#D62A2A",
|
||||
"#FFB1B1",
|
||||
];
|
||||
|
||||
const colorBar2 = [
|
||||
"#7F20F0",
|
||||
"#0e03fd",
|
||||
"#3B5CE3",
|
||||
"#2684f6",
|
||||
"#09b0ff",
|
||||
"#56c4f4",
|
||||
"#b0ddf3",
|
||||
"#FEF687",
|
||||
"#ffcd1e",
|
||||
"#ff9700",
|
||||
"#fe5100",
|
||||
"#f60100",
|
||||
"#cd0d0c",
|
||||
"#FFB1B1",
|
||||
];
|
||||
|
||||
function Legend({ style }) {
|
||||
return (
|
||||
<Fragment>
|
||||
<div className={styles.legend} style={{ bottom: 14 }}>
|
||||
<div className="legend-title">
|
||||
南半球冬季南极半岛区域地表气温年代际分量(单位:K)
|
||||
</div>
|
||||
<div className="colorbar">
|
||||
{colorBar.map((color, index) => {
|
||||
return (
|
||||
<div
|
||||
key={`colorbar-item-${index}`}
|
||||
className="colorbar-item"
|
||||
style={{ backgroundColor: color }}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
<div className="legend-text">
|
||||
{[-0.8, -0.4, 0, 0.4, 0.8].map((item, index) => {
|
||||
return (
|
||||
<div
|
||||
key={`legend-text-item-${index}`}
|
||||
className="legend-text-item"
|
||||
style={{
|
||||
textAlign:
|
||||
index === 2 ? "center" : index < 2 ? "left" : "right",
|
||||
}}
|
||||
>
|
||||
{item}
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
<div className={styles.legend} style={{ bottom: 116 }}>
|
||||
<div className="legend-title">
|
||||
南半球冬季热带大西洋海表温度(单位:K)
|
||||
</div>
|
||||
<div className="colorbar">
|
||||
{colorBar.map((color, index) => {
|
||||
return (
|
||||
<div
|
||||
key={`colorbar-item-${index}`}
|
||||
className="colorbar-item"
|
||||
style={{ backgroundColor: color }}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
<div className="legend-text">
|
||||
{[-0.2, -0.1, 0, 0.1, 0.2].map((item, index) => {
|
||||
return (
|
||||
<div
|
||||
key={`legend-text-item-${index}`}
|
||||
className="legend-text-item"
|
||||
style={{
|
||||
textAlign:
|
||||
index === 2 ? "center" : index < 2 ? "left" : "right",
|
||||
}}
|
||||
>
|
||||
{item}
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
<div className={styles.legend} style={{ bottom: 220 }}>
|
||||
<div className="legend-title">
|
||||
南半球冬季200hPa涡动位势高度异常(单位:gpm)
|
||||
</div>
|
||||
<div className="colorbar">
|
||||
{colorBar2.map((color, index) => {
|
||||
return (
|
||||
<div
|
||||
key={`colorbar-item-${index}`}
|
||||
className="colorbar-item"
|
||||
style={{ backgroundColor: color }}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
<div className="legend-text">
|
||||
{[
|
||||
"",
|
||||
-15,
|
||||
"",
|
||||
"",
|
||||
-10,
|
||||
"",
|
||||
"",
|
||||
-5,
|
||||
"",
|
||||
"",
|
||||
0,
|
||||
"",
|
||||
"",
|
||||
5,
|
||||
"",
|
||||
"",
|
||||
10,
|
||||
"",
|
||||
"",
|
||||
15,
|
||||
"",
|
||||
].map((item, index) => {
|
||||
return (
|
||||
<div
|
||||
key={`legend-text-item-${index}`}
|
||||
className="legend-text-item"
|
||||
style={{
|
||||
textAlign: "center",
|
||||
// textAlign:
|
||||
// index === 2 ? "center" : index < 2 ? "left" : "right",
|
||||
}}
|
||||
>
|
||||
{item}
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</Fragment>
|
||||
);
|
||||
}
|
||||
|
||||
export default Legend;
|
31
src/components/domain/Three/SceneTwo/SSTImageLayer.jsx
Normal file
31
src/components/domain/Three/SceneTwo/SSTImageLayer.jsx
Normal file
@ -0,0 +1,31 @@
|
||||
import { useMemo } from "react";
|
||||
import { ImageryLayer } from "resium";
|
||||
import { WebMapServiceImageryProvider } from "cesium";
|
||||
|
||||
const url = "http://analysis.tpdc.ac.cn/gs/geoserver/phitrellis/wms";
|
||||
const name = "phitrellis:4_3_2_a_sst_Layer11";
|
||||
|
||||
function SSTImageLayer() {
|
||||
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 SSTImageLayer;
|
@ -6,8 +6,37 @@ for (let year = 1950; year <= 2020; year++) {
|
||||
years.push(year);
|
||||
}
|
||||
|
||||
const SATData = [];
|
||||
const SSTData = [];
|
||||
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 = {
|
||||
@ -18,7 +47,7 @@ function SceneChartPanel() {
|
||||
trigger: "axis",
|
||||
},
|
||||
legend: {
|
||||
data: ["SAT_SVD1", "SST_SVD1"],
|
||||
data: ["南极半岛", "热带大西洋"],
|
||||
textStyle: { color: "#04fbfd", cursor: "point" },
|
||||
},
|
||||
animationDuration: 10 * 1000,
|
||||
@ -67,22 +96,10 @@ function SceneChartPanel() {
|
||||
dataZoom: { type: "inside", start: 0, end: 100 },
|
||||
series: [
|
||||
{
|
||||
name: "SAT_SVD1",
|
||||
type: "line",
|
||||
stack: "Total",
|
||||
data: SATData,
|
||||
smooth: true,
|
||||
color: "red",
|
||||
symbol: "none",
|
||||
itemStyle: {
|
||||
color: "red",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "SST_SVD1",
|
||||
name: "南极半岛",
|
||||
type: "line",
|
||||
// stack: "Total",
|
||||
data: SSTData,
|
||||
data: SATData,
|
||||
smooth: true,
|
||||
color: "blue",
|
||||
symbol: "none",
|
||||
@ -90,6 +107,18 @@ function SceneChartPanel() {
|
||||
color: "blue",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "热带大西洋",
|
||||
type: "line",
|
||||
// stack: "Total",
|
||||
data: SSTData,
|
||||
smooth: true,
|
||||
color: "red",
|
||||
symbol: "none",
|
||||
itemStyle: {
|
||||
color: "red",
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
|
31
src/components/domain/Three/SceneTwo/TSImageLayer.jsx
Normal file
31
src/components/domain/Three/SceneTwo/TSImageLayer.jsx
Normal file
@ -0,0 +1,31 @@
|
||||
import { useMemo } from "react";
|
||||
import { ImageryLayer } from "resium";
|
||||
import { WebMapServiceImageryProvider } from "cesium";
|
||||
|
||||
const url = "http://analysis.tpdc.ac.cn/gs/geoserver/phitrellis/wms";
|
||||
const name = "phitrellis:4_3_2_b_ts_Layer11";
|
||||
|
||||
function TSImageLayer() {
|
||||
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 TSImageLayer;
|
@ -1,18 +1,33 @@
|
||||
import Legend from "../Legend";
|
||||
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";
|
||||
|
||||
function SceneTwo() {
|
||||
return (
|
||||
<div className="scene_two">
|
||||
<ViewerOne>
|
||||
<MapLayout>
|
||||
<div className="title">
|
||||
两极协同—连接南极和北极的热带大西洋经向模的媒介作用
|
||||
</div>
|
||||
<div className="right-panel one" style={{ height: "unset" }}>
|
||||
<div className="bottom-panel">
|
||||
<SceneChartPanel />
|
||||
</div>
|
||||
</div>
|
||||
<Legend style={{ bottom: "40px" }} />
|
||||
</ViewerOne>
|
||||
<CustomFlyTo />
|
||||
<Legend />
|
||||
<HGTImageLayer />
|
||||
<SSTImageLayer />
|
||||
<TSImageLayer />
|
||||
</MapLayout>
|
||||
{/* <ViewerOne>
|
||||
|
||||
</ViewerOne> */}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
52
src/components/domain/Three/SceneTwo/index.module.less
Normal file
52
src/components/domain/Three/SceneTwo/index.module.less
Normal file
@ -0,0 +1,52 @@
|
||||
.legend :global {
|
||||
position: absolute;
|
||||
bottom: 270px;
|
||||
width: 450px;
|
||||
left: 12px;
|
||||
// left: 25%;
|
||||
z-index: 1000;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
background-color: #1f485690;
|
||||
border: 1px solid #04fbfd;
|
||||
border-radius: 8px;
|
||||
padding: 8px;
|
||||
|
||||
.legend-title {
|
||||
color: #04fbfd;
|
||||
}
|
||||
|
||||
.colorbar {
|
||||
width: 100%;
|
||||
height: 14px;
|
||||
display: flex;
|
||||
margin: 8px 0;
|
||||
|
||||
.colorbar-item {
|
||||
flex: 1;
|
||||
height: 100%;
|
||||
border: 1px black solid;
|
||||
|
||||
&:not(:nth-child(1)) {
|
||||
border-left: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.legend-text {
|
||||
display: flex;
|
||||
justify-content: space-evenly;
|
||||
width: 100%;
|
||||
height: 20px;
|
||||
|
||||
.legend-text-item {
|
||||
flex: 1;
|
||||
text-align: right;
|
||||
font-weight: 600;
|
||||
color: white;
|
||||
-webkit-text-stroke: #04fbfd 1px;
|
||||
}
|
||||
}
|
||||
}
|
@ -22,6 +22,7 @@
|
||||
color: #02f9ff !important;
|
||||
background-color: #1f485690;
|
||||
transition: all 0.3s ease-in-out;
|
||||
border-radius: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -32,163 +33,7 @@
|
||||
top: 8px;
|
||||
}
|
||||
|
||||
.left-panel {
|
||||
position: absolute;
|
||||
left: 12px;
|
||||
bottom: 12px;
|
||||
width: 450px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 230px;
|
||||
|
||||
.top-panel {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.bottom-panel {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.text-info-panel {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 12px;
|
||||
border: 1px solid #04fbfd;
|
||||
color: #02f9ff !important;
|
||||
background-color: #1f485690;
|
||||
pointer-events: auto;
|
||||
font-size: 18px;
|
||||
text-indent: 2em;
|
||||
line-height: 1.5;
|
||||
z-index: 999;
|
||||
}
|
||||
}
|
||||
|
||||
.right-panel {
|
||||
position: absolute;
|
||||
right: 12px;
|
||||
bottom: 12px;
|
||||
width: 450px;
|
||||
height: 230px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
|
||||
.top-panel {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.bottom-panel {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.form-panel {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
pointer-events: auto;
|
||||
padding: 12px;
|
||||
border: 1px solid #04fbfd;
|
||||
color: #02f9ff !important;
|
||||
background-color: #1f485690;
|
||||
|
||||
.ant-form-item-label {
|
||||
label {
|
||||
color: white;
|
||||
}
|
||||
}
|
||||
|
||||
.ant-form-item-control {
|
||||
.ant-select-multiple {
|
||||
max-height: 300px;
|
||||
overflow-y: scroll;
|
||||
|
||||
&::-webkit-scrollbar {
|
||||
width: 6px;
|
||||
height: 1px;
|
||||
}
|
||||
&::-webkit-scrollbar-thumb {
|
||||
border-radius: 6px;
|
||||
background: #00a2a2;
|
||||
}
|
||||
&::-webkit-scrollbar-track {
|
||||
border-radius: 6px;
|
||||
background: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.chart-info-panel {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
pointer-events: auto;
|
||||
padding: 12px;
|
||||
border: 1px solid #04fbfd;
|
||||
color: #02f9ff !important;
|
||||
background-color: #1f485690;
|
||||
transition: all 0.3s ease-in-out;
|
||||
}
|
||||
|
||||
.highlight {
|
||||
outline: 4px solid #04fbfd;
|
||||
box-shadow: 0 0 30px #04e0fd;
|
||||
}
|
||||
}
|
||||
|
||||
.one {
|
||||
top: 50%;
|
||||
}
|
||||
}
|
||||
|
||||
.legend :global {
|
||||
position: absolute;
|
||||
bottom: 270px;
|
||||
width: 50%;
|
||||
left: 25%;
|
||||
z-index: 1000;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
background-color: #1f485690;
|
||||
border: 1px solid #04fbfd;
|
||||
border-radius: 8px;
|
||||
padding: 8px;
|
||||
|
||||
.legend-title {
|
||||
color: #04fbfd;
|
||||
}
|
||||
|
||||
.colorbar {
|
||||
width: 100%;
|
||||
height: 14px;
|
||||
display: flex;
|
||||
margin: 8px 0;
|
||||
|
||||
.colorbar-item {
|
||||
flex: 1;
|
||||
height: 100%;
|
||||
border: 1px black solid;
|
||||
|
||||
&:not(:nth-child(1)) {
|
||||
border-left: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.legend-text {
|
||||
display: flex;
|
||||
justify-content: space-evenly;
|
||||
width: 100%;
|
||||
height: 20px;
|
||||
margin-left: 8px;
|
||||
|
||||
.legend-text-item {
|
||||
flex: 1;
|
||||
text-align: right;
|
||||
font-weight: 600;
|
||||
color: white;
|
||||
-webkit-text-stroke: #04fbfd 1px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -6,8 +6,7 @@ import {
|
||||
PolylineGraphics,
|
||||
LabelGraphics,
|
||||
} from "resium";
|
||||
import { useInterval, useThrottleFn } from "ahooks";
|
||||
import { useDispatch } from "react-redux";
|
||||
import { useInterval } from "ahooks";
|
||||
import {
|
||||
Cartesian3,
|
||||
Color,
|
||||
@ -43,27 +42,6 @@ const highCircle = (
|
||||
|
||||
function Circles() {
|
||||
const { viewer } = useCesium();
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const { run: showInfo } = useThrottleFn(
|
||||
() => {
|
||||
dispatch.data.updateImageLayer({ indianOcean: true });
|
||||
dispatch.data.update({ showSite: true });
|
||||
},
|
||||
{
|
||||
wait: 1000,
|
||||
}
|
||||
);
|
||||
|
||||
const { run: closeInfo } = useThrottleFn(
|
||||
() => {
|
||||
dispatch.data.updateImageLayer({ indianOcean: false });
|
||||
dispatch.data.update({ showSite: false });
|
||||
},
|
||||
{
|
||||
wait: 1000,
|
||||
}
|
||||
);
|
||||
|
||||
const Circle = ({ id, lon, lat, isLow, showTime }) => {
|
||||
const circle = isLow ? lowCircle : highCircle;
|
||||
@ -75,11 +53,6 @@ function Circles() {
|
||||
currentTime.secondsOfDay - startTime.secondsOfDay
|
||||
);
|
||||
if (!shouldAnimate) return;
|
||||
if (_time === 20) {
|
||||
showInfo();
|
||||
} else if (_time === 0) {
|
||||
closeInfo();
|
||||
}
|
||||
if (_time >= showTime) {
|
||||
setShow(true);
|
||||
} else {
|
||||
|
@ -1,27 +1,10 @@
|
||||
import { Cartesian3, EasingFunction, Math } from "cesium";
|
||||
import { useDispatch } from "react-redux";
|
||||
import { Cartesian3, EasingFunction } from "cesium";
|
||||
import { useCesium } from "resium";
|
||||
|
||||
function CustomFlyTo() {
|
||||
const dispatch = useDispatch();
|
||||
const { viewer, camera } = useCesium();
|
||||
|
||||
function cameraFlyToLine() {
|
||||
// // 南极
|
||||
// const antarcticalOptions = {
|
||||
// destination: Cartesian3.fromDegrees(88, -89, 1600000),
|
||||
// orientation: {
|
||||
// heading: Math.toRadians(15.0),
|
||||
// pitch: Math.toRadians(-60),
|
||||
// roll: 0.0,
|
||||
// },
|
||||
// duration: 5,
|
||||
// complete: function () {
|
||||
// camera.flyTo(area1Options);
|
||||
// },
|
||||
// easingFunction: EasingFunction.LINEAR_NONE,
|
||||
// };
|
||||
|
||||
const area1Options = {
|
||||
destination: Cartesian3.fromDegrees(-110, -86, 10000000),
|
||||
duration: 5,
|
||||
@ -32,7 +15,6 @@ function CustomFlyTo() {
|
||||
},
|
||||
complete: function () {
|
||||
viewer.clock.shouldAnimate = true;
|
||||
dispatch.data.updateToolbar({ showPanel: true });
|
||||
setTimeout(() => {
|
||||
camera.flyTo(area2Options);
|
||||
}, 5000);
|
||||
@ -72,65 +54,14 @@ function CustomFlyTo() {
|
||||
roll: -6,
|
||||
},
|
||||
complete: function () {
|
||||
setTimeout(() => {
|
||||
camera.flyTo({
|
||||
duration: 5,
|
||||
destination: Cartesian3.fromDegrees(90, -12, 14000000),
|
||||
});
|
||||
}, 5 * 1000);
|
||||
camera.flyTo({
|
||||
duration: 7,
|
||||
destination: Cartesian3.fromDegrees(90, 5, 14000000),
|
||||
});
|
||||
},
|
||||
easingFunction: EasingFunction.LINEAR_NONE,
|
||||
};
|
||||
|
||||
const area5Options = {
|
||||
destination: Cartesian3.fromDegrees(95, -30, 10000000),
|
||||
duration: 5,
|
||||
complete: function () {
|
||||
// camera.flyTo(sideViewOptions);
|
||||
setTimeout(() => {
|
||||
camera.flyTo({
|
||||
duration: 5,
|
||||
destination: Cartesian3.fromDegrees(90, -12, 14000000),
|
||||
});
|
||||
}, 5 * 1000);
|
||||
},
|
||||
easingFunction: EasingFunction.LINEAR_NONE,
|
||||
};
|
||||
|
||||
// 侧边
|
||||
// const sideViewOptions = {
|
||||
// destination: Cartesian3.fromDegrees(80, -60, 16000000),
|
||||
// // destination: Cesium.Cartesian3.fromDegrees(130, -10.5, 20000000),
|
||||
// duration: 5,
|
||||
// orientation: {
|
||||
// heading: Math.toRadians(-10.0),
|
||||
// pitch: Math.toRadians(-92),
|
||||
// roll: 6.0,
|
||||
// },
|
||||
// complete: () => {
|
||||
// viewer.clock.shouldAnimate = true;
|
||||
// dispatch.data.updateToolbar({ showPanel: true });
|
||||
// setTimeout(() => {
|
||||
// camera.flyTo({
|
||||
// duration: 5,
|
||||
// destination: Cartesian3.fromDegrees(90, -12, 14000000),
|
||||
// });
|
||||
// }, 40 * 1000);
|
||||
// },
|
||||
// };
|
||||
|
||||
const xx = {
|
||||
destination: Cartesian3.fromDegrees(65, -55, 10000000),
|
||||
duration: 5,
|
||||
orientation: {
|
||||
heading: 6,
|
||||
pitch: -1.3,
|
||||
roll: -6,
|
||||
},
|
||||
|
||||
easingFunction: EasingFunction.LINEAR_NONE,
|
||||
};
|
||||
|
||||
camera.flyTo(area1Options);
|
||||
}
|
||||
cameraFlyToLine();
|
||||
|
@ -6,7 +6,7 @@ import moisture from "@/assets/moisture.png";
|
||||
|
||||
function EntityLegend() {
|
||||
return (
|
||||
<div className="entity-legend" style={{ bottom: 40 }}>
|
||||
<div className="entity-legend" style={{ bottom: 116 }}>
|
||||
<div className="entity-legend-item">
|
||||
<div>
|
||||
<img src={low} alt="low" width={32} />
|
||||
|
@ -1,12 +1,26 @@
|
||||
import { useMemo } from "react";
|
||||
import { ImageryLayer } from "resium";
|
||||
import { useCallback, useMemo, useState } from "react";
|
||||
import { ImageryLayer, useCesium } from "resium";
|
||||
import { WebMapServiceImageryProvider } from "cesium";
|
||||
import { useSelector } from "react-redux";
|
||||
import { useInterval } from "ahooks";
|
||||
|
||||
const url = "http://analysis.tpdc.ac.cn/gs/geoserver/phitrellis/wms";
|
||||
|
||||
function IndianOceanSST() {
|
||||
const { imageLayer } = useSelector((state) => state.data);
|
||||
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 < 5) {
|
||||
setShow(true);
|
||||
} else if (show) setShow(false);
|
||||
}, [show]);
|
||||
|
||||
useInterval(showAnimate, 100);
|
||||
|
||||
const tempProvider = useMemo(
|
||||
() =>
|
||||
@ -24,6 +38,7 @@ function IndianOceanSST() {
|
||||
|
||||
return (
|
||||
<ImageryLayer
|
||||
show={show}
|
||||
key={`ImageryLayer-india-ocean`}
|
||||
imageryProvider={tempProvider}
|
||||
/>
|
||||
|
@ -1,11 +1,44 @@
|
||||
import { useInterval } from "ahooks";
|
||||
import { Cartesian2, Cartesian3, Color, LabelStyle } from "cesium";
|
||||
import { Fragment } from "react";
|
||||
import { Entity, LabelGraphics } from "resium";
|
||||
import { Fragment, useCallback, useState } from "react";
|
||||
import { Entity, LabelGraphics, useCesium } from "resium";
|
||||
|
||||
function Labels() {
|
||||
const { viewer } = useCesium();
|
||||
const [showIO, setShowIO] = useState(false);
|
||||
const [showTB, setShowTB] = useState(false);
|
||||
|
||||
const showAnimate = useCallback(() => {
|
||||
const { currentTime, stopTime } = viewer.clock;
|
||||
const leftTime = Math.floor(
|
||||
stopTime.secondsOfDay - currentTime.secondsOfDay
|
||||
);
|
||||
|
||||
if (leftTime < 5) {
|
||||
setShowIO(true);
|
||||
setShowTB(true);
|
||||
} else if (showIO) {
|
||||
setShowIO(false);
|
||||
setShowTB(false);
|
||||
}
|
||||
}, [showIO]);
|
||||
|
||||
useInterval(showAnimate, 100);
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<Entity position={Cartesian3.fromDegrees(73, -7, 0)}>
|
||||
<Entity position={Cartesian3.fromDegrees(-110, -60, 0)}>
|
||||
<LabelGraphics
|
||||
text={"5月南极涛动"}
|
||||
font="24px Helvetica"
|
||||
fillColor={Color.SKYBLUE}
|
||||
outlineColor={Color.BLACK}
|
||||
outlineWidth={2}
|
||||
style={LabelStyle.FILL_AND_OUTLINE}
|
||||
eyeOffset={new Cartesian2(0, 200000)}
|
||||
/>
|
||||
</Entity>
|
||||
<Entity show={showIO} position={Cartesian3.fromDegrees(73, -7, 0)}>
|
||||
<LabelGraphics
|
||||
text={"印度洋海温异常"}
|
||||
font="24px Helvetica"
|
||||
@ -16,7 +49,7 @@ function Labels() {
|
||||
eyeOffset={new Cartesian2(0, 200000)}
|
||||
/>
|
||||
</Entity>
|
||||
<Entity position={Cartesian3.fromDegrees(94, 24, 0)}>
|
||||
<Entity show={showTB} position={Cartesian3.fromDegrees(94, 24, 0)}>
|
||||
<LabelGraphics
|
||||
text={"6月青藏高原降水和加热"}
|
||||
font="24px Helvetica"
|
||||
|
@ -1,103 +1,67 @@
|
||||
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",
|
||||
"#4160ac",
|
||||
"#4363ae",
|
||||
"#4867b1",
|
||||
"#4d6bb3",
|
||||
"#5370b6",
|
||||
"#5d79bb",
|
||||
"#6c85c1",
|
||||
"#778dc7",
|
||||
"#8297cd",
|
||||
"#8fa3d3",
|
||||
"#9baed9",
|
||||
"#a6b7de",
|
||||
"#b0c0e3",
|
||||
"#bcc9e6",
|
||||
"#c9d3eb",
|
||||
"#d4ddf1",
|
||||
"#fbd1d2",
|
||||
"#fac4c6",
|
||||
"#f9b8ba",
|
||||
"#f8abae",
|
||||
"#f79fa2",
|
||||
"#f59496",
|
||||
"#f4878a",
|
||||
"#f37a7c",
|
||||
"#f36e70",
|
||||
"#f26264",
|
||||
"#f15759",
|
||||
"#f04c4f",
|
||||
"#f14145",
|
||||
"#ef3637",
|
||||
"#ee2e30",
|
||||
"#ee2529",
|
||||
];
|
||||
|
||||
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 className="legend">
|
||||
<div className="legend-title">印度洋海温异常值</div>
|
||||
<div className="colorbar">
|
||||
{colorBar.map((color, index) => {
|
||||
return (
|
||||
<div
|
||||
key={`colorbar-item-${index}`}
|
||||
className="colorbar-item"
|
||||
style={{ backgroundColor: color }}
|
||||
title={`${(-3.2 + index * 0.2).toFixed(1)}~${(
|
||||
-3.2 +
|
||||
(index + 1) * 0.2
|
||||
).toFixed(1)}`}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</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 className="legend-text">
|
||||
{[-2.4, -1.6, -0.8, 0, 0.8, 1.6, 2.4, ""].map((item, index) => {
|
||||
return (
|
||||
<div key={`legend-text-item-${index}`} className="legend-text-item">
|
||||
{item}
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</Fragment>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -13,7 +13,7 @@ function MoistureTransport() {
|
||||
stopTime.secondsOfDay - currentTime.secondsOfDay
|
||||
);
|
||||
|
||||
if (leftTime < 10) {
|
||||
if (leftTime < 5) {
|
||||
setShow(true);
|
||||
} else if (show) setShow(false);
|
||||
}, [show]);
|
||||
|
@ -1,36 +0,0 @@
|
||||
import { useCallback, useState } from "react";
|
||||
import { Entity, PolygonGraphics, useCesium } from "resium";
|
||||
import { useInterval } from "ahooks";
|
||||
import { Cartesian3, Color } from "cesium";
|
||||
|
||||
function PlateauPolygon() {
|
||||
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 < 5) {
|
||||
setShow(true);
|
||||
} else if (show) setShow(false);
|
||||
}, [show]);
|
||||
|
||||
useInterval(showAnimate, 100);
|
||||
|
||||
return (
|
||||
<Entity id="plateau" show={show}>
|
||||
<PolygonGraphics
|
||||
hierarchy={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 Color(1, 0, 0, 0.1)}
|
||||
/>
|
||||
</Entity>
|
||||
);
|
||||
}
|
||||
|
||||
export default PlateauPolygon;
|
99
src/components/domain/Two/Site/HeatFlux copy.jsx
Normal file
99
src/components/domain/Two/Site/HeatFlux copy.jsx
Normal file
@ -0,0 +1,99 @@
|
||||
import { Entity, EllipseGraphics } from "resium";
|
||||
import { Cartesian3, Color } from "cesium";
|
||||
|
||||
const fluxData = [
|
||||
0.03256254, -0.23182425, -0.040055223, -0.03476936, -0.40450656, -0.18742515,
|
||||
0.045675285, -0.1613145, 0.06295018, -0.14455463, -0.30952197, 0.08164308,
|
||||
0.019849295, 0.08785298, -0.22862722, -0.29176497, -0.1504006, 0.06978327,
|
||||
0.10036364, -0.1807746, -0.21565104, -0.28437, -0.16798478, -0.214204,
|
||||
-0.049326606, -0.094635, -0.09530785, -0.3044696, -0.28540367, -0.032144096,
|
||||
-0.20508154, -0.1721087, -0.12554182, -0.11001358, 0.002132158, 0.055833075,
|
||||
-0.1926637, -0.313678, 0.45139277, -0.22535999, -0.24989001, -0.024313157,
|
||||
-0.2859986, 0.019246876, -0.02536043, -0.46465757, -0.32723987, -0.1926801,
|
||||
-0.28803313, 0.005735828, 0.055759758, 0.10569655, -0.14558661, -0.1924466,
|
||||
-0.035115488, -0.48584095, -0.15169029, -0.0734382, -0.21065243, -0.1338741,
|
||||
-0.5154115, -0.19396217, -0.10661117, -0.24887498, -0.36621347, -0.39322242,
|
||||
-0.14620663, -0.1848758, -0.36631036, -0.07608904, -0.161032, 0.08955761,
|
||||
-0.46289977, -0.19713691, -0.237024, -0.10819046, -0.10532822, -0.20728564,
|
||||
-0.04151492, -0.1793385,
|
||||
];
|
||||
|
||||
const colorBar = [
|
||||
"#73d13d",
|
||||
"#95de64",
|
||||
"#b7eb8f",
|
||||
"#d9f7be",
|
||||
"#f6ffed",
|
||||
"#fff1f0",
|
||||
"#ffccc7",
|
||||
"#ffa39e",
|
||||
"#ff7875",
|
||||
"#ff4d4f",
|
||||
];
|
||||
|
||||
const ranges = [
|
||||
[-999, -0.4],
|
||||
[-0.4, -0.3],
|
||||
[-0.3, -0.2],
|
||||
[-0.2, -0.1],
|
||||
[-0.1, 0],
|
||||
[0, 0.1],
|
||||
[0.1, 0.2],
|
||||
[0.2, 0.3],
|
||||
[0.3, 0.4],
|
||||
[0.4, 999],
|
||||
];
|
||||
|
||||
let dataIndex = 0;
|
||||
const height = 201000;
|
||||
|
||||
// 热通量异常
|
||||
function HeatFlux({ position, index }) {
|
||||
const [lon, lat] = position;
|
||||
|
||||
for (let i = 0; i < ranges.length; i++) {
|
||||
const start = ranges[i][0];
|
||||
const end = ranges[i][1];
|
||||
if (fluxData[index] >= start && fluxData[index] <= end) {
|
||||
dataIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<Entity
|
||||
id={`site-heat-flux-${index}`}
|
||||
position={Cartesian3.fromDegrees(lon, lat, 0)}
|
||||
description={`
|
||||
<table className="description-table" style='width:100%'>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th style='width:40%; background-color:#4b4b4b; padding: 3' >
|
||||
感热通量数据
|
||||
</th>
|
||||
<td style='background-color:#4b4b4b; padding: 3'>
|
||||
${fluxData[index]}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th style=' width: 40%; background-color: #323232; padding: 3 ' >
|
||||
站点坐标
|
||||
</th>
|
||||
<td style=' background-color: #323232; padding: 3 ' > ${lon},${lat} </td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
`}
|
||||
>
|
||||
<EllipseGraphics
|
||||
material={new Color.fromCssColorString(colorBar[dataIndex])}
|
||||
semiMinorAxis={30000.0}
|
||||
semiMajorAxis={30000.0}
|
||||
extrudedHeight={400000}
|
||||
height={height}
|
||||
/>
|
||||
</Entity>
|
||||
);
|
||||
}
|
||||
|
||||
export default HeatFlux;
|
@ -1,5 +1,5 @@
|
||||
import { Entity, EllipseGraphics } from "resium";
|
||||
import { Cartesian3, Color } from "cesium";
|
||||
import { Entity, PolylineGraphics } from "resium";
|
||||
import { Cartesian3, Color, PolylineArrowMaterialProperty } from "cesium";
|
||||
|
||||
const fluxData = [
|
||||
0.03256254, -0.23182425, -0.040055223, -0.03476936, -0.40450656, -0.18742515,
|
||||
@ -18,19 +18,6 @@ const fluxData = [
|
||||
-0.04151492, -0.1793385,
|
||||
];
|
||||
|
||||
const colorBar = [
|
||||
"#73d13d",
|
||||
"#95de64",
|
||||
"#b7eb8f",
|
||||
"#d9f7be",
|
||||
"#f6ffed",
|
||||
"#fff1f0",
|
||||
"#ffccc7",
|
||||
"#ffa39e",
|
||||
"#ff7875",
|
||||
"#ff4d4f",
|
||||
];
|
||||
|
||||
const ranges = [
|
||||
[-999, -0.4],
|
||||
[-0.4, -0.3],
|
||||
@ -44,8 +31,8 @@ const ranges = [
|
||||
[0.4, 999],
|
||||
];
|
||||
|
||||
let dataIndex = 0;
|
||||
const height = 201000;
|
||||
const height = 1210000;
|
||||
let length = height + 510000;
|
||||
|
||||
// 热通量异常
|
||||
function HeatFlux({ position, index }) {
|
||||
@ -55,7 +42,11 @@ function HeatFlux({ position, index }) {
|
||||
const start = ranges[i][0];
|
||||
const end = ranges[i][1];
|
||||
if (fluxData[index] >= start && fluxData[index] <= end) {
|
||||
dataIndex = i;
|
||||
if (i < 5) {
|
||||
length = height + (i - 5) * 100000;
|
||||
} else {
|
||||
length = height + (i - 4) * 100000;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -64,33 +55,19 @@ function HeatFlux({ position, index }) {
|
||||
<Entity
|
||||
id={`site-heat-flux-${index}`}
|
||||
position={Cartesian3.fromDegrees(lon, lat, 0)}
|
||||
description={`
|
||||
<table className="description-table" style='width:100%'>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th style='width:40%; background-color:#4b4b4b; padding: 3' >
|
||||
感热通量数据
|
||||
</th>
|
||||
<td style='background-color:#4b4b4b; padding: 3'>
|
||||
${fluxData[index]}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th style=' width: 40%; background-color: #323232; padding: 3 ' >
|
||||
站点坐标
|
||||
</th>
|
||||
<td style=' background-color: #323232; padding: 3 ' > ${lon},${lat} </td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
`}
|
||||
>
|
||||
<EllipseGraphics
|
||||
material={new Color.fromCssColorString(colorBar[dataIndex])}
|
||||
semiMinorAxis={30000.0}
|
||||
semiMajorAxis={30000.0}
|
||||
extrudedHeight={400000}
|
||||
height={height}
|
||||
<PolylineGraphics
|
||||
positions={Cartesian3.fromDegreesArrayHeights([
|
||||
lon,
|
||||
lat,
|
||||
height,
|
||||
lon,
|
||||
lat,
|
||||
length,
|
||||
])}
|
||||
material={new PolylineArrowMaterialProperty(Color.RED)}
|
||||
arcType={"NONE"}
|
||||
width={10}
|
||||
/>
|
||||
</Entity>
|
||||
);
|
||||
|
97
src/components/domain/Two/Site/Rain copy.jsx
Normal file
97
src/components/domain/Two/Site/Rain copy.jsx
Normal file
@ -0,0 +1,97 @@
|
||||
import { Entity, EllipseGraphics } from "resium";
|
||||
import { Cartesian3, Color } from "cesium";
|
||||
|
||||
const rainData = [
|
||||
0.25309432, 0.296679, 0.39937696, -0.15093477, 0.17799897, 0.1186297,
|
||||
0.07794944, 0.086336374, -0.016019614, -0.10862, 0.026069753, -0.005777068,
|
||||
-0.04960121, -0.13736366, 0.268846, 0.32549506, 0.16180113, 0.34738356,
|
||||
0.21825098, 0.56309533, 0.15624292, 0.1915884, -0.08074772, -0.021623861,
|
||||
-0.03270335, 0.011358996, -0.09346678, -0.07257225, 0.19685836, -0.004689489,
|
||||
0.018297506, 0.089315325, 0.07057168, 0.13153072, 0.036938984, -0.17923261,
|
||||
0.3985438, 0.171897, -0.113426015, 0.4553916, 0.1476996, 0.158635,
|
||||
-0.041355144, 0.14970288, 0.19565174, 0.213287, 0.0603011, 0.35724494,
|
||||
-0.13986075, 0.16652703, -0.016419323, -0.09197042, -0.04890049, 0.22730026,
|
||||
0.4451923, 0.102407545, 0.28357506, 0.259764, 0.2361199, 0.32204336,
|
||||
0.39939404, 0.4786999, 0.12142443, -0.1493137, 0.3154582, 0.39657483,
|
||||
-0.08021964, 0.20489447, 0.26629895, -0.34400544, 0.29385626, 0.15458098,
|
||||
0.016143948, 0.04906382, -0.043581244, 0.1752981, -0.18351379, 0.071934514,
|
||||
0.10854135, -0.10280543,
|
||||
];
|
||||
|
||||
const colorBar = [
|
||||
"#ffc53d",
|
||||
"#ffd666",
|
||||
"#ffe58f",
|
||||
"#fff1b8",
|
||||
"#fffbe6",
|
||||
"#e6f7ff",
|
||||
"#bae7ff",
|
||||
"#91d5ff",
|
||||
"#69c0ff",
|
||||
"#40a9ff",
|
||||
];
|
||||
|
||||
const ranges = [
|
||||
[-999, -0.4],
|
||||
[-0.4, -0.3],
|
||||
[-0.3, -0.2],
|
||||
[-0.2, -0.1],
|
||||
[-0.1, 0],
|
||||
[0, 0.1],
|
||||
[0.1, 0.2],
|
||||
[0.2, 0.3],
|
||||
[0.3, 0.4],
|
||||
[0.4, 999],
|
||||
];
|
||||
|
||||
let dataIndex = 0;
|
||||
|
||||
// 降水异常
|
||||
function Rain({ position, index }) {
|
||||
const [lon, lat] = position;
|
||||
|
||||
for (let i = 0; i < ranges.length; i++) {
|
||||
const start = ranges[i][0];
|
||||
const end = ranges[i][1];
|
||||
if (rainData[index] >= start && rainData[index] <= end) {
|
||||
dataIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<Entity
|
||||
id={`site-rain-${index}`}
|
||||
position={Cartesian3.fromDegrees(lon, lat, 2000000)}
|
||||
description={`
|
||||
<table className="description-table" style='width:100%'>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th style='width:40%; background-color:#4b4b4b; padding: 3' >
|
||||
青藏高原降水
|
||||
</th>
|
||||
<td style='background-color:#4b4b4b; padding: 3'>
|
||||
${rainData[index]}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th style=' width: 40%; background-color: #323232; padding: 3 ' >
|
||||
站点坐标
|
||||
</th>
|
||||
<td style=' background-color: #323232; padding: 3 ' > ${lon},${lat} </td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
`}
|
||||
>
|
||||
<EllipseGraphics
|
||||
material={new Color.fromCssColorString(colorBar[dataIndex])}
|
||||
semiMinorAxis={30000.0}
|
||||
semiMajorAxis={30000.0}
|
||||
extrudedHeight={200000}
|
||||
/>
|
||||
</Entity>
|
||||
);
|
||||
}
|
||||
|
||||
export default Rain;
|
@ -1,5 +1,5 @@
|
||||
import { Entity, EllipseGraphics } from "resium";
|
||||
import { Cartesian3, Color } from "cesium";
|
||||
import { Entity, PolylineGraphics } from "resium";
|
||||
import { Cartesian3, Color, PolylineArrowMaterialProperty } from "cesium";
|
||||
|
||||
const rainData = [
|
||||
0.25309432, 0.296679, 0.39937696, -0.15093477, 0.17799897, 0.1186297,
|
||||
@ -18,19 +18,6 @@ const rainData = [
|
||||
0.10854135, -0.10280543,
|
||||
];
|
||||
|
||||
const colorBar = [
|
||||
"#ffc53d",
|
||||
"#ffd666",
|
||||
"#ffe58f",
|
||||
"#fff1b8",
|
||||
"#fffbe6",
|
||||
"#e6f7ff",
|
||||
"#bae7ff",
|
||||
"#91d5ff",
|
||||
"#69c0ff",
|
||||
"#40a9ff",
|
||||
];
|
||||
|
||||
const ranges = [
|
||||
[-999, -0.4],
|
||||
[-0.4, -0.3],
|
||||
@ -44,7 +31,8 @@ const ranges = [
|
||||
[0.4, 999],
|
||||
];
|
||||
|
||||
let dataIndex = 0;
|
||||
const height = 400000;
|
||||
let length = height + 510000;
|
||||
|
||||
// 降水异常
|
||||
function Rain({ position, index }) {
|
||||
@ -54,7 +42,11 @@ function Rain({ position, index }) {
|
||||
const start = ranges[i][0];
|
||||
const end = ranges[i][1];
|
||||
if (rainData[index] >= start && rainData[index] <= end) {
|
||||
dataIndex = i;
|
||||
if (i < 5) {
|
||||
length = height + (i - 5) * 100000;
|
||||
} else {
|
||||
length = height + (i - 4) * 100000;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -63,32 +55,19 @@ function Rain({ position, index }) {
|
||||
<Entity
|
||||
id={`site-rain-${index}`}
|
||||
position={Cartesian3.fromDegrees(lon, lat, 2000000)}
|
||||
description={`
|
||||
<table className="description-table" style='width:100%'>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th style='width:40%; background-color:#4b4b4b; padding: 3' >
|
||||
青藏高原降水
|
||||
</th>
|
||||
<td style='background-color:#4b4b4b; padding: 3'>
|
||||
${rainData[index]}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th style=' width: 40%; background-color: #323232; padding: 3 ' >
|
||||
站点坐标
|
||||
</th>
|
||||
<td style=' background-color: #323232; padding: 3 ' > ${lon},${lat} </td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
`}
|
||||
>
|
||||
<EllipseGraphics
|
||||
material={new Color.fromCssColorString(colorBar[dataIndex])}
|
||||
semiMinorAxis={30000.0}
|
||||
semiMajorAxis={30000.0}
|
||||
extrudedHeight={200000}
|
||||
<PolylineGraphics
|
||||
positions={Cartesian3.fromDegreesArrayHeights([
|
||||
lon,
|
||||
lat,
|
||||
height,
|
||||
lon,
|
||||
lat,
|
||||
length,
|
||||
])}
|
||||
material={new PolylineArrowMaterialProperty(Color.SKYBLUE)}
|
||||
arcType={"NONE"}
|
||||
width={10}
|
||||
/>
|
||||
</Entity>
|
||||
);
|
||||
|
@ -15,10 +15,6 @@ const positions = [
|
||||
];
|
||||
|
||||
function Sites() {
|
||||
// const { showSite } = useSelector((state) => state.data);
|
||||
|
||||
// if (!showSite) return <></>;
|
||||
|
||||
return chunk(positions, 2).map((position, index) => {
|
||||
return <Site key={`site-${index}`} index={index} position={position} />;
|
||||
});
|
||||
|
46
src/components/domain/Two/SiteLegend.jsx
Normal file
46
src/components/domain/Two/SiteLegend.jsx
Normal file
@ -0,0 +1,46 @@
|
||||
import rain from "@/assets/rain.png";
|
||||
import heatflux from "@/assets/heatflux.png";
|
||||
import styles from "./index.module.less";
|
||||
|
||||
function SiteLegend() {
|
||||
return (
|
||||
<div className={styles.siteLegend}>
|
||||
<div className="site-legend-item">
|
||||
<div>
|
||||
<img src={rain} alt="rain-increase" width={32} />
|
||||
</div>
|
||||
<div className="site-legend-item-name">降水异常增加</div>
|
||||
</div>
|
||||
<div className="site-legend-item">
|
||||
<div>
|
||||
<img
|
||||
src={rain}
|
||||
alt="rain-decrease"
|
||||
width={32}
|
||||
style={{ transform: "rotate(180deg)" }}
|
||||
/>
|
||||
</div>
|
||||
<div className="site-legend-item-name">降水异常降低</div>
|
||||
</div>
|
||||
<div className="site-legend-item">
|
||||
<div>
|
||||
<img src={heatflux} alt="heatflux-increase" width={32} />
|
||||
</div>
|
||||
<div className="site-legend-item-name">感热通量异常增加</div>
|
||||
</div>
|
||||
<div className="site-legend-item">
|
||||
<div>
|
||||
<img
|
||||
src={heatflux}
|
||||
alt="heatflux-decrease"
|
||||
width={32}
|
||||
style={{ transform: "rotate(180deg)" }}
|
||||
/>
|
||||
</div>
|
||||
<div className="site-legend-item-name">感热通量异常降低</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default SiteLegend;
|
@ -4,8 +4,8 @@ import WavePoint from "@/components/common/WavePoint";
|
||||
export default function WavePoints() {
|
||||
return (
|
||||
<Fragment>
|
||||
<WavePoint stationLon={88} stationLat={-85} />
|
||||
<WavePoint stationLon={88} stationLat={32.5} />
|
||||
<WavePoint stationLon={88} stationLat={-85} labelText={"南极"} />
|
||||
<WavePoint stationLon={88} stationLat={32.5} labelText={"青藏高原"} />
|
||||
</Fragment>
|
||||
);
|
||||
}
|
||||
|
@ -4,7 +4,6 @@ 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";
|
||||
@ -13,9 +12,11 @@ import Circles from "./Circles";
|
||||
import SurfaceAnomaly from "./SurfaceAnomaly";
|
||||
import MoistureTransport from "./MoistureTransport";
|
||||
import Sites from "./Site";
|
||||
import SiteLegend from "./SiteLegend";
|
||||
import Labels from "./Labels";
|
||||
|
||||
export default function DomainTwo() {
|
||||
console.log("111 :>> ", 111);
|
||||
return (
|
||||
<MapLayout>
|
||||
<div className="title">两极协同—南极涛动有效调节青藏高原降水和加热</div>
|
||||
@ -29,8 +30,8 @@ export default function DomainTwo() {
|
||||
<Legend />
|
||||
<MoistureTransport />
|
||||
<Point />
|
||||
<PlateauPolygon />
|
||||
<Sites />
|
||||
<SiteLegend />
|
||||
<div className="left-panel one">
|
||||
<TextInfoPanel content="利用ERA5再分析数据诊断和CESM印度洋海温强迫数值实验,发现5月的南极涛动正位相(AAO)激发原子阿蒙森海的纬向波列异常。该异常造成印度洋海温降低进而激发环流异常造成高原上空降水增加、感热通量降低。这一结果有助于提高青藏高原热源的预测技巧,改进亚洲夏季风的预测。" />
|
||||
</div>
|
||||
|
24
src/components/domain/Two/index.module.less
Normal file
24
src/components/domain/Two/index.module.less
Normal file
@ -0,0 +1,24 @@
|
||||
.siteLegend :global {
|
||||
position: absolute;
|
||||
width: 200px;
|
||||
height: 300px;
|
||||
right: 12px;
|
||||
bottom: 14px;
|
||||
display: grid;
|
||||
background-color: #1f485690;
|
||||
border: 1px solid #04fbfd;
|
||||
border-radius: 8px;
|
||||
padding: 8px;
|
||||
color: white;
|
||||
user-select: none;
|
||||
|
||||
.site-legend-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
|
||||
.site-legend-item-name {
|
||||
font-weight: 700;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,12 +1,10 @@
|
||||
import { useCallback } from "react";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { useDispatch } from "react-redux";
|
||||
import { createFromIconfontCN } from "@ant-design/icons";
|
||||
import NavBarButton from "./NavBarButton";
|
||||
|
||||
function NavBar() {
|
||||
const navigate = useNavigate();
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const MyIcon = createFromIconfontCN({
|
||||
scriptUrl: "//at.alicdn.com/t/c/font_4281629_4lq551rfhki.js",
|
||||
@ -15,13 +13,8 @@ function NavBar() {
|
||||
const navigateHandler = useCallback(
|
||||
(type) => {
|
||||
navigate(`/map/${type}`, { replace: true });
|
||||
if (type !== 1 && type !== 2) {
|
||||
dispatch.data.update({
|
||||
toolbar: { showPanel: true },
|
||||
});
|
||||
}
|
||||
},
|
||||
[navigate, dispatch]
|
||||
[navigate]
|
||||
);
|
||||
|
||||
return (
|
||||
|
@ -1,8 +1,9 @@
|
||||
import { Entity, PointGraphics, Viewer } from "resium";
|
||||
import styles from "./index.module.less";
|
||||
import { Cartesian3, Color } from "cesium";
|
||||
import Picker from "./Picker";
|
||||
import HeadingPitchRoll from "./HeadingPitchRoll";
|
||||
import CustomToolbar from "@/components/common/CustomToolbar";
|
||||
import styles from "./index.module.less";
|
||||
|
||||
function MapLayout({ children, className, ...rest }) {
|
||||
return (
|
||||
@ -24,6 +25,7 @@ function MapLayout({ children, className, ...rest }) {
|
||||
<Entity position={Cartesian3.fromDegreesArray([0, 90])}>
|
||||
<PointGraphics color={Color.SKYBLUE} pixelSize={10} />
|
||||
</Entity>
|
||||
<CustomToolbar />
|
||||
<Picker />
|
||||
{/* <HeadingPitchRoll /> */}
|
||||
{children}
|
||||
|
@ -28,16 +28,6 @@
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.toolbar {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 12px;
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
width: 370px;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.left-panel {
|
||||
position: absolute;
|
||||
top: 84px;
|
||||
@ -67,12 +57,13 @@
|
||||
text-indent: 2em;
|
||||
line-height: 1.5;
|
||||
z-index: 999;
|
||||
border-radius: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
.right-panel {
|
||||
position: absolute;
|
||||
top: 84px;
|
||||
// top: 84px;
|
||||
right: 12px;
|
||||
bottom: 12px;
|
||||
width: 450px;
|
||||
@ -96,6 +87,7 @@
|
||||
border: 1px solid #04fbfd;
|
||||
color: #02f9ff !important;
|
||||
background-color: #1f485690;
|
||||
border-radius: 8px;
|
||||
|
||||
.ant-form-item-label {
|
||||
label {
|
||||
@ -133,6 +125,7 @@
|
||||
color: #02f9ff !important;
|
||||
background-color: #1f485690;
|
||||
transition: all 0.3s ease-in-out;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.highlight {
|
||||
@ -173,7 +166,7 @@
|
||||
|
||||
.legend {
|
||||
position: absolute;
|
||||
bottom: 40px;
|
||||
bottom: 12px;
|
||||
width: 50%;
|
||||
left: 25%;
|
||||
// height: 40px;
|
||||
|
@ -1,36 +1,9 @@
|
||||
export const data = {
|
||||
state: {
|
||||
showSite: false,
|
||||
toolbar: {},
|
||||
imageLayer: {
|
||||
labrador: undefined,
|
||||
indianOcean: undefined,
|
||||
},
|
||||
},
|
||||
state: {},
|
||||
reducers: {
|
||||
update(state, payload) {
|
||||
return { ...state, ...payload };
|
||||
},
|
||||
updateToolbar(state, payload) {
|
||||
const { toolbar } = state;
|
||||
return { ...state, toolbar: { ...toolbar, ...payload } };
|
||||
},
|
||||
updateImageLayer(state, payload) {
|
||||
const { imageLayer } = state;
|
||||
return { ...state, imageLayer: { ...imageLayer, ...payload } };
|
||||
},
|
||||
resetState(state, payload) {
|
||||
return {
|
||||
showSite: false,
|
||||
toolbar: {
|
||||
showPanel: undefined,
|
||||
},
|
||||
imageLayer: {
|
||||
labrador: undefined,
|
||||
indianOcean: undefined,
|
||||
},
|
||||
};
|
||||
},
|
||||
},
|
||||
effects: (dispatch) => ({}),
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user