fix
This commit is contained in:
parent
117523a7dd
commit
953a201081
@ -1,9 +1,10 @@
|
|||||||
|
import { ClockRange, JulianDate } from "cesium";
|
||||||
import { Clock } from "resium";
|
import { Clock } from "resium";
|
||||||
|
|
||||||
// 起始时间
|
// 起始时间
|
||||||
const start = Cesium.JulianDate.fromDate(new Date());
|
const start = JulianDate.fromDate(new Date());
|
||||||
// 结束时间
|
// 结束时间
|
||||||
const stop = Cesium.JulianDate.addSeconds(start, 60, new Cesium.JulianDate());
|
const stop = JulianDate.addSeconds(start, 30, new JulianDate());
|
||||||
|
|
||||||
function CustomClock() {
|
function CustomClock() {
|
||||||
return (
|
return (
|
||||||
@ -13,7 +14,7 @@ function CustomClock() {
|
|||||||
startTime={start.clone()}
|
startTime={start.clone()}
|
||||||
stopTime={stop.clone()}
|
stopTime={stop.clone()}
|
||||||
currentTime={start.clone()}
|
currentTime={start.clone()}
|
||||||
clockRange={Cesium.ClockRange.LOOP_STOP}
|
clockRange={ClockRange.LOOP_STOP}
|
||||||
// onTick={(clock) => {
|
// onTick={(clock) => {
|
||||||
// if (!clock.shouldAnimate) return;
|
// if (!clock.shouldAnimate) return;
|
||||||
// }}
|
// }}
|
||||||
|
@ -1,6 +1,14 @@
|
|||||||
import { Fragment } from "react";
|
import { Fragment } from "react";
|
||||||
import { Entity, EllipseGraphics } from "resium";
|
import { Entity, EllipseGraphics, LabelGraphics } from "resium";
|
||||||
import wave from "@/assets/wave.png";
|
import wave from "@/assets/wave.png";
|
||||||
|
import {
|
||||||
|
CallbackProperty,
|
||||||
|
Cartesian2,
|
||||||
|
Cartesian3,
|
||||||
|
Color,
|
||||||
|
ImageMaterialProperty,
|
||||||
|
LabelStyle,
|
||||||
|
} from "cesium";
|
||||||
|
|
||||||
function WavePoint({
|
function WavePoint({
|
||||||
stationLon,
|
stationLon,
|
||||||
@ -10,6 +18,7 @@ function WavePoint({
|
|||||||
eachInterval = 1500,
|
eachInterval = 1500,
|
||||||
maxR = 3600 * 100,
|
maxR = 3600 * 100,
|
||||||
color = "WHITE",
|
color = "WHITE",
|
||||||
|
labelText,
|
||||||
}) {
|
}) {
|
||||||
const data = {
|
const data = {
|
||||||
stationLon, // 经度
|
stationLon, // 经度
|
||||||
@ -43,25 +52,21 @@ function WavePoint({
|
|||||||
const point1 = (
|
const point1 = (
|
||||||
<Entity
|
<Entity
|
||||||
id={`wave-point-1-${stationLon}-${stationLat}`}
|
id={`wave-point-1-${stationLon}-${stationLat}`}
|
||||||
position={Cesium.Cartesian3.fromDegrees(
|
position={Cartesian3.fromDegrees(data.stationLon, data.stationLat, 0)}
|
||||||
data.stationLon,
|
|
||||||
data.stationLat,
|
|
||||||
0
|
|
||||||
)}
|
|
||||||
show={true}
|
show={true}
|
||||||
>
|
>
|
||||||
<EllipseGraphics
|
<EllipseGraphics
|
||||||
semiMinorAxis={new Cesium.CallbackProperty(changeOne, false)}
|
semiMinorAxis={new CallbackProperty(changeOne, false)}
|
||||||
semiMajorAxis={new Cesium.CallbackProperty(changeR2, false)}
|
semiMajorAxis={new CallbackProperty(changeR2, false)}
|
||||||
height={10}
|
height={10}
|
||||||
material={
|
material={
|
||||||
new Cesium.ImageMaterialProperty({
|
new ImageMaterialProperty({
|
||||||
image: data.imageUrl,
|
image: data.imageUrl,
|
||||||
repeat: Cesium.Cartesian2(1.0, 1.0),
|
repeat: Cartesian2(1.0, 1.0),
|
||||||
transparent: true,
|
transparent: true,
|
||||||
color: new Cesium.CallbackProperty(function () {
|
color: new CallbackProperty(function () {
|
||||||
var alp = 1 - r1 / data.maxR;
|
var alp = 1 - r1 / data.maxR;
|
||||||
return Cesium.Color[color].withAlpha(alp);
|
return Color[color].withAlpha(alp);
|
||||||
}, false),
|
}, false),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -89,26 +94,22 @@ function WavePoint({
|
|||||||
}
|
}
|
||||||
point2 = (
|
point2 = (
|
||||||
<Entity
|
<Entity
|
||||||
position={Cesium.Cartesian3.fromDegrees(
|
position={Cartesian3.fromDegrees(stationLon, stationLat, 0)}
|
||||||
data.stationLon,
|
|
||||||
data.stationLat,
|
|
||||||
0
|
|
||||||
)}
|
|
||||||
show={true}
|
show={true}
|
||||||
id={`wave-point-2-${stationLon}-${stationLat}`}
|
id={`wave-point-2-${stationLon}-${stationLat}`}
|
||||||
>
|
>
|
||||||
<EllipseGraphics
|
<EllipseGraphics
|
||||||
semiMinorAxis={new Cesium.CallbackProperty(changeTwo, false)}
|
semiMinorAxis={new CallbackProperty(changeTwo, false)}
|
||||||
semiMajorAxis={new Cesium.CallbackProperty(changeR12, false)}
|
semiMajorAxis={new CallbackProperty(changeR12, false)}
|
||||||
height={10}
|
height={10}
|
||||||
material={
|
material={
|
||||||
new Cesium.ImageMaterialProperty({
|
new ImageMaterialProperty({
|
||||||
image: data.imageUrl,
|
image: data.imageUrl,
|
||||||
repeat: Cesium.Cartesian2(1.0, 1.0),
|
repeat: Cartesian2(1.0, 1.0),
|
||||||
transparent: true,
|
transparent: true,
|
||||||
color: new Cesium.CallbackProperty(function () {
|
color: new CallbackProperty(function () {
|
||||||
var alp = 1 - r1 / data.maxR;
|
var alp = 1 - r1 / data.maxR;
|
||||||
return Cesium.Color.WHITE.withAlpha(alp);
|
return Color.WHITE.withAlpha(alp);
|
||||||
//entity的颜色透明 并不影响材质,并且 entity也会透明
|
//entity的颜色透明 并不影响材质,并且 entity也会透明
|
||||||
}, false),
|
}, false),
|
||||||
})
|
})
|
||||||
@ -122,6 +123,20 @@ function WavePoint({
|
|||||||
<Fragment>
|
<Fragment>
|
||||||
{point1}
|
{point1}
|
||||||
{point2}
|
{point2}
|
||||||
|
|
||||||
|
{labelText && (
|
||||||
|
<Entity position={Cartesian3.fromDegrees(stationLon, stationLat, 0)}>
|
||||||
|
<LabelGraphics
|
||||||
|
text={labelText}
|
||||||
|
font="24px Helvetica"
|
||||||
|
fillColor={Color.SKYBLUE}
|
||||||
|
outlineColor={Color.BLACK}
|
||||||
|
outlineWidth={2}
|
||||||
|
style={LabelStyle.FILL_AND_OUTLINE}
|
||||||
|
eyeOffset={new Cartesian2(0, 200000)}
|
||||||
|
/>{" "}
|
||||||
|
</Entity>
|
||||||
|
)}
|
||||||
</Fragment>
|
</Fragment>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
80
src/components/domain/Four/Labels.jsx
Normal file
80
src/components/domain/Four/Labels.jsx
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
import { Cartesian2, Cartesian3, Color, LabelStyle } from "cesium";
|
||||||
|
import { Fragment } from "react";
|
||||||
|
import { Entity, LabelGraphics } from "resium";
|
||||||
|
|
||||||
|
const points = [
|
||||||
|
{
|
||||||
|
position: [13, -70, 30, -67],
|
||||||
|
name: "sic_s",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
position: [93, 29, 99, 35],
|
||||||
|
name: "sc_tp",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
position: [68, 48, 76, 52],
|
||||||
|
name: "sc_ea",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
position: [150, 60, 160, 70],
|
||||||
|
name: "ts_ac",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
position: [130, 20, 140, 28],
|
||||||
|
name: "ts_wp",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
position: [150, 12, 175, 22],
|
||||||
|
name: "ts_np",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
position: [-110, 20, -95, 35],
|
||||||
|
name: "ts_arn",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
position: [10, -12, 45, -2],
|
||||||
|
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: [145, -30, 155, -20],
|
||||||
|
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" },
|
||||||
|
];
|
||||||
|
|
||||||
|
function Labels() {
|
||||||
|
return (
|
||||||
|
<Fragment>
|
||||||
|
{points.map((point, index) => {
|
||||||
|
const { position, name } = point;
|
||||||
|
const [x, y, z, m] = position;
|
||||||
|
const lon = (x + z) / 2;
|
||||||
|
const lat = (y + m) / 2;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Entity
|
||||||
|
key={`rectangle-label-${index}`}
|
||||||
|
position={Cartesian3.fromDegrees(lon, lat, 0)}
|
||||||
|
>
|
||||||
|
<LabelGraphics
|
||||||
|
text={name}
|
||||||
|
font="24px Helvetica"
|
||||||
|
fillColor={Color.SKYBLUE}
|
||||||
|
outlineColor={Color.BLACK}
|
||||||
|
outlineWidth={2}
|
||||||
|
style={LabelStyle.FILL_AND_OUTLINE}
|
||||||
|
eyeOffset={new Cartesian2(0, 0)}
|
||||||
|
/>
|
||||||
|
</Entity>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</Fragment>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Labels;
|
@ -1,21 +1,21 @@
|
|||||||
import { Rectangle, Color, Math as CesiumMath } from "cesium";
|
import { Rectangle, Color, Math as CesiumMath } from "cesium";
|
||||||
import { Entity, RectangleGraphics } from "resium";
|
import { Entity, RectangleGraphics } from "resium";
|
||||||
const points = [
|
const points = [
|
||||||
[13, -70, 30, -67],
|
[13, -70, 30, -67], //sic_s
|
||||||
[93, 29, 99, 35],
|
[93, 29, 99, 35], //sc_tp
|
||||||
[68, 48, 76, 52],
|
[68, 48, 76, 52], //sc_ea
|
||||||
[150, 60, 160, 70],
|
[150, 60, 160, 70], //ts_ac
|
||||||
[130, 20, 140, 28],
|
[130, 20, 140, 28], //wp
|
||||||
[150, 12, 175, 22],
|
[150, 12, 175, 22], //np
|
||||||
[-110, 20, -95, 35],
|
[-110, 20, -95, 35], //arn
|
||||||
[10, -12, 45, -2],
|
[10, -12, 45, -2], // af
|
||||||
[80, 10, 110, 20],
|
[80, 10, 110, 20], // io
|
||||||
[-150, -10, -40, 5],
|
[-150, -10, -40, 5], //ep
|
||||||
[65, -62, 90, -57],
|
[65, -62, 90, -57], // aa
|
||||||
[145, -30, 155, -20],
|
[145, -30, 155, -20], // ea
|
||||||
[165, -45, 180, -30],
|
[165, -45, 180, -30], // nz
|
||||||
[-140, -60, -110, -45],
|
[-140, -60, -110, -45], // sp
|
||||||
[-70, -78, -50, -70],
|
[-70, -78, -50, -70], // wd
|
||||||
];
|
];
|
||||||
export default function RectangleLayer() {
|
export default function RectangleLayer() {
|
||||||
return points.map((p, i) => (
|
return points.map((p, i) => (
|
||||||
|
@ -8,6 +8,7 @@ import ChartPanel from "./ChartPanel";
|
|||||||
import RectangleLayer from "./RectangleLayer";
|
import RectangleLayer from "./RectangleLayer";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import Legend from "./Legend";
|
import Legend from "./Legend";
|
||||||
|
import Labels from "./Labels";
|
||||||
|
|
||||||
export default function DomainFour() {
|
export default function DomainFour() {
|
||||||
const [show, setShow] = useState(false);
|
const [show, setShow] = useState(false);
|
||||||
@ -31,6 +32,7 @@ XGBoos是基于梯度提升决策树方法的分类和回归模型。 LightGBM
|
|||||||
<div className="bottom-panel">{show && <ChartPanel />}</div>
|
<div className="bottom-panel">{show && <ChartPanel />}</div>
|
||||||
</div>
|
</div>
|
||||||
{/* <Legend /> */}
|
{/* <Legend /> */}
|
||||||
|
<Labels />
|
||||||
<RectangleLayer />
|
<RectangleLayer />
|
||||||
</MapLayout>
|
</MapLayout>
|
||||||
);
|
);
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { useCallback, useState } from "react";
|
import { useCallback, useState } from "react";
|
||||||
import { Entity, LabelGraphics, EllipseGraphics, useCesium } from "resium";
|
import { Entity, EllipseGraphics, useCesium } from "resium";
|
||||||
import { Color, Cartesian3, LabelStyle } from "cesium";
|
import { Color, Cartesian3 } from "cesium";
|
||||||
import { useInterval } from "ahooks";
|
import { useInterval } from "ahooks";
|
||||||
|
|
||||||
function Barotropic() {
|
function Barotropic() {
|
||||||
@ -14,7 +14,7 @@ function Barotropic() {
|
|||||||
stopTime.secondsOfDay - currentTime.secondsOfDay
|
stopTime.secondsOfDay - currentTime.secondsOfDay
|
||||||
);
|
);
|
||||||
|
|
||||||
if (leftTime < 10) {
|
if (leftTime < 5) {
|
||||||
setShow(true);
|
setShow(true);
|
||||||
} else if (show) setShow(false);
|
} else if (show) setShow(false);
|
||||||
}, [show]);
|
}, [show]);
|
||||||
@ -34,16 +34,6 @@ function Barotropic() {
|
|||||||
extrudedHeight={1000000.0}
|
extrudedHeight={1000000.0}
|
||||||
rotation={0}
|
rotation={0}
|
||||||
/>
|
/>
|
||||||
<LabelGraphics
|
|
||||||
position={Cartesian3.fromDegrees(98, 48, 0)}
|
|
||||||
text={"barotropic"}
|
|
||||||
font="24px Helvetica"
|
|
||||||
fillColor={Color.SKYBLUE}
|
|
||||||
outlineColor={Color.BLACK}
|
|
||||||
outlineWidth={2}
|
|
||||||
style={LabelStyle.FILL_AND_OUTLINE}
|
|
||||||
eyeOffset={new Cesium.Cartesian2(0, 500000)}
|
|
||||||
/>
|
|
||||||
</Entity>
|
</Entity>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,75 +1,64 @@
|
|||||||
|
import { Cartesian3, EasingFunction, Math } from "cesium";
|
||||||
import { useDispatch } from "react-redux";
|
import { useDispatch } from "react-redux";
|
||||||
import { Camera, useCesium } from "resium";
|
import { useCesium } from "resium";
|
||||||
|
|
||||||
function CustomFlyTo() {
|
function CustomFlyTo() {
|
||||||
const { viewer } = useCesium();
|
const { viewer } = useCesium();
|
||||||
const { camera } = viewer;
|
const { camera } = viewer;
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
|
|
||||||
function cameraFlyToLine(adjustPitch) {
|
function cameraFlyToLine() {
|
||||||
|
const step1 = {
|
||||||
|
destination: Cartesian3.fromDegrees(-10, 50, 6000000),
|
||||||
|
duration: 5,
|
||||||
|
complete: () => {
|
||||||
|
camera.flyTo(step2);
|
||||||
|
},
|
||||||
|
easingFunction: EasingFunction.LINEAR_NONE,
|
||||||
|
};
|
||||||
|
|
||||||
|
const step2 = {
|
||||||
|
destination: Cartesian3.fromDegrees(35, 49, 10000000),
|
||||||
|
duration: 8,
|
||||||
|
complete: () => {
|
||||||
|
camera.flyTo(barotorpic);
|
||||||
|
},
|
||||||
|
easingFunction: EasingFunction.LINEAR_NONE,
|
||||||
|
};
|
||||||
|
|
||||||
// barotorpic
|
// barotorpic
|
||||||
const barotorpic = {
|
const barotorpic = {
|
||||||
destination: Cesium.Cartesian3.fromDegrees(80, 46, 15000000),
|
destination: Cartesian3.fromDegrees(75, 48, 15000000),
|
||||||
duration: 30,
|
duration: 7,
|
||||||
complete: () => {},
|
complete: () => {},
|
||||||
|
easingFunction: EasingFunction.LINEAR_NONE,
|
||||||
|
orientation: {
|
||||||
|
heading: 6.283,
|
||||||
|
pitch: -1.569,
|
||||||
|
roll: 0.45,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
// 俯视看箭头上升
|
// 俯视看箭头上升
|
||||||
const sideViewOptions = {
|
const sideViewOptions = {
|
||||||
destination: Cesium.Cartesian3.fromDegrees(-50, 46, 2000000),
|
destination: Cartesian3.fromDegrees(-50, 46, 2000000),
|
||||||
duration: 5,
|
duration: 5,
|
||||||
orientation: {
|
orientation: {
|
||||||
heading: Cesium.Math.toRadians(-15.0),
|
heading: Math.toRadians(-15.0),
|
||||||
pitch: -Cesium.Math.PI_OVER_FOUR,
|
pitch: -Math.PI_OVER_FOUR,
|
||||||
roll: 0.0,
|
roll: 0.0,
|
||||||
},
|
},
|
||||||
complete: () => {
|
complete: () => {
|
||||||
viewer.clock.shouldAnimate = true;
|
viewer.clock.shouldAnimate = true;
|
||||||
setTimeout(function () {
|
setTimeout(function () {
|
||||||
camera.flyTo(barotorpic);
|
camera.flyTo(step1);
|
||||||
}, 1000);
|
}, 5000);
|
||||||
dispatch.data.updateImageLayer({
|
dispatch.data.updateImageLayer({
|
||||||
labrador: true,
|
labrador: true,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
// 青藏高原
|
|
||||||
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 labrador = {
|
|
||||||
destination: Cesium.Cartesian3.fromDegrees(-55, 45, 1600000),
|
|
||||||
duration: 10,
|
|
||||||
orientation: {
|
|
||||||
heading: Cesium.Math.toRadians(-15.0),
|
|
||||||
pitch: -Cesium.Math.PI_OVER_FOUR,
|
|
||||||
roll: 0.0,
|
|
||||||
},
|
|
||||||
complete: function () {
|
|
||||||
setTimeout(function () {
|
|
||||||
camera.flyTo(plateauOptions);
|
|
||||||
}, 1000);
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
if (adjustPitch) {
|
|
||||||
plateauOptions.pitchAdjustHeight = 1000;
|
|
||||||
sideViewOptions.pitchAdjustHeight = 1000;
|
|
||||||
}
|
|
||||||
camera.flyTo(sideViewOptions);
|
camera.flyTo(sideViewOptions);
|
||||||
}
|
}
|
||||||
cameraFlyToLine();
|
cameraFlyToLine();
|
||||||
|
@ -1,6 +1,14 @@
|
|||||||
import { Fragment, useCallback } from "react";
|
import { Fragment, useCallback } from "react";
|
||||||
import { Entity, ModelGraphics, useCesium } from "resium";
|
import { Entity, LabelGraphics, ModelGraphics, useCesium } from "resium";
|
||||||
import arrowRound from "@/assets/arrow_round.glb";
|
import arrowRound from "@/assets/arrow_round.glb";
|
||||||
|
import {
|
||||||
|
CallbackProperty,
|
||||||
|
Cartesian2,
|
||||||
|
Cartesian3,
|
||||||
|
Color,
|
||||||
|
ColorBlendMode,
|
||||||
|
LabelStyle,
|
||||||
|
} from "cesium";
|
||||||
|
|
||||||
let totalSeconds = 60;
|
let totalSeconds = 60;
|
||||||
let numberOfSamples = 120;
|
let numberOfSamples = 120;
|
||||||
@ -44,18 +52,18 @@ function Cyclone() {
|
|||||||
return _time;
|
return _time;
|
||||||
}, [viewer]);
|
}, [viewer]);
|
||||||
|
|
||||||
const anticycloneColor = Cesium.Color.fromCssColorString("#f70000");
|
const anticycloneColor = Color.fromCssColorString("#f70000");
|
||||||
const cycloneColor = Cesium.Color.fromCssColorString("#00AC4D");
|
const cycloneColor = Color.fromCssColorString("#00AC4D");
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
<Entity
|
<Entity
|
||||||
id={"Anticyclone-1"}
|
id={"Anticyclone-1"}
|
||||||
position={
|
position={
|
||||||
new Cesium.CallbackProperty(function (time, result) {
|
new CallbackProperty(function (time, result) {
|
||||||
const passTime = getPassTime();
|
const passTime = getPassTime();
|
||||||
if (passTime < 10) return;
|
if (passTime < 5) return;
|
||||||
return Cesium.Cartesian3.fromDegrees(-62, 69, 1000000);
|
return Cartesian3.fromDegrees(-62, 69, 1000000);
|
||||||
}, true)
|
}, true)
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
@ -69,16 +77,26 @@ function Cyclone() {
|
|||||||
// }),
|
// }),
|
||||||
// }}
|
// }}
|
||||||
color={anticycloneColor}
|
color={anticycloneColor}
|
||||||
colorBlendMode={Cesium.ColorBlendMode.REPLACE}
|
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>
|
||||||
<Entity
|
<Entity
|
||||||
id={"Cyclone-1"}
|
id={"Cyclone-1"}
|
||||||
position={
|
position={
|
||||||
new Cesium.CallbackProperty(function (time, result) {
|
new CallbackProperty(function (time, result) {
|
||||||
const passTime = getPassTime();
|
const passTime = getPassTime();
|
||||||
if (passTime < 20) return;
|
if (passTime < 10) return;
|
||||||
return Cesium.Cartesian3.fromDegrees(-20, 55, 1000000);
|
return Cartesian3.fromDegrees(-20, 55, 1000000);
|
||||||
}, true)
|
}, true)
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
@ -86,16 +104,16 @@ function Cyclone() {
|
|||||||
uri={arrowRound}
|
uri={arrowRound}
|
||||||
minimumPixelSize={128}
|
minimumPixelSize={128}
|
||||||
color={cycloneColor}
|
color={cycloneColor}
|
||||||
colorBlendMode={Cesium.ColorBlendMode.REPLACE}
|
colorBlendMode={ColorBlendMode.REPLACE}
|
||||||
/>
|
/>
|
||||||
</Entity>
|
</Entity>
|
||||||
<Entity
|
<Entity
|
||||||
id={"Anticyclone-2"}
|
id={"Anticyclone-2"}
|
||||||
position={
|
position={
|
||||||
new Cesium.CallbackProperty(function (time, result) {
|
new CallbackProperty(function (time, result) {
|
||||||
const passTime = getPassTime();
|
const passTime = getPassTime();
|
||||||
if (passTime < 30) return;
|
if (passTime < 15) return;
|
||||||
return Cesium.Cartesian3.fromDegrees(29, 49, 1000000);
|
return Cartesian3.fromDegrees(29, 49, 1000000);
|
||||||
}, true)
|
}, true)
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
@ -103,16 +121,16 @@ function Cyclone() {
|
|||||||
uri={arrowRound}
|
uri={arrowRound}
|
||||||
minimumPixelSize={128}
|
minimumPixelSize={128}
|
||||||
color={anticycloneColor}
|
color={anticycloneColor}
|
||||||
colorBlendMode={Cesium.ColorBlendMode.REPLACE}
|
colorBlendMode={ColorBlendMode.REPLACE}
|
||||||
/>
|
/>
|
||||||
</Entity>
|
</Entity>
|
||||||
<Entity
|
<Entity
|
||||||
id={"Cyclone-2"}
|
id={"Cyclone-2"}
|
||||||
position={
|
position={
|
||||||
new Cesium.CallbackProperty(function (time, result) {
|
new CallbackProperty(function (time, result) {
|
||||||
const passTime = getPassTime();
|
const passTime = getPassTime();
|
||||||
if (passTime < 40) return;
|
if (passTime < 20) return;
|
||||||
return Cesium.Cartesian3.fromDegrees(62, 45, 1000000);
|
return Cartesian3.fromDegrees(62, 45, 1000000);
|
||||||
}, true)
|
}, true)
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
@ -120,16 +138,16 @@ function Cyclone() {
|
|||||||
uri={arrowRound}
|
uri={arrowRound}
|
||||||
minimumPixelSize={128}
|
minimumPixelSize={128}
|
||||||
color={cycloneColor}
|
color={cycloneColor}
|
||||||
colorBlendMode={Cesium.ColorBlendMode.REPLACE}
|
colorBlendMode={ColorBlendMode.REPLACE}
|
||||||
/>
|
/>
|
||||||
</Entity>
|
</Entity>
|
||||||
<Entity
|
<Entity
|
||||||
id={"Anticyclone-3"}
|
id={"Anticyclone-3"}
|
||||||
position={
|
position={
|
||||||
new Cesium.CallbackProperty(function (time, result) {
|
new CallbackProperty(function (time, result) {
|
||||||
const passTime = getPassTime();
|
const passTime = getPassTime();
|
||||||
if (passTime < 50) return;
|
if (passTime < 25) return;
|
||||||
return Cesium.Cartesian3.fromDegrees(98, 48, 1000000);
|
return Cartesian3.fromDegrees(98, 48, 1000000);
|
||||||
}, true)
|
}, true)
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
@ -137,16 +155,16 @@ function Cyclone() {
|
|||||||
uri={arrowRound}
|
uri={arrowRound}
|
||||||
minimumPixelSize={128}
|
minimumPixelSize={128}
|
||||||
color={anticycloneColor}
|
color={anticycloneColor}
|
||||||
colorBlendMode={Cesium.ColorBlendMode.REPLACE}
|
colorBlendMode={ColorBlendMode.REPLACE}
|
||||||
/>
|
/>
|
||||||
</Entity>
|
</Entity>
|
||||||
<Entity
|
<Entity
|
||||||
id={"Anticyclone-4"}
|
id={"Anticyclone-4"}
|
||||||
position={
|
position={
|
||||||
new Cesium.CallbackProperty(function (time, result) {
|
new CallbackProperty(function (time, result) {
|
||||||
const passTime = getPassTime();
|
const passTime = getPassTime();
|
||||||
if (passTime < 50) return;
|
if (passTime < 25) return;
|
||||||
return Cesium.Cartesian3.fromDegrees(98, 48, 0);
|
return Cartesian3.fromDegrees(98, 48, 0);
|
||||||
}, true)
|
}, true)
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
@ -154,7 +172,7 @@ function Cyclone() {
|
|||||||
uri={arrowRound}
|
uri={arrowRound}
|
||||||
minimumPixelSize={128}
|
minimumPixelSize={128}
|
||||||
color={anticycloneColor}
|
color={anticycloneColor}
|
||||||
colorBlendMode={Cesium.ColorBlendMode.REPLACE}
|
colorBlendMode={ColorBlendMode.REPLACE}
|
||||||
/>
|
/>
|
||||||
</Entity>
|
</Entity>
|
||||||
</Fragment>
|
</Fragment>
|
||||||
|
55
src/components/domain/One/JJAImageLayer.jsx
Normal file
55
src/components/domain/One/JJAImageLayer.jsx
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
import { Fragment, useMemo } from "react";
|
||||||
|
import { ImageryLayer } from "resium";
|
||||||
|
import { WebMapServiceImageryProvider } from "cesium";
|
||||||
|
|
||||||
|
const url = "http://analysis.tpdc.ac.cn/gs/geoserver/phitrellis/wms";
|
||||||
|
|
||||||
|
const name1 = "phitrellis:4_1_sst_JJA_G_dif";
|
||||||
|
const name2 = "phitrellis:4_1_t2m_JJA_TP_dif ";
|
||||||
|
|
||||||
|
function JJAImageLayer() {
|
||||||
|
const tempProvider1 = useMemo(
|
||||||
|
() =>
|
||||||
|
new WebMapServiceImageryProvider({
|
||||||
|
url: url,
|
||||||
|
layers: name1,
|
||||||
|
parameters: {
|
||||||
|
service: "WMS",
|
||||||
|
format: "image/png",
|
||||||
|
transparent: true,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
[name1, url]
|
||||||
|
);
|
||||||
|
|
||||||
|
const tempProvider2 = useMemo(
|
||||||
|
() =>
|
||||||
|
new WebMapServiceImageryProvider({
|
||||||
|
url: url,
|
||||||
|
layers: name2,
|
||||||
|
parameters: {
|
||||||
|
service: "WMS",
|
||||||
|
format: "image/png",
|
||||||
|
transparent: true,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
[name2, url]
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Fragment>
|
||||||
|
<ImageryLayer
|
||||||
|
key={`ImageryLayer-sst`}
|
||||||
|
imageryProvider={tempProvider1}
|
||||||
|
show={true}
|
||||||
|
/>
|
||||||
|
<ImageryLayer
|
||||||
|
key={`ImageryLayer-t2m`}
|
||||||
|
imageryProvider={tempProvider2}
|
||||||
|
show={true}
|
||||||
|
/>
|
||||||
|
</Fragment>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default JJAImageLayer;
|
63
src/components/domain/One/Labels.jsx
Normal file
63
src/components/domain/One/Labels.jsx
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
import { Entity, LabelGraphics, useCesium } from "resium";
|
||||||
|
import { Cartesian2, Cartesian3, Color, LabelStyle } from "cesium";
|
||||||
|
import { Fragment, useCallback, useState } from "react";
|
||||||
|
import { useInterval } from "ahooks";
|
||||||
|
|
||||||
|
function Labels() {
|
||||||
|
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 (
|
||||||
|
<Fragment>
|
||||||
|
<Entity 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>
|
||||||
|
<Entity position={Cartesian3.fromDegrees(-55, 45, 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>
|
||||||
|
<Entity show={show} position={Cartesian3.fromDegrees(98, 48, 0)}>
|
||||||
|
<LabelGraphics
|
||||||
|
text={"barotropic"}
|
||||||
|
font="24px Helvetica"
|
||||||
|
fillColor={Color.SKYBLUE}
|
||||||
|
outlineColor={Color.BLACK}
|
||||||
|
outlineWidth={2}
|
||||||
|
style={LabelStyle.FILL_AND_OUTLINE}
|
||||||
|
eyeOffset={new Cartesian2(0, 1200000)}
|
||||||
|
/>
|
||||||
|
</Entity>
|
||||||
|
</Fragment>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Labels;
|
@ -1,67 +0,0 @@
|
|||||||
import { useEffect, useMemo, useState } from "react";
|
|
||||||
import { ImageryLayer, useCesium } from "resium";
|
|
||||||
import { WebMapServiceImageryProvider } from "cesium";
|
|
||||||
import { useInterval } from "ahooks";
|
|
||||||
import { useDispatch, useSelector } from "react-redux";
|
|
||||||
|
|
||||||
const url = "http://analysis.tpdc.ac.cn/gs/geoserver/phitrellis/wms";
|
|
||||||
const nameList = [
|
|
||||||
1980, 1981, 1982, 1983, 1984, 1985, 1986, 1987, 1988, 1989, 1990, 1991, 1992,
|
|
||||||
1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
|
|
||||||
2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017,
|
|
||||||
].map((item) => "phitrellis:4_1_la_" + item);
|
|
||||||
|
|
||||||
function LabradorImageLayer() {
|
|
||||||
const dispatch = useDispatch();
|
|
||||||
const { viewer } = useCesium();
|
|
||||||
const { imageLayer } = useSelector((state) => state.data);
|
|
||||||
const [delay, setDelay] = useState(undefined);
|
|
||||||
const [index, setIndex] = useState(0);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
const { labrador } = imageLayer;
|
|
||||||
if (!!labrador) {
|
|
||||||
setDelay((60 / nameList.length) * 1000);
|
|
||||||
setIndex(0);
|
|
||||||
}
|
|
||||||
}, [imageLayer]);
|
|
||||||
|
|
||||||
const layers = nameList.map((name, index) => {
|
|
||||||
const tempProvider = useMemo(
|
|
||||||
() =>
|
|
||||||
new WebMapServiceImageryProvider({
|
|
||||||
url: url,
|
|
||||||
layers: name,
|
|
||||||
parameters: {
|
|
||||||
service: "WMS",
|
|
||||||
format: "image/png",
|
|
||||||
transparent: true,
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
[name, url]
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<ImageryLayer
|
|
||||||
key={`ImageryLayer-${index}`}
|
|
||||||
imageryProvider={tempProvider}
|
|
||||||
show={true}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
useInterval(() => {
|
|
||||||
setIndex((index) => index + 1);
|
|
||||||
|
|
||||||
if (index >= nameList.length) {
|
|
||||||
setIndex(0);
|
|
||||||
setDelay((60 / nameList.length) * 1000);
|
|
||||||
}
|
|
||||||
}, delay);
|
|
||||||
|
|
||||||
if (!viewer.clock?.shouldAnimate) return;
|
|
||||||
|
|
||||||
return layers[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
export default LabradorImageLayer;
|
|
@ -36,7 +36,7 @@ const colorBar = [
|
|||||||
function Legend() {
|
function Legend() {
|
||||||
return (
|
return (
|
||||||
<div className="legend">
|
<div className="legend">
|
||||||
<div className="legend-title">拉布拉多海海表温度夏季年代际异常值</div>
|
<div className="legend-title">夏季温度年代际异常值</div>
|
||||||
<div className="colorbar">
|
<div className="colorbar">
|
||||||
{colorBar.map((color, index) => {
|
{colorBar.map((color, index) => {
|
||||||
return (
|
return (
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { useCallback, useState } from "react";
|
import { useCallback, useState } from "react";
|
||||||
import { Entity, PolygonGraphics, useCesium } from "resium";
|
import { Entity, PolygonGraphics, useCesium } from "resium";
|
||||||
import { useInterval } from "ahooks";
|
import { useInterval } from "ahooks";
|
||||||
|
import { Cartesian3, Color } from "cesium";
|
||||||
|
|
||||||
function PlateauPolygon() {
|
function PlateauPolygon() {
|
||||||
const { viewer } = useCesium();
|
const { viewer } = useCesium();
|
||||||
@ -22,11 +23,11 @@ function PlateauPolygon() {
|
|||||||
return (
|
return (
|
||||||
<Entity id="plateau" show={show}>
|
<Entity id="plateau" show={show}>
|
||||||
<PolygonGraphics
|
<PolygonGraphics
|
||||||
hierarchy={Cesium.Cartesian3.fromDegreesArray([
|
hierarchy={Cartesian3.fromDegreesArray([
|
||||||
// 85, 30, 91, 30, 91, 35, 85, 35,
|
// 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,
|
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)}
|
material={new Color(1, 0, 0, 0.1)}
|
||||||
/>
|
/>
|
||||||
</Entity>
|
</Entity>
|
||||||
);
|
);
|
||||||
|
@ -1,14 +1,25 @@
|
|||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { Entity, PointGraphics, useCesium } from "resium";
|
import { Entity, PointGraphics, useCesium } from "resium";
|
||||||
import { useInterval } from "ahooks";
|
import { useInterval } from "ahooks";
|
||||||
|
import {
|
||||||
|
Cartesian3,
|
||||||
|
Color,
|
||||||
|
JulianDate,
|
||||||
|
LagrangePolynomialApproximation,
|
||||||
|
PolylineDashMaterialProperty,
|
||||||
|
SampledPositionProperty,
|
||||||
|
TimeInterval,
|
||||||
|
TimeIntervalCollection,
|
||||||
|
VelocityOrientationProperty,
|
||||||
|
} from "cesium";
|
||||||
|
|
||||||
// 从拉布拉多海到青藏高原
|
// 从拉布拉多海到青藏高原
|
||||||
const dataLabToQTP = [
|
const dataLabToQTP = [
|
||||||
{ longitude: -62, latitude: 69, height: 1000000, time: 10 },
|
{ longitude: -62, latitude: 69, height: 1000000, time: 5 },
|
||||||
{ longitude: -20, latitude: 55, height: 1000000, time: 20 },
|
{ longitude: -20, latitude: 55, height: 1000000, time: 10 },
|
||||||
{ longitude: 29, latitude: 49, height: 1000000, time: 30 },
|
{ longitude: 29, latitude: 49, height: 1000000, time: 15 },
|
||||||
{ longitude: 62, latitude: 45, height: 1000000, time: 40 },
|
{ longitude: 62, latitude: 45, height: 1000000, time: 20 },
|
||||||
{ longitude: 98, latitude: 48, height: 1000000, time: 50 },
|
{ longitude: 98, latitude: 48, height: 1000000, time: 25 },
|
||||||
];
|
];
|
||||||
|
|
||||||
function Point() {
|
function Point() {
|
||||||
@ -18,9 +29,9 @@ function Point() {
|
|||||||
const start = viewer.clock.startTime;
|
const start = viewer.clock.startTime;
|
||||||
const stop = viewer.clock.stopTime;
|
const stop = viewer.clock.stopTime;
|
||||||
|
|
||||||
const pathMaterial = new Cesium.PolylineDashMaterialProperty({
|
const pathMaterial = new PolylineDashMaterialProperty({
|
||||||
dashLength: 20,
|
dashLength: 20,
|
||||||
color: new Cesium.Color(4 / 255, 251 / 255, 253 / 255),
|
color: new Color(4 / 255, 251 / 255, 253 / 255),
|
||||||
});
|
});
|
||||||
|
|
||||||
useInterval(() => {
|
useInterval(() => {
|
||||||
@ -33,14 +44,10 @@ function Point() {
|
|||||||
* {SampledPositionProperty|*}
|
* {SampledPositionProperty|*}
|
||||||
*/
|
*/
|
||||||
function createProperty(source) {
|
function createProperty(source) {
|
||||||
let property = new Cesium.SampledPositionProperty();
|
let property = new SampledPositionProperty();
|
||||||
for (let i = 0; i < source.length; i++) {
|
for (let i = 0; i < source.length; i++) {
|
||||||
let time = Cesium.JulianDate.addSeconds(
|
let time = JulianDate.addSeconds(start, source[i].time, new JulianDate());
|
||||||
start,
|
let position = Cartesian3.fromDegrees(
|
||||||
source[i].time,
|
|
||||||
new Cesium.JulianDate()
|
|
||||||
);
|
|
||||||
let position = Cesium.Cartesian3.fromDegrees(
|
|
||||||
source[i].longitude,
|
source[i].longitude,
|
||||||
source[i].latitude,
|
source[i].latitude,
|
||||||
source[i].height
|
source[i].height
|
||||||
@ -50,7 +57,7 @@ function Point() {
|
|||||||
}
|
}
|
||||||
property.setInterpolationOptions({
|
property.setInterpolationOptions({
|
||||||
interpolationDegree: 10,
|
interpolationDegree: 10,
|
||||||
interpolationAlgorithm: Cesium.LagrangePolynomialApproximation,
|
interpolationAlgorithm: LagrangePolynomialApproximation,
|
||||||
});
|
});
|
||||||
|
|
||||||
return property;
|
return property;
|
||||||
@ -63,14 +70,14 @@ function Point() {
|
|||||||
id={"point"}
|
id={"point"}
|
||||||
position={property}
|
position={property}
|
||||||
availability={
|
availability={
|
||||||
new Cesium.TimeIntervalCollection([
|
new TimeIntervalCollection([
|
||||||
new Cesium.TimeInterval({
|
new TimeInterval({
|
||||||
start: start,
|
start: start,
|
||||||
stop: stop,
|
stop: stop,
|
||||||
}),
|
}),
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
orientation={new Cesium.VelocityOrientationProperty(property)}
|
orientation={new VelocityOrientationProperty(property)}
|
||||||
path={{
|
path={{
|
||||||
resolution: 1,
|
resolution: 1,
|
||||||
material: pathMaterial,
|
material: pathMaterial,
|
||||||
@ -82,9 +89,9 @@ function Point() {
|
|||||||
>
|
>
|
||||||
<PointGraphics
|
<PointGraphics
|
||||||
show={true}
|
show={true}
|
||||||
color={Cesium.Color.SKYBLUE}
|
color={Color.SKYBLUE}
|
||||||
pixelSize={10}
|
pixelSize={10}
|
||||||
outlineColor={Cesium.Color.YELLOW}
|
outlineColor={Color.YELLOW}
|
||||||
outlineWidth={3}
|
outlineWidth={3}
|
||||||
/>
|
/>
|
||||||
</Entity>
|
</Entity>
|
||||||
|
@ -1,65 +0,0 @@
|
|||||||
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 nameList = [
|
|
||||||
1980, 1981, 1982, 1983, 1984, 1985, 1986, 1987, 1988, 1989, 1990, 1991, 1992,
|
|
||||||
1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
|
|
||||||
2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017,
|
|
||||||
].map((item) => "phitrellis:4_1_tp_" + item);
|
|
||||||
|
|
||||||
function TibetImageLayer() {
|
|
||||||
const { viewer } = useCesium();
|
|
||||||
const { imageLayer } = useSelector((state) => state.data);
|
|
||||||
const [delay, setDelay] = useState(undefined);
|
|
||||||
const [index, setIndex] = useState(0);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
const { labrador } = imageLayer;
|
|
||||||
if (!!labrador) {
|
|
||||||
setDelay((60 / nameList.length) * 1000);
|
|
||||||
setIndex(0);
|
|
||||||
}
|
|
||||||
}, [imageLayer]);
|
|
||||||
|
|
||||||
const layers = nameList.map((name, index) => {
|
|
||||||
const tempProvider = useMemo(
|
|
||||||
() =>
|
|
||||||
new WebMapServiceImageryProvider({
|
|
||||||
url: url,
|
|
||||||
layers: name,
|
|
||||||
parameters: {
|
|
||||||
service: "WMS",
|
|
||||||
format: "image/png",
|
|
||||||
transparent: true,
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
[name, url]
|
|
||||||
);
|
|
||||||
return (
|
|
||||||
<ImageryLayer
|
|
||||||
key={`ImageryLayer-${index}`}
|
|
||||||
imageryProvider={tempProvider}
|
|
||||||
show={true}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
useInterval(() => {
|
|
||||||
setIndex((index) => index + 1);
|
|
||||||
|
|
||||||
if (index >= nameList.length) {
|
|
||||||
setIndex(0);
|
|
||||||
setDelay((60 / nameList.length) * 1000);
|
|
||||||
}
|
|
||||||
}, delay);
|
|
||||||
|
|
||||||
if (!viewer.clock?.shouldAnimate) return;
|
|
||||||
|
|
||||||
return layers[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
export default TibetImageLayer;
|
|
@ -1,5 +1,11 @@
|
|||||||
import { Entity, PolylineGraphics, useCesium } from "resium";
|
import { Entity, PolylineGraphics, useCesium } from "resium";
|
||||||
import { Cartesian3 } from "cesium";
|
import {
|
||||||
|
CallbackProperty,
|
||||||
|
Cartesian3,
|
||||||
|
Color,
|
||||||
|
Ellipsoid,
|
||||||
|
PolylineArrowMaterialProperty,
|
||||||
|
} from "cesium";
|
||||||
import { min } from "lodash-es";
|
import { min } from "lodash-es";
|
||||||
|
|
||||||
function Updraft() {
|
function Updraft() {
|
||||||
@ -12,19 +18,19 @@ function Updraft() {
|
|||||||
>
|
>
|
||||||
<PolylineGraphics
|
<PolylineGraphics
|
||||||
positions={
|
positions={
|
||||||
new Cesium.CallbackProperty(function (time, result) {
|
new CallbackProperty(function (time, result) {
|
||||||
const { currentTime, startTime } = viewer.clock;
|
const { currentTime, startTime } = viewer.clock;
|
||||||
const passTime = currentTime.secondsOfDay - startTime.secondsOfDay;
|
const passTime = currentTime.secondsOfDay - startTime.secondsOfDay;
|
||||||
const height = 100000 * passTime;
|
const height = 200000 * passTime;
|
||||||
return Cesium.Cartesian3.fromDegreesArrayHeights(
|
return Cartesian3.fromDegreesArrayHeights(
|
||||||
[-62, 69, 0, -62, 69, min([height, 1000000])],
|
[-62, 69, 0, -62, 69, min([height, 1000000])],
|
||||||
Cesium.Ellipsoid.WGS84,
|
Ellipsoid.WGS84,
|
||||||
result
|
result
|
||||||
);
|
);
|
||||||
}, false)
|
}, false)
|
||||||
}
|
}
|
||||||
width={30}
|
width={30}
|
||||||
material={new Cesium.PolylineArrowMaterialProperty(Cesium.Color.RED)}
|
material={new PolylineArrowMaterialProperty(Color.RED)}
|
||||||
/>
|
/>
|
||||||
</Entity>
|
</Entity>
|
||||||
);
|
);
|
||||||
|
@ -1,3 +1,9 @@
|
|||||||
|
import {
|
||||||
|
Cartesian3,
|
||||||
|
Color,
|
||||||
|
PolylineArrowMaterialProperty,
|
||||||
|
PolylineDashMaterialProperty,
|
||||||
|
} from "cesium";
|
||||||
import { Fragment } from "react";
|
import { Fragment } from "react";
|
||||||
import { Entity, PolylineGraphics } from "resium";
|
import { Entity, PolylineGraphics } from "resium";
|
||||||
|
|
||||||
@ -6,13 +12,13 @@ function WaterVaporPath() {
|
|||||||
<Fragment>
|
<Fragment>
|
||||||
<Entity>
|
<Entity>
|
||||||
<PolylineGraphics
|
<PolylineGraphics
|
||||||
positions={Cesium.Cartesian3.fromDegreesArrayHeights([
|
positions={Cartesian3.fromDegreesArrayHeights([
|
||||||
103, 46, 0, 93, 38, 0,
|
103, 46, 0, 93, 38, 0,
|
||||||
])}
|
])}
|
||||||
width={10}
|
width={10}
|
||||||
material={
|
material={
|
||||||
new Cesium.PolylineDashMaterialProperty({
|
new PolylineDashMaterialProperty({
|
||||||
color: Cesium.Color.fromCssColorString("#406ec5"),
|
color: Color.fromCssColorString("#406ec5"),
|
||||||
dashLength: 20,
|
dashLength: 20,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -20,13 +26,13 @@ function WaterVaporPath() {
|
|||||||
</Entity>
|
</Entity>
|
||||||
<Entity>
|
<Entity>
|
||||||
<PolylineGraphics
|
<PolylineGraphics
|
||||||
positions={Cesium.Cartesian3.fromDegreesArrayHeights([
|
positions={Cartesian3.fromDegreesArrayHeights([
|
||||||
93, 38, 0, 93, 37.9, 0,
|
93, 38, 0, 93, 37.9, 0,
|
||||||
])}
|
])}
|
||||||
width={30}
|
width={30}
|
||||||
material={
|
material={
|
||||||
new Cesium.PolylineArrowMaterialProperty(
|
new PolylineArrowMaterialProperty(
|
||||||
Cesium.Color.fromCssColorString("#406ec5")
|
Color.fromCssColorString("#406ec5")
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
@ -10,10 +10,10 @@ import Barotropic from "./Barotorpic";
|
|||||||
import WavePoints from "./WavePoints";
|
import WavePoints from "./WavePoints";
|
||||||
import Updraft from "./Updraft";
|
import Updraft from "./Updraft";
|
||||||
import Legend from "./Legend";
|
import Legend from "./Legend";
|
||||||
import LabradorImageLayer from "./LabradorImageLayer";
|
import JJAImageLayer from "./JJAImageLayer";
|
||||||
import TibetImageLayer from "./TibetImageLayer";
|
|
||||||
import ChartPanel from "./ChartPanel";
|
import ChartPanel from "./ChartPanel";
|
||||||
import EntityLegend from "./EntityLegend";
|
import EntityLegend from "./EntityLegend";
|
||||||
|
import Labels from "./Labels";
|
||||||
// import WaterVaporPath from "./WaterVaporPath";
|
// import WaterVaporPath from "./WaterVaporPath";
|
||||||
|
|
||||||
export default function DomainOne() {
|
export default function DomainOne() {
|
||||||
@ -39,9 +39,9 @@ export default function DomainOne() {
|
|||||||
{/* <WaterVaporPath /> */}
|
{/* <WaterVaporPath /> */}
|
||||||
<Updraft />
|
<Updraft />
|
||||||
<EntityLegend />
|
<EntityLegend />
|
||||||
|
<Labels />
|
||||||
<Legend />
|
<Legend />
|
||||||
<LabradorImageLayer />
|
<JJAImageLayer />
|
||||||
<TibetImageLayer />
|
|
||||||
</MapLayout>
|
</MapLayout>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -83,7 +83,7 @@ function ChartPanel() {
|
|||||||
data: ["南极", "北极", "青藏高原"],
|
data: ["南极", "北极", "青藏高原"],
|
||||||
textStyle: { color: "#04fbfd", cursor: "point" },
|
textStyle: { color: "#04fbfd", cursor: "point" },
|
||||||
},
|
},
|
||||||
animationDuration: years.length * 500,
|
animationDuration: 10 * 1000,
|
||||||
animationEasing: "cubicInOut",
|
animationEasing: "cubicInOut",
|
||||||
grid: {
|
grid: {
|
||||||
left: "3%",
|
left: "3%",
|
||||||
|
@ -21,9 +21,9 @@ const colorBar = [
|
|||||||
"#FFB1B1",
|
"#FFB1B1",
|
||||||
];
|
];
|
||||||
|
|
||||||
function Legend() {
|
function Legend({ style }) {
|
||||||
return (
|
return (
|
||||||
<div className={styles.legend}>
|
<div className={styles.legend} style={{ ...style }}>
|
||||||
<div className="legend-title"></div>
|
<div className="legend-title"></div>
|
||||||
<div className="colorbar">
|
<div className="colorbar">
|
||||||
{colorBar.map((color, index) => {
|
{colorBar.map((color, index) => {
|
||||||
|
31
src/components/domain/Three/SceneOne/ViewerOne.jsx
Normal file
31
src/components/domain/Three/SceneOne/ViewerOne.jsx
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
import { CameraFlyTo } from "resium";
|
||||||
|
import { Cartesian3 } from "cesium";
|
||||||
|
import MapLayout from "@/components/map/Layout";
|
||||||
|
import CustomToolbar from "@/components/common/CustomToolbar";
|
||||||
|
import CustomClock from "@/components/common/CustomClock";
|
||||||
|
import LandImageLayer from "../LandImageLayer";
|
||||||
|
import WavePoint from "@/components/common/WavePoint";
|
||||||
|
|
||||||
|
function ViewerOne({ children }) {
|
||||||
|
return (
|
||||||
|
<div className="domain-viewer">
|
||||||
|
<MapLayout>
|
||||||
|
<div className="title" style={{ zIndex: 999 }}>
|
||||||
|
两极协同—连接南极和北极的热带大西洋经向模的媒介作用
|
||||||
|
</div>
|
||||||
|
<CustomToolbar />
|
||||||
|
<CustomClock />
|
||||||
|
<CameraFlyTo
|
||||||
|
duration={5}
|
||||||
|
destination={Cartesian3.fromDegrees(80, -85, 10000000)}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<WavePoint stationLon={88} stationLat={-85} labelText={"南极"} />
|
||||||
|
<LandImageLayer />
|
||||||
|
{children}
|
||||||
|
</MapLayout>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ViewerOne;
|
21
src/components/domain/Three/SceneOne/ViewerThree.jsx
Normal file
21
src/components/domain/Three/SceneOne/ViewerThree.jsx
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
import { CameraFlyTo } from "resium";
|
||||||
|
import { Cartesian3 } from "cesium";
|
||||||
|
import MapLayout from "@/components/map/Layout";
|
||||||
|
import WavePoint from "@/components/common/WavePoint";
|
||||||
|
|
||||||
|
function ViewerThree({ children }) {
|
||||||
|
return (
|
||||||
|
<div className="domain-viewer">
|
||||||
|
<MapLayout>
|
||||||
|
<CameraFlyTo
|
||||||
|
duration={5}
|
||||||
|
destination={Cartesian3.fromDegrees(100, 33, 10000000)}
|
||||||
|
/>
|
||||||
|
<WavePoint stationLon={88} stationLat={33} labelText={"青藏高原"} />
|
||||||
|
{children}
|
||||||
|
</MapLayout>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ViewerThree;
|
28
src/components/domain/Three/SceneOne/ViewerTwo.jsx
Normal file
28
src/components/domain/Three/SceneOne/ViewerTwo.jsx
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
import { CameraFlyTo } from "resium";
|
||||||
|
import { Cartesian3 } from "cesium";
|
||||||
|
import MapLayout from "@/components/map/Layout";
|
||||||
|
import OceanImageLayer from "../OceanImageLayer";
|
||||||
|
import WavePoint from "@/components/common/WavePoint";
|
||||||
|
|
||||||
|
function ViewerTwo({ children }) {
|
||||||
|
return (
|
||||||
|
<div className="domain-viewer">
|
||||||
|
<MapLayout>
|
||||||
|
<OceanImageLayer />
|
||||||
|
<CameraFlyTo
|
||||||
|
duration={5}
|
||||||
|
destination={Cartesian3.fromDegrees(0, 88, 10000000)}
|
||||||
|
/>
|
||||||
|
<WavePoint
|
||||||
|
color={"WHITE"}
|
||||||
|
stationLon={0}
|
||||||
|
stationLat={87}
|
||||||
|
labelText={"北极"}
|
||||||
|
/>
|
||||||
|
{children}
|
||||||
|
</MapLayout>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ViewerTwo;
|
28
src/components/domain/Three/SceneOne/index.jsx
Normal file
28
src/components/domain/Three/SceneOne/index.jsx
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
import TextInfoPanel from "@/components/common/TextInfoPanel";
|
||||||
|
import ChartPanel from "../ChartPanel";
|
||||||
|
import Legend from "../Legend";
|
||||||
|
import ViewerOne from "./ViewerOne";
|
||||||
|
import ViewerTwo from "./ViewerTwo";
|
||||||
|
import ViewerThree from "./ViewerThree";
|
||||||
|
import styles from "./index.module.less";
|
||||||
|
|
||||||
|
function SceneOne() {
|
||||||
|
return (
|
||||||
|
<div className={styles.sceneOne}>
|
||||||
|
<div className="domain-viewers">
|
||||||
|
<ViewerOne />
|
||||||
|
<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>
|
||||||
|
<Legend />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default SceneOne;
|
21
src/components/domain/Three/SceneOne/index.module.less
Normal file
21
src/components/domain/Three/SceneOne/index.module.less
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
.sceneOne :global {
|
||||||
|
display: flex;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background-color: gray;
|
||||||
|
|
||||||
|
.domain-viewers {
|
||||||
|
width: 100%;
|
||||||
|
height: calc(100% - 250px);
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
.domain-viewer {
|
||||||
|
flex: 1;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
.title {
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
15
src/components/domain/Three/SceneSwitch.jsx
Normal file
15
src/components/domain/Three/SceneSwitch.jsx
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import { Button } from "antd";
|
||||||
|
|
||||||
|
function SceneSwitch({ scene, setScene }) {
|
||||||
|
const switchHandler = () => {
|
||||||
|
setScene(scene === 1 ? 2 : 1);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Button className="scene-switch" type="primary" onClick={switchHandler}>
|
||||||
|
切换到场景{scene === 1 ? "二" : "一"}
|
||||||
|
</Button>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default SceneSwitch;
|
110
src/components/domain/Three/SceneTwo/SceneChartPanel.jsx
Normal file
110
src/components/domain/Three/SceneTwo/SceneChartPanel.jsx
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
import ReactECharts from "echarts-for-react";
|
||||||
|
|
||||||
|
const years = [];
|
||||||
|
|
||||||
|
for (let year = 1950; year <= 2020; year++) {
|
||||||
|
years.push(year);
|
||||||
|
}
|
||||||
|
|
||||||
|
const SATData = [];
|
||||||
|
const SSTData = [];
|
||||||
|
|
||||||
|
function SceneChartPanel() {
|
||||||
|
const option = {
|
||||||
|
title: {
|
||||||
|
// text: "Stacked Line",
|
||||||
|
},
|
||||||
|
tooltip: {
|
||||||
|
trigger: "axis",
|
||||||
|
},
|
||||||
|
legend: {
|
||||||
|
data: ["SAT_SVD1", "SST_SVD1"],
|
||||||
|
textStyle: { color: "#04fbfd", cursor: "point" },
|
||||||
|
},
|
||||||
|
animationDuration: 10 * 1000,
|
||||||
|
animationEasing: "cubicInOut",
|
||||||
|
grid: {
|
||||||
|
left: "3%",
|
||||||
|
right: "4%",
|
||||||
|
bottom: "3%",
|
||||||
|
containLabel: true,
|
||||||
|
},
|
||||||
|
xAxis: {
|
||||||
|
type: "category",
|
||||||
|
boundaryGap: false,
|
||||||
|
data: years,
|
||||||
|
axisLine: {
|
||||||
|
onZero: false,
|
||||||
|
symbol: ["none", "arrow"],
|
||||||
|
symbolOffser: [0, 10],
|
||||||
|
lineStyle: {
|
||||||
|
color: "#04fbfd",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
yAxis: {
|
||||||
|
type: "value",
|
||||||
|
min: -3.0,
|
||||||
|
max: 2.0,
|
||||||
|
interval: 1.0,
|
||||||
|
splitNumber: 5,
|
||||||
|
splitLine: { show: false },
|
||||||
|
axisLine: {
|
||||||
|
onZero: false,
|
||||||
|
show: true,
|
||||||
|
symbol: ["none", "arrow"],
|
||||||
|
symbolOffset: [0, 10],
|
||||||
|
lineStyle: {
|
||||||
|
color: "#04fbfd",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
axisLabel: {
|
||||||
|
show: true,
|
||||||
|
},
|
||||||
|
axisTick: { show: true },
|
||||||
|
scale: true,
|
||||||
|
},
|
||||||
|
dataZoom: { type: "inside", start: 0, end: 100 },
|
||||||
|
series: [
|
||||||
|
{
|
||||||
|
name: "SAT_SVD1",
|
||||||
|
type: "line",
|
||||||
|
stack: "Total",
|
||||||
|
data: SATData,
|
||||||
|
smooth: true,
|
||||||
|
color: "red",
|
||||||
|
symbol: "none",
|
||||||
|
itemStyle: {
|
||||||
|
color: "red",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "SST_SVD1",
|
||||||
|
type: "line",
|
||||||
|
// stack: "Total",
|
||||||
|
data: SSTData,
|
||||||
|
smooth: true,
|
||||||
|
color: "blue",
|
||||||
|
symbol: "none",
|
||||||
|
itemStyle: {
|
||||||
|
color: "blue",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="scene-chart-panel chart-info-panel">
|
||||||
|
<ReactECharts
|
||||||
|
option={option}
|
||||||
|
lazyUpdate={true}
|
||||||
|
style={{
|
||||||
|
height: "100%",
|
||||||
|
width: "100%",
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default SceneChartPanel;
|
20
src/components/domain/Three/SceneTwo/index.jsx
Normal file
20
src/components/domain/Three/SceneTwo/index.jsx
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
import Legend from "../Legend";
|
||||||
|
import ViewerOne from "../SceneOne/ViewerOne";
|
||||||
|
import SceneChartPanel from "./SceneChartPanel";
|
||||||
|
|
||||||
|
function SceneTwo() {
|
||||||
|
return (
|
||||||
|
<div className="scene_two">
|
||||||
|
<ViewerOne>
|
||||||
|
<div className="right-panel one" style={{ height: "unset" }}>
|
||||||
|
<div className="bottom-panel">
|
||||||
|
<SceneChartPanel />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<Legend style={{ bottom: "40px" }} />
|
||||||
|
</ViewerOne>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default SceneTwo;
|
@ -1,64 +1,16 @@
|
|||||||
import MapLayout from "@/components/map/Layout";
|
import { useState } from "react";
|
||||||
import CustomToolbar from "@/components/common/CustomToolbar";
|
import styles from "./index.module.less";
|
||||||
import CustomClock from "@/components/common/CustomClock";
|
import SceneOne from "./SceneOne";
|
||||||
import TextInfoPanel from "@/components/common/TextInfoPanel";
|
import SceneTwo from "./SceneTwo";
|
||||||
import ChartPanel from "./ChartPanel";
|
import SceneSwitch from "./SceneSwitch";
|
||||||
import LandImageLayer from "./LandImageLayer";
|
|
||||||
import OceanImageLayer from "./OceanImageLayer";
|
export default function DomainThree() {
|
||||||
import WavePoint from "@/components/common/WavePoint";
|
const [scene, setScene] = useState(1);
|
||||||
import { CameraFlyTo } from "resium";
|
|
||||||
import { Cartesian3 } from "cesium";
|
|
||||||
import Legend from "./Legend";
|
|
||||||
|
|
||||||
export default function DomainOne() {
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div className={styles.domainThree}>
|
||||||
style={{
|
{scene === 1 ? <SceneOne /> : <SceneTwo />}
|
||||||
display: "flex",
|
<SceneSwitch scene={scene} setScene={setScene} />
|
||||||
height: "100%",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div style={{ flex: 1, position: "relative" }}>
|
|
||||||
<MapLayout>
|
|
||||||
<div className="title" style={{ zIndex: 999 }}>
|
|
||||||
两极协同—连接南极和北极的热带大西洋经向模的媒介作用
|
|
||||||
</div>
|
|
||||||
<CustomToolbar />
|
|
||||||
<CustomClock />
|
|
||||||
<CameraFlyTo
|
|
||||||
duration={5}
|
|
||||||
destination={Cartesian3.fromDegrees(80, -85, 10000000)}
|
|
||||||
/>
|
|
||||||
<div className="left-panel one">
|
|
||||||
<TextInfoPanel content="利用GISTEMP资料,通过EEMD分解方法提取两极温度多年代际变化序列,发现南北极温度变化的跷跷板现象与大西洋多年代际振荡AMO紧密相关。而AMO与热带大西洋经向模AMM在年代际尺度上显著相关。ERA5再分析资料显示AMM可以通过Rossby波影响西南极的气温与海冰偶极子。因此,AMM可能在联系南北极气候变化的中起到了重要的媒介作用。" />
|
|
||||||
</div>
|
|
||||||
<WavePoint stationLon={88} stationLat={-85} />
|
|
||||||
<LandImageLayer />
|
|
||||||
</MapLayout>
|
|
||||||
</div>
|
|
||||||
<div style={{ flex: 1, position: "relative" }}>
|
|
||||||
<MapLayout>
|
|
||||||
<OceanImageLayer />
|
|
||||||
<CameraFlyTo
|
|
||||||
duration={5}
|
|
||||||
destination={Cartesian3.fromDegrees(0, 88, 10000000)}
|
|
||||||
/>
|
|
||||||
<WavePoint color={"WHITE"} stationLon={0} stationLat={87} />
|
|
||||||
</MapLayout>
|
|
||||||
</div>
|
|
||||||
<div style={{ flex: 1, position: "relative" }}>
|
|
||||||
<MapLayout>
|
|
||||||
<CameraFlyTo
|
|
||||||
duration={5}
|
|
||||||
destination={Cartesian3.fromDegrees(100, 33, 10000000)}
|
|
||||||
/>
|
|
||||||
<div className="right-panel one">
|
|
||||||
<ChartPanel />
|
|
||||||
</div>
|
|
||||||
<WavePoint maxR={3600 * 200} stationLon={88} stationLat={33} />
|
|
||||||
</MapLayout>
|
|
||||||
</div>
|
|
||||||
{/* <Legend /> */}
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,148 @@
|
|||||||
|
.domainThree :global {
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
.scene_two {
|
||||||
|
display: flex;
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
.domain-viewer {
|
||||||
|
flex: 1;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
.title {
|
||||||
|
pointer-events: 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.scene-switch {
|
||||||
|
position: absolute;
|
||||||
|
left: 8px;
|
||||||
|
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 {
|
.legend :global {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: 40px;
|
bottom: 270px;
|
||||||
width: 50%;
|
width: 50%;
|
||||||
left: 25%;
|
left: 25%;
|
||||||
z-index: 1000;
|
z-index: 1000;
|
||||||
@ -26,7 +168,6 @@
|
|||||||
.colorbar-item {
|
.colorbar-item {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
// border-radius: 8px;
|
|
||||||
border: 1px black solid;
|
border: 1px black solid;
|
||||||
|
|
||||||
&:not(:nth-child(1)) {
|
&:not(:nth-child(1)) {
|
||||||
|
@ -1,27 +1,46 @@
|
|||||||
import { Fragment, useState } from "react";
|
import { Fragment, useState } from "react";
|
||||||
import { Entity, EllipsoidGraphics, useCesium, PolylineGraphics } from "resium";
|
import {
|
||||||
|
Entity,
|
||||||
|
EllipsoidGraphics,
|
||||||
|
useCesium,
|
||||||
|
PolylineGraphics,
|
||||||
|
LabelGraphics,
|
||||||
|
} from "resium";
|
||||||
import { useInterval, useThrottleFn } from "ahooks";
|
import { useInterval, useThrottleFn } from "ahooks";
|
||||||
import { useDispatch } from "react-redux";
|
import { useDispatch } from "react-redux";
|
||||||
|
import {
|
||||||
|
Cartesian3,
|
||||||
|
Color,
|
||||||
|
Math as CesiumMath,
|
||||||
|
LabelStyle,
|
||||||
|
PolylineDashMaterialProperty,
|
||||||
|
Cartesian2,
|
||||||
|
} from "cesium";
|
||||||
|
|
||||||
const lowCircle = (
|
const lowCircle = (
|
||||||
<EllipsoidGraphics
|
<EllipsoidGraphics
|
||||||
radii={new Cesium.Cartesian3(460000.0, 460000.0, 460000.0)}
|
radii={new Cartesian3(460000.0, 460000.0, 460000.0)}
|
||||||
innerRadii={new Cesium.Cartesian3(415000.0, 415000.0, 415000.0)}
|
innerRadii={new Cartesian3(415000.0, 415000.0, 415000.0)}
|
||||||
minimumCone={Cesium.Math.toRadians(89.8)}
|
minimumCone={CesiumMath.toRadians(89.8)}
|
||||||
maximumCone={Cesium.Math.toRadians(90.2)}
|
maximumCone={CesiumMath.toRadians(90.2)}
|
||||||
material={new Cesium.Color(0.29, 0.46, 0.77, 1)}
|
material={new Color(0.29, 0.46, 0.77, 1)}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
||||||
const highCircle = (
|
const highCircle = (
|
||||||
<EllipsoidGraphics
|
<EllipsoidGraphics
|
||||||
radii={new Cesium.Cartesian3(460000.0, 460000.0, 460000.0)}
|
radii={new Cartesian3(460000.0, 460000.0, 460000.0)}
|
||||||
innerRadii={new Cesium.Cartesian3(415000.0, 415000.0, 415000.0)}
|
innerRadii={new Cartesian3(415000.0, 415000.0, 415000.0)}
|
||||||
minimumCone={Cesium.Math.toRadians(89.8)}
|
minimumCone={CesiumMath.toRadians(89.8)}
|
||||||
maximumCone={Cesium.Math.toRadians(90.2)}
|
maximumCone={CesiumMath.toRadians(90.2)}
|
||||||
material={new Cesium.Color(0.99, 0.23, 0.23, 1)}
|
material={new Color(0.99, 0.23, 0.23, 1)}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// const labelText={
|
||||||
|
// '5月南极涛动','Rossby波列' , '印度洋海温异常(信号存储)', '6月青藏高原降水(80个站点)和加热'
|
||||||
|
// }
|
||||||
|
|
||||||
function Circles() {
|
function Circles() {
|
||||||
const { viewer } = useCesium();
|
const { viewer } = useCesium();
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
@ -56,7 +75,7 @@ function Circles() {
|
|||||||
currentTime.secondsOfDay - startTime.secondsOfDay
|
currentTime.secondsOfDay - startTime.secondsOfDay
|
||||||
);
|
);
|
||||||
if (!shouldAnimate) return;
|
if (!shouldAnimate) return;
|
||||||
if (_time === 40) {
|
if (_time === 20) {
|
||||||
showInfo();
|
showInfo();
|
||||||
} else if (_time === 0) {
|
} else if (_time === 0) {
|
||||||
closeInfo();
|
closeInfo();
|
||||||
@ -75,14 +94,12 @@ function Circles() {
|
|||||||
<Fragment>
|
<Fragment>
|
||||||
<Entity
|
<Entity
|
||||||
id={`${id}-up`}
|
id={`${id}-up`}
|
||||||
position={Cesium.Cartesian3.fromDegrees(lon, lat, 1000000)}
|
position={Cartesian3.fromDegrees(lon, lat, 1000000)}
|
||||||
>
|
>
|
||||||
{circle}
|
{circle}
|
||||||
</Entity>
|
|
||||||
{show && (
|
|
||||||
<Entity id={`${id}-connection-line`}>
|
<Entity id={`${id}-connection-line`}>
|
||||||
<PolylineGraphics
|
<PolylineGraphics
|
||||||
positions={Cesium.Cartesian3.fromDegreesArrayHeights([
|
positions={Cartesian3.fromDegreesArrayHeights([
|
||||||
lon,
|
lon,
|
||||||
lat,
|
lat,
|
||||||
1000000,
|
1000000,
|
||||||
@ -92,20 +109,31 @@ function Circles() {
|
|||||||
])}
|
])}
|
||||||
width={2}
|
width={2}
|
||||||
material={
|
material={
|
||||||
new Cesium.PolylineDashMaterialProperty({
|
new PolylineDashMaterialProperty({
|
||||||
color: Cesium.Color.WHITE,
|
color: Color.WHITE,
|
||||||
dashLength: 4,
|
dashLength: 4,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</Entity>
|
</Entity>
|
||||||
)}
|
</Entity>
|
||||||
<Entity
|
<Entity
|
||||||
id={`${id}-down`}
|
id={`${id}-down`}
|
||||||
position={Cesium.Cartesian3.fromDegrees(lon, lat, 0)}
|
position={Cartesian3.fromDegrees(lon, lat, 0)}
|
||||||
>
|
>
|
||||||
{circle}
|
{circle}
|
||||||
</Entity>
|
</Entity>
|
||||||
|
<Entity position={Cartesian3.fromDegrees(lon, lat, 0)}>
|
||||||
|
<LabelGraphics
|
||||||
|
text={"Rossby波列"}
|
||||||
|
font="24px Helvetica"
|
||||||
|
fillColor={Color.SKYBLUE}
|
||||||
|
outlineColor={Color.BLACK}
|
||||||
|
outlineWidth={2}
|
||||||
|
style={LabelStyle.FILL_AND_OUTLINE}
|
||||||
|
eyeOffset={new Cartesian2(0, 10000000)}
|
||||||
|
/>
|
||||||
|
</Entity>
|
||||||
</Fragment>
|
</Fragment>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
@ -115,35 +143,35 @@ function Circles() {
|
|||||||
<Circle
|
<Circle
|
||||||
isLow={true}
|
isLow={true}
|
||||||
id={`low-circle-1`}
|
id={`low-circle-1`}
|
||||||
showTime={10}
|
showTime={5}
|
||||||
lon={-110}
|
lon={-110}
|
||||||
lat={-60}
|
lat={-60}
|
||||||
/>
|
/>
|
||||||
<Circle
|
<Circle
|
||||||
isLow={false}
|
isLow={false}
|
||||||
id={`height-circle-1`}
|
id={`height-circle-1`}
|
||||||
showTime={20}
|
showTime={10}
|
||||||
lon={-30}
|
lon={-30}
|
||||||
lat={-55}
|
lat={-55}
|
||||||
/>
|
/>
|
||||||
<Circle
|
<Circle
|
||||||
isLow={true}
|
isLow={true}
|
||||||
id={`low-circle-2`}
|
id={`low-circle-2`}
|
||||||
showTime={30}
|
showTime={15}
|
||||||
lon={30}
|
lon={30}
|
||||||
lat={-40}
|
lat={-40}
|
||||||
/>
|
/>
|
||||||
<Circle
|
<Circle
|
||||||
isLow={false}
|
isLow={false}
|
||||||
id={`height-circle-2`}
|
id={`height-circle-2`}
|
||||||
showTime={40}
|
showTime={20}
|
||||||
lon={65}
|
lon={65}
|
||||||
lat={-35}
|
lat={-35}
|
||||||
/>
|
/>
|
||||||
<Circle
|
<Circle
|
||||||
isLow={true}
|
isLow={true}
|
||||||
id={`low-circle-3`}
|
id={`low-circle-3`}
|
||||||
showTime={50}
|
showTime={27}
|
||||||
lon={95}
|
lon={95}
|
||||||
lat={-30}
|
lat={-30}
|
||||||
/>
|
/>
|
||||||
|
@ -1,30 +1,31 @@
|
|||||||
import { useCesium } from "resium";
|
import { Cartesian2, Cartesian3, Math } from "cesium";
|
||||||
|
import { CloudCollection, useCesium } from "resium";
|
||||||
|
|
||||||
function Cloud() {
|
function Cloud() {
|
||||||
const { viewer } = useCesium();
|
const { viewer } = useCesium();
|
||||||
const scene = viewer.scene;
|
const scene = viewer.scene;
|
||||||
const position = Cesium.Cartesian3.fromDegrees(-123.0744619, 44.0503706, 50);
|
const position = Cartesian3.fromDegrees(-123.0744619, 44.0503706, 50);
|
||||||
|
|
||||||
Cesium.Math.setRandomNumberSeed(2.5);
|
Math.setRandomNumberSeed(2.5);
|
||||||
function getRandomNumberInRange(minValue, maxValue) {
|
function getRandomNumberInRange(minValue, maxValue) {
|
||||||
return minValue + Cesium.Math.nextRandomNumber() * (maxValue - minValue);
|
return minValue + Math.nextRandomNumber() * (maxValue - minValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
const clouds = new Cesium.CloudCollection();
|
const clouds = new CloudCollection();
|
||||||
|
|
||||||
// manually position clouds in the mountains
|
// manually position clouds in the mountains
|
||||||
function createBackLayerClouds() {
|
function createBackLayerClouds() {
|
||||||
clouds.add({
|
clouds.add({
|
||||||
position: Cesium.Cartesian3.fromDegrees(-122.6908, 45.496, 300),
|
position: new Cartesian3.fromDegrees(-122.6908, 45.496, 300),
|
||||||
scale: new Cesium.Cartesian2(1500, 250),
|
scale: new Cartesian2(1500, 250),
|
||||||
maximumSize: new Cesium.Cartesian3(50, 15, 13),
|
maximumSize: new Cartesian3(50, 15, 13),
|
||||||
slice: 0.3,
|
slice: 0.3,
|
||||||
});
|
});
|
||||||
|
|
||||||
clouds.add({
|
clouds.add({
|
||||||
position: Cesium.Cartesian3.fromDegrees(-122.72, 45.5, 335),
|
position: new Cartesian3.fromDegrees(-122.72, 45.5, 335),
|
||||||
scale: new Cesium.Cartesian2(1500, 300),
|
scale: new Cartesian2(1500, 300),
|
||||||
maximumSize: new Cesium.Cartesian3(50, 12, 15),
|
maximumSize: new Cartesian3(50, 12, 15),
|
||||||
slice: 0.36,
|
slice: 0.36,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -53,9 +54,9 @@ function Cloud() {
|
|||||||
aspectRatio = getRandomNumberInRange(1.5, 2.1);
|
aspectRatio = getRandomNumberInRange(1.5, 2.1);
|
||||||
cloudHeight = getRandomNumberInRange(5, 20);
|
cloudHeight = getRandomNumberInRange(5, 20);
|
||||||
clouds.add({
|
clouds.add({
|
||||||
position: Cesium.Cartesian3.fromDegrees(long, lat, height),
|
position: Cartesian3.fromDegrees(long, lat, height),
|
||||||
scale: new Cesium.Cartesian2(scaleX, scaleY),
|
scale: new Cartesian2(scaleX, scaleY),
|
||||||
maximumSize: new Cesium.Cartesian3(
|
maximumSize: new Cartesian3(
|
||||||
aspectRatio * cloudHeight,
|
aspectRatio * cloudHeight,
|
||||||
cloudHeight,
|
cloudHeight,
|
||||||
depth
|
depth
|
||||||
@ -65,19 +66,19 @@ function Cloud() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// manually position clouds in front
|
// manually position clouds in front
|
||||||
const scratch = new Cesium.Cartesian3();
|
const scratch = new Cartesian3();
|
||||||
function createFrontLayerClouds() {
|
function createFrontLayerClouds() {
|
||||||
clouds.add({
|
clouds.add({
|
||||||
position: Cesium.Cartesian3.fromDegrees(-122.666, 45.5126, 97),
|
position: Cartesian3.fromDegrees(-122.666, 45.5126, 97),
|
||||||
scale: new Cesium.Cartesian2(400, 150),
|
scale: new Cartesian2(400, 150),
|
||||||
maximumSize: new Cesium.Cartesian3(25, 12, 15),
|
maximumSize: new Cartesian3(25, 12, 15),
|
||||||
slice: 0.36,
|
slice: 0.36,
|
||||||
});
|
});
|
||||||
|
|
||||||
clouds.add({
|
clouds.add({
|
||||||
position: Cesium.Cartesian3.fromDegrees(-122.6665, 45.5262, 76),
|
position: Cartesian3.fromDegrees(-122.6665, 45.5262, 76),
|
||||||
scale: new Cesium.Cartesian2(450, 200),
|
scale: new Cartesian2(450, 200),
|
||||||
maximumSize: new Cesium.Cartesian3(25, 14, 12),
|
maximumSize: new Cartesian3(25, 14, 12),
|
||||||
slice: 0.3,
|
slice: 0.3,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -1,112 +1,137 @@
|
|||||||
|
import { Cartesian3, EasingFunction, Math } from "cesium";
|
||||||
import { useDispatch } from "react-redux";
|
import { useDispatch } from "react-redux";
|
||||||
import { useCesium } from "resium";
|
import { useCesium } from "resium";
|
||||||
|
|
||||||
function CustomFlyTo() {
|
function CustomFlyTo() {
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
const { viewer } = useCesium();
|
const { viewer, camera } = useCesium();
|
||||||
const { camera } = viewer;
|
|
||||||
|
|
||||||
function cameraFlyToLine(adjustPitch) {
|
function cameraFlyToLine() {
|
||||||
// 南极
|
// // 南极
|
||||||
const antarcticalOptions = {
|
// const antarcticalOptions = {
|
||||||
destination: Cesium.Cartesian3.fromDegrees(88, -89, 1600000),
|
// destination: Cartesian3.fromDegrees(88, -89, 1600000),
|
||||||
orientation: {
|
// orientation: {
|
||||||
heading: Cesium.Math.toRadians(15.0),
|
// heading: Math.toRadians(15.0),
|
||||||
pitch: Cesium.Math.toRadians(-60),
|
// pitch: Math.toRadians(-60),
|
||||||
roll: 0.0,
|
// roll: 0.0,
|
||||||
},
|
// },
|
||||||
duration: 10,
|
// duration: 5,
|
||||||
complete: function () {
|
// complete: function () {
|
||||||
setTimeout(() => {
|
// camera.flyTo(area1Options);
|
||||||
camera.flyTo(plateauOptions);
|
// },
|
||||||
}, 1000);
|
// easingFunction: EasingFunction.LINEAR_NONE,
|
||||||
},
|
// };
|
||||||
};
|
|
||||||
|
|
||||||
const area1Options = {
|
const area1Options = {
|
||||||
destination: Cesium.Cartesian3.fromDegrees(-110, -60, 6000000),
|
destination: Cartesian3.fromDegrees(-110, -86, 10000000),
|
||||||
duration: 5,
|
duration: 5,
|
||||||
complete: function () {
|
orientation: {
|
||||||
setTimeout(function () {
|
heading: 6,
|
||||||
camera.flyTo(area2Options);
|
pitch: -1.3,
|
||||||
}, 1000);
|
roll: -6,
|
||||||
},
|
},
|
||||||
|
complete: function () {
|
||||||
|
viewer.clock.shouldAnimate = true;
|
||||||
|
dispatch.data.updateToolbar({ showPanel: true });
|
||||||
|
setTimeout(() => {
|
||||||
|
camera.flyTo(area2Options);
|
||||||
|
}, 5000);
|
||||||
|
},
|
||||||
|
easingFunction: EasingFunction.LINEAR_NONE,
|
||||||
};
|
};
|
||||||
|
|
||||||
const area2Options = {
|
const area2Options = {
|
||||||
destination: Cesium.Cartesian3.fromDegrees(-30, -55, 6000000),
|
destination: Cartesian3.fromDegrees(-30, -65, 10000000),
|
||||||
duration: 5,
|
duration: 5,
|
||||||
complete: function () {
|
complete: function () {
|
||||||
setTimeout(function () {
|
|
||||||
camera.flyTo(area3Options);
|
camera.flyTo(area3Options);
|
||||||
}, 1000);
|
},
|
||||||
|
easingFunction: EasingFunction.LINEAR_NONE,
|
||||||
|
orientation: {
|
||||||
|
heading: 6,
|
||||||
|
pitch: -1.3,
|
||||||
|
roll: -6,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const area3Options = {
|
const area3Options = {
|
||||||
destination: Cesium.Cartesian3.fromDegrees(30, -40, 6000000),
|
destination: Cartesian3.fromDegrees(30, -40, 10000000),
|
||||||
duration: 5,
|
duration: 5,
|
||||||
complete: function () {
|
complete: function () {
|
||||||
setTimeout(function () {
|
|
||||||
camera.flyTo(area4Options);
|
camera.flyTo(area4Options);
|
||||||
}, 1000);
|
|
||||||
},
|
},
|
||||||
|
easingFunction: EasingFunction.LINEAR_NONE,
|
||||||
};
|
};
|
||||||
|
|
||||||
const area4Options = {
|
const area4Options = {
|
||||||
destination: Cesium.Cartesian3.fromDegrees(65, -35, 6000000),
|
destination: Cartesian3.fromDegrees(65, -55, 10000000),
|
||||||
duration: 5,
|
|
||||||
complete: function () {
|
|
||||||
setTimeout(function () {
|
|
||||||
camera.flyTo(sideViewOptions);
|
|
||||||
}, 1000);
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
// 青藏高原
|
|
||||||
const plateauOptions = {
|
|
||||||
destination: Cesium.Cartesian3.fromDegrees(90, 20, 1600000),
|
|
||||||
duration: 5,
|
duration: 5,
|
||||||
orientation: {
|
orientation: {
|
||||||
heading: Cesium.Math.toRadians(-15.0),
|
heading: 6,
|
||||||
pitch: -Cesium.Math.PI_OVER_FOUR,
|
pitch: -1.3,
|
||||||
roll: 0.0,
|
roll: -6,
|
||||||
},
|
},
|
||||||
complete: function () {
|
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(() => {
|
setTimeout(() => {
|
||||||
camera.flyTo({
|
camera.flyTo({
|
||||||
duration: 5,
|
duration: 5,
|
||||||
destination: Cesium.Cartesian3.fromDegrees(90, -12, 14000000),
|
destination: Cartesian3.fromDegrees(90, -12, 14000000),
|
||||||
});
|
});
|
||||||
}, 40 * 1000);
|
}, 5 * 1000);
|
||||||
},
|
},
|
||||||
|
easingFunction: EasingFunction.LINEAR_NONE,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (adjustPitch) {
|
const area5Options = {
|
||||||
antarcticalOptions.pitchAdjustHeight = 1000;
|
destination: Cartesian3.fromDegrees(95, -30, 10000000),
|
||||||
plateauOptions.pitchAdjustHeight = 1000;
|
duration: 5,
|
||||||
sideViewOptions.pitchAdjustHeight = 1000;
|
complete: function () {
|
||||||
}
|
// camera.flyTo(sideViewOptions);
|
||||||
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();
|
cameraFlyToLine();
|
||||||
return <></>;
|
return <></>;
|
||||||
|
34
src/components/domain/Two/Labels.jsx
Normal file
34
src/components/domain/Two/Labels.jsx
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
import { Cartesian2, Cartesian3, Color, LabelStyle } from "cesium";
|
||||||
|
import { Fragment } from "react";
|
||||||
|
import { Entity, LabelGraphics } from "resium";
|
||||||
|
|
||||||
|
function Labels() {
|
||||||
|
return (
|
||||||
|
<Fragment>
|
||||||
|
<Entity position={Cartesian3.fromDegrees(73, -7, 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>
|
||||||
|
<Entity position={Cartesian3.fromDegrees(94, 24, 0)}>
|
||||||
|
<LabelGraphics
|
||||||
|
text={"6月青藏高原降水和加热"}
|
||||||
|
font="24px Helvetica"
|
||||||
|
fillColor={Color.SKYBLUE}
|
||||||
|
outlineColor={Color.BLACK}
|
||||||
|
outlineWidth={2}
|
||||||
|
style={LabelStyle.FILL_AND_OUTLINE}
|
||||||
|
eyeOffset={new Cartesian2(0, 0)}
|
||||||
|
/>
|
||||||
|
</Entity>
|
||||||
|
</Fragment>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Labels;
|
@ -1,4 +1,5 @@
|
|||||||
import { useInterval } from "ahooks";
|
import { useInterval } from "ahooks";
|
||||||
|
import { Cartesian3, Color, PolylineArrowMaterialProperty } from "cesium";
|
||||||
import { Fragment, useCallback, useState } from "react";
|
import { Fragment, useCallback, useState } from "react";
|
||||||
import { Entity, PolylineGraphics, useCesium } from "resium";
|
import { Entity, PolylineGraphics, useCesium } from "resium";
|
||||||
|
|
||||||
@ -23,26 +24,24 @@ function MoistureTransport() {
|
|||||||
<Fragment>
|
<Fragment>
|
||||||
<Entity show={show}>
|
<Entity show={show}>
|
||||||
<PolylineGraphics
|
<PolylineGraphics
|
||||||
positions={Cesium.Cartesian3.fromDegreesArrayHeights([
|
positions={Cartesian3.fromDegreesArrayHeights([
|
||||||
85, 33, 200000, 87, 32, 0,
|
85, 33, 200000, 87, 32, 0,
|
||||||
])}
|
])}
|
||||||
width={15}
|
width={15}
|
||||||
material={
|
material={
|
||||||
new Cesium.PolylineArrowMaterialProperty(
|
new PolylineArrowMaterialProperty(
|
||||||
Cesium.Color.fromCssColorString("#70ad47")
|
Color.fromCssColorString("#70ad47")
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</Entity>
|
</Entity>
|
||||||
<Entity show={show}>
|
<Entity show={show}>
|
||||||
<PolylineGraphics
|
<PolylineGraphics
|
||||||
positions={Cesium.Cartesian3.fromDegreesArrayHeights([
|
positions={Cartesian3.fromDegreesArrayHeights([83, 27, 0, 87, 31, 0])}
|
||||||
83, 27, 0, 87, 31, 0,
|
|
||||||
])}
|
|
||||||
width={15}
|
width={15}
|
||||||
material={
|
material={
|
||||||
new Cesium.PolylineArrowMaterialProperty(
|
new PolylineArrowMaterialProperty(
|
||||||
Cesium.Color.fromCssColorString("#70ad47")
|
Color.fromCssColorString("#70ad47")
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { useCallback, useState } from "react";
|
import { useCallback, useState } from "react";
|
||||||
import { Entity, PolygonGraphics, useCesium } from "resium";
|
import { Entity, PolygonGraphics, useCesium } from "resium";
|
||||||
import { useInterval } from "ahooks";
|
import { useInterval } from "ahooks";
|
||||||
|
import { Cartesian3, Color } from "cesium";
|
||||||
|
|
||||||
function PlateauPolygon() {
|
function PlateauPolygon() {
|
||||||
const { viewer } = useCesium();
|
const { viewer } = useCesium();
|
||||||
@ -12,7 +13,7 @@ function PlateauPolygon() {
|
|||||||
stopTime.secondsOfDay - currentTime.secondsOfDay
|
stopTime.secondsOfDay - currentTime.secondsOfDay
|
||||||
);
|
);
|
||||||
|
|
||||||
if (leftTime < 20) {
|
if (leftTime < 5) {
|
||||||
setShow(true);
|
setShow(true);
|
||||||
} else if (show) setShow(false);
|
} else if (show) setShow(false);
|
||||||
}, [show]);
|
}, [show]);
|
||||||
@ -22,11 +23,11 @@ function PlateauPolygon() {
|
|||||||
return (
|
return (
|
||||||
<Entity id="plateau" show={show}>
|
<Entity id="plateau" show={show}>
|
||||||
<PolygonGraphics
|
<PolygonGraphics
|
||||||
hierarchy={Cesium.Cartesian3.fromDegreesArray([
|
hierarchy={Cartesian3.fromDegreesArray([
|
||||||
// 85, 30, 91, 30, 91, 35, 85, 35,
|
// 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,
|
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)}
|
material={new Color(1, 0, 0, 0.1)}
|
||||||
/>
|
/>
|
||||||
</Entity>
|
</Entity>
|
||||||
);
|
);
|
||||||
|
@ -1,16 +1,26 @@
|
|||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { Entity, PointGraphics, useCesium } from "resium";
|
import { Entity, PointGraphics, useCesium } from "resium";
|
||||||
import { useInterval } from "ahooks";
|
import { useInterval } from "ahooks";
|
||||||
|
import {
|
||||||
|
Cartesian3,
|
||||||
|
Color,
|
||||||
|
JulianDate,
|
||||||
|
LinearApproximation,
|
||||||
|
SampledPositionProperty,
|
||||||
|
TimeInterval,
|
||||||
|
TimeIntervalCollection,
|
||||||
|
VelocityOrientationProperty,
|
||||||
|
} from "cesium";
|
||||||
|
|
||||||
// 从南极到青藏高原
|
// 从南极到青藏高原
|
||||||
const dataAntarcticaToQTP = [
|
const dataAntarcticaToQTP = [
|
||||||
{ longitude: -110, latitude: -60, height: 0, time: 0 },
|
{ longitude: -110, latitude: -60, height: 0, time: 0 },
|
||||||
{ longitude: -110, latitude: -60, height: 1000000, time: 10 },
|
{ longitude: -110, latitude: -60, height: 1000000, time: 5 },
|
||||||
{ longitude: -30, latitude: -55, height: 1000000, time: 20 },
|
{ longitude: -30, latitude: -55, height: 1000000, time: 10 },
|
||||||
{ longitude: 30, latitude: -40, height: 1000000, time: 30 },
|
{ longitude: 30, latitude: -40, height: 1000000, time: 15 },
|
||||||
{ longitude: 65, latitude: -35, height: 1000000, time: 40 },
|
{ longitude: 65, latitude: -35, height: 1000000, time: 20 },
|
||||||
{ longitude: 95, latitude: -30, height: 1000000, time: 50 },
|
{ longitude: 95, latitude: -30, height: 1000000, time: 27 },
|
||||||
{ longitude: 95, latitude: -30, height: 0, time: 60 },
|
{ longitude: 95, latitude: -30, height: 0, time: 30 },
|
||||||
];
|
];
|
||||||
|
|
||||||
function Point() {
|
function Point() {
|
||||||
@ -21,7 +31,7 @@ function Point() {
|
|||||||
const start = viewer.clock.startTime;
|
const start = viewer.clock.startTime;
|
||||||
const stop = viewer.clock.stopTime;
|
const stop = viewer.clock.stopTime;
|
||||||
|
|
||||||
const pathMaterial = new Cesium.Color(4 / 255, 251 / 255, 253 / 255);
|
const pathMaterial = new Color(4 / 255, 251 / 255, 253 / 255);
|
||||||
|
|
||||||
useInterval(() => {
|
useInterval(() => {
|
||||||
if (viewer.clock?.shouldAnimate) setDelay(undefined);
|
if (viewer.clock?.shouldAnimate) setDelay(undefined);
|
||||||
@ -33,14 +43,10 @@ function Point() {
|
|||||||
* {SampledPositionProperty|*}
|
* {SampledPositionProperty|*}
|
||||||
*/
|
*/
|
||||||
function createProperty(source) {
|
function createProperty(source) {
|
||||||
let property = new Cesium.SampledPositionProperty();
|
let property = new SampledPositionProperty();
|
||||||
for (let i = 0; i < source.length; i++) {
|
for (let i = 0; i < source.length; i++) {
|
||||||
let time = Cesium.JulianDate.addSeconds(
|
let time = JulianDate.addSeconds(start, source[i].time, new JulianDate());
|
||||||
start,
|
let position = Cartesian3.fromDegrees(
|
||||||
source[i].time,
|
|
||||||
new Cesium.JulianDate()
|
|
||||||
);
|
|
||||||
let position = Cesium.Cartesian3.fromDegrees(
|
|
||||||
source[i].longitude,
|
source[i].longitude,
|
||||||
source[i].latitude,
|
source[i].latitude,
|
||||||
source[i].height
|
source[i].height
|
||||||
@ -50,7 +56,7 @@ function Point() {
|
|||||||
}
|
}
|
||||||
property.setInterpolationOptions({
|
property.setInterpolationOptions({
|
||||||
interpolationDegree: 1,
|
interpolationDegree: 1,
|
||||||
interpolationAlgorithm: Cesium.LinearApproximation,
|
interpolationAlgorithm: LinearApproximation,
|
||||||
});
|
});
|
||||||
return property;
|
return property;
|
||||||
}
|
}
|
||||||
@ -62,14 +68,14 @@ function Point() {
|
|||||||
id={"point"}
|
id={"point"}
|
||||||
position={property}
|
position={property}
|
||||||
availability={
|
availability={
|
||||||
new Cesium.TimeIntervalCollection([
|
new TimeIntervalCollection([
|
||||||
new Cesium.TimeInterval({
|
new TimeInterval({
|
||||||
start,
|
start,
|
||||||
stop,
|
stop,
|
||||||
}),
|
}),
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
orientation={new Cesium.VelocityOrientationProperty(property)}
|
orientation={new VelocityOrientationProperty(property)}
|
||||||
path={{
|
path={{
|
||||||
resolution: 1,
|
resolution: 1,
|
||||||
material: pathMaterial,
|
material: pathMaterial,
|
||||||
@ -81,8 +87,8 @@ function Point() {
|
|||||||
>
|
>
|
||||||
<PointGraphics
|
<PointGraphics
|
||||||
show={true}
|
show={true}
|
||||||
color={Cesium.Color.SKYBLUE}
|
color={Color.SKYBLUE}
|
||||||
outlineColor={Cesium.Color.YELLOW}
|
outlineColor={Color.YELLOW}
|
||||||
outlineWidth={3}
|
outlineWidth={3}
|
||||||
/>
|
/>
|
||||||
</Entity>
|
</Entity>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { Entity, EllipseGraphics } from "resium";
|
import { Entity, EllipseGraphics } from "resium";
|
||||||
import { Cartesian3 } from "cesium";
|
import { Cartesian3, Color } from "cesium";
|
||||||
|
|
||||||
const fluxData = [
|
const fluxData = [
|
||||||
0.03256254, -0.23182425, -0.040055223, -0.03476936, -0.40450656, -0.18742515,
|
0.03256254, -0.23182425, -0.040055223, -0.03476936, -0.40450656, -0.18742515,
|
||||||
@ -86,7 +86,7 @@ function HeatFlux({ position, index }) {
|
|||||||
`}
|
`}
|
||||||
>
|
>
|
||||||
<EllipseGraphics
|
<EllipseGraphics
|
||||||
material={new Cesium.Color.fromCssColorString(colorBar[dataIndex])}
|
material={new Color.fromCssColorString(colorBar[dataIndex])}
|
||||||
semiMinorAxis={30000.0}
|
semiMinorAxis={30000.0}
|
||||||
semiMajorAxis={30000.0}
|
semiMajorAxis={30000.0}
|
||||||
extrudedHeight={400000}
|
extrudedHeight={400000}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { Entity, EllipseGraphics } from "resium";
|
import { Entity, EllipseGraphics } from "resium";
|
||||||
import { Cartesian3 } from "cesium";
|
import { Cartesian3, Color } from "cesium";
|
||||||
|
|
||||||
const rainData = [
|
const rainData = [
|
||||||
0.25309432, 0.296679, 0.39937696, -0.15093477, 0.17799897, 0.1186297,
|
0.25309432, 0.296679, 0.39937696, -0.15093477, 0.17799897, 0.1186297,
|
||||||
@ -85,7 +85,7 @@ function Rain({ position, index }) {
|
|||||||
`}
|
`}
|
||||||
>
|
>
|
||||||
<EllipseGraphics
|
<EllipseGraphics
|
||||||
material={new Cesium.Color.fromCssColorString(colorBar[dataIndex])}
|
material={new Color.fromCssColorString(colorBar[dataIndex])}
|
||||||
semiMinorAxis={30000.0}
|
semiMinorAxis={30000.0}
|
||||||
semiMajorAxis={30000.0}
|
semiMajorAxis={30000.0}
|
||||||
extrudedHeight={200000}
|
extrudedHeight={200000}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { useCallback, useState } from "react";
|
import { useCallback, useState } from "react";
|
||||||
import { useInterval } from "ahooks";
|
import { useInterval } from "ahooks";
|
||||||
import { Entity, PolylineGraphics, useCesium } from "resium";
|
import { Entity, PolylineGraphics, useCesium } from "resium";
|
||||||
|
import { Cartesian3, Color, PolylineArrowMaterialProperty } from "cesium";
|
||||||
|
|
||||||
function SurfaceAnomaly() {
|
function SurfaceAnomaly() {
|
||||||
const { viewer } = useCesium();
|
const { viewer } = useCesium();
|
||||||
@ -22,14 +23,10 @@ function SurfaceAnomaly() {
|
|||||||
return (
|
return (
|
||||||
<Entity show={show}>
|
<Entity show={show}>
|
||||||
<PolylineGraphics
|
<PolylineGraphics
|
||||||
positions={Cesium.Cartesian3.fromDegreesArrayHeights([
|
positions={Cartesian3.fromDegreesArrayHeights([90, -30, 0, 90, -21, 0])}
|
||||||
90, -30, 0, 90, -21, 0,
|
|
||||||
])}
|
|
||||||
width={10}
|
width={10}
|
||||||
material={
|
material={
|
||||||
new Cesium.PolylineArrowMaterialProperty(
|
new PolylineArrowMaterialProperty(Color.fromCssColorString("#000"))
|
||||||
Cesium.Color.fromCssColorString("#000")
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</Entity>
|
</Entity>
|
||||||
|
@ -13,6 +13,7 @@ import Circles from "./Circles";
|
|||||||
import SurfaceAnomaly from "./SurfaceAnomaly";
|
import SurfaceAnomaly from "./SurfaceAnomaly";
|
||||||
import MoistureTransport from "./MoistureTransport";
|
import MoistureTransport from "./MoistureTransport";
|
||||||
import Sites from "./Site";
|
import Sites from "./Site";
|
||||||
|
import Labels from "./Labels";
|
||||||
|
|
||||||
export default function DomainTwo() {
|
export default function DomainTwo() {
|
||||||
return (
|
return (
|
||||||
@ -22,18 +23,19 @@ export default function DomainTwo() {
|
|||||||
<CustomClock />
|
<CustomClock />
|
||||||
<CustomFlyTo />
|
<CustomFlyTo />
|
||||||
<Circles />
|
<Circles />
|
||||||
|
<EntityLegend />
|
||||||
|
<IndianOceanSST />
|
||||||
|
<Labels />
|
||||||
|
<Legend />
|
||||||
|
<MoistureTransport />
|
||||||
<Point />
|
<Point />
|
||||||
<PlateauPolygon />
|
<PlateauPolygon />
|
||||||
|
<Sites />
|
||||||
<div className="left-panel one">
|
<div className="left-panel one">
|
||||||
<TextInfoPanel content="利用ERA5再分析数据诊断和CESM印度洋海温强迫数值实验,发现5月的南极涛动正位相(AAO)激发原子阿蒙森海的纬向波列异常。该异常造成印度洋海温降低进而激发环流异常造成高原上空降水增加、感热通量降低。这一结果有助于提高青藏高原热源的预测技巧,改进亚洲夏季风的预测。" />
|
<TextInfoPanel content="利用ERA5再分析数据诊断和CESM印度洋海温强迫数值实验,发现5月的南极涛动正位相(AAO)激发原子阿蒙森海的纬向波列异常。该异常造成印度洋海温降低进而激发环流异常造成高原上空降水增加、感热通量降低。这一结果有助于提高青藏高原热源的预测技巧,改进亚洲夏季风的预测。" />
|
||||||
</div>
|
</div>
|
||||||
<WavePoints />
|
<WavePoints />
|
||||||
<EntityLegend />
|
|
||||||
<Legend />
|
|
||||||
<IndianOceanSST />
|
|
||||||
{/* <SurfaceAnomaly /> */}
|
{/* <SurfaceAnomaly /> */}
|
||||||
<MoistureTransport />
|
|
||||||
<Sites />
|
|
||||||
</MapLayout>
|
</MapLayout>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
16
src/components/map/Layout/HeadingPitchRoll.jsx
Normal file
16
src/components/map/Layout/HeadingPitchRoll.jsx
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
import { useCesium } from "resium";
|
||||||
|
|
||||||
|
function HeadingPitchRoll() {
|
||||||
|
const { camera } = useCesium();
|
||||||
|
|
||||||
|
camera.moveEnd?.addEventListener(function (event) {
|
||||||
|
const heading = camera.heading;
|
||||||
|
const pitch = camera.pitch;
|
||||||
|
const roll = camera.roll;
|
||||||
|
console.log("heading,pitch,roll :>> ", heading, pitch, roll);
|
||||||
|
});
|
||||||
|
|
||||||
|
return <></>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default HeadingPitchRoll;
|
@ -1,3 +1,9 @@
|
|||||||
|
import {
|
||||||
|
Cartographic,
|
||||||
|
Math,
|
||||||
|
ScreenSpaceEventHandler,
|
||||||
|
ScreenSpaceEventType,
|
||||||
|
} from "cesium";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { useCesium } from "resium";
|
import { useCesium } from "resium";
|
||||||
|
|
||||||
@ -7,26 +13,22 @@ function Picker() {
|
|||||||
const [lon, setLon] = useState();
|
const [lon, setLon] = useState();
|
||||||
const [lat, setLat] = useState();
|
const [lat, setLat] = useState();
|
||||||
|
|
||||||
const handler = new Cesium.ScreenSpaceEventHandler(scene.canvas);
|
const handler = new ScreenSpaceEventHandler(scene.canvas);
|
||||||
handler.setInputAction(function (movement) {
|
handler.setInputAction(function (movement) {
|
||||||
const cartesian = viewer.camera.pickEllipsoid(
|
const cartesian = viewer.camera.pickEllipsoid(
|
||||||
movement.endPosition,
|
movement.endPosition,
|
||||||
scene.globe.ellipsoid
|
scene.globe.ellipsoid
|
||||||
);
|
);
|
||||||
if (cartesian) {
|
if (cartesian) {
|
||||||
const cartographic = Cesium.Cartographic.fromCartesian(cartesian);
|
const cartographic = Cartographic.fromCartesian(cartesian);
|
||||||
const longitudeString = Cesium.Math.toDegrees(
|
const longitudeString = Math.toDegrees(cartographic.longitude).toFixed(4);
|
||||||
cartographic.longitude
|
const latitudeString = Math.toDegrees(cartographic.latitude).toFixed(4);
|
||||||
).toFixed(4);
|
|
||||||
const latitudeString = Cesium.Math.toDegrees(
|
|
||||||
cartographic.latitude
|
|
||||||
).toFixed(4);
|
|
||||||
setLon(longitudeString);
|
setLon(longitudeString);
|
||||||
setLat(latitudeString);
|
setLat(latitudeString);
|
||||||
} else {
|
} else {
|
||||||
// entity.label.show = false;
|
// entity.label.show = false;
|
||||||
}
|
}
|
||||||
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
|
}, ScreenSpaceEventType.MOUSE_MOVE);
|
||||||
|
|
||||||
if (!lon && !lat) return <></>;
|
if (!lon && !lat) return <></>;
|
||||||
|
|
||||||
|
@ -1,20 +1,10 @@
|
|||||||
import { Entity, PointGraphics, Viewer } from "resium";
|
import { Entity, PointGraphics, Viewer } from "resium";
|
||||||
import styles from "./index.module.less";
|
import styles from "./index.module.less";
|
||||||
import { useMemo } from "react";
|
import { Cartesian3, Color } from "cesium";
|
||||||
import { BingMapsImageryProvider, BingMapsStyle } from "cesium";
|
|
||||||
import Picker from "./Picker";
|
import Picker from "./Picker";
|
||||||
|
import HeadingPitchRoll from "./HeadingPitchRoll";
|
||||||
|
|
||||||
function MapLayout({ children, className, ...rest }) {
|
function MapLayout({ children, className, ...rest }) {
|
||||||
const imageryProvider = useMemo(
|
|
||||||
() =>
|
|
||||||
new BingMapsImageryProvider({
|
|
||||||
url: "https://dev.virtualearth.net",
|
|
||||||
key: "Ahv1KDJwbpJl4V8zklaRXcoueWXoNLo16osJiU4Zk07vc-VNNzJ0gB81TZyPqNFz",
|
|
||||||
mapStyle: BingMapsStyle.AERIAL,
|
|
||||||
}),
|
|
||||||
[]
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Viewer
|
<Viewer
|
||||||
className={`${styles.cesiumContainer} ${className}`}
|
className={`${styles.cesiumContainer} ${className}`}
|
||||||
@ -30,12 +20,12 @@ function MapLayout({ children, className, ...rest }) {
|
|||||||
baseLayerPicker={false}
|
baseLayerPicker={false}
|
||||||
animation={false}
|
animation={false}
|
||||||
selectionIndicator={false}
|
selectionIndicator={false}
|
||||||
// imageryProvider={imageryProvider}
|
|
||||||
>
|
>
|
||||||
<Entity position={Cesium.Cartesian3.fromDegreesArray([0, 90])}>
|
<Entity position={Cartesian3.fromDegreesArray([0, 90])}>
|
||||||
<PointGraphics color={Cesium.Color.SKYBLUE} pixelSize={10} />
|
<PointGraphics color={Color.SKYBLUE} pixelSize={10} />
|
||||||
</Entity>
|
</Entity>
|
||||||
<Picker />
|
<Picker />
|
||||||
|
{/* <HeadingPitchRoll /> */}
|
||||||
{children}
|
{children}
|
||||||
</Viewer>
|
</Viewer>
|
||||||
);
|
);
|
||||||
|
@ -63,7 +63,7 @@
|
|||||||
color: #02f9ff !important;
|
color: #02f9ff !important;
|
||||||
background-color: #1f485690;
|
background-color: #1f485690;
|
||||||
pointer-events: auto;
|
pointer-events: auto;
|
||||||
font-size: 16px;
|
font-size: 18px;
|
||||||
text-indent: 2em;
|
text-indent: 2em;
|
||||||
line-height: 1.5;
|
line-height: 1.5;
|
||||||
z-index: 999;
|
z-index: 999;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user