|
|
|
@ -1,224 +1,31 @@
|
|
|
|
|
import { useEffect, useState, useRef, useLayoutEffect } from 'react'; |
|
|
|
|
import { useSelector, useDispatch } from 'react-redux'; |
|
|
|
|
import { Button, Modal, ModalHeader, ModalBody, ModalFooter } from 'reactstrap'; |
|
|
|
|
// mapbox
|
|
|
|
|
import 'mapbox-gl/dist/mapbox-gl.css'; |
|
|
|
|
import { MAPBOX_TOKEN } from '../../../configs/constants'; |
|
|
|
|
import mapboxgl from 'mapbox-gl'; |
|
|
|
|
import threebox from 'threebox-plugin'; |
|
|
|
|
import { Button, Modal, ModalHeader, ModalBody, ModalFooter } from 'reactstrap'; |
|
|
|
|
// import * as THREE from 'three';
|
|
|
|
|
import MapboxLanguage from '@mapbox/mapbox-gl-language'; |
|
|
|
|
import { MAPBOX_TOKEN } from '../../../configs/constants'; |
|
|
|
|
import { useEffect, useState, useRef, useLayoutEffect } from 'react'; |
|
|
|
|
import { useSelector, useDispatch } from 'react-redux'; |
|
|
|
|
|
|
|
|
|
import { DronToast } from './dron/DronToast'; |
|
|
|
|
import { DronMarker } from './dron/DronMarker'; |
|
|
|
|
// import { DronHistory } from './dron/DronHistory';
|
|
|
|
|
// import MapBoxMapControl from './MapBoxMapControl';
|
|
|
|
|
// import { NaverMapSearch } from './search/NaverMapSearch';
|
|
|
|
|
import { DronPlan } from './dron/DronPlan'; |
|
|
|
|
import { FeatureAirZone } from './feature/FeatureAirZone'; |
|
|
|
|
|
|
|
|
|
import threebox from 'threebox-plugin'; |
|
|
|
|
|
|
|
|
|
import geoJson from '../../map/geojson/airArea.json'; |
|
|
|
|
// import gimPo from '../../map/geojson/gimpoAirportAirArea.json';
|
|
|
|
|
import gimPo from '../../map/geojson/gimpoAirportAirArea.json'; |
|
|
|
|
// 김포 격자 공역
|
|
|
|
|
import gimPoGrid from '../../../components/map/geojson/airportAirArea.json'; |
|
|
|
|
// 김포 선형 공역
|
|
|
|
|
import flatGimpo from '../../map/geojson/flatGimpoAirportAirArea.json'; |
|
|
|
|
// import DronPlan from './dron/DronPlan';
|
|
|
|
|
// import NewDronPlan from './dron/NewDronPlan';
|
|
|
|
|
// import { NewDronHistory } from './dron/NewDronHistroy';
|
|
|
|
|
// import DronToast from './dron/DronToast';
|
|
|
|
|
// import SensorZone from './sensor/SensorZone';
|
|
|
|
|
|
|
|
|
|
import { mapInitAction } from '../../../modules/control/map/actions/controlMapActions'; |
|
|
|
|
import DronPlan from './dron/DronPlan'; |
|
|
|
|
import DronToast from './dron/DronToast'; |
|
|
|
|
import * as THREE from 'three'; |
|
|
|
|
|
|
|
|
|
// example 3d gltf 파일
|
|
|
|
|
import Gltf from '../../../assets/images/3dpea.gltf'; |
|
|
|
|
|
|
|
|
|
const uamPosition = { |
|
|
|
|
type: 'FeatureCollection', |
|
|
|
|
features: [ |
|
|
|
|
{ |
|
|
|
|
type: 'Feature', |
|
|
|
|
properties: { |
|
|
|
|
name: 'V1', |
|
|
|
|
background: '#ffffff', |
|
|
|
|
border: '#15298A', |
|
|
|
|
spanColor: '#000000' |
|
|
|
|
}, |
|
|
|
|
geometry: { |
|
|
|
|
type: 'Point', |
|
|
|
|
coordinates: [126.540668, 37.4797865] |
|
|
|
|
} |
|
|
|
|
}, |
|
|
|
|
{ |
|
|
|
|
type: 'Feature', |
|
|
|
|
properties: { |
|
|
|
|
name: 'V2', |
|
|
|
|
background: '#ffffff', |
|
|
|
|
border: '#15298A', |
|
|
|
|
spanColor: '#000000' |
|
|
|
|
}, |
|
|
|
|
geometry: { |
|
|
|
|
type: 'Point', |
|
|
|
|
coordinates: [126.6107763, 37.521245] |
|
|
|
|
} |
|
|
|
|
}, |
|
|
|
|
{ |
|
|
|
|
type: 'Feature', |
|
|
|
|
properties: { |
|
|
|
|
name: 'V3', |
|
|
|
|
background: '#ffffff', |
|
|
|
|
border: '#15298A', |
|
|
|
|
spanColor: '#000000' |
|
|
|
|
}, |
|
|
|
|
geometry: { |
|
|
|
|
type: 'Point', |
|
|
|
|
coordinates: [126.6243464, 37.5642352] |
|
|
|
|
} |
|
|
|
|
}, |
|
|
|
|
{ |
|
|
|
|
type: 'Feature', |
|
|
|
|
properties: { |
|
|
|
|
name: 'V4', |
|
|
|
|
background: '#ffffff', |
|
|
|
|
border: '#15298A', |
|
|
|
|
spanColor: '#000000' |
|
|
|
|
}, |
|
|
|
|
geometry: { |
|
|
|
|
type: 'Point', |
|
|
|
|
coordinates: [126.6650669, 37.3658236] |
|
|
|
|
} |
|
|
|
|
}, |
|
|
|
|
{ |
|
|
|
|
type: 'Feature', |
|
|
|
|
properties: { |
|
|
|
|
name: 'V5', |
|
|
|
|
background: '#ffffff', |
|
|
|
|
border: '#15298A', |
|
|
|
|
spanColor: '#000000' |
|
|
|
|
}, |
|
|
|
|
geometry: { |
|
|
|
|
type: 'Point', |
|
|
|
|
coordinates: [126.7074861, 37.4520753] |
|
|
|
|
} |
|
|
|
|
}, |
|
|
|
|
{ |
|
|
|
|
type: 'Feature', |
|
|
|
|
properties: { |
|
|
|
|
name: 'R1', |
|
|
|
|
background: '#429629', |
|
|
|
|
border: '#ffffff', |
|
|
|
|
spanColor: '#ffffff' |
|
|
|
|
}, |
|
|
|
|
geometry: { |
|
|
|
|
type: 'Point', |
|
|
|
|
coordinates: [126.5801572, 37.492581] |
|
|
|
|
} |
|
|
|
|
}, |
|
|
|
|
{ |
|
|
|
|
type: 'Feature', |
|
|
|
|
properties: { |
|
|
|
|
name: 'R2', |
|
|
|
|
background: '#429629', |
|
|
|
|
border: '#ffffff', |
|
|
|
|
spanColor: '#ffffff' |
|
|
|
|
}, |
|
|
|
|
geometry: { |
|
|
|
|
type: 'Point', |
|
|
|
|
coordinates: [126.6036588, 37.542031] |
|
|
|
|
} |
|
|
|
|
}, |
|
|
|
|
{ |
|
|
|
|
type: 'Feature', |
|
|
|
|
properties: { |
|
|
|
|
name: 'R3', |
|
|
|
|
background: '#429629', |
|
|
|
|
border: '#ffffff', |
|
|
|
|
spanColor: '#ffffff' |
|
|
|
|
}, |
|
|
|
|
geometry: { |
|
|
|
|
type: 'Point', |
|
|
|
|
coordinates: [126.6005224, 37.5764269] |
|
|
|
|
} |
|
|
|
|
}, |
|
|
|
|
{ |
|
|
|
|
type: 'Feature', |
|
|
|
|
properties: { |
|
|
|
|
name: 'R4', |
|
|
|
|
background: '#429629', |
|
|
|
|
border: '#ffffff', |
|
|
|
|
spanColor: '#ffffff' |
|
|
|
|
}, |
|
|
|
|
geometry: { |
|
|
|
|
type: 'Point', |
|
|
|
|
coordinates: [126.6600404, 37.5790407] |
|
|
|
|
} |
|
|
|
|
}, |
|
|
|
|
{ |
|
|
|
|
type: 'Feature', |
|
|
|
|
properties: { |
|
|
|
|
name: 'R5', |
|
|
|
|
background: '#429629', |
|
|
|
|
border: '#ffffff', |
|
|
|
|
spanColor: '#ffffff' |
|
|
|
|
}, |
|
|
|
|
geometry: { |
|
|
|
|
type: 'Point', |
|
|
|
|
coordinates: [126.649562, 37.524016] |
|
|
|
|
} |
|
|
|
|
}, |
|
|
|
|
{ |
|
|
|
|
type: 'Feature', |
|
|
|
|
properties: { |
|
|
|
|
name: 'R6', |
|
|
|
|
background: '#429629', |
|
|
|
|
border: '#ffffff', |
|
|
|
|
spanColor: '#ffffff' |
|
|
|
|
}, |
|
|
|
|
geometry: { |
|
|
|
|
type: 'Point', |
|
|
|
|
coordinates: [126.693722, 37.5506488] |
|
|
|
|
} |
|
|
|
|
}, |
|
|
|
|
{ |
|
|
|
|
type: 'Feature', |
|
|
|
|
properties: { |
|
|
|
|
name: 'R7', |
|
|
|
|
background: '#429629', |
|
|
|
|
border: '#ffffff', |
|
|
|
|
spanColor: '#ffffff' |
|
|
|
|
}, |
|
|
|
|
geometry: { |
|
|
|
|
type: 'Point', |
|
|
|
|
coordinates: [126.6023981, 37.4712333] |
|
|
|
|
} |
|
|
|
|
}, |
|
|
|
|
{ |
|
|
|
|
type: 'Feature', |
|
|
|
|
properties: { |
|
|
|
|
name: 'R8', |
|
|
|
|
background: '#429629', |
|
|
|
|
border: '#ffffff', |
|
|
|
|
spanColor: '#ffffff' |
|
|
|
|
}, |
|
|
|
|
geometry: { |
|
|
|
|
type: 'Point', |
|
|
|
|
coordinates: [126.6202759, 37.4046495] |
|
|
|
|
} |
|
|
|
|
}, |
|
|
|
|
{ |
|
|
|
|
type: 'Feature', |
|
|
|
|
properties: { |
|
|
|
|
name: 'R9', |
|
|
|
|
background: '#429629', |
|
|
|
|
border: '#ffffff', |
|
|
|
|
spanColor: '#ffffff' |
|
|
|
|
}, |
|
|
|
|
geometry: { |
|
|
|
|
type: 'Point', |
|
|
|
|
coordinates: [126.6296542, 37.3450207] |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
] |
|
|
|
|
}; |
|
|
|
|
import UamGltf from './models/out.glb'; |
|
|
|
|
|
|
|
|
|
let gridCoords = []; |
|
|
|
|
let altitudeMarker = []; |
|
|
|
@ -263,51 +70,32 @@ let linerAltitude = [
|
|
|
|
|
let linerAltitudeMarker = []; |
|
|
|
|
|
|
|
|
|
export default function MapBoxMap() { |
|
|
|
|
const naver = window.naver; |
|
|
|
|
const dispatch = useDispatch(); |
|
|
|
|
// 공역표출 타입
|
|
|
|
|
const mapControl = useSelector(state => state.controlMapReducer); |
|
|
|
|
|
|
|
|
|
// 지도
|
|
|
|
|
const mapContainer = useRef(null); |
|
|
|
|
const [mapObject, setMapObject] = useState(null); |
|
|
|
|
// 지도 로드 여부
|
|
|
|
|
const [isMapLoaded, setMapLoaded] = useState(false); |
|
|
|
|
const [arrPolyline, setArrPolyline] = useState([]); |
|
|
|
|
|
|
|
|
|
// 노탐 정보 모달
|
|
|
|
|
const [centeredModal, setCenteredModal] = useState(false); |
|
|
|
|
const mapContainer = useRef(null); |
|
|
|
|
const dispatch = useDispatch(); |
|
|
|
|
const mapControl = useSelector(state => state.controlMapReducer); |
|
|
|
|
|
|
|
|
|
// 비행예상경로 geoJson 정보
|
|
|
|
|
const [planGeo, setPlanGeo] = useState({ |
|
|
|
|
type: 'FeatureCollection', |
|
|
|
|
features: [] |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
// 지도 초기 셋팅
|
|
|
|
|
useLayoutEffect(() => { |
|
|
|
|
mapBoxMapInit(); |
|
|
|
|
}, []); |
|
|
|
|
|
|
|
|
|
// useEffect(() => {
|
|
|
|
|
// if (mapObject) {
|
|
|
|
|
// uamPosition.features.map(uam => {
|
|
|
|
|
// const el = document.createElement('div');
|
|
|
|
|
// const elChild = document.createElement('span');
|
|
|
|
|
// elChild.innerText = uam.properties.name;
|
|
|
|
|
// elChild.style.color = uam.properties.spanColor;
|
|
|
|
|
// el.className = 'marker';
|
|
|
|
|
// el.style.background = uam.properties.background;
|
|
|
|
|
// el.style.borderRadius = '50%';
|
|
|
|
|
// el.style.border = `4px solid ${uam.properties.border}`;
|
|
|
|
|
// el.style.padding = '5px';
|
|
|
|
|
// el.style.width = '40px';
|
|
|
|
|
// el.style.height = '40px';
|
|
|
|
|
// el.style.textAlign = 'center';
|
|
|
|
|
// el.appendChild(elChild);
|
|
|
|
|
|
|
|
|
|
// new mapboxgl.Marker(el)
|
|
|
|
|
// .setLngLat(uam.geometry.coordinates)
|
|
|
|
|
// .addTo(mapObject);
|
|
|
|
|
// });
|
|
|
|
|
// }
|
|
|
|
|
// }, [mapObject]);
|
|
|
|
|
|
|
|
|
|
// 공역 표출 정보에 따른 공역 변경
|
|
|
|
|
useEffect(() => { |
|
|
|
|
console.log(mapObject); |
|
|
|
|
if (mapObject) { |
|
|
|
|
handlerCreateAirSpace(mapObject); |
|
|
|
|
} |
|
|
|
@ -321,6 +109,7 @@ export default function MapBoxMap() {
|
|
|
|
|
mapControl.liner |
|
|
|
|
]); |
|
|
|
|
|
|
|
|
|
// 공역 생성
|
|
|
|
|
const handlerCreateAirSpace = ( |
|
|
|
|
map, |
|
|
|
|
useGeoJson = { |
|
|
|
@ -494,6 +283,13 @@ export default function MapBoxMap() {
|
|
|
|
|
}); |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
let stats; |
|
|
|
|
const animate = () => { |
|
|
|
|
requestAnimationFrame(animate); |
|
|
|
|
stats.update(); |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
// 맵박스 지도 초기 셋팅
|
|
|
|
|
const mapBoxMapInit = () => { |
|
|
|
|
mapboxgl.accessToken = MAPBOX_TOKEN; |
|
|
|
|
|
|
|
|
@ -515,9 +311,12 @@ export default function MapBoxMap() {
|
|
|
|
|
map, |
|
|
|
|
map.getCanvas().getContext('webgl'), |
|
|
|
|
{ |
|
|
|
|
defaultLights: true, |
|
|
|
|
enableSelectingFeatures: true, |
|
|
|
|
enableSelectingObjects: true, |
|
|
|
|
enableTooltips: true, |
|
|
|
|
defaultLights: true |
|
|
|
|
enableDraggingObjects: true, |
|
|
|
|
enableRotatingObjects: true, |
|
|
|
|
enableTooltips: true |
|
|
|
|
} |
|
|
|
|
)); |
|
|
|
|
|
|
|
|
@ -629,6 +428,7 @@ export default function MapBoxMap() {
|
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
/*************************************************************** 3D UAM Model Layer 추기 코드 start */ |
|
|
|
|
|
|
|
|
|
// map.addLayer({
|
|
|
|
|
// id: 'custom-threebox-model',
|
|
|
|
|
// type: 'custom',
|
|
|
|
@ -636,9 +436,9 @@ export default function MapBoxMap() {
|
|
|
|
|
// onAdd: function () {
|
|
|
|
|
// // 3d model option
|
|
|
|
|
// const options = {
|
|
|
|
|
// obj: Gltf, // 3D Model 파일
|
|
|
|
|
// obj: UamGltf, // 3D Model 파일
|
|
|
|
|
// type: 'gltf', // 3D Model 확장자 타입
|
|
|
|
|
// scale: { x: 200, y: 200, z: 200 }, // 3D Model 크기 값
|
|
|
|
|
// scale: { x: 50, y: 50, z: 50 }, // 3D Model 크기 값
|
|
|
|
|
// units: 'meters', // 높이 단위
|
|
|
|
|
// rotation: { x: 90, y: -90, z: 0 } // // 3D Model 방향 각도 초기 값
|
|
|
|
|
// };
|
|
|
|
@ -646,7 +446,7 @@ export default function MapBoxMap() {
|
|
|
|
|
// tb.loadObj(options, model => {
|
|
|
|
|
// let longitude = 127.81101412107547; // 3D Model 경도 값
|
|
|
|
|
// const latitude = 37.510357; // 3D Model 위도 값
|
|
|
|
|
// let hei = 100; // 3D Model 높이 값
|
|
|
|
|
// let hei = 0; // 3D Model 높이 값
|
|
|
|
|
|
|
|
|
|
// model.setCoords([longitude, latitude, hei]); // 3D Model 위치 지정
|
|
|
|
|
// model.setRotation({ x: 0, y: 0, z: 241 }); // 3D Model 방향 각도 지정
|
|
|
|
@ -657,7 +457,26 @@ export default function MapBoxMap() {
|
|
|
|
|
// longitude += 0.001; // 경도를 약간 증가시킵니다.
|
|
|
|
|
// hei += 50; // 높이값 증가
|
|
|
|
|
// model.setCoords([longitude, latitude, hei]);
|
|
|
|
|
// }, 500);
|
|
|
|
|
// }, 1000);
|
|
|
|
|
|
|
|
|
|
// const mixer = new THREE.AnimationMixer(model);
|
|
|
|
|
|
|
|
|
|
// // 애니메이션 클립 찾기
|
|
|
|
|
// const clips = model.animations;
|
|
|
|
|
// if (clips && clips.length) {
|
|
|
|
|
// // 모든 애니메이션 클립 재생
|
|
|
|
|
// clips.forEach(clip => {
|
|
|
|
|
// mixer.clipAction(clip).play();
|
|
|
|
|
// });
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
// function update() {
|
|
|
|
|
// mixer.update(0.005); // 프레임 간격을 제공하여 애니메이션을 업데이트합니다.
|
|
|
|
|
// // tb.update();
|
|
|
|
|
// requestAnimationFrame(update);
|
|
|
|
|
// }
|
|
|
|
|
// // 애니메이션 시작
|
|
|
|
|
// update();
|
|
|
|
|
// });
|
|
|
|
|
// },
|
|
|
|
|
|
|
|
|
@ -777,13 +596,13 @@ export default function MapBoxMap() {
|
|
|
|
|
'fill-outline-color': '#000000' |
|
|
|
|
}, |
|
|
|
|
filter: ['in', '$type', 'Polygon'] |
|
|
|
|
// filter: ['==', ['get', 'id'], ['polygon', 'circle']]
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
setMapLoaded(true); |
|
|
|
|
}); |
|
|
|
|
setMapObject(map); |
|
|
|
|
dispatch(mapInitAction(map)); |
|
|
|
|
|
|
|
|
|
// map.on('style.load', () => {
|
|
|
|
|
// map.addLayer({
|
|
|
|
|
// id: 'custom-threebox-model',
|
|
|
|
@ -817,28 +636,6 @@ export default function MapBoxMap() {
|
|
|
|
|
// });
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
const createUamArea = uam => { |
|
|
|
|
const title = uam.title; |
|
|
|
|
const position = new naver.maps.LatLng(uam.lat, uam.lon); |
|
|
|
|
|
|
|
|
|
const circle = new naver.maps.Circle({ |
|
|
|
|
strokeColor: '#283046', |
|
|
|
|
strokeOpacity: 1, |
|
|
|
|
fillColor: '#8a1c05', |
|
|
|
|
fillOpacity: 0.1, |
|
|
|
|
center: position, |
|
|
|
|
// map: mapObject,
|
|
|
|
|
radius: 100, |
|
|
|
|
clickable: true |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
// circle.setMap(mapObject);
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
const handleHistoryInit = line => { |
|
|
|
|
setArrPolyline([...arrPolyline, line]); |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
return ( |
|
|
|
|
<> |
|
|
|
|
<div |
|
|
|
@ -848,28 +645,10 @@ export default function MapBoxMap() {
|
|
|
|
|
></div> |
|
|
|
|
{isMapLoaded && mapObject ? ( |
|
|
|
|
<> |
|
|
|
|
<DronToast /> |
|
|
|
|
<DronMarker map={mapObject} mapboxgl={mapboxgl} /> |
|
|
|
|
<DronPlan map={mapObject} planGeo={planGeo} setPlanGeo={setPlanGeo} /> |
|
|
|
|
<DronToast /> |
|
|
|
|
|
|
|
|
|
{/* <MapBoxMapControl map={mapObject} /> */} |
|
|
|
|
|
|
|
|
|
{/* <DronHistory |
|
|
|
|
map={mapObject} |
|
|
|
|
naver={naver} |
|
|
|
|
arrPolyline={arrPolyline} |
|
|
|
|
handleHistoryInit={handleHistoryInit} |
|
|
|
|
/> */} |
|
|
|
|
{/* <NewDronHistory |
|
|
|
|
map={mapObject} |
|
|
|
|
naver={naver} |
|
|
|
|
arrPolyline={arrPolyline} |
|
|
|
|
handleHistoryInit={handleHistoryInit} |
|
|
|
|
/> */} |
|
|
|
|
|
|
|
|
|
<FeatureAirZone map={mapObject} mapboxgl={mapboxgl} /> |
|
|
|
|
{/* <NaverMapSearch map={mapObject} naver={naver} /> */} |
|
|
|
|
{/* <SensorZone map={mapObject} naver={naver} /> */} |
|
|
|
|
</> |
|
|
|
|
) : null} |
|
|
|
|
|
|
|
|
|