feat(map): HNS ���� ���� ���� ? SR �ΰ��ڿ� ��������, ����Ʈ���� ����, ���̾� ���� ���� #160

병합
jhkang feature/hns 에서 develop 로 10 commits 를 머지했습니다 2026-04-06 22:38:38 +09:00
7개의 변경된 파일16개의 추가작업 그리고 32개의 파일을 삭제
Showing only changes of commit 7921bfef96 - Show all commits

파일 보기

@ -1,10 +1,10 @@
import { useEffect, useRef } from 'react';
import { useMap } from '@vis.gl/react-maplibre';
import type { HydrDataStep } from '@tabs/prediction/services/predictionApi';
import { useThemeStore } from '@common/store/themeStore';
interface HydrParticleOverlayProps {
hydrStep: HydrDataStep | null;
lightMode?: boolean;
}
const PARTICLE_COUNT = 3000;
@ -27,8 +27,8 @@ interface Particle {
export default function HydrParticleOverlay({
hydrStep,
lightMode = false,
}: HydrParticleOverlayProps) {
const lightMode = useThemeStore((s) => s.theme) === 'light';
const { current: map } = useMap();
const animRef = useRef<number>();

파일 보기

@ -18,6 +18,7 @@ import { useMeasureTool } from '@common/hooks/useMeasureTool'
import { hexToRgba } from './mapUtils'
import { S57EncOverlay } from './S57EncOverlay'
import { useMapStore } from '@common/store/mapStore'
import { useThemeStore } from '@common/store/themeStore'
import { useBaseMapStyle } from '@common/hooks/useBaseMapStyle'
const GEOSERVER_URL = import.meta.env.VITE_GEOSERVER_URL || 'http://localhost:8080'
@ -142,8 +143,6 @@ interface MapViewProps {
analysisPolygonPoints?: Array<{ lat: number; lon: number }>
analysisCircleCenter?: { lat: number; lon: number } | null
analysisCircleRadiusM?: number
/** 밝은 톤 지도 스타일 사용 (CartoDB Positron) */
lightMode?: boolean
/** false로 설정 시 WeatherInfoPanel, MapLegend, CoordinateDisplay 숨김 (기본: true) */
showOverlays?: boolean
}
@ -328,9 +327,9 @@ export function MapView({
analysisPolygonPoints = [],
analysisCircleCenter,
analysisCircleRadiusM = 0,
lightMode = false,
showOverlays = true,
}: MapViewProps) {
const lightMode = useThemeStore((s) => s.theme) === 'light'
const { mapToggles, measureMode, measureInProgress, measurements } = useMapStore()
const { handleMeasureClick } = useMeasureTool()
const isControlled = externalCurrentTime !== undefined
@ -1102,8 +1101,8 @@ export function MapView({
analysisPolygonPoints, analysisCircleCenter, analysisCircleRadiusM, lightMode,
])
// 3D 모드 / 밝은 톤에 따른 지도 스타일 전환
const currentMapStyle = useBaseMapStyle(lightMode)
// 3D 모드 / 테마에 따른 지도 스타일 전환
const currentMapStyle = useBaseMapStyle()
return (
<div className="w-full h-full relative">
@ -1164,7 +1163,7 @@ export function MapView({
{/* 해류 파티클 오버레이 */}
{hydrData.length > 0 && showCurrent && (
<HydrParticleOverlay hydrStep={hydrData[currentTime] ?? null} lightMode={lightMode} />
<HydrParticleOverlay hydrStep={hydrData[currentTime] ?? null} />
)}
{/* 사고 위치 마커 (MapLibre Marker) */}

파일 보기

@ -1,5 +1,6 @@
import type { StyleSpecification } from 'maplibre-gl';
import { useMapStore } from '@common/store/mapStore';
import { useThemeStore } from '@common/store/themeStore';
import {
BASE_STYLE,
LIGHT_STYLE,
@ -7,11 +8,12 @@ import {
ENC_EMPTY_STYLE,
} from '@common/components/map/mapStyles';
export function useBaseMapStyle(lightMode = false): StyleSpecification {
export function useBaseMapStyle(): StyleSpecification {
const theme = useThemeStore((s) => s.theme);
const mapToggles = useMapStore((s) => s.mapToggles);
if (mapToggles.s57) return ENC_EMPTY_STYLE;
if (mapToggles.threeD) return SATELLITE_3D_STYLE;
if (lightMode) return LIGHT_STYLE;
if (theme === 'light') return LIGHT_STYLE;
return BASE_STYLE;
}

파일 보기

@ -131,7 +131,7 @@ export function IncidentsView() {
const [baselineLoaded, setBaselineLoaded] = useState(() => getCachedBaseline() !== null && getCachedZones() !== null)
// Map style & toggles
const currentMapStyle = useBaseMapStyle(true)
const currentMapStyle = useBaseMapStyle()
const mapToggles = useMapStore((s) => s.mapToggles)
// Measure tool

파일 보기

@ -1240,7 +1240,6 @@ export function OilSpillView() {
sensitiveResourceGeojson={
displayControls.showSensitiveResources ? sensitiveResourceGeojson : null
}
lightMode
centerPoints={centerPoints.filter((p) =>
visibleModels.has((p.model || 'OpenDrift') as PredictionModel),
)}

파일 보기

@ -59,7 +59,6 @@ const MapSlot = ({ label, step, mapData, captured, onCapture, onReset }: MapSlot
simulationStartTime={mapData.simulationStartTime || undefined}
mapCaptureRef={captureRef}
showOverlays={false}
lightMode
/>
{captured && (

파일 보기

@ -2,27 +2,10 @@ import { useState, useEffect } from 'react';
import { Map, useControl } from '@vis.gl/react-maplibre';
import { MapboxOverlay } from '@deck.gl/mapbox';
import { ScatterplotLayer } from '@deck.gl/layers';
import type { StyleSpecification } from 'maplibre-gl';
import 'maplibre-gl/dist/maplibre-gl.css';
import type { ScatDetail } from './scatTypes';
import { hexToRgba } from '@common/components/map/mapUtils';
// ── 베이스맵 스타일 ──────────────────────────────────────
const BASE_STYLE: StyleSpecification = {
version: 8,
sources: {
'carto-dark': {
type: 'raster',
tiles: [
'https://a.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}@2x.png',
'https://b.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}@2x.png',
'https://c.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}@2x.png',
],
tileSize: 256,
},
},
layers: [{ id: 'carto-dark-layer', type: 'raster', source: 'carto-dark' }],
};
import { useBaseMapStyle } from '@common/hooks/useBaseMapStyle';
// ── DeckGLOverlay ──────────────────────────────────────
// eslint-disable-next-line @typescript-eslint/no-explicit-any
@ -94,12 +77,14 @@ function PopupMap({
}),
];
const currentMapStyle = useBaseMapStyle();
return (
<div className="relative w-full h-full">
<Map
key={`${lat}-${lng}`}
initialViewState={{ longitude: lng, latitude: lat, zoom: 15 }}
mapStyle={BASE_STYLE}
mapStyle={currentMapStyle}
style={{ width: '100%', height: '100%' }}
attributionControl={false}
onLoad={onMapLoad}