2023-10-12 18:02:30 +08:00

183 lines
4.2 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { Fragment, useState } from "react";
import {
Entity,
EllipsoidGraphics,
useCesium,
PolylineGraphics,
LabelGraphics,
} from "resium";
import { useInterval, useThrottleFn } from "ahooks";
import { useDispatch } from "react-redux";
import {
Cartesian3,
Color,
Math as CesiumMath,
LabelStyle,
PolylineDashMaterialProperty,
Cartesian2,
} from "cesium";
const lowCircle = (
<EllipsoidGraphics
radii={new Cartesian3(460000.0, 460000.0, 460000.0)}
innerRadii={new Cartesian3(415000.0, 415000.0, 415000.0)}
minimumCone={CesiumMath.toRadians(89.8)}
maximumCone={CesiumMath.toRadians(90.2)}
material={new Color(0.29, 0.46, 0.77, 1)}
/>
);
const highCircle = (
<EllipsoidGraphics
radii={new Cartesian3(460000.0, 460000.0, 460000.0)}
innerRadii={new Cartesian3(415000.0, 415000.0, 415000.0)}
minimumCone={CesiumMath.toRadians(89.8)}
maximumCone={CesiumMath.toRadians(90.2)}
material={new Color(0.99, 0.23, 0.23, 1)}
/>
);
// const labelText={
// '5月南极涛动','Rossby波列' , '印度洋海温异常(信号存储)', '6月青藏高原降水80个站点和加热'
// }
function Circles() {
const { viewer } = useCesium();
const dispatch = useDispatch();
const { run: showInfo } = useThrottleFn(
() => {
dispatch.data.updateImageLayer({ indianOcean: true });
dispatch.data.update({ showSite: true });
},
{
wait: 1000,
}
);
const { run: closeInfo } = useThrottleFn(
() => {
dispatch.data.updateImageLayer({ indianOcean: false });
dispatch.data.update({ showSite: false });
},
{
wait: 1000,
}
);
const Circle = ({ id, lon, lat, isLow, showTime }) => {
const circle = isLow ? lowCircle : highCircle;
const [show, setShow] = useState(false);
useInterval(() => {
const { startTime, currentTime, shouldAnimate } = viewer.clock;
const _time = Math.floor(
currentTime.secondsOfDay - startTime.secondsOfDay
);
if (!shouldAnimate) return;
if (_time === 20) {
showInfo();
} else if (_time === 0) {
closeInfo();
}
if (_time >= showTime) {
setShow(true);
} else {
if (!show) return;
setShow(false);
}
}, 300);
if (!show) return <></>;
return (
<Fragment>
<Entity
id={`${id}-up`}
position={Cartesian3.fromDegrees(lon, lat, 1000000)}
>
{circle}
<Entity id={`${id}-connection-line`}>
<PolylineGraphics
positions={Cartesian3.fromDegreesArrayHeights([
lon,
lat,
1000000,
lon,
lat,
0,
])}
width={2}
material={
new PolylineDashMaterialProperty({
color: Color.WHITE,
dashLength: 4,
})
}
/>
</Entity>
</Entity>
<Entity
id={`${id}-down`}
position={Cartesian3.fromDegrees(lon, lat, 0)}
>
{circle}
</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, 1000000)}
/>
</Entity>
</Fragment>
);
};
return (
<Fragment>
<Circle
isLow={true}
id={`low-circle-1`}
showTime={5}
lon={-110}
lat={-60}
/>
<Circle
isLow={false}
id={`height-circle-1`}
showTime={10}
lon={-30}
lat={-55}
/>
<Circle
isLow={true}
id={`low-circle-2`}
showTime={15}
lon={30}
lat={-40}
/>
<Circle
isLow={false}
id={`height-circle-2`}
showTime={20}
lon={65}
lat={-35}
/>
<Circle
isLow={true}
id={`low-circle-3`}
showTime={27}
lon={95}
lat={-30}
/>
</Fragment>
);
}
export default Circles;