diff --git a/package-lock.json b/package-lock.json
index d0fff620..894a75c8 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1973,6 +1973,11 @@
"resolved": "https://registry.npmjs.org/@mapbox/jsonlint-lines-primitives/-/jsonlint-lines-primitives-2.0.2.tgz",
"integrity": "sha512-rY0o9A5ECsTQRVhv7tL/OyDpGAoUB4tTvLiW1DSzQGq4bvTPhNw1VpSNjDJc5GFZ2XuyOtSWSVN05qOtcD71qQ=="
},
+ "@mapbox/mapbox-gl-language": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/@mapbox/mapbox-gl-language/-/mapbox-gl-language-1.0.1.tgz",
+ "integrity": "sha512-gL58ojl7gaWLfbSISoB2QJEfTK3j+NKvPH9og0r+c3bd5BNqhY19Eb4OPfDc5+dGmjW03LhtZBc4n2b7Xn8kjA=="
+ },
"@mapbox/mapbox-gl-supported": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/@mapbox/mapbox-gl-supported/-/mapbox-gl-supported-2.0.1.tgz",
@@ -24895,6 +24900,11 @@
"resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
"integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ="
},
+ "threebox-plugin": {
+ "version": "2.2.7",
+ "resolved": "https://registry.npmjs.org/threebox-plugin/-/threebox-plugin-2.2.7.tgz",
+ "integrity": "sha512-H87Nm4w1PfisHPHzavTGXlwIoJpx2+QU57GooQYIhF51lsg+U5A0KGf3Jrv/HWsLCGOwV2BTnv7UTLfpO1EccQ=="
+ },
"throat": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/throat/-/throat-5.0.0.tgz",
diff --git a/package.json b/package.json
index 95f2a30e..f15f57f9 100644
--- a/package.json
+++ b/package.json
@@ -13,6 +13,7 @@
"@fullcalendar/timegrid": "5.7.2",
"@fullcalendar/timeline": "5.7.2",
"@hookform/resolvers": "1.3.4",
+ "@mapbox/mapbox-gl-language": "1.0.1",
"@stomp/stompjs": "^6.1.0",
"@turf/buffer": "^6.5.0",
"@turf/turf": "6.5.0",
@@ -110,6 +111,7 @@
"sweetalert2": "10.14.0",
"sweetalert2-react-content": "3.0.1",
"swiper": "6.0.4",
+ "threebox-plugin": "2.2.7",
"typesafe-actions": "^5.1.0",
"uppy": "1.21.2",
"webpack": "4.43.0",
diff --git a/src/components/map/MapControl.js b/src/components/map/MapControl.js
index 993c7138..e550c41e 100644
--- a/src/components/map/MapControl.js
+++ b/src/components/map/MapControl.js
@@ -5,8 +5,8 @@ import MapBoxMap from './mapbox/MapBoxMap';
export const MapControl = props => {
return (
- // <>{props.mapType === 'google' ? : }>
+ <>{props.mapType === 'google' ? : }>
//
-
+ //
);
};
diff --git a/src/components/map/mapbox/MapBoxMap.js b/src/components/map/mapbox/MapBoxMap.js
index 1100437f..07e81586 100644
--- a/src/components/map/mapbox/MapBoxMap.js
+++ b/src/components/map/mapbox/MapBoxMap.js
@@ -1,7 +1,7 @@
import { MAPBOX_TOKEN } from '../../../configs/constants';
import { useEffect, useState, useRef } from 'react';
import { useSelector, useDispatch } from 'react-redux';
-// import { DronMarker } from './dron/DronMarker';
+import { DronMarker } from './dron/DronMarker';
// import { DronHistory } from './dron/DronHistory';
// import NaverMapControl from './NaverMapControl';
// import { NaverMapSearch } from './search/NaverMapSearch';
@@ -13,7 +13,8 @@ import { FeatureAirZone } from './feature/FeatureAirZone';
// import SensorZone from './sensor/SensorZone';
import 'mapbox-gl/dist/mapbox-gl.css';
import mapboxgl from 'mapbox-gl';
-
+import threebox from 'threebox-plugin';
+import MapboxLanguage from '@mapbox/mapbox-gl-language';
// mapboxgl.accessToken = MAPBOX_TOKEN;
export default function MapBoxMap() {
// const mapContainer = useRef(null);
@@ -234,7 +235,7 @@ export default function MapBoxMap() {
};
useEffect(() => {
- NaverMapInit();
+ mapBoxMapInit();
}, []);
useEffect(() => {
@@ -261,7 +262,7 @@ export default function MapBoxMap() {
}
}, [mapObject]);
let popup;
- const NaverMapInit = () => {
+ const mapBoxMapInit = () => {
mapboxgl.accessToken = MAPBOX_TOKEN;
// const mapOptions = {
// center: new naver.maps.LatLng(37.520357, 126.610166),
@@ -280,12 +281,30 @@ export default function MapBoxMap() {
container: 'map', // container ID
style: 'mapbox://styles/mapbox/streets-v12', // style URL
center: [127.85101412107547, 37.520357], // starting position [lng, lat]
- zoom: 9 // starting zoom
+ zoom: 8.5, // starting zoom
+ antialias: true
+ // pitch: 64.9,
+ // bearing: 172.5
});
+ const language = new MapboxLanguage();
+ map.addControl(language);
+
+ // const tb = (window.tb = new threebox.Threebox(
+ // map,
+ // map.getCanvas().getContext('webgl'),
+ // {
+ // defaultLights: true,
+ // enableSelectingObjects: true,
+ // enableDraggingObjects: true,
+ // enableRotatingObjects: true,
+ // enableTooltips: true
+ // }
+ // ));
+
map.on('load', () => {
const layers = map.getStyle().layers;
- map.setLayoutProperty('country-label', 'text-field', ['get', `name_kr`]);
+
const labelLayerId = layers.find(
layer => layer.type === 'symbol' && layer.layout['text-field']
).id;
@@ -390,31 +409,62 @@ export default function MapBoxMap() {
setMapObject(map);
setMapLoaded(true);
});
- map.on('mouseover', 'maine', e => {
- const feature = e.features[0];
- const properties = feature.properties;
-
- // Remove the existing popup if it exists
- if (popup) {
- popup.remove();
- }
-
- // Create a new popup with the feature's properties
- popup = new mapboxgl.Popup()
- .setLngLat(e.lngLat)
- .setHTML(
- Object.entries(properties)
- .map(([key, value]) => `${key}: ${value}`)
- .join('
')
- )
- .addTo(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();
+ // }
+ // });
+ // });
+ // map.on('mouseover', 'maine', e => {
+ // const feature = e.features[0];
+ // const properties = feature.properties;
+
+ // // Remove the existing popup if it exists
+ // if (popup) {
+ // popup.remove();
+ // }
- map.on('mouseout', 'maine', () => {
- if (popup) {
- popup.remove();
- }
- });
+ // // Create a new popup with the feature's properties
+ // popup = new mapboxgl.Popup()
+ // .setLngLat(e.lngLat)
+ // .setHTML(
+ // Object.entries(properties)
+ // .map(([key, value]) => `${key}: ${value}`)
+ // .join('
')
+ // )
+ // .addTo(map);
+ // });
+
+ // map.on('mouseout', 'maine', () => {
+ // if (popup) {
+ // popup.remove();
+ // }
+ // });
// airPort?.map(air => polyArea(air, map));
};
@@ -588,7 +638,7 @@ export default function MapBoxMap() {
>
{isMapLoaded && mapObject ? (
<>
- {/* */}
+
{/*
@@ -610,7 +660,7 @@ export default function MapBoxMap() {
{/* */}
-
+
{/* */}
{/* */}
>
diff --git a/src/components/map/mapbox/dron/DronMarker.js b/src/components/map/mapbox/dron/DronMarker.js
new file mode 100644
index 00000000..bbcd23dc
--- /dev/null
+++ b/src/components/map/mapbox/dron/DronMarker.js
@@ -0,0 +1,657 @@
+import $ from 'jquery';
+import { useEffect, useState } from 'react';
+import { useDispatch, useSelector, shallowEqual } from 'react-redux';
+import '../../../../assets/css/custom.css';
+import FlightIcon from '../../../../assets/images/airplan_org.svg';
+import FlightDetailIcon from '../../../../assets/images/airplan_pp.svg';
+import DronIcon from '../../../../assets/images/drone-marker-icon.png';
+import DronDetailIcon from '../../../../assets/images/drone-marker-icon-pulple.png';
+import DronUamIcon from '../../../../assets/images/uam_icon.png';
+import DronUamDetailIcon from '../../../../assets/images/uam_icon_purple.png';
+import {
+ controlGpDtlAction,
+ controlGpFlightPlanAction,
+ controlGpCountAction
+} from '../../../../modules/control/gp';
+import {
+ objectClickAction,
+ objectUnClickAction
+} from '../../../../modules/control/map/actions/controlMapActions';
+import { JOIN_LIST } from '../../../../modules/basis/group/actions/basisGroupAction';
+
+export const DronMarker = props => {
+ const dispatch = useDispatch();
+
+ const { controlGpList, controlGroupAuthInfo } = useSelector(
+ state => state.controlGpState
+ );
+ const { objectId, isClickObject } = useSelector(
+ state => state.controlMapReducer,
+ shallowEqual
+ );
+ // const { controlGroupAuthInfo } = useSelector(
+ // state => state.controlGroupAuthState
+ // );
+ const { controlGpArcrftWarnList } = useSelector(
+ state => state.controlGpLogState
+ );
+
+ const { user } = useSelector(state => state.authState);
+ const { joinList } = useSelector(state => state.groupState);
+
+ const [arrMarkers, setArrMarkers] = useState([]);
+ const [arrInfos, setArrInfos] = useState([]);
+
+ const [count, setCount] = useState({
+ drone: [],
+ flight: []
+ });
+
+ let mapboxgl = props.mapboxgl;
+ let map = props.map;
+ let CustomOverlay;
+ let infoWindow;
+ // const infowindowOpen = data => {
+ // const content = `
+ //
+ //
+ // ${data?.id}
+ //
+ //
+ //
+ // ${
+ // data?.speed
+ // }${data?.speedType} | ${data?.elev}${data?.elevType} | ${
+ // data?.heading
+ // }
+ // ${(data?.coord._lat).toFixed(
+ // 6
+ // )} | ${(data?.coord._lng).toFixed(6)}
+ //
+ //
+ //
+ //
+ // `;
+
+ // infoWindow = new naver.maps.InfoWindow({
+ // class: 'tooltip-dblock',
+ // content: content,
+ // maxWidth: 160,
+ // backgroundColor: '#283046', //박스안쪽영역 컬러
+ // // borderColor: '#333', //테두리컬러
+ // // borderWidth: 3, //테두리 굵기
+ // // anchorSize: new naver.maps.Size(30, -10),
+ // anchorSkew: false,
+ // anchorColor: '#283046',
+
+ // pixelOffset: new naver.maps.Point(20, -20)
+ // });
+
+ // infoWindow.open(props.map, data.coord);
+ // };
+
+ // useLayoutEffect(() => {
+ // dispatch(controlGroupAuthAction.request());
+ // }, [controlGpList]);
+
+ useEffect(() => {
+ if (count.drone.length > 0 || count.flight.length > 0) {
+ dispatch(
+ controlGpCountAction.request({
+ count
+ })
+ );
+ } else {
+ const count = {
+ drone: [],
+ flight: []
+ };
+ dispatch(
+ controlGpCountAction.request({
+ count
+ })
+ );
+ }
+ }, [count]);
+
+ useEffect(() => {
+ dispatch(
+ JOIN_LIST.request({
+ cstmrSno: user?.cstmrSno
+ })
+ );
+ }, []);
+
+ useEffect(() => {
+ if (arrMarkers.length != 0) {
+ markerInfo(arrMarkers);
+ }
+ }, [arrMarkers]);
+
+ useEffect(() => {
+ markerInit();
+ }, [controlGpList]);
+
+ // useEffect(() => {
+ // let imageUrl;
+ // arrMarkers.map(clickMarker => {
+ // if (objectId === clickMarker.controlId && isClickObject) {
+ // // console.log(clickMarker.gps.objectId, '><><');
+ // imageUrl =
+ // // clickMarker.type === 'DRONE' ? DronUamDetailIcon : FlightDetailIcon;
+ // clickMarker.type === 'DRONE'
+ // ? clickMarker.gps.objectId.includes('UAM')
+ // ? DronUamDetailIcon
+ // : DronDetailIcon
+ // : FlightDetailIcon;
+ // clickMarker.setIcon({
+ // content: ``,
+ // origin: new naver.maps.Point(0, 0),
+ // anchor: new naver.maps.Point(15, 15)
+ // });
+ // } else {
+ // // imageUrl = clickMarker.type === 'DRONE' ? DronUamIcon : FlightIcon;
+ // imageUrl =
+ // clickMarker.type === 'DRONE'
+ // ? clickMarker.gps.objectId.includes('UAM')
+ // ? DronUamIcon
+ // : DronIcon
+ // : FlightIcon;
+ // clickMarker.setIcon({
+ // content: ``,
+ // origin: new naver.maps.Point(0, 0),
+ // anchor: new naver.maps.Point(15, 15)
+ // });
+ // }
+ // });
+ // }, [objectId, isClickObject]);
+
+ // useEffect(() => {
+ // arrMarkers.map(clickMarker => {
+ // if (objectId === clickMarker.controlId) {
+ // dispatch(controlGpDtlAction.request(objectId));
+ // props.map.setCenter(clickMarker.getPosition());
+ // props.map.setZoom(13, true);
+ // }
+ // });
+ // }, [objectId]);
+
+ //마커를 그린다.
+ const addMarkers = (position, id, controlId, gps) => {
+ const gpsCnt = {
+ gps: gps,
+ type: ''
+ };
+
+ const markerOption = {};
+
+ if (id.substring(0, 2) === 'PA') {
+ const pal = controlGroupAuthInfo?.find(
+ prev => prev.idntfNum === gps.objectId
+ );
+ if (pal || !pal || id.includes('NAMWON')) {
+ if (id.includes('UAM')) {
+ markerOption.url = DronUamIcon;
+ } else {
+ markerOption.url = DronIcon;
+ }
+
+ markerOption.type = 'DRONE';
+ gpsCnt.type = 'drone';
+ } else {
+ if (user?.authId === 'SUPER' || user?.authId === 'ADMIN') {
+ markerOption.url = FlightIcon;
+ markerOption.type = 'FLIGHT';
+ gpsCnt.type = 'flight';
+ } else {
+ const terminal = joinList?.find(prev => prev.trmnlId === gps.trmnlId);
+ if (
+ terminal?.groupAuthCd === 'MASTER' ||
+ terminal?.groupAuthCd === 'LEADER'
+ ) {
+ markerOption.url = FlightIcon;
+ markerOption.type = 'FLIGHT';
+ gpsCnt.type = 'flight';
+ }
+ }
+ }
+ } else {
+ if (user?.authId === 'SUPER' || user?.authId === 'ADMIN') {
+ markerOption.url = FlightIcon;
+ markerOption.type = 'FLIGHT';
+ gpsCnt.type = 'flight';
+ } else {
+ const terminal = joinList?.find(prev => prev.trmnlId === gps.trmnlId);
+ if (
+ terminal?.groupAuthCd === 'MASTER' ||
+ terminal?.groupAuthCd === 'LEADER'
+ ) {
+ markerOption.url = FlightIcon;
+ markerOption.type = 'FLIGHT';
+ gpsCnt.type = 'flight';
+ }
+ }
+ }
+
+ if (gpsCnt.type === 'drone') {
+ setCount(prev => ({
+ ...prev,
+ drone: [...prev.drone, gpsCnt]
+ }));
+ } else if (gpsCnt.type === 'flight') {
+ setCount(prev => ({
+ ...prev,
+ flight: [...prev.flight, gpsCnt]
+ }));
+ }
+
+ // if (id.substring(0, 2) === 'PA') {
+ // const pal = controlGroupAuthInfo?.find(
+ // prev => prev.idntfNum === gps.objectId
+ // );
+ // markerOption.url = pal ? DronIcon : FlightIcon;
+ // markerOption.type = pal ? 'DRONE' : 'FLIGHT';
+ // } else {
+ // markerOption.url = FlightIcon;
+ // markerOption.type = 'FLIGHT';
+ // }
+
+ // markerOption.origin = new naver.maps.Point(0, 0);
+ // markerOption.anchor = new naver.maps.Point(15, 15);
+
+ // const marker = new naver.maps.Marker({
+ // position: position,
+ // title: id,
+ // id: id,
+ // controlId: controlId,
+ // type: markerOption.type,
+ // icon: {
+ // content: ``,
+ // origin: markerOption.origin,
+ // anchor: markerOption.anchor
+ // },
+ // gps: gps
+ // });
+ // marker.setMap(props.map);
+ const el = document.createElement('img');
+ el.id = id;
+ el.src = markerOption.url;
+ el.style.transform = `rotate(${gps.heading}deg)`;
+
+ const marker = new props.mapboxgl.Marker({
+ element: el,
+ rotation: gps.heading
+ })
+ .setLngLat(position)
+ .addTo(props.map);
+ marker.id = id;
+ marker.title = id;
+ marker.controlId = controlId;
+ marker.type = markerOption.type;
+ marker.gps = gps;
+ marker.position = position;
+ marker.icon = {
+ content: ``,
+ origin: markerOption.origin,
+ anchor: markerOption.anchor
+ };
+
+ dispatch(controlGpFlightPlanAction.request(marker.id)); //예상경로
+ // dispatch(controlGpHisAction.request({ id: marker.controlId })); //진행경로;
+
+ /** drone 상세보기 */
+ marker.getElement().addEventListener('click', function (e) {
+ handlerDronClick(marker.controlId, marker.id);
+ });
+
+ if (markerOption.url) {
+ setArrMarkers(m => [...m, marker]);
+ }
+ };
+
+ const handlerDronClick = (controlId, idntfNum) => {
+ // get detail, history, flight-plan
+ dispatch(objectClickAction(controlId));
+ // dispatch(controlGpDtlAction.request(controlId));
+ // dispatch(controlGpFlightPlanAction.request(idntfNum));
+ };
+
+ //마커를 삭제 한다.
+ const removeMarkers = marker => {
+ // marker.setMap(null);
+ marker.remove();
+ };
+
+ const removeInfos = info => {
+ // info.setMap(null);
+ info.remove();
+ };
+
+ //마커에 위치를 이동한다.
+ const moveMarkers = (marker, position, gps) => {
+ const getIcon = marker.icon;
+
+ marker.setLngLat(position);
+ const warnList = controlGpArcrftWarnList?.filter(
+ i => i.cntrlId === gps.controlId
+ );
+
+ if (warnList?.length > 0) {
+ if (warnList[0].controlWarnCd) {
+ // marker.setIcon({
+ // content: ``,
+ // anchor: getIcon.anchor
+ // });
+ } else {
+ // console.log(marker);
+ // marker.setIcon({
+ // content: ``,
+ // anchor: getIcon.anchor
+ // });
+ marker.setRotation(gps.heading);
+ }
+ return;
+ }
+ marker.setRotation(gps.heading);
+ // marker.setIcon({
+ // content: ``,
+ // anchor: getIcon.anchor
+ // });
+ };
+
+ const moveInfos = (info, position, item, idx) => {
+ if (info) {
+ info.setLngLat([position.lng, position.lat]);
+ // info.setPosition(position, info);
+ // // info._element.html(`${info?._id}
+ // // ${item?.speed}${item?.speedType} | ${item?.elev}${item?.elevType} | ${item?.heading}
`);
+ // info._element.html(`
+ //
+ // ${info?._id}
+ //
+ //
+ //
+ // ${item?.elev}M
+ // ${item?.speed}km
+ // ${
+ // typeof item?.lat === 'number' && typeof item?.lng === 'number'
+ // ? `
+ //
+ // ${(item?.lat).toFixed(6)} ${(item?.lng).toFixed(6)}
+ // `
+ // : ''
+ // }
+ //
+ //
+ // `);
+ }
+ };
+
+ //데이터가 없는 마커를 모두 삭제 한다.
+ const allRemoveMarkers = () => {
+ let isUnClick = false;
+ if (arrMarkers && controlGpList) {
+ arrMarkers.map(marker => {
+ const isExists = controlGpList.find(
+ item => item.objectId === marker.id
+ );
+
+ if (!isExists) {
+ removeMarkers(marker);
+ const arrData = arrMarkers.filter(item => item.id != marker.id);
+
+ const drone = count.drone.filter(d => d.gps.objectId != marker.id);
+ const flight = count.flight.filter(d => d.gps.objectId != marker.id);
+
+ setCount({
+ drone: drone,
+ flight: flight
+ });
+
+ removeArrMarkers(arrData);
+ if (marker.controlId === objectId) {
+ dispatch(objectUnClickAction());
+ }
+ }
+ });
+
+ arrInfos.map(info => {
+ const isExists = controlGpList.find(item => item.objectId === info._id);
+ if (!isExists) {
+ removeInfos(info);
+ const arrData = arrInfos.filter(item => item.id != info._id);
+ removeArrInfos(arrData);
+ }
+ });
+ }
+ return isUnClick;
+ };
+
+ //마커를 셋팅 한다.
+ const markerInit = () => {
+ if (controlGpList) {
+ allRemoveMarkers();
+ controlGpList.map((item, idx) => {
+ // let position = new naver.maps.LatLng(item.lat, item.lng);
+ let position = new props.mapboxgl.LngLat(item.lng, item.lat);
+
+ if (arrMarkers.length > 0) {
+ const isExists = arrMarkers.find(ele => ele.id === item.objectId);
+ const isInfos = arrInfos.find(info => info._id === item.objectId);
+ if (isExists) {
+ moveMarkers(isExists, position, item);
+ moveInfos(isInfos, position, item, idx);
+ } else {
+ addMarkers(position, item.objectId, item.controlId, item);
+ }
+ } else {
+ addMarkers(position, item.objectId, item.controlId, item);
+ }
+ });
+ }
+ };
+
+ //운항정보 창 셋팅
+ const infoInit = (marker, gps, idx) => {
+ CustomOverlay = function (options) {
+ this._element = $(`
+
+
+ ${marker?.id}
+
+
+
+ ${gps?.elev}M
+ ${gps?.speed}km
+ ${
+ typeof gps?.lat === 'number' && typeof gps?.lng === 'number'
+ ? `
+
+ ${(gps?.lat).toFixed(6)} ${(gps?.lng).toFixed(6)}
+ `
+ : ''
+ }
+
+
+
+ `);
+
+ // this._element = $(`
+ //
+ //
+ // `)
+
+ this.setPosition(options.position, idx);
+ this.setMap(options.map || null);
+ this.setId(options.id);
+ this.setIdx(idx);
+ this.setControlId(options.controlId);
+ };
+
+ CustomOverlay.prototype = new naver.maps.OverlayView();
+ CustomOverlay.prototype.constructor = CustomOverlay;
+
+ //메소드 재정의
+ //필수
+ CustomOverlay.prototype.onAdd = function () {
+ let overlayLayer = this.getPanes().overlayLayer;
+
+ this._element.appendTo(overlayLayer);
+ };
+
+ CustomOverlay.prototype.draw = function (idx) {
+ if (!this.getMap()) {
+ return;
+ }
+
+ let projection = this.getProjection(),
+ position = this.getPosition(),
+ pixelPosition = projection.fromCoordToOffset(position);
+
+ // let cnt = 0;
+ // let index = idx?._idx;
+ // cnt = index * 98;
+ this._element.css('left', pixelPosition.x);
+ this._element.css('top', pixelPosition.y);
+ // this._element.css('top', pixelPosition.y + -cnt)
+ };
+
+ CustomOverlay.prototype.onRemove = function () {
+ let overlayLayer = this.getPanes().overlayLayer;
+
+ this._element.remove();
+ this._element.off();
+ };
+
+ //속성
+ CustomOverlay.prototype.setPosition = function (position, idx) {
+ this._position = position;
+ this.draw(idx);
+ };
+
+ CustomOverlay.prototype.getPosition = function () {
+ return this._position;
+ };
+
+ CustomOverlay.prototype.setId = function (id) {
+ this._id = id;
+ };
+
+ CustomOverlay.prototype.getId = function () {
+ return this._id;
+ };
+
+ CustomOverlay.prototype.setIdx = function (idx) {
+ this._idx = idx;
+ };
+
+ CustomOverlay.prototype.getIdx = function () {
+ return this._idx;
+ };
+
+ CustomOverlay.prototype.setControlId = function (controlId) {
+ this._controlId = controlId;
+ };
+
+ CustomOverlay.prototype.getControlId = function () {
+ return this._controlId;
+ };
+ };
+
+ const removeArrMarkers = arrData => {
+ setArrMarkers(arrData);
+ };
+
+ const removeArrInfos = arrData => {
+ setArrInfos(arrData);
+ };
+
+ const markerInfo = arrMarkers => {
+ arrMarkers.forEach((marker, idx) => {
+ if (arrInfos.filter(i => i._controlId === marker.controlId).length > 0) {
+ return;
+ }
+
+ const info = new props.mapboxgl.Popup({
+ closeButton: false,
+ closeOnClick: false
+ })
+ .setLngLat([marker.position.lng, marker.position.lat])
+ .setHTML(
+ `
+
+
+ ${marker?.id}
+
+
+
+ ${marker.gps?.elev}M
+ ${marker.gps?.speed}km
+ ${
+ typeof marker.gps?.lat === 'number' &&
+ typeof marker.gps?.lng === 'number'
+ ? `
+
+ ${(marker.gps?.lat).toFixed(
+ 6
+ )} ${(marker.gps?.lng).toFixed(6)}
+ `
+ : ''
+ }
+
+
+
+ `
+ )
+ .addTo(props.map);
+ // infoInit(marker, controlGpList[idx], idx);
+ info._id = marker.id;
+ info.gps = marker.gps;
+ // if (controlGpList.length != 0) {
+ // const info = new CustomOverlay({
+ // position: new naver.maps.LatLng(
+ // controlGpList[idx]?.lat,
+ // controlGpList[idx]?.lng
+ // ),
+ // // map: map,
+ // id: marker.id,
+ // idx: idx,
+ // controlId: marker.controlId
+ // });
+ // info.setMap(map);
+
+ setArrInfos(m => [...m, info]);
+ // }
+ });
+ };
+
+ return null;
+};
diff --git a/src/components/map/mapbox/feature/FeatureAirZone.js b/src/components/map/mapbox/feature/FeatureAirZone.js
index ad09a1a0..f4343892 100644
--- a/src/components/map/mapbox/feature/FeatureAirZone.js
+++ b/src/components/map/mapbox/feature/FeatureAirZone.js
@@ -5,6 +5,7 @@ import geoJson from '../../../../components/map/geojson/airArea.json';
import gimPo from '../../../../components/map/geojson/airportAirArea.json';
import '../../../../assets/css/custom.css';
+// 격자 공역 Source
const airPort = [
{
title: '김포공항',
@@ -34,34 +35,13 @@ const airPort = [
export const FeatureAirZone = props => {
const mapControl = useSelector(state => state.controlMapReducer);
+ let popup;
let infoWindow;
useEffect(() => {
featureAirZoneInit();
- // featureAirEvent();
}, [mapControl]);
- // useEffect(() => {
- // const addLayers = () => {
- // props.poly.forEach((layer, idx) => {
- // // console.log(layer);
- // props.map.addSource(`line${idx}`, {
- // type: 'geojson',
- // data: {
- // layer
- // }
- // });
- // props.map.addLayer(layer);
- // });
- // };
-
- // addLayers();
-
- // // return () => {
- // // props.map.remove();
- // // };
- // }, [props.poly]);
-
const infowindowOpen = data => {
const content =
'' +
@@ -72,48 +52,99 @@ export const FeatureAirZone = props => {
'
' +
'' +
- // '' +
'';
- infoWindow = new props.naver.maps.InfoWindow({
- class: 'tooltip-test',
- content: content,
- maxWidth: 200,
- backgroundColor: '#283046', //박스안쪽영역 컬러
- // borderColor: '#333', //테두리컬러
- // borderWidth: 3, //테두리 굵기
- anchorSize: new props.naver.maps.Size(30, -10),
- anchorSkew: false,
- anchorColor: '#283046',
-
- pixelOffset: new props.naver.maps.Point(20, -20)
+ if (popup) {
+ popup.remove();
+ }
+
+ // Create a popup element
+ popup = new props.mapboxgl.Popup({
+ offset: [20, -20],
+ closeButton: false,
+ closeOnClick: false,
+ closeOnMove: true
+ })
+ .setLngLat(data.coord)
+ .setHTML(content)
+ .addTo(props.map);
+ };
+
+ const featureAirEvent = markers => {
+ markers.forEach(marker => {
+ marker.getElement().addEventListener('mouseover', e => {
+ const data = {};
+ data.coord = marker.getLngLat();
+ data.title = marker.properties.name;
+ data.description = marker.properties.description;
+
+ infowindowOpen(data);
+ });
+ marker.getElement().addEventListener('mouseout', () => {
+ if (popup) {
+ popup.remove();
+ }
+ });
+ });
+
+ props.map.on('mouseover', 'maine', e => {
+ props.map.getCanvas().style.cursor = 'pointer';
+ const feature = e.features[0];
+ const data = feature.properties;
+ data.coord = e.lngLat;
+ data.title = feature.properties.name;
+
+ infowindowOpen(data);
+ });
+
+ props.map.on('mouseout', 'maine', () => {
+ props.map.getCanvas().style.cursor = '';
+ if (popup) {
+ popup.remove();
+ }
});
- infoWindow.open(props.map, data.coord);
+ props.map.on('click', e => {
+ // 클릭한 지점의 피처들을 얻어옵니다.
+ const features = props.map.queryRenderedFeatures(e.point, {
+ layers: ['add-3d-buildings'] // 빌딩 레이어의 ID를 지정합니다.
+ });
+
+ // 빌딩 피처가 있는 경우
+ if (features.length > 0) {
+ // 첫 번째 빌딩 피처의 높이 값을 얻어옵니다.
+ const height = features[0].properties.height;
+
+ // 팝업을 생성하고 지도에 추가합니다.
+ new props.mapboxgl.Popup()
+ .setLngLat(e.lngLat)
+ .setHTML(`Building height: ${height}m`)
+ .addTo(props.map);
+ }
+ });
};
+ // 공역 생성 함수
const featureAirZoneInit = () => {
let arrGeoJson = [];
- // props.map.data.removeGeoJson(props.geoJson);
- // let geoJson = originGeoJson;
+
const useGeoJson = {
...geoJson,
features: [...geoJson.features, ...gimPo.features]
};
// props.map.data.removeGeoJson(useGeoJson);
- // props.map.removeLayer('maine');
+ if (props.map.getLayer('maine')) {
+ props.map.removeLayer('maine');
+ props.map.removeSource('maine');
+ }
+ // 공역 색상 및 공역 표출 정보에 따른 노출
useGeoJson.features.map(item => {
if (item.properties.type === '0001' && mapControl.area0001) {
arrGeoJson.push({
@@ -149,6 +180,7 @@ export const FeatureAirZone = props => {
});
useGeoJson.features = arrGeoJson;
+ // 공역 생성 start
props.map.addSource('maine', {
type: 'geojson',
data: {
@@ -158,81 +190,33 @@ export const FeatureAirZone = props => {
props.map.addLayer({
id: 'maine',
type: 'fill',
- source: 'maine', // reference the data source
+ source: 'maine',
layout: {},
paint: {
'fill-color': ['get', 'color'],
'fill-opacity': 0.5
}
});
-
- airPort.map(air => polyArea(air));
-
- // useGeoJson.features = arrGeoJson;
- // props.map.data.addGeoJson(useGeoJson);
-
- // props.map.data.setStyle(feature => {
- // var color;
-
- // //0001 비행금지구역 #FF3648
- // //0002 비행제한구역 #FFA1AA
- // //0003 관제권(공항) #FFA800
- // //0004 비행장(군사) #A16B00
- // //0005 이착륙장(RC비행장) #AB40FF
- // //0006 초경량비행장치 #009cad
-
- // // 공역 색상 변경
- // const type = feature.getProperty('type');
- // if (type === '0001') {
- // color = '#FF3648';
- // } else if (type === '0002') {
- // color = '#FFA1AA';
- // } else if (type === '0003') {
- // color = '#FFA800';
- // } else if (type === '0004') {
- // color = '#A16B00';
- // } else if (type === '0005') {
- // color = '#AB40FF';
- // } else if (type === '0006') {
- // color = '#009cad';
- // }
-
- // return {
- // fillColor: color,
- // strokeColor: color,
- // strokeWeight: 0.7,
- // icon: null
- // };
- // });
- };
-
- const featureAirEvent = () => {
- props.map.data.addListener('click', function (e) {
- // e.feature.setProperty('isColorful', true);
- });
-
- props.map.data.addListener('mouseover', function (e) {
- const data = {};
- data.coord = e.coord;
- data.title = e.feature.property_name;
- data.description = e.feature.property_description;
- props.map.data.overrideStyle(e.feature, {
- strokeWeight: 3
- // icon: HOME_PATH +'/img/example/pin_spot.png'
+ // 공역 생성 end
+
+ // 비행장 마커 생성
+ const markers = useGeoJson.features
+ .filter(i => i.geometry.type === 'Point')
+ .map(i => {
+ const marker = new props.mapboxgl.Marker()
+ .setLngLat(i.geometry.coordinates)
+ .addTo(props.map);
+ marker.properties = i.properties;
+ return marker;
});
- infowindowOpen(data);
- });
-
- props.map.data.addListener('mouseout', function (e) {
- props.map.data.revertStyle();
-
- if (infoWindow) {
- infoWindow.close();
- }
- });
+ // 격자 공역 생성
+ airPort.map(air => polyArea(air));
+ // 마우스 오버 이벤트 생성
+ featureAirEvent(markers);
};
+ // 격자 공역 셋팅 함수
const polyArea = air => {
const polyArr = [];
const radius = air.buffer;
@@ -374,7 +358,10 @@ export const FeatureAirZone = props => {
};
polyArr.push(EW);
-
+ if (props.map.getLayer(air.title)) {
+ props.map.removeLayer(air.title);
+ props.map.removeSource(air.title);
+ }
props.map.addSource(air.title, {
type: 'geojson',
data: {
diff --git a/test/pav-warning.js b/test/pav-warning.js
index 2d8b8dcf..2e5f2edb 100644
--- a/test/pav-warning.js
+++ b/test/pav-warning.js
@@ -2,18 +2,20 @@ const { getConnection, writeData } = require('./pav-client');
const { getCoordsFormBetweenCoord, dumyData } = require('./pav-utils');
// const host = "192.168.0.24"
-const host = 'localhost';
+// const host = 'localhost';
// const host = '192.168.0.34';
+// const port = 8082;
+const host = '211.253.38.218';
const port = 8082;
// 기본정보
-const prefix = 'PA';
-const terminalId = 'SANDBOX-001';
+const prefix = '';
+const terminalId = '';
const pathSampleCoord = [
[37.5215, 126.605],
- [37.5215, 126.61], //비정상, 날릴 것
- // [37.5215, 126.6082], 계획서
+ // [37.5215, 126.61], //비정상, 날릴 것
+ [37.5215, 126.6082], //계획서
[37.521, 126.6082],
[37.521, 126.6057],
[37.5205, 126.6057],