新增固有属性的样式计算

This commit is contained in:
JIANG
2025-12-29 11:17:43 +08:00
parent 187e8e93b4
commit 4b257aa959
2 changed files with 138 additions and 23 deletions

View File

@@ -195,6 +195,8 @@ const StyleEditorPanel: React.FC<StyleEditorPanelProps> = ({
setJunctionText,
setPipeText,
setContours,
diameterRange,
elevationRange,
} = data;
const { open } = useNotification();
@@ -398,10 +400,15 @@ const StyleEditorPanel: React.FC<StyleEditorPanelProps> = ({
layerType: "junctions" | "pipes",
styleConfig: any
) => {
const isElevation =
layerType === "junctions" && styleConfig.property === "elevation";
const isDiameter =
layerType === "pipes" && styleConfig.property === "diameter";
if (
layerType === "junctions" &&
currentJunctionCalData &&
currentJunctionCalData.length > 0
((currentJunctionCalData && currentJunctionCalData.length > 0) ||
(isElevation && elevationRange))
) {
// 应用节点样式
let junctionStyleConfigState = layerStyleStates.find(
@@ -411,6 +418,14 @@ const StyleEditorPanel: React.FC<StyleEditorPanelProps> = ({
// 更新节点数据属性
const segments = junctionStyleConfigState?.styleConfig.segments ?? 5;
let breaks: number[] = [];
const dataValues =
isElevation && elevationRange
? [elevationRange[0], elevationRange[1]]
: currentJunctionCalData?.map((d: any) => d.value) || [];
if (dataValues.length === 0) return;
if (
junctionStyleConfigState?.styleConfig.classificationMethod ===
"custom_breaks"
@@ -428,7 +443,7 @@ const StyleEditorPanel: React.FC<StyleEditorPanelProps> = ({
breaks.push(breaks[breaks.length - 1] ?? 0);
} else {
const calc = calculateClassification(
currentJunctionCalData.map((d) => d.value),
dataValues,
segments,
styleConfig.classificationMethod
);
@@ -439,12 +454,14 @@ const StyleEditorPanel: React.FC<StyleEditorPanelProps> = ({
return;
}
// 计算最大最小值,判断是否包含并插入 breaks
const data = currentJunctionCalData.map((d) => d.value);
const min_val = Math.max(
data.reduce((min, val) => Math.min(min, val), Infinity),
dataValues.reduce((min, val) => Math.min(min, val), Infinity),
0
);
const max_val = data.reduce((max, val) => Math.max(max, val), -Infinity);
const max_val = dataValues.reduce(
(max, val) => Math.max(max, val),
-Infinity
);
if (breaks.includes(min_val) === false) {
breaks.push(min_val);
breaks.sort((a, b) => a - b);
@@ -459,8 +476,8 @@ const StyleEditorPanel: React.FC<StyleEditorPanelProps> = ({
}
} else if (
layerType === "pipes" &&
currentPipeCalData &&
currentPipeCalData.length > 0
((currentPipeCalData && currentPipeCalData.length > 0) ||
(isDiameter && diameterRange))
) {
// 应用管道样式
let pipeStyleConfigState = layerStyleStates.find(
@@ -469,6 +486,14 @@ const StyleEditorPanel: React.FC<StyleEditorPanelProps> = ({
// 更新管道数据属性
const segments = pipeStyleConfigState?.styleConfig.segments ?? 5;
let breaks: number[] = [];
const dataValues =
isDiameter && diameterRange
? [diameterRange[0], diameterRange[1]]
: currentPipeCalData?.map((d: any) => d.value) || [];
if (dataValues.length === 0) return;
if (
pipeStyleConfigState?.styleConfig.classificationMethod ===
"custom_breaks"
@@ -485,7 +510,7 @@ const StyleEditorPanel: React.FC<StyleEditorPanelProps> = ({
breaks.push(breaks[breaks.length - 1] ?? 0);
} else {
const calc = calculateClassification(
currentPipeCalData.map((d) => d.value),
dataValues,
segments,
styleConfig.classificationMethod
);
@@ -496,12 +521,14 @@ const StyleEditorPanel: React.FC<StyleEditorPanelProps> = ({
return;
}
// 计算最大最小值,判断是否包含并插入 breaks
const data = currentPipeCalData.map((d) => d.value);
const min_val = Math.max(
data.reduce((min, val) => Math.min(min, val), Infinity),
dataValues.reduce((min, val) => Math.min(min, val), Infinity),
0
);
const max_val = data.reduce((max, val) => Math.max(max, val), -Infinity);
const max_val = dataValues.reduce(
(max, val) => Math.max(max, val),
-Infinity
);
if (breaks.includes(min_val) === false) {
breaks.push(min_val);
breaks.sort((a, b) => a - b);
@@ -883,16 +910,25 @@ const StyleEditorPanel: React.FC<StyleEditorPanelProps> = ({
prevStyleUpdateTriggerRef.current = styleUpdateTrigger;
const updateJunctionStyle = () => {
if (!currentJunctionCalData) return;
const junctionStyleConfigState = layerStyleStates.find(
(s) => s.layerId === "junctions"
);
const isElevation =
junctionStyleConfigState?.styleConfig.property === "elevation";
// setStyle() 会清除渲染器缓存,这是闪烁的主要原因 WebGLVectorTile.js:114-118
// 尝试考虑使用 updateStyleVariables() 更新
applyClassificationStyle(
"junctions",
junctionStyleConfigState?.styleConfig
);
if (isElevation) {
removeVectorTileSourceLoadedEvent("junctions");
return;
}
if (!currentJunctionCalData) return;
// 更新现有的 VectorTileSource
updateVectorTileSource(junctionText, currentJunctionCalData);
// 移除旧的监听器,并添加新的监听器
@@ -904,11 +940,20 @@ const StyleEditorPanel: React.FC<StyleEditorPanelProps> = ({
);
};
const updatePipeStyle = () => {
if (!currentPipeCalData) return;
const pipeStyleConfigState = layerStyleStates.find(
(s) => s.layerId === "pipes"
);
const isDiameter =
pipeStyleConfigState?.styleConfig.property === "diameter";
applyClassificationStyle("pipes", pipeStyleConfigState?.styleConfig);
if (isDiameter) {
removeVectorTileSourceLoadedEvent("pipes");
return;
}
if (!currentPipeCalData) return;
// 更新现有的 VectorTileSource
updateVectorTileSource(pipeText, currentPipeCalData);
// 移除旧的监听器,并添加新的监听器
@@ -923,14 +968,21 @@ const StyleEditorPanel: React.FC<StyleEditorPanelProps> = ({
}
return;
}
const isElevation = junctionText === "elevation";
const isDiameter = pipeText === "diameter";
if (
applyJunctionStyle &&
currentJunctionCalData &&
currentJunctionCalData.length > 0
((currentJunctionCalData && currentJunctionCalData.length > 0) ||
isElevation)
) {
updateJunctionStyle();
}
if (applyPipeStyle && currentPipeCalData && currentPipeCalData.length > 0) {
if (
applyPipeStyle &&
((currentPipeCalData && currentPipeCalData.length > 0) || isDiameter)
) {
updatePipeStyle();
}
if (!applyJunctionStyle) {
@@ -945,6 +997,8 @@ const StyleEditorPanel: React.FC<StyleEditorPanelProps> = ({
applyPipeStyle,
currentJunctionCalData,
currentPipeCalData,
elevationRange,
diameterRange,
]);
// 获取地图中的矢量图层,用于选择图层选项
@@ -1018,10 +1072,21 @@ const StyleEditorPanel: React.FC<StyleEditorPanelProps> = ({
const selectedLayerId = selectedRenderLayer?.get("value");
let dataArr: number[] = [];
if (selectedLayerId === "junctions" && currentJunctionCalData)
dataArr = currentJunctionCalData.map((d) => d.value);
else if (selectedLayerId === "pipes" && currentPipeCalData)
dataArr = currentPipeCalData.map((d) => d.value);
const isElevation =
selectedLayerId === "junctions" && styleConfig.property === "elevation";
const isDiameter =
selectedLayerId === "pipes" && styleConfig.property === "diameter";
if (isElevation && elevationRange) {
dataArr = [elevationRange[0], elevationRange[1]];
} else if (isDiameter && diameterRange) {
dataArr = [diameterRange[0], diameterRange[1]];
} else if (selectedLayerId === "junctions" && currentJunctionCalData) {
dataArr = currentJunctionCalData.map((d: any) => d.value);
} else if (selectedLayerId === "pipes" && currentPipeCalData) {
dataArr = currentPipeCalData.map((d: any) => d.value);
}
let defaultBreaks: number[] = Array.from({ length: numBreaks }, () => 0);
if (dataArr && dataArr.length > 0) {
@@ -1041,9 +1106,12 @@ const StyleEditorPanel: React.FC<StyleEditorPanelProps> = ({
}, [
styleConfig.classificationMethod,
styleConfig.segments,
styleConfig.property,
selectedRenderLayer,
currentJunctionCalData,
currentPipeCalData,
elevationRange,
diameterRange,
]);
// 初始化或调整自定义颜色数组长度