diff --git a/src/components/MapSection.tsx b/src/components/MapSection.tsx index 0c63a8c..e60674a 100644 --- a/src/components/MapSection.tsx +++ b/src/components/MapSection.tsx @@ -1,17 +1,15 @@ 'use client'; -import React, { useMemo, useRef, useState, useEffect, useCallback } from 'react'; -import Map, { NavigationControl, Source, Layer, type MapRef } from 'react-map-gl/maplibre'; +import React, { useMemo, useState, useEffect } from 'react'; +import Map, { Marker } from 'react-map-gl/maplibre'; import 'maplibre-gl/dist/maplibre-gl.css'; -import { fetchAndProcessStationData, type StationGeoJSON } from '@/lib/rts'; +import { fetchAndProcessStationData, type StationGeoJSON, type StationFeature } from '@/lib/rts'; +import StationMarker from './StationMarker'; const MapSection = React.memo(() => { - const mapRef = useRef(null); const [stationData, setStationData] = useState(null); const [dataTime, setDataTime] = useState(0); const [maxIntensity, setMaxIntensity] = useState(-3); - const [isMapReady, setIsMapReady] = useState(false); - const sourceInitializedRef = useRef(false); const mapStyle: any = useMemo(() => ({ version: 8, @@ -98,52 +96,6 @@ const MapSection = React.memo(() => { return `${year}/${month}/${day} ${hours}:${minutes}:${seconds}`; }; - const initializeMapSource = useCallback(() => { - if (!mapRef.current || !stationData || sourceInitializedRef.current) return; - - const map = mapRef.current.getMap(); - - if (!map.getSource('stations')) { - map.addSource('stations', { - type: 'geojson', - data: stationData, - }); - - map.addLayer({ - id: 'station-circles', - type: 'circle', - source: 'stations', - layout: { - 'circle-sort-key': ['get', 'sortKey'], - }, - paint: { - 'circle-radius': 4, - 'circle-color': ['get', 'color'], - 'circle-opacity': 1, - 'circle-stroke-width': 1, - 'circle-stroke-color': '#ffffff', - }, - }); - - sourceInitializedRef.current = true; - } - }, [stationData]); - - const updateMapData = useCallback((newData: StationGeoJSON) => { - if (!mapRef.current || !sourceInitializedRef.current) return; - - const map = mapRef.current.getMap(); - const source = map.getSource('stations') as any; - - if (source && source.setData) { - source.setData(newData); - } - }, []); - - const handleMapLoad = useCallback(() => { - setIsMapReady(true); - }, []); - useEffect(() => { const fetchData = async () => { try { @@ -153,17 +105,17 @@ const MapSection = React.memo(() => { setDataTime(data.time); let max = -3; - data.geojson.features.forEach(feature => { - if (feature.properties.intensity > max) { - max = feature.properties.intensity; - } - }); + if (data.geojson && data.geojson.features) { + data.geojson.features.forEach(feature => { + if (feature.properties.intensity > max) { + max = feature.properties.intensity; + } + }); + } setMaxIntensity(max); - if (isMapReady && sourceInitializedRef.current) { - updateMapData(data.geojson); - } } catch (error) { + console.error("Failed to fetch station data:", error); } }; @@ -171,18 +123,29 @@ const MapSection = React.memo(() => { const interval = setInterval(fetchData, 1000); return () => clearInterval(interval); - }, [isMapReady, updateMapData]); + }, []); - useEffect(() => { - if (isMapReady && stationData) { - initializeMapSource(); - } - }, [isMapReady, stationData, initializeMapSource]); + const stationMarkers = useMemo(() => { + if (!stationData) return null; + return stationData.features.map((station: StationFeature) => ( + + + + )); + }, [stationData]); return (
{ dragRotate={false} touchZoomRotate={false} boxZoom={false} - onLoad={handleMapLoad} onError={() => {}} > + {stationMarkers} {dataTime > 0 && (
diff --git a/src/components/StationMarker.tsx b/src/components/StationMarker.tsx new file mode 100644 index 0000000..2c3d05d --- /dev/null +++ b/src/components/StationMarker.tsx @@ -0,0 +1,88 @@ +import React from 'react'; + +interface StationMarkerProps { + intensity: number; + color: string; + alert?: boolean; +} + +const StationMarker: React.FC = ({ intensity, color, alert }) => { + const size = 23; + + if (!alert || intensity < 0.5) { + return ( +
+ ); + } + + let bgColor = ''; + let textColor = ''; + let text = ''; + + if (intensity >= 0.5 && intensity <= 1.4) { + bgColor = '#003264'; + textColor = '#ffffff'; + text = '1'; + } else if (intensity >= 1.5 && intensity <= 2.4) { + bgColor = '#0064c8'; + textColor = '#ffffff'; + text = '2'; + } else if (intensity >= 2.5 && intensity <= 3.4) { + bgColor = '#1e9632'; + textColor = '#ffffff'; + text = '3'; + } else if (intensity >= 3.5 && intensity <= 4.4) { + bgColor = '#ffc800'; + textColor = '#000000'; + text = '4'; + } else if (intensity >= 4.5 && intensity <= 4.9) { + bgColor = '#ff9600'; + textColor = '#000000'; + text = '5⁻'; + } else if (intensity >= 5.0 && intensity <= 5.4) { + bgColor = '#ff6400'; + textColor = '#000000'; + text = '5⁺'; + } else if (intensity >= 5.5 && intensity <= 5.9) { + bgColor = '#ff0000'; + textColor = '#ffffff'; + text = '6⁻'; + } else if (intensity >= 6.0 && intensity <= 6.4) { + bgColor = '#c00000'; + textColor = '#ffffff'; + text = '6⁺'; + } else if (intensity >= 6.5) { + bgColor = '#9600c8'; + textColor = '#ffffff'; + text = '7'; + } + + return ( +
+ {text} +
+ ); +}; + +export default StationMarker; \ No newline at end of file diff --git a/src/lib/rts.ts b/src/lib/rts.ts index e8f05f0..b0c26e9 100644 --- a/src/lib/rts.ts +++ b/src/lib/rts.ts @@ -38,6 +38,7 @@ export interface StationFeature { intensity: number; color: string; sortKey: number; + alert?: boolean; }; } @@ -171,6 +172,7 @@ export function createStationGeoJSON( intensity, color, sortKey: intensity, + alert: !!rts.alert, }, }); }