feat(aerial): 완료 촬영 클릭 시 VWorld 위성 영상 오버레이 표시

- Mapbox placeholder → VWorld 위성 타일(WMTS) 실제 영상으로 교체
- 완료 항목 클릭 시 해당 지역에 위성 영상 레이어 오버레이
- 선택 지점에 📷 마커 표시
- VWorld API 키 환경변수(VITE_VWORLD_API_KEY) 연동

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Nan Kyung Lee 2026-03-17 10:50:48 +09:00
부모 8c0ada08fd
커밋 7fb98ebb08

파일 보기

@ -2,7 +2,10 @@ import { useState, useRef, useEffect, useCallback } from 'react'
import { Map, Source, Layer } from '@vis.gl/react-maplibre'
import type { StyleSpecification } from 'maplibre-gl'
import 'maplibre-gl/dist/maplibre-gl.css'
import { Marker } from '@vis.gl/react-maplibre'
import { fetchSatellitePasses } from '../services/aerialApi'
const VWORLD_API_KEY = import.meta.env.VITE_VWORLD_API_KEY || ''
import type { SatellitePass } from '../services/aerialApi'
interface SatRequest {
@ -433,26 +436,28 @@ export function SatelliteRequest() {
)
})}
{/* 선택된 항목의 위성 영상 오버레이 (시뮬레이션) */}
{mapSelectedItem && mapSelectedItem.status === '완료' && (() => {
{/* 선택된 완료 항목: VWorld 위성 영상 오버레이 */}
{mapSelectedItem && mapSelectedItem.status === '완료' && VWORLD_API_KEY && (
<Source
id="sat-vworld-overlay"
type="raster"
tiles={[`https://api.vworld.kr/req/wmts/1.0.0/${VWORLD_API_KEY}/Satellite/{z}/{y}/{x}.jpeg`]}
tileSize={256}
>
<Layer id="sat-vworld-layer" type="raster" paint={{ 'raster-opacity': 0.9 }} />
</Source>
)}
{/* 선택된 항목 마커 + 팝업 */}
{mapSelectedItem && (() => {
const coord = parseCoord(mapSelectedItem.zoneCoord)
if (!coord) return null
const areaKm = parseFloat(mapSelectedItem.zoneArea) || 10
const delta = Math.sqrt(areaKm) * 0.006
return (
<Source
id="sat-image-overlay"
type="image"
url={`https://api.mapbox.com/styles/v1/mapbox/satellite-v9/static/${coord.lon},${coord.lat},12,0/400x400?access_token=pk.placeholder`}
coordinates={[
[coord.lon - delta, coord.lat + delta],
[coord.lon + delta, coord.lat + delta],
[coord.lon + delta, coord.lat - delta],
[coord.lon - delta, coord.lat - delta],
]}
>
<Layer id="sat-image-layer" type="raster" paint={{ 'raster-opacity': 0.85 }} />
</Source>
<Marker longitude={coord.lon} latitude={coord.lat} anchor="bottom">
<div className="flex flex-col items-center">
<div className="w-5 h-5 rounded-full flex items-center justify-center text-[10px]" style={{ background: 'rgba(6,182,212,.8)', border: '2px solid #fff', boxShadow: '0 0 10px rgba(6,182,212,.5)' }}>📷</div>
</div>
</Marker>
)
})()}
</Map>