fix(map): stabilize tiled style rendering

This commit is contained in:
2026-07-17 15:12:10 +08:00
parent 59447a100c
commit 589cf45aa7
28 changed files with 3884 additions and 2461 deletions
@@ -1,9 +1,13 @@
import { Map as OlMap, VectorTile } from "ol";
import { Map as OlMap } from "ol";
import WebGLVectorTileLayer from "ol/layer/WebGLVectorTile";
import VectorTileSource from "ol/source/VectorTile";
import { FlatStyleLike } from "ol/style/flat";
import { config } from "@/config/config";
import {
VectorTileStyleSession,
versionedPropertyCase,
} from "@components/olmap/core/vectorTileStyleSession";
import { getAreaColor } from "./utils";
const JUNCTION_LAYER_VALUE = "junctions";
@@ -83,40 +87,6 @@ export const applyJunctionAreaRender = (
}
});
const applyFeatureAreaIndex = (renderFeature: any) => {
const featureId = String(renderFeature.get("id") ?? "");
const areaIndex = nodeAreaIndexMap.get(featureId);
if (areaIndex !== undefined) {
renderFeature.properties_[propertyKey] = areaIndex;
}
};
const sourceTiles = (source as any).sourceTiles_;
if (sourceTiles) {
Object.values(sourceTiles).forEach((vectorTile: any) => {
const renderFeatures = vectorTile.getFeatures();
if (!renderFeatures || renderFeatures.length === 0) return;
renderFeatures.forEach((renderFeature: any) => {
applyFeatureAreaIndex(renderFeature);
});
});
}
const listener = (event: any) => {
try {
if (!(event.tile instanceof VectorTile)) return;
const renderFeatures = event.tile.getFeatures();
if (!renderFeatures || renderFeatures.length === 0) return;
renderFeatures.forEach((renderFeature: any) => {
applyFeatureAreaIndex(renderFeature);
});
} catch (error) {
console.error("Error applying junction area render:", error);
}
};
source.on("tileloadend", listener);
const fillCases: any[] = [];
areaIds.forEach((areaId, index) => {
fillCases.push(
@@ -131,14 +101,34 @@ export const applyJunctionAreaRender = (
);
junctionLayer.set(RENDER_OWNER_KEY, ownerId);
junctionLayer.setStyle({
...config.MAP_DEFAULT_STYLE,
"circle-fill-color": ["case", ...fillCases, defaultFillColor],
"circle-stroke-color": ["case", ...fillCases, defaultStrokeColor],
} as FlatStyleLike);
const session = new VectorTileStyleSession({
layer: junctionLayer,
source,
propertyKey,
defaultStyle: config.MAP_DEFAULT_STYLE as FlatStyleLike,
buildStyle: (statePropertyKey, versionKey, version) =>
({
...config.MAP_DEFAULT_STYLE,
"circle-fill-color": versionedPropertyCase(
statePropertyKey,
versionKey,
version,
fillCases,
defaultFillColor,
),
"circle-stroke-color": versionedPropertyCase(
statePropertyKey,
versionKey,
version,
fillCases,
defaultStrokeColor,
),
}) as FlatStyleLike,
});
session.commit(nodeAreaIndexMap);
return () => {
source.un("tileloadend", listener);
session.dispose();
if (junctionLayer.get(RENDER_OWNER_KEY) === ownerId) {
junctionLayer.unset(RENDER_OWNER_KEY, true);
junctionLayer.setStyle(config.MAP_DEFAULT_STYLE as FlatStyleLike);