refactor(map): UI 개선 — 3D 명칭, 수심 줌, 레거시 비활성

- "지구본" → "3D" 명칭 변경, 헤더 우측으로 이동
- 레거시 베이스맵 비활성 (주석처리)
- 수심 minzoom 통일: fill 3, borders 5, major 3
- NavigationControl 통합, 기어 버튼 겹침 수정
- constants.ts 미사용 BATHY_ZOOM_RANGES 제거

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
htlee 2026-02-16 07:04:31 +09:00
부모 d2178a6134
커밋 3acda7432e
5개의 변경된 파일30개의 추가작업 그리고 34개의 파일을 삭제

파일 보기

@ -925,7 +925,7 @@ body {
.map-settings-gear { .map-settings-gear {
position: absolute; position: absolute;
top: 95px; top: 100px;
left: 10px; left: 10px;
z-index: 850; z-index: 850;
width: 29px; width: 29px;

파일 보기

@ -113,7 +113,9 @@ export function DashboardPage() {
const [showTargets, setShowTargets] = useState(true); const [showTargets, setShowTargets] = useState(true);
const [showOthers, setShowOthers] = useState(false); const [showOthers, setShowOthers] = useState(false);
const [baseMap, setBaseMap] = useState<BaseMapId>("enhanced"); // 레거시 베이스맵 비활성 — 향후 위성/라이트 등 추가 시 재활용
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const [baseMap, _setBaseMap] = useState<BaseMapId>("enhanced");
const [projection, setProjection] = useState<MapProjectionId>("mercator"); const [projection, setProjection] = useState<MapProjectionId>("mercator");
const [mapStyleSettings, setMapStyleSettings] = useState<MapStyleSettings>(DEFAULT_MAP_STYLE_SETTINGS); const [mapStyleSettings, setMapStyleSettings] = useState<MapStyleSettings>(DEFAULT_MAP_STYLE_SETTINGS);
@ -357,30 +359,28 @@ export function DashboardPage() {
</div> </div>
<div className="sb"> <div className="sb">
<div className="sb-t"> </div> <div className="sb-t" style={{ display: "flex", alignItems: "center" }}>
<MapToggles value={overlays} onToggle={(k) => setOverlays((prev) => ({ ...prev, [k]: !prev[k] }))} />
<div style={{ fontSize: 9, fontWeight: 700, color: "var(--muted)", letterSpacing: 1.5, marginTop: 8, marginBottom: 6 }}> <div style={{ flex: 1 }} />
<div
className={`tog-btn ${projection === "globe" ? "on" : ""}`}
onClick={() => setProjection((p) => (p === "globe" ? "mercator" : "globe"))}
title="3D 지구본 투영: 드래그로 회전, 휠로 확대/축소"
style={{ fontSize: 9, padding: "2px 8px" }}
>
3D
</div>
</div> </div>
<div className="tog" style={{ flexWrap: "nowrap", alignItems: "center" }}> <MapToggles value={overlays} onToggle={(k) => setOverlays((prev) => ({ ...prev, [k]: !prev[k] }))} />
{/* enhanced ,
<div className="tog" style={{ flexWrap: "nowrap", alignItems: "center", marginTop: 8 }}>
<div className={`tog-btn ${baseMap === "enhanced" ? "on" : ""}`} onClick={() => setBaseMap("enhanced")} title="현재 지도(해저지형/3D 표현 포함)"> <div className={`tog-btn ${baseMap === "enhanced" ? "on" : ""}`} onClick={() => setBaseMap("enhanced")} title="현재 지도(해저지형/3D 표현 포함)">
</div> </div>
<div className={`tog-btn ${baseMap === "legacy" ? "on" : ""}`} onClick={() => setBaseMap("legacy")} title="레거시 대시보드(Carto Dark) 베이스맵"> <div className={`tog-btn ${baseMap === "legacy" ? "on" : ""}`} onClick={() => setBaseMap("legacy")} title="레거시 대시보드(Carto Dark) 베이스맵">
</div> </div>
</div> */}
<div style={{ flex: 1 }} />
<div
className={`tog-btn ${projection === "globe" ? "on" : ""}`}
onClick={() => setProjection((p) => (p === "globe" ? "mercator" : "globe"))}
title="지구본(globe) 투영: 드래그로 회전, 휠로 확대/축소"
>
</div>
</div>
{/* Attribution (license) stays visible in the map UI; no need to repeat it here. */}
</div> </div>
<div className="sb"> <div className="sb">

파일 보기

@ -3,7 +3,6 @@ import {
OVERLAY_RGB, OVERLAY_RGB,
rgba as rgbaCss, rgba as rgbaCss,
} from '../../shared/lib/map/palette'; } from '../../shared/lib/map/palette';
import type { BathyZoomRange } from './types';
// ── Re-export palette aliases used throughout Map3D ── // ── Re-export palette aliases used throughout Map3D ──
@ -158,9 +157,5 @@ export const FLEET_LINE_ML = rgbaCss(OVERLAY_FLEET_RANGE_RGB, 0.65);
export const FLEET_LINE_ML_HL = rgbaCss(OVERLAY_FLEET_RANGE_RGB, 0.95); export const FLEET_LINE_ML_HL = rgbaCss(OVERLAY_FLEET_RANGE_RGB, 0.95);
// ── Bathymetry zoom ranges ── // ── Bathymetry zoom ranges ──
// NOTE: BATHY_ZOOM_RANGES는 bathymetry.ts에서 로컬 정의 + applyBathymetryZoomProfile()에서 사용
export const BATHY_ZOOM_RANGES: BathyZoomRange[] = [ // 이 파일의 export는 사용처가 없어 제거됨 (2026-02-16)
{ id: 'bathymetry-fill', mercator: [5, 24], globe: [7, 24] },
{ id: 'bathymetry-borders', mercator: [5, 24], globe: [7, 24] },
{ id: 'bathymetry-borders-major', mercator: [3, 24], globe: [7, 24] },
];

파일 보기

@ -91,8 +91,7 @@ export function useMapInit(
scrollZoom: { around: 'center' }, scrollZoom: { around: 'center' },
}); });
map.addControl(new maplibregl.NavigationControl({ showZoom: true, showCompass: false }), 'top-left'); map.addControl(new maplibregl.NavigationControl({ showZoom: true, showCompass: true }), 'top-left');
map.addControl(new maplibregl.NavigationControl({ showZoom: false, showCompass: true }), 'top-left');
map.addControl(new maplibregl.ScaleControl({ maxWidth: 120, unit: 'metric' }), 'bottom-left'); map.addControl(new maplibregl.ScaleControl({ maxWidth: 120, unit: 'metric' }), 'bottom-left');
mapRef.current = map; mapRef.current = map;

파일 보기

@ -10,9 +10,9 @@ export const SHALLOW_WATER_FILL_DEFAULT = '#14606e';
export const SHALLOW_WATER_LINE_DEFAULT = '#114f5c'; export const SHALLOW_WATER_LINE_DEFAULT = '#114f5c';
const BATHY_ZOOM_RANGES: BathyZoomRange[] = [ const BATHY_ZOOM_RANGES: BathyZoomRange[] = [
{ id: 'bathymetry-fill', mercator: [6, 24], globe: [8, 24] }, { id: 'bathymetry-fill', mercator: [3, 24], globe: [3, 24] },
{ id: 'bathymetry-borders', mercator: [6, 24], globe: [8, 24] }, { id: 'bathymetry-borders', mercator: [5, 24], globe: [5, 24] },
{ id: 'bathymetry-borders-major', mercator: [4, 24], globe: [8, 24] }, { id: 'bathymetry-borders-major', mercator: [3, 24], globe: [3, 24] },
]; ];
export function injectOceanBathymetryLayers(style: StyleSpecification, maptilerKey: string) { export function injectOceanBathymetryLayers(style: StyleSpecification, maptilerKey: string) {
@ -69,7 +69,7 @@ export function injectOceanBathymetryLayers(style: StyleSpecification, maptilerK
type: 'fill', type: 'fill',
source: oceanSourceId, source: oceanSourceId,
'source-layer': 'contour', 'source-layer': 'contour',
minzoom: 5, minzoom: 3,
maxzoom: 24, maxzoom: 24,
paint: { paint: {
'fill-color': bathyFillColor, 'fill-color': bathyFillColor,
@ -82,7 +82,7 @@ export function injectOceanBathymetryLayers(style: StyleSpecification, maptilerK
type: 'line', type: 'line',
source: oceanSourceId, source: oceanSourceId,
'source-layer': 'contour', 'source-layer': 'contour',
minzoom: 5, minzoom: 5, // fill은 3부터, borders는 5부터
maxzoom: 24, maxzoom: 24,
paint: { paint: {
'line-color': 'rgba(255,255,255,0.06)', 'line-color': 'rgba(255,255,255,0.06)',
@ -304,6 +304,8 @@ export async function resolveInitialMapStyle(signal: AbortSignal): Promise<strin
} }
export async function resolveMapStyle(baseMap: BaseMapId, signal: AbortSignal): Promise<string | StyleSpecification> { export async function resolveMapStyle(baseMap: BaseMapId, signal: AbortSignal): Promise<string | StyleSpecification> {
if (baseMap === 'legacy') return '/map/styles/carto-dark.json'; // 레거시 베이스맵 비활성 — 향후 위성/라이트 테마 등 추가 시 재활용
// if (baseMap === 'legacy') return '/map/styles/carto-dark.json';
void baseMap;
return resolveInitialMapStyle(signal); return resolveInitialMapStyle(signal);
} }