diff --git a/src/components/map/mapbox/MapBoxMap.js b/src/components/map/mapbox/MapBoxMap.js index d66d6cb..ecf92b6 100644 --- a/src/components/map/mapbox/MapBoxMap.js +++ b/src/components/map/mapbox/MapBoxMap.js @@ -20,6 +20,8 @@ import gimPo from '../../map/geojson/gimpoAirportAirArea.json'; import gimPoGrid from '../../../components/map/geojson/airportAirArea.json'; // 김포 선형 공역 import flatGimpo from '../../map/geojson/flatGimpoAirportAirArea.json'; +// uam 회랑 +import uamRoute from '../../map/geojson/uamRouteArea.json'; import { mapInitAction } from '../../../modules/control/map/actions/controlMapActions'; import * as THREE from 'three'; @@ -31,8 +33,155 @@ import * as THREE from 'three'; * drone-1.glb : 드론 3D Model * out.glb : UAM 3D Model */ -import UamGltf from './models/boeing_777_airplane.glb'; +import uamGltf from './models/drone-1.glb'; +import uamVertipad from './models/scene.glb'; + +const buffer = [ + [126.6238280624428, 37.564054382187464, 150], + [126.62380067423932, 37.56411591628361, 150], + [126.62378474611053, 37.56417995533479, 150], + [126.62378061257233, 37.56424515453873, 150], + [126.6237883604588, 37.56431014472685, 150], + [126.6238078270962, 37.56437356111632, 150], + [126.62732637084741, 37.5730511544423, 150], + [126.62735773537004, 37.57311260229055, 150], + [126.62740009559104, 37.57316971869807, 150], + [126.62745253331413, 37.57322126558242, 150], + [126.62751391189128, 37.573266125586436, 150], + [126.6275829008607, 37.57330332629931, 150], + [126.6310262460951, 37.57487889004297, 150], + [126.6311005070863, 37.57490735776204, 150], + [126.63117917555974, 37.57492693911049, 150], + [126.6312605831535, 37.574937218816025, 150], + [126.63134300341268, 37.574937978871155, 150], + [126.63142468840485, 37.574929203156806, 150], + [126.64795456355091, 37.57216433020499, 150], + [126.66064609063244, 37.573287735663136, 150], + [126.66073135497469, 37.57329012862925, 150], + [126.71219610879939, 37.57163150905567, 150], + [126.71228541231419, 37.57162291700238, 150], + [126.7123718776867, 37.57160317203693, 150], + [126.71245332079684, 37.57157277291867, 150], + [126.71252768439354, 37.57153248753101, 150], + [126.71259309006285, 37.57148333348379, 150], + [126.71264788567753, 37.571426552407196, 150], + [126.72361603679022, 37.55796529876466, 150], + [126.74227560152673, 37.551779117463816, 150], + [126.7522040720733, 37.55337217735081, 150], + [126.75229129293449, 37.55338062802695, 150], + [126.7523791055154, 37.55337822666518, 150], + [126.75246539247529, 37.5533650311671, 150], + [126.7525480732611, 37.55334135970284, 150], + [126.75579364309328, 37.55217829789471, 150], + [126.75587070921613, 37.55214472546204, 150], + [126.75594031949056, 37.55210206049736, 150], + [126.75600079604776, 37.5520513313947, 150], + [126.75605068118615, 37.55199376092348, 150], + [126.76760589086275, 37.53615038008557, 150], + [126.7676438204641, 37.5360876464801, 150], + [126.76766915789482, 37.53602100786133, 150], + [126.76768129795232, 37.53595205602986, 150], + [126.7676799506836, 37.53588243803773, 150], + [126.76766514830807, 37.53581381684507, 150], + [126.76763724444433, 37.53574783159705, 150], + [126.76759690565989, 37.53568605847025, 150], + [126.76754509554623, 37.535629973023376, 150], + [126.76748305169939, 37.535580914951915, 150], + [126.76290194626132, 37.53247981789287, 150], + [126.76283115783357, 37.53243895709915, 150], + [126.76275330879855, 37.53240727079065, 150], + [126.76267025862583, 37.53238551581021, 150], + [126.76258399101054, 37.53237421178551, 150], + [126.76249656649381, 37.53237362871809, 150], + [126.76241007324829, 37.53238378053468, 150], + [126.76232657720405, 37.53240442475447, 150], + [126.76224807270525, 37.53243506828064, 150], + [126.76217643487661, 37.53247497917769, 150], + [126.74069262521496, 37.54652770230293, 150], + [126.72105613762403, 37.55331395924351, 150], + [126.72097009222837, 37.55335102626893, 150], + [126.72089335254, 37.553399339183436, 150], + [126.72082821258904, 37.55345745374941, 150], + [126.72077661966293, 37.55352363272091, 150], + [126.7105550480309, 37.56958294101868, 150], + [126.66089003046397, 37.57103223184973, 150], + [126.65014220764405, 37.570104447257165, 150], + [126.63441483345441, 37.55518901290653, 150], + [126.63434836939835, 37.555135703657484, 150], + [126.63427170362114, 37.555091927023575, 150], + [126.6341869673753, 37.55505889995413, 150], + [126.63409651625435, 37.55503754056923, 150], + [126.63400286471169, 37.555028442638, 150], + [126.63390861616429, 37.55503185907338, 150], + [126.62880364618123, 37.55555880057077, 150], + [126.62872224261918, 37.555572099756354, 150], + [126.62864416342086, 37.55559474708482, 150], + [126.62857109246927, 37.55562625413686, 150], + [126.62850460564319, 37.55566594142098, 150], + [126.62844613683232, 37.55571295302701, 150], + [126.62839694701388, 37.555766275084146, 150], + [126.62835809705736, 37.55582475762566, 150], + [126.6238280624428, 37.564054382187464, 150], + [126.62495091356033, 37.56425948073808, 150], + [126.62926632180132, 37.55641957645043, 150], + [126.63374703115862, 37.55595707199735, 150], + [126.64942152536467, 37.57082243176737, 150], + [126.6494819929003, 37.57087159202163, 150], + [126.64955116006975, 37.57091285020618, 150], + [126.64962741370097, 37.57094524405693, 150], + [126.64970897533686, 37.570968018051374, 150], + [126.64979394271542, 37.57098064103046, 150], + [126.66080873003172, 37.57193148030834, 150], + [126.66089030862557, 37.57193380561681, 150], + [126.71093005399068, 37.570473520518696, 150], + [126.7110155200376, 37.570465802242325, 150], + [126.7110985296507, 37.57044786442179, 150], + [126.71117716556726, 37.570420121365, 150], + [126.71124961154851, 37.57038321384983, 150], + [126.71131419433043, 37.57033799432348, 150], + [126.71136942227176, 37.570285507212816, 150], + [126.71141401980613, 37.57022696480039, 150], + [126.72169390796309, 37.5540757881264, 150], + [126.74121589806943, 37.54732905907567, 150], + [126.74128561673987, 37.547300221836394, 150], + [126.7413496462557, 37.54726397318036, 150], + [126.76252938140514, 37.533410153819155, 150], + [126.76639001938337, 37.53602356058272, 150], + [126.7551633910013, 37.551416100325476, 150], + [126.75224937646537, 37.55246034604165, 150], + [126.74232959475833, 37.55086866548583, 150], + [126.74224635295539, 37.55086035633522, 150], + [126.74216248299645, 37.55086193774384, 150], + [126.74207982856083, 37.55087337494807, 150], + [126.742000206609, 37.550894416528266, 150], + [126.7230191831106, 37.55718716011606, 150], + [126.7229434377238, 37.55721776091386, 150], + [126.72287429905668, 37.55725704285292, 150], + [126.72281332488005, 37.55730412087391, 150], + [126.72276188901834, 37.557357934262605, 150], + [126.71185752948423, 37.5707407582132, 150], + [126.6607286127792, 37.572388503067096, 150], + [126.64798953962035, 37.571260882439994, 150], + [126.64789967413597, 37.5712586421025, 150], + [126.64781049681692, 37.57126775684084, 150], + [126.63140325396725, 37.57401214044211, 150], + [126.62833651270446, 37.57260890346539, 150], + [126.62495091356033, 37.56425948073808, 150] +]; +const ghlfkd = [ + [126.6243464, 37.5642352], + [126.62469825999999, 37.565102957777775], + [126.62505012, 37.56597071555556], + [126.62540197999999, 37.566838473333334], + [126.62575384, 37.56770623111111], + [126.6261057, 37.568573988888886], + [126.62645755999999, 37.56944174666667], + [126.62680942, 37.570309504444445], + [126.62716128, 37.57117726222222], + [126.62751314, 37.572045020000004], + [126.627865, 37.57291277777778] +]; let gridCoords = []; let altitudeMarker = []; let linerAltitude = [ @@ -142,7 +291,7 @@ export default function MapBoxMap() { map.removeLayer('maine'); map.removeSource('maine'); } - console.log(mapControl.areaType); + if (altitudeMarker.length > 0) { altitudeMarker.map(i => { i.remove(); @@ -293,12 +442,6 @@ export default function MapBoxMap() { }); }; - let stats; - const animate = () => { - requestAnimationFrame(animate); - stats.update(); - }; - // 맵박스 지도 초기 셋팅 const mapBoxMapInit = () => { mapboxgl.accessToken = MAPBOX_TOKEN; @@ -314,11 +457,15 @@ export default function MapBoxMap() { const language = new MapboxLanguage(); map.addControl(language); // 거리 축적 - // map.addControl(new mapboxgl.ScaleControl()); + map.addControl(new mapboxgl.ScaleControl()); // 드래그 제한 2d // map.dragRotate.disable(); + map.on('click', e => { + console.log(e); + }); + const tb = (window.tb = new threebox.Threebox( map, map.getCanvas().getContext('webgl'), @@ -441,62 +588,104 @@ export default function MapBoxMap() { /*************************************************************** 3D UAM Model Layer 추기 코드 start */ - // map.addLayer({ - // id: 'custom-threebox-model', - // type: 'custom', - // renderingMode: '3d', - // onAdd: function () { - // // 3d model option - // const options = { - // obj: UamGltf, // 3D Model 파일 - // type: 'gltf', // 3D Model 확장자 타입 - // scale: { x: 0, y: 0, z: 0 }, // 3D Model 크기 값 - // units: 'meters', // 높이 단위 - // rotation: { x: 90, y: -90, z: 0 } // // 3D Model 방향 각도 초기 값 - // }; - - // tb.loadObj(options, model => { - // let longitude = 127.81101412107547; // 3D Model 경도 값 - // const latitude = 37.510357; // 3D Model 위도 값 - // let hei = 0; // 3D Model 높이 값 - - // model.setCoords([longitude, latitude, hei]); // 3D Model 위치 지정 - // model.setRotation({ x: 0, y: 0, z: 90 }); // 3D Model 방향 각도 지정 - // tb.add(model); - - // // 0.5초마다 모델의 위치를 변경 - // setInterval(() => { - // longitude += 0.001; // 경도를 약간 증가시킵니다. - // hei += 50; // 높이값 증가 - // model.setCoords([longitude, latitude, hei]); - // }, 1000); - - // const mixer = new THREE.AnimationMixer(model); - - // // 애니메이션 클립 찾기 - // const clips = model.animations; - // console.log(clips); - // if (clips && clips.length) { - // // 모든 애니메이션 클립 재생 - // clips.forEach(clip => { - // mixer.clipAction(clip).play(); - // }); - // } - - // function update() { - // mixer.update(0.005); // 프레임 간격을 제공하여 애니메이션을 업데이트합니다. - // // tb.update(); - // requestAnimationFrame(update); - // } - // // 애니메이션 시작 - // update(); - // }); - // }, + map.addLayer({ + id: 'custom-threebox-model', + type: 'custom', + renderingMode: '3d', + onAdd: function () { + // 3d model option + const options = { + obj: uamGltf, // 3D Model 파일 + type: 'gltf', // 3D Model 확장자 타입 + scale: { x: 0, y: 0, z: 0 }, // 3D Model 크기 값 + units: 'meters', // 높이 단위 + rotation: { x: 90, y: -90, z: 0 } // // 3D Model 방향 각도 초기 값 + }; + + tb.loadObj(options, model => { + let longitude = 126.6243464; // 3D Model 경도 값 + const latitude = 37.5642352; // 3D Model 위도 값 + let hei = 150; // 3D Model 높이 값 + + model.setCoords([longitude, latitude, hei]); // 3D Model 위치 지정 + model.setRotation({ x: 0, y: 0, z: 90 }); // 3D Model 방향 각도 지정 + tb.add(model); + let index = 0; + // 0.5초마다 모델의 위치를 변경 + setInterval(() => { + // longitude += 0.001; // 경도를 약간 증가시킵니다. + + model.setCoords([ghlfkd[index][0], ghlfkd[index][1], hei]); + index++; + if (index === ghlfkd.length) { + // 배열의 끝에 도달하면 인덱스를 0으로 재설정하고 계속 반복합니다. + index = 0; + } + // hei += 50; // 높이값 증가 + }, 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(); + }); + }, + + render: function () { + tb.update(); + } + }); + const uamRouteArr = [ + ...uamRoute.features[0].geometry.coordinates, + [126.8045935, 37.56016, 150] + ]; + + for (let i = 0; i < uamRouteArr.length; i++) { + map.addLayer({ + id: `custom-threebox-model_${i}`, + type: 'custom', + renderingMode: '3d', + onAdd: function () { + // 3d model option + const options = { + obj: uamVertipad, // 3D Model 파일 + type: 'gltf', // 3D Model 확장자 타입 + scale: { x: 0, y: 0, z: 0 }, // 3D Model 크기 값 + units: 'meters', // 높이 단위 + rotation: { x: 90, y: -90, z: 0 } // // 3D Model 방향 각도 초기 값 + }; + tb.loadObj(options, model => { + let longitude = uamRouteArr[i][0]; // 3D Model 경도 값 + const latitude = uamRouteArr[i][1]; // 3D Model 위도 값 + let hei = 0; // 3D Model 높이 값 + + model.setCoords([longitude, latitude, hei]); // 3D Model 위치 지정 + model.setRotation({ x: 0, y: 0, z: 90 }); // 3D Model 방향 각도 지정 + tb.add(model); + }); + }, + + render: function () { + tb.update(); + } + }); + } - // render: function () { - // tb.update(); - // } - // }); /*************************************************************** 3D UAM Model Layer 추기 코드 end */ // 김포 3d 공역 @@ -518,43 +707,65 @@ export default function MapBoxMap() { }); tb.add(line); } - // const scene = new THREE.Scene(); - // const geojsonGeometry = new THREE.Geometry(); - // gimPo.features.forEach(feature => { - // const coordinates = feature.geometry.coordinates; - - // for (let i = 0; i < coordinates.length; i++) { - // const coordinate = coordinates[i]; - // const height = coordinate[2]; // Get the height from the GeoJSON - - // // Create a vertex for each coordinate with height - // const vertex = new THREE.Vector3( - // coordinate[0], - // coordinate[1], - // height - // ); - // geojsonGeometry.vertices.push(vertex); - // } - // }); - // console.log(tb); - // // Create Line Material - // const lineMaterial = new THREE.LineBasicMaterial({ color: 0x00ff00 }); // Color for lines - - // // Create Line Mesh - // const geojsonLines = new THREE.Line(geojsonGeometry, lineMaterial); - - // // Add the lines to Threebox - // tb.add(geojsonLines); - // // Adjust position if needed - // // geojsonLines.position.set(0, 0, 0); - - // // Create a filled mesh (optional) - // const filledGeometry = new THREE.Geometry(); - // // Add vertices and faces to filledGeometry to fill between the lines - - // const fillMaterial = new THREE.MeshBasicMaterial({ color: 0xff0000 }); // Color for fill - // const geojsonFill = new THREE.Mesh(filledGeometry, fillMaterial); - // tb.add(geojsonFill); + }, + render: function () { + tb.update(); + } + }); + + // uam 회랑 + map.addLayer({ + id: 'uamRoute', + type: 'custom', + renderingMode: '3d', + onAdd: function () { + const uamRouteLoad = uamRoute.features.filter( + i => i.geometry.type === 'LineString' + ); + for (let i = 0; i < uamRouteLoad.length; i++) { + let line; + + for ( + let j = 0; + j < uamRouteLoad[i].geometry.coordinates.length; + j++ + ) { + uamRouteLoad[i].geometry.coordinates[j].push(150); + } + + const options = { + path: uamRouteLoad[i].geometry.coordinates + }; + let lineGeometry = options.path; + line = tb.line({ + geometry: lineGeometry, + width: 2, + color: 'red' + }); + tb.add(line); + } + }, + render: function () { + tb.update(); + } + }); + // buffer + map.addLayer({ + id: 'uamBuffers', + type: 'custom', + renderingMode: '3d', + onAdd: function () { + let line; + const options = { + path: buffer + }; + let lineGeometry = options.path; + line = tb.line({ + geometry: lineGeometry, + width: 2, + color: 'black' + }); + tb.add(line); }, render: function () { tb.update(); @@ -615,38 +826,6 @@ export default function MapBoxMap() { }); setMapObject(map); dispatch(mapInitAction(map)); - - // map.on('style.load', () => { - // map.addLayer({ - // id: 'custom-threebox-model', - // type: 'custom', - // renderingMode: '3d', - // onAdd: function () { - // // Creative Commons License attribution: Metlife Building model by https://sketchfab.com/NanoRay - // // https://sketchfab.com/3d-models/metlife-building-32d3a4a1810a4d64abb9547bb661f7f3 - // const scale = -20; - // const options = { - // obj: './src/components/map/mapbox/diorama/scene.gltf', - // // obj: 'https://docs.mapbox.com/mapbox-gl-js/assets/metlife-building.gltf', - // type: 'gltf', - // units: 'meters', - // scale: 1, - // anchor: 'center', - // rotation: { x: 90, y: 0, z: 0 } - // }; - - // tb.loadObj(options, model => { - // model.setCoords([127.85101412107547, 37.520357, 1000]); - // model.setRotation({ x: 0, y: 0, z: 241 }); - // tb.add(model); - // }); - // }, - - // render: function () { - // tb.update(); - // } - // }); - // }); }; return ( diff --git a/src/components/map/mapbox/feature/FeatureAirZone.js b/src/components/map/mapbox/feature/FeatureAirZone.js index e370c20..7350a2e 100644 --- a/src/components/map/mapbox/feature/FeatureAirZone.js +++ b/src/components/map/mapbox/feature/FeatureAirZone.js @@ -53,6 +53,7 @@ export const FeatureAirZone = props => { ...uamGeoJson, features: [...uamGeoJson.features, bufferGeoJson] }; + setUamGeoJson(obj); props.map.getSource('uam').setData(obj); } @@ -374,7 +375,6 @@ export const FeatureAirZone = props => { const path = [buffer.x, buffer.y]; paths.push(path); }); - const bufferObj = { type: 'Feature', geometry: { @@ -413,7 +413,6 @@ export const FeatureAirZone = props => { ) .addTo(props.map); }); - // uam 관련 Source, Layer props.map.addSource('uam', { type: 'geojson', @@ -449,18 +448,18 @@ export const FeatureAirZone = props => { }, filter: ['==', ['get', 'type'], 'routeBuffer'] }); - props.map.addLayer({ - id: 'routePoint', - type: 'circle', - source: 'uam', - paint: { - 'circle-radius': 5, - 'circle-color': '#ffffff', - 'circle-stroke-color': '#000000', - 'circle-stroke-width': 1 - }, - filter: ['==', ['get', 'type'], 'routePoint'] - }); + // props.map.addLayer({ + // id: 'routePoint', + // type: 'circle', + // source: 'uam', + // paint: { + // 'circle-radius': 5, + // 'circle-color': '#ffffff', + // 'circle-stroke-color': '#000000', + // 'circle-stroke-width': 1 + // }, + // filter: ['==', ['get', 'type'], 'routePoint'] + // }); props.map.addLayer({ id: 'towerLine', type: 'line', diff --git a/src/components/map/mapbox/models/scene.glb b/src/components/map/mapbox/models/scene.glb new file mode 100644 index 0000000..1de57e1 Binary files /dev/null and b/src/components/map/mapbox/models/scene.glb differ