This commit is contained in:
Aifeilong 2023-10-19 16:03:41 +08:00
parent fc4fb9efb1
commit 1c364a65a8
20 changed files with 271 additions and 69 deletions

View File

@ -7,6 +7,7 @@ function ClimateReconDataAssim() {
return (
<div className={styles.climateReconDataAssim}>
<MapLayout>
<div className="title">过去千年气候重建数据同化</div>
<div className="formPanel">
<FormPanel />
</div>

View File

@ -2,10 +2,10 @@
width: 100%;
height: 100%;
border: 1px solid #04fbfd;
color: #02f9ff !important;
color: white !important;
background-color: #000000e7;
pointer-events: auto;
font-size: 18px;
font-size: 19px;
text-indent: 2em;
line-height: 1.5;
z-index: 999;

View File

@ -129,7 +129,7 @@ function WavePoint({
<LabelGraphics
text={labelText}
font="24px Helvetica"
fillColor={Color.SKYBLUE}
fillColor={Color.fromCssColorString("#04fbfd")}
outlineColor={Color.BLACK}
outlineWidth={2}
style={LabelStyle.FILL_AND_OUTLINE}

View File

@ -84,10 +84,9 @@ function ChartPanel() {
type: "line",
stack: "Total",
data: observedData,
color: "black",
symbol: "none",
itemStyle: {
color: "black",
color: "lightgrey",
},
},
{
@ -95,7 +94,6 @@ function ChartPanel() {
type: "line",
// stack: "Total",
data: predictedData,
color: "red",
symbol: "none",
itemStyle: {
color: "red",

View File

@ -67,7 +67,7 @@ function Labels() {
<LabelGraphics
text={name}
font="24px Helvetica"
fillColor={Color.SKYBLUE}
fillColor={Color.fromCssColorString("#04fbfd")}
outlineColor={Color.BLACK}
outlineWidth={2}
style={LabelStyle.FILL_AND_OUTLINE}

View File

@ -52,7 +52,7 @@ function ChartPanel() {
trigger: "axis",
},
legend: {
data: ["ERSST_lancozs", "JRA55_lancozs"],
data: ["拉布拉多海夏季海温(异常值)", "高原夏季气温(异常值)"],
textStyle: { color: "#04fbfd", cursor: "point" },
},
animationDuration: years.length * 1000,
@ -65,6 +65,7 @@ function ChartPanel() {
},
xAxis: {
type: "category",
// name: "",
boundaryGap: false,
data: years,
axisLine: {
@ -81,6 +82,7 @@ function ChartPanel() {
},
yAxis: {
type: "value",
name: "℃",
min: -1.5,
max: 2.0,
interval: 0.5,
@ -104,7 +106,7 @@ function ChartPanel() {
dataZoom: { type: "inside", start: 0, end: 100 },
series: [
{
name: "ERSST_lancozs",
name: "拉布拉多海夏季海温(异常值)",
type: "line",
stack: "Total",
data: laBrudata,
@ -116,7 +118,7 @@ function ChartPanel() {
},
},
{
name: "JRA55_lancozs",
name: "高原夏季气温(异常值)",
type: "line",
// stack: "Total",
data: plateauData,

View File

@ -26,20 +26,20 @@ function CustomFlyTo() {
// barotorpic
const barotorpic = {
destination: Cartesian3.fromDegrees(75, 48, 15000000),
destination: Cartesian3.fromDegrees(60, 15, 15000000),
duration: 7,
complete: () => {},
easingFunction: EasingFunction.LINEAR_NONE,
orientation: {
heading: 6.283,
pitch: -1.569,
roll: 0.45,
pitch: -1.4,
roll: 0,
},
};
//
const sideViewOptions = {
destination: Cartesian3.fromDegrees(-50, 46, 2000000),
destination: Cartesian3.fromDegrees(-50, 46, 2200000),
duration: 5,
orientation: {
heading: Math.toRadians(-15.0),

View File

@ -14,6 +14,8 @@ let totalSeconds = 60;
let numberOfSamples = 120;
let wheelAngle = 0;
const height = 1000000;
function Cyclone() {
const { viewer } = useCesium();
@ -48,7 +50,9 @@ function Cyclone() {
const getPassTime = useCallback(() => {
const { startTime, currentTime } = viewer.clock;
const _time = Math.floor(currentTime.secondsOfDay - startTime.secondsOfDay);
const _time = (currentTime.secondsOfDay - startTime.secondsOfDay).toFixed(
1
);
return _time;
}, [viewer]);
@ -63,7 +67,7 @@ function Cyclone() {
new CallbackProperty(function (time, result) {
const passTime = getPassTime();
if (passTime < 5) return;
return Cartesian3.fromDegrees(-62, 69, 1000000);
return Cartesian3.fromDegrees(-62, 69, height);
}, true)
}
>
@ -79,15 +83,22 @@ function Cyclone() {
color={anticycloneColor}
colorBlendMode={ColorBlendMode.REPLACE}
/>
<LabelGraphics
position={Cartesian3.fromDegrees(98, 48, 0)}
text={"Anticyclone"}
font="24px Helvetica"
fillColor={Color.SKYBLUE}
outlineColor={Color.BLACK}
outlineWidth={2}
style={LabelStyle.FILL_AND_OUTLINE}
eyeOffset={new Cartesian2(0, 200000)}
</Entity>
<Entity
id={"Anticyclone-add-1"}
position={
new CallbackProperty(function (time, result) {
const passTime = getPassTime();
if (passTime < 7.5) return;
return Cartesian3.fromDegrees(-45, 59, height);
}, true)
}
>
<ModelGraphics
uri={arrowRound}
minimumPixelSize={128}
color={anticycloneColor}
colorBlendMode={ColorBlendMode.REPLACE}
/>
</Entity>
<Entity
@ -96,7 +107,24 @@ function Cyclone() {
new CallbackProperty(function (time, result) {
const passTime = getPassTime();
if (passTime < 10) return;
return Cartesian3.fromDegrees(-20, 55, 1000000);
return Cartesian3.fromDegrees(-20, 55, height);
}, true)
}
>
<ModelGraphics
uri={arrowRound}
minimumPixelSize={128}
color={cycloneColor}
colorBlendMode={ColorBlendMode.REPLACE}
/>
</Entity>
<Entity
id={"Cyclone-add-1"}
position={
new CallbackProperty(function (time, result) {
const passTime = getPassTime();
if (passTime < 12.5) return;
return Cartesian3.fromDegrees(5, 53, height);
}, true)
}
>
@ -113,7 +141,24 @@ function Cyclone() {
new CallbackProperty(function (time, result) {
const passTime = getPassTime();
if (passTime < 15) return;
return Cartesian3.fromDegrees(29, 49, 1000000);
return Cartesian3.fromDegrees(29, 49, height);
}, true)
}
>
<ModelGraphics
uri={arrowRound}
minimumPixelSize={128}
color={anticycloneColor}
colorBlendMode={ColorBlendMode.REPLACE}
/>
</Entity>
<Entity
id={"Anticyclone-add-2"}
position={
new CallbackProperty(function (time, result) {
const passTime = getPassTime();
if (passTime < 17.5) return;
return Cartesian3.fromDegrees(46, 46, height);
}, true)
}
>
@ -130,7 +175,24 @@ function Cyclone() {
new CallbackProperty(function (time, result) {
const passTime = getPassTime();
if (passTime < 20) return;
return Cartesian3.fromDegrees(62, 45, 1000000);
return Cartesian3.fromDegrees(62, 45, height);
}, true)
}
>
<ModelGraphics
uri={arrowRound}
minimumPixelSize={128}
color={cycloneColor}
colorBlendMode={ColorBlendMode.REPLACE}
/>
</Entity>
<Entity
id={"Cyclone-add-2"}
position={
new CallbackProperty(function (time, result) {
const passTime = getPassTime();
if (passTime < 22.5) return;
return Cartesian3.fromDegrees(81, 46.5, height);
}, true)
}
>
@ -147,7 +209,7 @@ function Cyclone() {
new CallbackProperty(function (time, result) {
const passTime = getPassTime();
if (passTime < 25) return;
return Cartesian3.fromDegrees(98, 48, 1000000);
return Cartesian3.fromDegrees(98, 48, height);
}, true)
}
>

View File

@ -37,7 +37,7 @@ function Labels() {
<LabelGraphics
text={"拉布拉多海海温偏暖"}
font="24px Helvetica"
fillColor={Color.SKYBLUE}
fillColor={Color.fromCssColorString("#04fbfd")}
outlineColor={Color.BLACK}
outlineWidth={2}
style={LabelStyle.FILL_AND_OUTLINE}
@ -48,7 +48,7 @@ function Labels() {
<LabelGraphics
text={"北大西洋大气环流异常"}
font="24px Helvetica"
fillColor={Color.SKYBLUE}
fillColor={Color.fromCssColorString("#04fbfd")}
outlineColor={Color.BLACK}
outlineWidth={2}
style={LabelStyle.FILL_AND_OUTLINE}
@ -59,7 +59,7 @@ function Labels() {
<LabelGraphics
text={"欧洲地区大气环流异常"}
font="24px Helvetica"
fillColor={Color.SKYBLUE}
fillColor={Color.fromCssColorString("#04fbfd")}
outlineColor={Color.BLACK}
outlineWidth={2}
style={LabelStyle.FILL_AND_OUTLINE}
@ -70,7 +70,7 @@ function Labels() {
<LabelGraphics
text={"barotropic"}
font="24px Helvetica"
fillColor={Color.SKYBLUE}
fillColor={Color.fromCssColorString("#04fbfd")}
outlineColor={Color.BLACK}
outlineWidth={2}
style={LabelStyle.FILL_AND_OUTLINE}
@ -81,7 +81,7 @@ function Labels() {
<LabelGraphics
text={"青藏高原夏季出现年代际增温"}
font="24px Helvetica"
fillColor={Color.SKYBLUE}
fillColor={Color.fromCssColorString("#04fbfd")}
outlineColor={Color.BLACK}
outlineWidth={2}
style={LabelStyle.FILL_AND_OUTLINE}

View File

@ -35,7 +35,7 @@
bottom: 0;
left: 25%;
color: #02f9ff;
width: 50%;
width: 960px;
}
}

View File

@ -22,7 +22,7 @@ const lowCircle = (
innerRadii={new Cartesian3(415000.0, 415000.0, 415000.0)}
minimumCone={CesiumMath.toRadians(89.8)}
maximumCone={CesiumMath.toRadians(90.2)}
material={new Color(0.29, 0.46, 0.77, 1)}
material={new Color(0, 0, 1, 1)}
/>
);
@ -32,7 +32,7 @@ const highCircle = (
innerRadii={new Cartesian3(415000.0, 415000.0, 415000.0)}
minimumCone={CesiumMath.toRadians(89.8)}
maximumCone={CesiumMath.toRadians(90.2)}
material={new Color(0.99, 0.23, 0.23, 1)}
material={new Color(1, 0, 0, 1)}
/>
);
@ -100,7 +100,7 @@ function Circles() {
<LabelGraphics
text={"Rossby波列"}
font="24px Helvetica"
fillColor={Color.SKYBLUE}
fillColor={Color.fromCssColorString("#04fbfd")}
outlineColor={Color.BLACK}
outlineWidth={2}
style={LabelStyle.FILL_AND_OUTLINE}
@ -116,35 +116,35 @@ function Circles() {
<Circle
isLow={true}
id={`low-circle-1`}
showTime={5}
showTime={2}
lon={-110}
lat={-60}
/>
<Circle
isLow={false}
id={`height-circle-1`}
showTime={10}
showTime={7}
lon={-30}
lat={-55}
/>
<Circle
isLow={true}
id={`low-circle-2`}
showTime={15}
showTime={12}
lon={30}
lat={-40}
/>
<Circle
isLow={false}
id={`height-circle-2`}
showTime={20}
showTime={16}
lon={65}
lat={-35}
/>
<Circle
isLow={true}
id={`low-circle-3`}
showTime={27}
showTime={20}
lon={95}
lat={-30}
/>

View File

@ -7,7 +7,7 @@ function CustomFlyTo() {
function cameraFlyToLine() {
const area1Options = {
destination: Cartesian3.fromDegrees(-110, -86, 10000000),
duration: 5,
duration: 2,
orientation: {
heading: 6,
pitch: -1.3,
@ -17,13 +17,14 @@ function CustomFlyTo() {
viewer.clock.shouldAnimate = true;
setTimeout(() => {
camera.flyTo(area2Options);
}, 5000);
}, 2000);
},
easingFunction: EasingFunction.LINEAR_NONE,
};
const area2Options = {
destination: Cartesian3.fromDegrees(-30, -65, 10000000),
destination: Cartesian3.fromDegrees(-30, -85, 10000000),
// destination: Cartesian3.fromDegrees(-30, -65, 10000000),
duration: 5,
complete: function () {
camera.flyTo(area3Options);
@ -37,31 +38,81 @@ function CustomFlyTo() {
};
const area3Options = {
destination: Cartesian3.fromDegrees(30, -40, 10000000),
destination: Cartesian3.fromDegrees(40, -75, 10000000),
duration: 5,
complete: function () {
camera.flyTo(area4Options);
},
easingFunction: EasingFunction.LINEAR_NONE,
orientation: {
heading: 5.8,
pitch: -1.3,
roll: -6,
},
};
const area4Options = {
destination: Cartesian3.fromDegrees(65, -55, 10000000),
duration: 5,
destination: Cartesian3.fromDegrees(65, -65, 10000000),
duration: 4,
orientation: {
heading: 6,
pitch: -1.3,
roll: -6,
},
complete: function () {
camera.flyTo({
duration: 7,
destination: Cartesian3.fromDegrees(90, 5, 14000000),
});
camera.flyTo(area5Options);
},
easingFunction: EasingFunction.LINEAR_NONE,
};
const area5Options = {
destination: Cartesian3.fromDegrees(90, -60, 10000000),
duration: 4,
orientation: {
heading: 6,
pitch: -1.3,
roll: -6,
},
complete: function () {
camera.flyTo(IndiaOceanOptions);
},
easingFunction: EasingFunction.LINEAR_NONE,
};
const IndiaOceanOptions = {
destination: Cartesian3.fromDegrees(80, 0, 14000000),
duration: 3,
complete: function () {
setTimeout(() => {
camera.flyTo(QTPlateauOption);
}, 3000);
},
easingFunction: EasingFunction.LINEAR_NONE,
};
const QTPlateauOption = {
destination: Cartesian3.fromDegrees(88, 18, 5000000),
duration: 2,
orientation: {
heading: 6,
pitch: -1.3,
roll: -6,
},
easingFunction: EasingFunction.LINEAR_NONE,
};
const xx = {
destination: Cartesian3.fromDegrees(80, 0, 14000000),
duration: 5,
// orientation: {
// heading: 6,
// pitch: -1.3,
// roll: -6,
// },
easingFunction: EasingFunction.LINEAR_NONE,
};
// camera.flyTo(xx);
camera.flyTo(area1Options);
}
cameraFlyToLine();

View File

@ -15,12 +15,12 @@ function IndianOceanSST() {
stopTime.secondsOfDay - currentTime.secondsOfDay
);
if (leftTime < 5) {
if (leftTime <= 10) {
setShow(true);
} else if (show) setShow(false);
}, [show]);
useInterval(showAnimate, 100);
useInterval(showAnimate, 300);
const tempProvider = useMemo(
() =>

View File

@ -31,7 +31,7 @@ function Labels() {
<LabelGraphics
text={"5月南极涛动"}
font="24px Helvetica"
fillColor={Color.SKYBLUE}
fillColor={Color.fromCssColorString("#04fbfd")}
outlineColor={Color.BLACK}
outlineWidth={2}
style={LabelStyle.FILL_AND_OUTLINE}
@ -42,7 +42,7 @@ function Labels() {
<LabelGraphics
text={"印度洋海温异常"}
font="24px Helvetica"
fillColor={Color.SKYBLUE}
fillColor={Color.fromCssColorString("#04fbfd")}
outlineColor={Color.BLACK}
outlineWidth={2}
style={LabelStyle.FILL_AND_OUTLINE}
@ -53,7 +53,7 @@ function Labels() {
<LabelGraphics
text={"6月青藏高原降水和加热"}
font="24px Helvetica"
fillColor={Color.SKYBLUE}
fillColor={Color.fromCssColorString("#04fbfd")}
outlineColor={Color.BLACK}
outlineWidth={2}
style={LabelStyle.FILL_AND_OUTLINE}

View File

@ -15,12 +15,12 @@ import {
//
const dataAntarcticaToQTP = [
{ longitude: -110, latitude: -60, height: 0, time: 0 },
{ longitude: -110, latitude: -60, height: 1000000, time: 5 },
{ longitude: -30, latitude: -55, height: 1000000, time: 10 },
{ longitude: 30, latitude: -40, height: 1000000, time: 15 },
{ longitude: 65, latitude: -35, height: 1000000, time: 20 },
{ longitude: 95, latitude: -30, height: 1000000, time: 27 },
{ longitude: 95, latitude: -30, height: 0, time: 30 },
{ longitude: -110, latitude: -60, height: 1000000, time: 2 },
{ longitude: -30, latitude: -55, height: 1000000, time: 7 },
{ longitude: 30, latitude: -40, height: 1000000, time: 12 },
{ longitude: 65, latitude: -35, height: 1000000, time: 16 },
{ longitude: 95, latitude: -30, height: 1000000, time: 20 },
{ longitude: 95, latitude: -30, height: 0, time: 23 },
];
function Point() {

View File

@ -0,0 +1,54 @@
import classNames from "classnames";
import styles from "./index.module.less";
import { useCesium } from "resium";
import { useState } from "react";
import { useInterval } from "ahooks";
const textList = [
"5月南极涛动",
"原子阿蒙森海的纬向波列异常",
"印度洋海温降低",
"环流异常",
"高原上空降水增加、感热通量降低",
];
export default function TimeLinePanel() {
const { viewer } = useCesium();
const [showIndex, setShowIndex] = useState(0);
useInterval(() => {
const { startTime, currentTime, shouldAnimate } = viewer.clock;
const passtime = Math.floor(
currentTime.secondsOfDay - startTime.secondsOfDay
);
if (!shouldAnimate) return;
if (passtime < 2) {
setShowIndex(0);
} else if (passtime > 2 && passtime < 20) {
setShowIndex(1);
} else if (passtime > 20 && passtime < 23) {
setShowIndex(2);
} else if (passtime > 23 && passtime < 25) {
setShowIndex(3);
} else if (passtime > 25 && passtime < 30) {
setShowIndex(4);
}
}, 300);
return (
<div className={styles.timeLinePanel}>
{textList.map((text, index) => (
<div
className={classNames("timeline-panel-item", {
highlight: index === showIndex,
})}
key={`timeline-panel-item-${index}`}
>
<span>{text}</span>
</div>
))}
</div>
);
}

View File

@ -14,6 +14,7 @@ import MoistureTransport from "./MoistureTransport";
import Sites from "./Site";
import SiteLegend from "./SiteLegend";
import Labels from "./Labels";
import TimeLinePanel from "./TimeLinePanel";
export default function DomainTwo() {
return (
@ -35,6 +36,7 @@ export default function DomainTwo() {
<TextInfoPanel content="利用ERA5再分析数据诊断和CESM印度洋海温强迫数值实验发现5月的南极涛动正位相AAO激发原子阿蒙森海的纬向波列异常。该异常造成印度洋海温降低进而激发环流异常造成高原上空降水增加、感热通量降低。这一结果有助于提高青藏高原热源的预测技巧改进亚洲夏季风的预测。" />
</div>
<WavePoints />
<TimeLinePanel />
{/* <SurfaceAnomaly /> */}
</MapLayout>
);

View File

@ -22,3 +22,33 @@
}
}
}
.timeLinePanel :global {
position: absolute;
top: 24px;
left: 12px;
width: 450px;
background-color: #00000000;
display: flex;
flex-direction: column;
.timeline-panel-item {
color: white;
padding: 4px 8px;
font-size: 18px;
span {
padding: 4px;
}
}
.highlight {
span {
font-size: 20px;
font-weight: 600;
color: #04fbfd;
background-color: #04fbfd1a;
border-radius: 8px;
}
}
}

View File

@ -27,7 +27,7 @@ function MapLayout({ children, className, ...rest }) {
</Entity>
<CustomToolbar />
<Picker />
{/* <HeadingPitchRoll /> */}
<HeadingPitchRoll />
{children}
</Viewer>
);

View File

@ -126,7 +126,7 @@
.entity-legend {
position: absolute;
bottom: 140px;
width: 50%;
width: 960px;
left: 25%;
display: grid;
grid-template-columns: repeat(3, 1fr);
@ -152,7 +152,7 @@
.legend {
position: absolute;
bottom: 12px;
width: 50%;
width: 960px;
left: 25%;
// height: 40px;
@ -166,7 +166,9 @@
padding: 8px;
.legend-title {
color: #04fbfd;
color: #fff;
font-size: 20px;
font-weight: 600;
}
.colorbar {
@ -199,7 +201,7 @@
text-align: right;
font-weight: 600;
color: white;
-webkit-text-stroke: #04fbfd 1px;
-webkit-text-stroke: white 1px;
}
}
}