From 84d602d25b5357892a613de8ce71e97380bfb3b1 Mon Sep 17 00:00:00 2001 From: htlee Date: Sun, 15 Feb 2026 13:14:03 +0900 Subject: [PATCH] fix(globe): avoid bathymetry overflow; fix ship halo expr --- apps/web/src/widgets/map3d/Map3D.tsx | 37 +++++++++++++++++++++------- 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/apps/web/src/widgets/map3d/Map3D.tsx b/apps/web/src/widgets/map3d/Map3D.tsx index 47497e6..fb7685a 100644 --- a/apps/web/src/widgets/map3d/Map3D.tsx +++ b/apps/web/src/widgets/map3d/Map3D.tsx @@ -754,11 +754,21 @@ export function Map3D({ const apply = () => { if (!map.isStyleLoaded()) return; - const disableBathy3D = projection === "globe" && baseMap === "enhanced"; - const vis = disableBathy3D ? "none" : "visible"; - for (const id of ["bathymetry-extrusion", "bathymetry-hillshade"]) { + const disableBathyHeavy = projection === "globe" && baseMap === "enhanced"; + const visHeavy = disableBathyHeavy ? "none" : "visible"; + + // Globe + our injected bathymetry fill polygons can exceed MapLibre's per-segment vertex limit + // (65535), causing broken ocean rendering. Keep globe mode stable by disabling the heavy fill. + const heavyIds = [ + "bathymetry-fill", + "bathymetry-borders", + "bathymetry-borders-major", + "bathymetry-extrusion", + "bathymetry-hillshade", + ]; + for (const id of heavyIds) { try { - if (map.getLayer(id)) map.setLayoutProperty(id, "visibility", vis); + if (map.getLayer(id)) map.setLayoutProperty(id, "visibility", visHeavy); } catch { // ignore } @@ -1019,12 +1029,21 @@ export function Map3D({ } const visibility = settings.showShips ? "visible" : "none"; + const isSelected = ["boolean", ["feature-state", "selected"], false] as const; + // Style-spec restriction: only one zoom-based step/interpolate is allowed in an expression. const circleRadius = [ - "case", - ["boolean", ["feature-state", "selected"], false], - ["interpolate", ["linear"], ["zoom"], 3, 5, 7, 8, 10, 10, 14, 14], - ["interpolate", ["linear"], ["zoom"], 3, 4, 7, 6, 10, 8, 14, 11], - ] as unknown as number[]; + "interpolate", + ["linear"], + ["zoom"], + 3, + ["case", isSelected, 5, 4], + 7, + ["case", isSelected, 8, 6], + 10, + ["case", isSelected, 10, 8], + 14, + ["case", isSelected, 14, 11], + ] as const; // Put ships at the top so they're always visible (especially important under globe projection). const before = undefined;