更新地图样式;调整时间轴,新增前进/后退一天按钮;新增爆管分析页面

This commit is contained in:
JIANG
2025-10-22 11:50:20 +08:00
parent 69b2e4fb98
commit 720f8a5dc2
12 changed files with 1557 additions and 59 deletions

View File

@@ -29,6 +29,7 @@ import { calculateClassification } from "@utils/breaks_classification";
import { parseColor } from "@utils/parseColor";
import { VectorTile } from "ol";
import { useNotification } from "@refinedev/core";
import { config } from "@/config/config";
interface StyleConfig {
property: string;
@@ -64,6 +65,9 @@ const SINGLE_COLOR_PALETTES = [
{
color: "rgba(51, 153, 204, 1)",
},
{
color: "rgba(255, 138, 92, 1)",
},
{
color: "rgba(204, 51, 51, 1)",
},
@@ -405,6 +409,25 @@ const StyleEditorPanel: React.FC = () => {
conditions.push(dimensions[i]);
}
conditions.push(dimensions[dimensions.length - 1]);
console.log("生成的尺寸条件表达式:", conditions);
return conditions;
};
const generateDimensionPointConditions = (property: string): any[] => {
const conditions: any[] = ["case"];
for (let i = 0; i < breaks.length; i++) {
conditions.push(["<=", ["get", property], breaks[i]]);
conditions.push([
"interpolate",
["linear"],
["zoom"],
12,
1, // 使用配置的最小尺寸
24,
dimensions[i],
]);
}
conditions.push(dimensions[dimensions.length - 1]);
console.log("生成的点尺寸条件表达式:", conditions);
return conditions;
};
// 创建基于 breaks 的动态 FlatStyle
@@ -422,7 +445,7 @@ const StyleEditorPanel: React.FC = () => {
dynamicStyle["circle-fill-color"] = generateColorConditions(
styleConfig.property
);
dynamicStyle["circle-radius"] = generateDimensionConditions(
dynamicStyle["circle-radius"] = generateDimensionPointConditions(
styleConfig.property
);
dynamicStyle["circle-stroke-color"] = generateColorConditions(
@@ -456,21 +479,7 @@ const StyleEditorPanel: React.FC = () => {
const resetStyle = useCallback(() => {
if (!selectedRenderLayer) return;
// 重置 WebGL 图层样式
const defaultFlatStyle: FlatStyleLike = {
"stroke-width": 3,
"stroke-color": "rgba(51, 153, 204, 0.9)",
"circle-fill-color": "rgba(255,255,255,0.4)",
"circle-stroke-color": "rgba(255,255,255,0.9)",
"circle-radius": [
"interpolate",
["linear"],
["zoom"],
12,
1, // 在缩放级别 12 时,圆形半径为 1px
24,
12, // 在缩放级别 24 时,圆形半径为 12px
],
};
const defaultFlatStyle: FlatStyleLike = config.mapDefaultStyle;
selectedRenderLayer.setStyle(defaultFlatStyle);
// 删除对应图层的样式状态,从而移除图例显示
@@ -531,6 +540,7 @@ const StyleEditorPanel: React.FC = () => {
const [tileLoadListeners, setTileLoadListeners] = useState<
Map<VectorTileSource, (event: any) => void>
>(new Map());
const attachVectorTileSourceLoadedEvent = (
layerId: string,
property: string,

View File

@@ -23,6 +23,7 @@ import { AdapterDateFns } from "@mui/x-date-pickers/AdapterDateFns";
import { zhCN } from "date-fns/locale";
import { PlayArrow, Pause, Stop, Refresh } from "@mui/icons-material";
import { TbRewindBackward15, TbRewindForward15 } from "react-icons/tb";
import { FiSkipBack, FiSkipForward } from "react-icons/fi";
import { useData } from "../MapComponent";
import { config } from "@/config/config";
import { useMap } from "../MapComponent";
@@ -210,7 +211,7 @@ const Timeline: React.FC = () => {
type: "error",
message: "请至少设定并应用一个图层的样式。",
});
return;
// return;
}
setIsPlaying(true);
@@ -233,7 +234,10 @@ const Timeline: React.FC = () => {
const handleStop = useCallback(() => {
setIsPlaying(false);
setCurrentTime(0);
// 设置为当前时间
const currentTime = new Date();
const minutes = currentTime.getHours() * 60 + currentTime.getMinutes();
setCurrentTime(minutes); // 组件卸载时重置时间
if (intervalRef.current) {
clearInterval(intervalRef.current);
intervalRef.current = null;
@@ -241,6 +245,20 @@ const Timeline: React.FC = () => {
}, []);
// 步进控制
const handleDayStepBackward = useCallback(() => {
setSelectedDate((prev) => {
const newDate = new Date(prev);
newDate.setDate(newDate.getDate() - 1);
return newDate;
});
}, []);
const handleDayStepForward = useCallback(() => {
setSelectedDate((prev) => {
const newDate = new Date(prev);
newDate.setDate(newDate.getDate() + 1);
return newDate;
});
}, []);
const handleStepBackward = useCallback(() => {
setCurrentTime((prev) => {
const next = prev <= 0 ? 1440 : prev - 15;
@@ -299,7 +317,7 @@ const Timeline: React.FC = () => {
type: "error",
message: "请至少设定并应用一个图层的样式。",
});
return;
// return;
}
fetchFrameData(
currentTimeToDate(selectedDate, currentTime),
@@ -311,7 +329,12 @@ const Timeline: React.FC = () => {
// 组件卸载时清理定时器和防抖
useEffect(() => {
setCurrentTime(0); // 组件卸载时重置时间
// 设置为当前时间
const currentTime = new Date();
const minutes = currentTime.getHours() * 60 + currentTime.getMinutes();
// 找到最近的前15分钟刻度
const roundedMinutes = Math.floor(minutes / 15) * 15;
setCurrentTime(roundedMinutes); // 组件卸载时重置时间
return () => {
if (intervalRef.current) {
@@ -363,6 +386,15 @@ const Timeline: React.FC = () => {
alignItems="center"
sx={{ mb: 2, flexWrap: "wrap", gap: 1 }}
>
<Tooltip title="后退一天">
<IconButton
color="primary"
onClick={handleDayStepBackward}
size="small"
>
<FiSkipBack />
</IconButton>
</Tooltip>
{/* 日期选择器 */}
<DatePicker
label="模拟数据日期选择"
@@ -379,9 +411,20 @@ const Timeline: React.FC = () => {
sx={{ width: 180, "& .MuiInputBase-root": { height: 40 } }}
maxDate={new Date()} // 禁止选取未来的日期
/>
<Tooltip title="前进一天">
<IconButton
color="primary"
onClick={handleDayStepForward}
size="small"
disabled={
selectedDate.toDateString() === new Date().toDateString()
}
>
<FiSkipForward />
</IconButton>
</Tooltip>
{/* 播放控制按钮 */}
<Box sx={{ display: "flex", gap: 1 }}>
<Box sx={{ display: "flex", gap: 1 }} className="ml-4">
{/* 播放间隔选择 */}
<FormControl size="small" sx={{ minWidth: 100 }}>
<InputLabel></InputLabel>
@@ -434,7 +477,7 @@ const Timeline: React.FC = () => {
</IconButton>
</Tooltip>
</Box>
<Box sx={{ display: "flex", gap: 1 }}>
<Box sx={{ display: "flex", gap: 1 }} className="ml-4">
{/* 强制计算时间段 */}
<FormControl size="small" sx={{ minWidth: 100 }}>
<InputLabel></InputLabel>

View File

@@ -21,6 +21,7 @@ import VectorTileSource from "ol/source/VectorTile";
import TileState from "ol/TileState";
import { toLonLat } from "ol/proj";
import { booleanIntersects, buffer, point, toWgs84 } from "@turf/turf";
// import { handleMapClickSelectFeatures as mapClickSelectFeatures } from "@/utils/mapQueryService";
import RenderFeature from "ol/render/Feature";
import { config } from "@/config/config";
@@ -329,7 +330,13 @@ const Toolbar: React.FC<ToolbarProps> = ({ hiddenButtons }) => {
},
[map, highlightLayer, setHighlightFeature]
);
// const handleMapClickSelectFeatures = useCallback(
// (event: { coordinate: number[] }) => {
// if (!map) return;
// mapClickSelectFeatures(event, map, setHighlightFeature); // 调用导入的函数
// },
// [map, setHighlightFeature]
// );
// 添加矢量属性查询事件监听器
useEffect(() => {
if (!activeTools.includes("info") || !map) return;