diff --git a/frontend/src/tabs/incidents/components/IncidentsView.tsx b/frontend/src/tabs/incidents/components/IncidentsView.tsx
index ef6516f..b0f7f73 100755
--- a/frontend/src/tabs/incidents/components/IncidentsView.tsx
+++ b/frontend/src/tabs/incidents/components/IncidentsView.tsx
@@ -3,8 +3,9 @@ import { Map as MapLibre, Popup, useControl, useMap } from '@vis.gl/react-maplib
import { MapboxOverlay } from '@deck.gl/mapbox'
import { ScatterplotLayer, IconLayer, PathLayer, TextLayer, GeoJsonLayer } from '@deck.gl/layers'
import { PathStyleExtension } from '@deck.gl/extensions'
-import type { StyleSpecification } from 'maplibre-gl'
import 'maplibre-gl/dist/maplibre-gl.css'
+import { useBaseMapStyle } from '@common/hooks/useBaseMapStyle'
+import { S57EncOverlay } from '@common/components/map/S57EncOverlay'
import { IncidentsLeftPanel, type Incident } from './IncidentsLeftPanel'
import { IncidentsRightPanel, type ViewMode, type AnalysisSection } from './IncidentsRightPanel'
import { mockVessels, VESSEL_LEGEND, type Vessel } from '@common/mock/vesselMockData'
@@ -43,24 +44,6 @@ function getCategoryColor(index: number): [number, number, number] {
return CATEGORY_PALETTE[index % CATEGORY_PALETTE.length]
}
-// ── CartoDB Positron 베이스맵 (밝은 테마) ────────────────
-const BASE_STYLE: StyleSpecification = {
- version: 8,
- sources: {
- 'carto-light': {
- type: 'raster',
- tiles: [
- 'https://a.basemaps.cartocdn.com/light_all/{z}/{x}/{y}@2x.png',
- 'https://b.basemaps.cartocdn.com/light_all/{z}/{x}/{y}@2x.png',
- 'https://c.basemaps.cartocdn.com/light_all/{z}/{x}/{y}@2x.png',
- ],
- tileSize: 256,
- attribution: '©
OpenStreetMap',
- },
- },
- layers: [{ id: 'carto-light-layer', type: 'raster', source: 'carto-light' }],
-}
-
// ── DeckGLOverlay ──────────────────────────────────────
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function DeckGLOverlay({ layers }: { layers: any[] }) {
@@ -146,6 +129,10 @@ export function IncidentsView() {
const [dischargeMode, setDischargeMode] = useState(false)
const [dischargeInfo, setDischargeInfo] = useState<{ lat: number; lon: number; distanceNm: number } | null>(null)
+ // Map style & toggles
+ const currentMapStyle = useBaseMapStyle(true)
+ const mapToggles = useMapStore((s) => s.mapToggles)
+
// Measure tool
const { handleMeasureClick, measureMode } = useMeasureTool()
const measureInProgress = useMapStore((s) => s.measureInProgress)
@@ -616,7 +603,7 @@ export function IncidentsView() {
{
@@ -633,6 +620,7 @@ export function IncidentsView() {
}}
cursor={(measureMode !== null || dischargeMode) ? 'crosshair' : undefined}
>
+
diff --git a/frontend/src/tabs/scat/components/ScatMap.tsx b/frontend/src/tabs/scat/components/ScatMap.tsx
index dfe87c2..54f7e3d 100644
--- a/frontend/src/tabs/scat/components/ScatMap.tsx
+++ b/frontend/src/tabs/scat/components/ScatMap.tsx
@@ -2,30 +2,15 @@ import { useState, useMemo, useCallback, useEffect, useRef } from 'react'
import { Map, useControl, useMap } from '@vis.gl/react-maplibre'
import { MapboxOverlay } from '@deck.gl/mapbox'
import { PathLayer, ScatterplotLayer } from '@deck.gl/layers'
-import type { StyleSpecification } from 'maplibre-gl'
import 'maplibre-gl/dist/maplibre-gl.css'
+import { useBaseMapStyle } from '@common/hooks/useBaseMapStyle'
+import { S57EncOverlay } from '@common/components/map/S57EncOverlay'
+import { useMapStore } from '@common/store/mapStore'
import type { ScatSegment } from './scatTypes'
import type { ApiZoneItem } from '../services/scatApi'
import { esiColor } from './scatConstants'
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,
- attribution: '© OSM © CARTO',
- },
- },
- layers: [{ id: 'carto-dark-layer', type: 'raster', source: 'carto-dark' }],
-}
-
interface ScatMapProps {
segments: ScatSegment[]
zones: ApiZoneItem[]
@@ -118,6 +103,9 @@ interface TooltipState {
// ── ScatMap ─────────────────────────────────────────────
function ScatMap({ segments, zones, selectedSeg, jurisdictionFilter, onSelectSeg, onOpenPopup }: ScatMapProps) {
+ const currentMapStyle = useBaseMapStyle()
+ const mapToggles = useMapStore((s) => s.mapToggles)
+
const [zoom, setZoom] = useState(10)
const [tooltip, setTooltip] = useState(null)
@@ -266,11 +254,12 @@ function ScatMap({ segments, zones, selectedSeg, jurisdictionFilter, onSelectSeg
}
return { longitude: 126.55, latitude: 33.38, zoom: 10 };
})()}
- mapStyle={BASE_STYLE}
+ mapStyle={currentMapStyle}
className="w-full h-full"
attributionControl={false}
onZoom={e => setZoom(e.viewState.zoom)}
>
+
diff --git a/frontend/src/tabs/weather/components/WeatherView.tsx b/frontend/src/tabs/weather/components/WeatherView.tsx
index 40a7450..653ac49 100755
--- a/frontend/src/tabs/weather/components/WeatherView.tsx
+++ b/frontend/src/tabs/weather/components/WeatherView.tsx
@@ -2,8 +2,11 @@ import { useState, useMemo, useCallback } from 'react'
import { Map, Marker, useControl } from '@vis.gl/react-maplibre'
import { MapboxOverlay } from '@deck.gl/mapbox'
import type { Layer } from '@deck.gl/core'
-import type { StyleSpecification, MapLayerMouseEvent } from 'maplibre-gl'
+import type { MapLayerMouseEvent } from 'maplibre-gl'
import 'maplibre-gl/dist/maplibre-gl.css'
+import { useBaseMapStyle } from '@common/hooks/useBaseMapStyle'
+import { S57EncOverlay } from '@common/components/map/S57EncOverlay'
+import { useMapStore } from '@common/store/mapStore'
import { WeatherRightPanel } from './WeatherRightPanel'
import { WeatherMapOverlay, useWeatherDeckLayers } from './WeatherMapOverlay'
// import { OceanForecastOverlay } from './OceanForecastOverlay'
@@ -82,33 +85,6 @@ const generateForecast = (timeOffset: TimeOffset): WeatherForecast[] => {
return forecasts
}
-// CartoDB Dark Matter 스타일 (기존 WeatherView와 동일)
-const WEATHER_MAP_STYLE: StyleSpecification = {
- version: 8,
- sources: {
- 'carto-dark': {
- type: 'raster',
- tiles: [
- 'https://a.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}.png',
- 'https://b.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}.png',
- 'https://c.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}.png',
- ],
- tileSize: 256,
- attribution:
- '© OpenStreetMap © CARTO',
- },
- },
- layers: [
- {
- id: 'carto-dark-layer',
- type: 'raster',
- source: 'carto-dark',
- minzoom: 0,
- maxzoom: 22,
- },
- ],
-}
-
// 한국 해역 중심 좌표 (한반도 중앙)
const WEATHER_MAP_CENTER: [number, number] = [127.8, 36.5] // [lng, lat]
const WEATHER_MAP_ZOOM = 7
@@ -226,6 +202,8 @@ function WeatherMapInner({
export function WeatherView() {
const { weatherStations, loading, error, lastUpdate } = useWeatherData(BASE_STATIONS)
+ const currentMapStyle = useBaseMapStyle()
+ const mapToggles = useMapStore((s) => s.mapToggles)
// const {
@@ -373,11 +351,12 @@ export function WeatherView() {
latitude: WEATHER_MAP_CENTER[1],
zoom: WEATHER_MAP_ZOOM,
}}
- mapStyle={WEATHER_MAP_STYLE}
+ mapStyle={currentMapStyle}
className="w-full h-full"
onClick={handleMapClick}
attributionControl={false}
>
+