Browse Source

naver map파일 삭제

pull/2/head
junh_eee(이준희) 10 months ago
parent
commit
a758d2f18d
  1. 543
      src/components/basis/flight/plan/FlightPlanAreaMapBox.js
  2. 544
      src/components/map/naver/NaverMap.js
  3. 89
      src/components/map/naver/dron/DronHistory.js
  4. 630
      src/components/map/naver/dron/DronMarker.js
  5. 200
      src/components/map/naver/dron/DronPlan.js
  6. 99
      src/components/map/naver/dron/DronToast.js
  7. 66
      src/components/map/naver/dron/NewDronHistroy.js
  8. 131
      src/components/map/naver/dron/NewDronPlan.js
  9. 170
      src/components/map/naver/feature/FeatureAirZone.js
  10. 23
      src/components/map/naver/search/NaverMapSearch.js

543
src/components/basis/flight/plan/FlightPlanAreaMapBox.js

@ -1,543 +0,0 @@
import { useEffect, useRef, useState } from 'react';
import 'mapbox-gl/dist/mapbox-gl.css';
import mapboxgl from 'mapbox-gl';
import MapboxLanguage from '@mapbox/mapbox-gl-language';
import { MAPBOX_TOKEN } from '../../../../configs/constants';
import {
Card,
CardBody,
Button,
ButtonGroup,
Input,
InputGroup,
InputGroupAddon,
InputGroupText,
Modal,
ModalHeader,
ModalBody,
ModalFooter
} from 'reactstrap';
import { useDispatch, useSelector } from 'react-redux';
import { initFlightBas } from '../../../../modules/basis/flight/models/basisFlightModel';
import {
AREA_COORDINATE_LIST_SAVE,
AREA_DETAIL_INIT,
FLIGHT_PLAN_AREA_BUFFER_LIST
} from '../../../../modules/basis/flight/actions/basisFlightAction';
import { flightPlanAPI } from '../../../../modules/basis/flight/apis/basisFlightApi';
import { Search } from 'react-feather';
import { FeatureAirZone } from '../../../map/mapbox/feature/FeatureAirZone';
import { drawTypeChangeAction } from '../../../../modules/control/map/actions/controlMapActions';
import { MapBoxDraw } from '../../../map/mapbox/draw/MapBoxDraw';
import { WeatherContainer } from '../../../../containers/basis/flight/plan/WeatherContainer';
export const FlightPlanAreaMapBox = props => {
const dispatch = useDispatch();
const mapControl = useSelector(state => state.controlMapReducer);
const { areaCoordList } = useSelector(state => state.flightState);
const mapContainer = useRef(null);
const [mapObject, setMapObject] = useState();
const [isMapLoad, setIsMapLoad] = useState(false);
const [mode, setMode] = useState();
const [mapAreaCoordList, setMapAreaCoordList] = useState(
initFlightBas.initDetail.areaList
);
const [query, setQuery] = useState('');
const [searchRes, setSearchRes] = useState([]);
const [isSearch, setIsSearch] = useState(false);
const [number, setNumber] = useState(0);
const [formModal, setFormModal] = useState(false);
const [layerId, setLayerId] = useState();
const buildingLayer = {
id: 'add-3d-buildings',
source: 'composite',
'source-layer': 'building',
filter: ['==', 'extrude', 'true'],
type: 'fill-extrusion',
minzoom: 15,
paint: {
'fill-extrusion-color': '#aaa',
// Use an 'interpolate' expression to
// add a smooth transition effect to
// the buildings as the user zooms in.
'fill-extrusion-height': [
'interpolate',
['linear'],
['zoom'],
15,
0,
15.05,
['get', 'height']
],
'fill-extrusion-base': [
'interpolate',
['linear'],
['zoom'],
15,
0,
15.05,
['get', 'min_height']
],
'fill-extrusion-opacity': 0.6
}
};
const terrainLayer = {
type: 'raster-dem',
url: 'mapbox://mapbox.mapbox-terrain-dem-v1'
// url: 'mapbox://mapbox.mapbox-street-v1',
// tileSize: 512,
// maxZoom: 16,
};
const geojson = {
type: 'FeatureCollection',
features: []
};
useEffect(() => {
mapBoxMapInit();
return () => {
dispatch(AREA_DETAIL_INIT());
};
}, []);
useEffect(() => {
setMode(mapControl.drawType);
}, [mapControl.drawType]);
useEffect(() => {
if (areaCoordList && mapObject) {
if (
areaCoordList[0].coordList[0].lat !== 0 &&
areaCoordList[0].coordList[0].lon !== 0
) {
if (number === 0) {
mapObject.setCenter([
areaCoordList[0].coordList[0].lon,
areaCoordList[0].coordList[0].lat
]);
setNumber(number + 1);
}
}
setMapAreaCoordList(areaCoordList);
}
}, [areaCoordList, mapObject, number]);
const mapBoxMapInit = () => {
const bufferZoom = {};
if (areaCoordList) {
if (
areaCoordList[0].bufferZone >= 0 &&
areaCoordList[0].bufferZone < 2000
) {
bufferZoom.bufferzoom = 13;
} else if (
areaCoordList[0].bufferZone >= 2000 &&
areaCoordList[0].bufferZone < 5000
) {
bufferZoom.bufferzoom = 12;
} else if (
areaCoordList[0].bufferZone >= 5000 &&
areaCoordList[0].bufferZone <= 9000
) {
bufferZoom.bufferzoom = 11;
} else {
bufferZoom.bufferzoom = 10;
}
}
mapboxgl.accessToken = MAPBOX_TOKEN;
const map = new mapboxgl.Map({
container: 'map', // container ID
style: 'mapbox://styles/mapbox/streets-v12', // style URL
center: [126.612647, 37.519893], // starting position [lng, lat]
// zoom: !areaCoordList ? 14 : bufferZoom.bufferzoom, // starting zoom
zoom: 15,
antialias: true,
attributionControl: false
});
const language = new MapboxLanguage();
map.addControl(language);
map.on('load', () => {
const layers = map.getStyle().layers;
const labelLayerId = layers.find(
layer => layer.type === 'symbol' && layer.layout['text-field']
).id;
setLayerId(labelLayerId);
// 지형 3d start
map.addSource('mapbox-dem', terrainLayer);
map.setTerrain({ source: 'mapbox-dem', exaggeration: 1.5 });
map.addLayer(buildingLayer, labelLayerId);
//mapDraw layer
map.addSource('geojson', {
type: 'geojson',
data: geojson
});
map.addLayer({
id: 'waypoint',
type: 'circle',
source: 'geojson',
paint: {
'circle-radius': 5,
'circle-color': '#ffffff',
'circle-stroke-color': '#000000',
'circle-stroke-width': 1
},
filter: ['in', '$type', 'Point']
});
map.addLayer({
id: 'guideline',
type: 'line',
source: 'geojson',
layout: {
'line-cap': 'round',
'line-join': 'round'
},
paint: {
'line-color': '#283046',
'line-width': 2,
'line-opacity': 0.5,
'line-dasharray': [5, 5]
},
filter: ['==', ['get', 'id'], 'guideline']
});
map.addLayer({
id: 'polyline',
type: 'line',
source: 'geojson',
layout: {
'line-cap': 'round',
'line-join': 'round'
},
paint: {
'line-color': '#283046',
'line-width': 2
},
filter: ['in', ['get', 'id'], ['literal', ['polyline', 'outline']]]
});
map.addLayer({
id: 'polygon',
type: 'fill',
source: 'geojson',
layout: {},
paint: {
'fill-color': '#8a1c05',
'fill-opacity': 0.5,
'fill-outline-color': '#000000'
},
//polygon, circle에 사용
filter: ['in', '$type', 'Polygon']
});
map.addLayer({
id: 'buffer',
type: 'line',
source: 'geojson',
layout: {
'line-cap': 'round',
'line-join': 'round'
},
paint: {
'line-color': '#283046',
'line-width': 1,
'line-dasharray': [5, 5]
},
filter: ['==', ['get', 'id'], 'buffer']
});
setMapObject(map);
setIsMapLoad(true);
});
};
const handlerMapTypeSwitch = type => {
if (type === '2d') {
mapObject.dragRotate.disable();
if (mapObject.getLayer('add-3d-buildings')) {
mapObject.removeLayer('add-3d-buildings');
mapObject.setTerrain();
mapObject.removeSource('mapbox-dem');
mapObject.flyTo({
pitch: 0,
bearing: 0
});
}
} else if (type === '3d') {
mapObject.dragRotate.enable();
if (!mapObject.getLayer('add-3d-buildings')) {
mapObject.addLayer(buildingLayer, layerId);
mapObject.addSource('mapbox-dem', terrainLayer);
mapObject.setTerrain({ source: 'mapbox-dem', exaggeration: 1.5 });
}
}
};
//지역 검색
const handlerSearch = async () => {
const res = await flightPlanAPI.searchArea({ query: query });
setIsSearch(true);
setSearchRes(res.data.items);
};
const handlerChange = e => {
const { name, value } = e.target;
if (name == 'searchInput') {
setQuery(value);
}
};
const handlerEnter = e => {
if (e.key == 'Enter') {
handlerSearch();
}
};
const handlerCoord = (mapx, mapy) => {
const numberString = [mapx, mapy];
const latlng = [];
numberString.map(coord => {
let digits = coord.split('');
if (digits[0] !== '1') {
digits.splice(2, 0, '.');
} else {
digits.splice(3, 0, '.');
}
latlng.push(Number(digits.join('')));
});
setIsSearch(false);
mapObject.setCenter(latlng);
mapObject.setZoom(15);
};
const handler = () => {
setFormModal(!formModal);
};
const handlerDrawType = val => {
dispatch(drawTypeChangeAction(val));
};
const handlerInitCoordinates = () => {
const init = initFlightBas.initDetail.areaList.concat();
dispatch(AREA_COORDINATE_LIST_SAVE(init));
};
const handlerCoordinates = areaInfo => {
const initAreaList = initFlightBas.initDetail.areaList.concat();
const coordList = [];
areaInfo.coordinates.forEach((c, idx) => {
const coord = Object.assign({}, initFlightBas['coord']);
coord.lat = c.lat;
coord.lon = c.lon;
coordList.push(coord);
});
const areaList = initAreaList.map((area, idx) => {
return {
...area,
bufferZone: areaInfo.bufferZone,
areaType: areaInfo.areaType,
coordList: coordList
};
});
if (areaInfo.areaType === 'LINE' || areaInfo.areaType === 'POLYGON') {
dispatch(FLIGHT_PLAN_AREA_BUFFER_LIST.request(areaList));
} else {
setMapAreaCoordList(areaList);
}
};
const handlerConfirm = areaList => {
if (areaList === undefined) {
alert('영역을 설정해 주세요.');
return false;
}
dispatch(AREA_COORDINATE_LIST_SAVE(areaList));
};
return (
<Card className='mb-0'>
<CardBody>
<div className='search-cont search-info pd-0'>
<div className='cont-ti mb-1 d-flex justify-content-between align-items-sm-center align-items-start flex-sm-row'>
<div>
<h4>지도 영역</h4>
</div>
</div>
</div>
<div style={{ position: 'relative' }}>
<div
id='map'
ref={mapContainer}
style={{ width: '100%', height: '60vh' }}
>
{isMapLoad && mapObject ? (
<MapBoxDraw
mapObject={mapObject}
mapboxgl={mapboxgl}
mode={mode}
areaCoordList={mapAreaCoordList}
handlerCoordinates={handlerCoordinates}
handlerInitCoordinates={handlerInitCoordinates}
handlerConfirm={handlerConfirm}
isDone={props.isDone}
isDisabled={props.isDisabled}
geojson={geojson}
handlerDrawType={handlerDrawType}
/>
) : null}
<div className='d-flex search-comp absolute'>
<div className=''>
<InputGroup className='search-feather'>
<InputGroupAddon addonType='prepend'>
<InputGroupText>
<Search size={14} onClick={handlerSearch} />
</InputGroupText>
</InputGroupAddon>
<Input
type='text'
id='searchInput'
name='searchInput'
bsSize='sm'
autoComplete='off'
placeholder='검색명을 입력하세요.'
onChange={handlerChange}
onKeyPress={handlerEnter}
/>
</InputGroup>
<div className='search-result-comp'>
<ul>
{searchRes?.length !== 0 && isSearch ? (
searchRes?.map(search => {
const title = search.title
.replaceAll('<b>', '')
.replaceAll('</b>', '');
return (
<li
key={search.mapx + search.mapy}
onClick={() =>
handlerCoord(search.mapx, search.mapy)
}
>
<a>
<div className='search-result'>
<div className='title'>
<span>
<strong>{title}</strong>
</span>
</div>
<div className='address'>
<span>{search.roadAddress}</span>
</div>
</div>
</a>
</li>
);
})
) : (
<></>
)}
</ul>
</div>
</div>
<div>
<ButtonGroup>
<Button onClick={() => handlerMapTypeSwitch('2d')}>2D</Button>
<Button onClick={() => handlerMapTypeSwitch('3d')}>3D</Button>
</ButtonGroup>
</div>
</div>
</div>
</div>
{isMapLoad ? (
<FeatureAirZone map={mapObject} mapboxgl={mapboxgl} />
) : null}
<div className='d-flex align-items-center mt-2'>
<Button.Ripple
className='mr-1'
color='primary'
onClick={e => handlerDrawType('LINE')}
disabled={props.isDisabled || props.isDone}
>
WayPoint
</Button.Ripple>
<Button.Ripple
className='mr-1'
color='primary'
onClick={e => handlerDrawType('CIRCLE')}
disabled={props.isDisabled || props.isDone}
>
Circle
</Button.Ripple>
<Button.Ripple
className='mr-1'
color='primary'
onClick={e => handlerDrawType('POLYGON')}
disabled={props.isDisabled || props.isDone}
>
Polygon
</Button.Ripple>
<Button.Ripple
color='primary'
className='mr-1'
onClick={e => handlerDrawType('RESET')}
disabled={props.isDisabled || props.isDone}
>
초기화
</Button.Ripple>
{areaCoordList ? (
areaCoordList[0].coordList[0].lat ? (
<Button.Ripple color='primary' onClick={handler}>
날씨
</Button.Ripple>
) : null
) : (
<></>
)}
</div>
<Modal
isOpen={formModal}
toggle={handler}
className='modal-dialog-centered'
>
<ModalHeader toggle={handler}>날씨 정보</ModalHeader>
<ModalBody>
<WeatherContainer mapAreaCoordList={mapAreaCoordList} />
</ModalBody>
<ModalFooter>
<Button color='primary' onClick={handler}>
확인
</Button>
</ModalFooter>
</Modal>
</CardBody>
</Card>
);
};

544
src/components/map/naver/NaverMap.js

@ -1,544 +0,0 @@
import React, { useEffect, useState } from 'react';
import { DronMarker } from './dron/DronMarker';
import NaverMapControl from './NaverMapControl';
import { FeatureAirZone } from './feature/FeatureAirZone';
import geoJson from '../geojson/airArea.json';
import gimPo from '../geojson/airportAirArea.json';
import NewDronPlan from './dron/NewDronPlan';
import DronToast from './dron/DronToast';
import ControlDraw from './draw/ControlDraw';
export const NaverCustomMap = () => {
const naver = window.naver;
const [mapObject, setMapObject] = useState(null);
const [arrPolyline, setArrPolyline] = useState([]);
const [poly, setPoly] = useState([]);
const [coordCenter, setCoordCenter] = useState([]);
const airPort = [
{
title: '김포공항',
buffer: 9300,
center: new naver.maps.LatLng(37.558522, 126.793722),
reduce: [54.4, 218.6, 500, 905.4, 1459.8, 2195, 3173.5, 4552.5, 6952.5]
},
{
title: '인천공항',
buffer: 9300,
center: new naver.maps.LatLng(37.4588105, 126.4409428),
reduce: [54.4, 218.6, 500, 905.4, 1459.8, 2195, 3173.5, 4552.5, 6952.5]
},
{
title: '제주공항',
buffer: 9300,
center: new naver.maps.LatLng(33.506848, 126.4930205),
reduce: [54.4, 218.6, 500, 905.4, 1459.8, 2195, 3173.5, 4552.5, 6952.5]
},
{
title: '정석비행장',
buffer: 9300,
center: new naver.maps.LatLng(33.3943517, 126.7142598),
reduce: [54.4, 218.6, 500, 905.4, 1459.8, 2195, 3173.5, 4552.5, 6952.5]
}
];
const [squarePaths, setSquarePaths] = useState([]);
const uamPosition = [
{
name: 'V1',
lat: 37.4797865,
lon: 126.540668
},
{
name: 'V2',
lat: 37.521245,
lon: 126.6107763
},
{
name: 'V3',
lat: 37.5642352,
lon: 126.6243464
},
{
name: 'V4',
lat: 37.3658236,
lon: 126.6650669
},
{
name: 'V5',
lat: 37.4520753,
lon: 126.7074861
},
{
name: 'R1',
lat: 37.492581,
lon: 126.5801572
},
{
name: 'R2',
lat: 37.542031,
lon: 126.6036588
},
{
name: 'R3',
lat: 37.5764269,
lon: 126.6005224
},
{
name: 'R4',
lat: 37.5790407,
lon: 126.6600404
},
{
name: 'R5',
lat: 37.524016,
lon: 126.649562
},
{
name: 'R6',
lat: 37.5506488,
lon: 126.693722
},
{
name: 'R7',
lat: 37.4712333,
lon: 126.6023981
},
{
name: 'R8',
lat: 37.4046495,
lon: 126.6202759
},
{
name: 'R9',
lat: 37.3450207,
lon: 126.6296542
}
];
let airArea = geoJson.features;
let gimPofeatures = gimPo.features;
let features = airArea.concat(gimPofeatures);
const coords = [];
useEffect(() => {
NaverMapInit();
airPort?.map((air, idx) => polyArea(air, idx));
// airPort?.map((air, idx) => airlist(air, idx));
// airPort?.map((air, idx) => polyArea(air, idx));
airPort?.map((air, idx) => {
gridgrid(air, idx);
});
gimPofeatures.map(air => {
coords.push({
lat:
(Math.max(
air.geometry.coordinates[0][0][1],
air.geometry.coordinates[0][1][1],
air.geometry.coordinates[0][2][1],
air.geometry.coordinates[0][3][1]
) +
Math.min(
air.geometry.coordinates[0][0][1],
air.geometry.coordinates[0][1][1],
air.geometry.coordinates[0][2][1],
air.geometry.coordinates[0][3][1]
)) /
2,
lng:
(Math.max(
air.geometry.coordinates[0][0][0],
air.geometry.coordinates[0][1][0],
air.geometry.coordinates[0][2][0],
air.geometry.coordinates[0][3][0]
) +
Math.min(
air.geometry.coordinates[0][0][0],
air.geometry.coordinates[0][1][0],
air.geometry.coordinates[0][2][0],
air.geometry.coordinates[0][3][0]
)) /
2,
airspace: air.properties.airspace
});
});
setCoordCenter(coords);
}, []);
useEffect(() => {
uamPosition.map(uam => {
const name = uam.name;
const position = new naver.maps.LatLng(uam.lat, uam.lon);
const cont =
name.substr(0, 1) == 'R'
? [
'<div style="border-radius:50%; background:#429629; border: 4px solid #ffffff; padding:5px; width:40px; height:40px; text-align:center">',
`<span style="color:#ffffff">${name}</span>`,
'</div>'
]
: [
'<div style="border-radius:50%; background:#ffffff; border: 4px solid #15298A; padding:5px; width:40px; height:40px; text-align:center ">',
`<span style="color:#000000">${name}</span>`,
'</div>'
];
new naver.maps.Marker({
position: position,
map: mapObject,
icon: {
content: cont.join(''),
anchor: new naver.maps.Point(20, 20)
}
});
});
// coordCenter = new nl();
coordCenter.map((val, idx) => {
const position = new naver.maps.LatLng(
val.lat.toFixed(6),
val.lng.toFixed(6)
);
// const cont = `<div style=font-size:5px;color:#000000; text-align:center">${val.airspace}</div>`;
const marker = new naver.maps.Marker({
position: position,
map: mapObject,
icon: {
content: `<div style="color:#000000;font-size:5px;">${val.airspace}</div>`,
size: new naver.maps.Size(0, 0),
origin: new naver.maps.Point(0, 0),
anchor: new naver.maps.Point(5, 5),
align: 'center'
}
});
});
}, [mapObject, coordCenter]);
// useEffect(() => {
// if (squarePaths.length > 315) {
// const arr = [];
// squarePaths.map((path, idx) => {
// const obj = {
// type: 'Feature',
// geometry: {
// type: 'Polygon',
// coordinates: [path]
// },
// properties: {
// name: `${idx + 1}번째 영역`,
// description: `${idx + 1}번째 영역 입니다.`,
// type: '0001'
// }
// };
// arr.push(obj);
// });
// console.log(arr, '>>>>>');
// }
// }, [squarePaths]);
const NaverMapInit = () => {
const mapOptions = {
center: new naver.maps.LatLng(37.558522, 126.793722),
// center: new naver.maps.LatLng(36.56793936069445, 127.85101412107547),
// zoom: 10,
zoom: 12,
zoomControl: true,
mapTypeId: naver.maps.MapTypeId.NORMAR,
zoomControlOptions: {
position: naver.maps.Position.TOP_LEFT,
style: naver.maps.ZoomControlStyle.SMALL
}
};
setMapObject(new naver.maps.Map('map', mapOptions));
};
const handleHistoryInit = line => {
setArrPolyline([...arrPolyline, line]);
};
//비행 공역 밖에 있는 값인지 확인하는 코드(추후 사용 할 수 있을 것 같아서 주석 걸어둠)
// const incoords = [];
// coords.map(coord => {
// let centerLat = 37.558522;
// let centerLng = 126.793722;
// let radius = 9.3;
// // let distance = Math.sqrt(
// // (coord._lat - centerLat) ** 2 + (coord._lng - centerLng) ** 2
// // );
// const centerLatRad = (centerLat * Math.PI) / 180;
// const centerLngRad = (centerLng * Math.PI) / 180;
// const coordlat = (coord._lat.toFixed(6) * Math.PI) / 180;
// const coordlng = (coord._lng.toFixed(6) * Math.PI) / 180;
// const R = 6371; // Radius of the earth in km
// const dLat = coordlat - centerLatRad;
// const dLon = coordlng - centerLngRad;
// const a =
// Math.sin(dLat / 2) * Math.sin(dLat / 2) +
// Math.sin(dLon / 2) *
// Math.sin(dLon / 2) *
// Math.cos(centerLatRad) *
// Math.cos(coordlat);
// const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
// const distance = R * c; // Distance in km
// if (distance <= radius) {
// incoords.push(coord);
// }
// });
// setCoordValue(incoords);
const polyArea = (air, idx) => {
if (idx === 0) return;
const polyArr = [];
const radius = air.buffer;
const position = air.center; //공역 센터
const color = '#000';
const opacity = 0.7;
const coords = [];
let angle = 0;
for (let i = 0; i < 4; i++) {
angle += 90;
let buffer = 0;
// for (let j = 0; j < 4; j++) {
for (let j = 0; j < 9; j++) {
// buffer += 2000;
buffer += 1000;
//EPSG3857.getDestinationCoord
//지정한 좌표에서 북쪽을 기준으로 각도와 거리만큼 떨어진 위치의 좌표 반환
const coord = new naver.maps.EPSG3857.getDestinationCoord(
position,
angle,
buffer
);
// console.log('coord>>>>>', coord);
// coords.push(coord);
// setCoordValue(coords);
let reduce = 0;
reduce = air.reduce[j];
// 2km reduce
// [218.6, 905.4, 2195, 4560.2]
if (angle % 180 == 0) {
const polyEW = new naver.maps.Polyline({
path: [
new naver.maps.EPSG3857.getDestinationCoord(
coord,
90,
radius - reduce
),
new naver.maps.EPSG3857.getDestinationCoord(
coord,
270,
radius - reduce
)
],
strokeWeight: 0.8,
strokeOpacity: opacity,
strokeColor: color
// map: map
});
polyArr.push(polyEW);
} else {
const polyNS = new naver.maps.Polyline({
path: [
new naver.maps.EPSG3857.getDestinationCoord(
coord,
0,
radius - reduce
),
new naver.maps.EPSG3857.getDestinationCoord(
coord,
180,
radius - reduce
)
],
strokeWeight: 0.8,
strokeOpacity: opacity,
strokeColor: color
// map: props.map
});
polyArr.push(polyNS);
}
}
}
const NS = new naver.maps.Polyline({
path: [
new naver.maps.EPSG3857.getDestinationCoord(position, 0, radius),
new naver.maps.EPSG3857.getDestinationCoord(position, 180, radius)
],
strokeWeight: 0.8,
strokeOpacity: opacity,
strokeColor: color
// map: props.map
});
polyArr.push(NS);
const EW = new naver.maps.Polyline({
path: [
new naver.maps.EPSG3857.getDestinationCoord(position, 90, radius),
new naver.maps.EPSG3857.getDestinationCoord(position, 270, radius)
],
strokeWeight: 0.8,
strokeOpacity: opacity,
strokeColor: color
// map: props.map
});
polyArr.push(EW);
setPoly(m => [...m, polyArr]);
};
const gridgrid = (air, idx) => {
if (idx !== 0) return;
const realCenter = air.center;
new naver.maps.Marker({
position: realCenter,
map: mapObject
});
let westEastAngle = 270;
for (let we = 0; we < 2; we++) {
if (we === 1) westEastAngle = 90;
let westEastBuffer = 0;
for (let westEast = 0; westEast < 10; westEast++) {
westEastBuffer += 1000;
const coord = new naver.maps.EPSG3857.getDestinationCoord(
realCenter,
westEastAngle,
westEastBuffer
);
let northSouthCoord = coord;
let notIncludes = 10;
if (westEast === 3 || westEast === 4) {
notIncludes = 9;
} else if (westEast === 5 || westEast === 6) {
notIncludes = 8;
} else if (westEast === 7) {
notIncludes = 7;
} else if (westEast === 8) {
notIncludes = 5;
} else if (westEast === 9) {
notIncludes = 3;
}
for (let ns = 0; ns < 2; ns++) {
getNorthSouth(northSouthCoord, notIncludes, we, ns);
}
}
}
};
const getNorthSouth = (northSouthCoord, notIncludes, weType, nsType) => {
for (let i = 0; i < notIncludes; i++) {
getSquare(northSouthCoord, weType, nsType);
const angle = nsType === 0 ? 0 : 180;
northSouthCoord = new naver.maps.EPSG3857.getDestinationCoord(
northSouthCoord,
angle,
1000
);
}
};
const getSquare = (coord, weType, nsType) => {
const square = [coord];
let angle = 0;
if (weType === 0 && nsType === 1) {
angle = 90;
} else if (weType === 1) {
if (nsType === 0) {
angle = 360;
} else if (nsType === 1) {
angle = 270;
}
}
for (let i = 2; i < 5; i++) {
const tt = new naver.maps.EPSG3857.getDestinationCoord(
square[i - 2],
angle,
1000
);
if (weType === 0) {
angle += 90;
} else if (weType === 1) {
angle -= 90;
}
square.push(tt);
}
const polygon = new naver.maps.Polygon({
strokeColor: '#283046',
strokeOpacity: 0.5,
// fillColor: '#8a1c05',
fillOpacity: 0.1,
paths: square,
map: mapObject
});
const path = polygon.getPath()._array;
const arr = [];
path.map(tt => {
const latlngJson = [tt.lng(), tt.lat(), 0];
arr.push(latlngJson);
});
arr.push([path[0].lng(), path[0].lat(), 0]);
setSquarePaths(prev => [...prev, arr]);
};
return (
<>
<div id='map' style={{ width: '100%', height: '100vh' }}></div>
{mapObject != null ? (
<>
<DronMarker map={mapObject} naver={naver} />
{/* <DronPlan map={mapObject} naver={naver} /> */}
<NewDronPlan map={mapObject} naver={naver} />
<NaverMapControl map={mapObject} />
{/* <DronHistory
map={mapObject}
naver={naver}
arrPolyline={arrPolyline}
handleHistoryInit={handleHistoryInit}
/> */}
{/* <NewDronHistory
map={mapObject}
naver={naver}
arrPolyline={arrPolyline}
handleHistoryInit={handleHistoryInit}
/> */}
<ControlDraw map={mapObject} naver={naver} />
<DronToast />
<FeatureAirZone
map={mapObject}
naver={naver}
features={features}
poly={poly}
/>
{/* <NaverMapSearch map={mapObject} naver={naver} /> */}
{/* <SensorZone map={mapObject} naver={naver} /> */}
</>
) : null}
{/* */}
</>
);
};

89
src/components/map/naver/dron/DronHistory.js

@ -1,89 +0,0 @@
import { object } from 'prop-types';
import { useEffect, useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { controlGpHisAction } from '../../../../modules/control/gp';
export const DronHistory = props => {
const { controlGpHistory } = useSelector(state => state.controlGpHisState);
const { controlGpList } = useSelector(state => state.controlGpState);
const { objectId, isClickObject } = useSelector(state => state.controlMapReducer);
const [arrHistory, setArrHistory] = useState([]);
let naver = props.naver;
let polyline;
let polylinePath = [];
const dispatch = useDispatch();
useEffect(() => {
if(objectId && isClickObject) {
if(arrHistory && arrHistory.length > 0) {
const gps = controlGpList.find((gps) => gps.controlId === objectId);
if(gps) {
const addHistory = {
objectId: gps.objectId,
lat: gps.lat,
lng: gps.lng
}
const history = [...arrHistory, addHistory];
polylineInit(history);
setArrHistory((his) => {
return [...his, addHistory];
});
}
}
}
}, [controlGpList]);
useEffect(() => {
polylineRemove();
setArrHistory(controlGpHistory);
polylineInit(controlGpHistory);
}, [controlGpHistory]);
useEffect(() => {
if (isClickObject) {
dispatch(controlGpHisAction.request({ id: objectId }));
} else {
polylineRemove();
}
}, [objectId, isClickObject]);
const polylineRemove = () => {
if (props.arrPolyline) {
props.arrPolyline.map(item => {
item.setMap(null);
});
}
};
const polylineInit = (history) => {
if (history) {
polyline = new naver.maps.Polyline({
clickable: false,
strokeColor: '#ff4961',
strokeStyle: 'solid',
strokeOpacity: 5,
strokeWeight: 1.5
});
history.map(item => {
if (item.lat > 0 && item.lng > 0) {
const position = new naver.maps.LatLng(item.lat, item.lng);
polylinePath.push(position);
}
});
polyline.setPath(polylinePath);
polyline.setMap(props.map);
props.handleHistoryInit(polyline);
}
};
return null;
};

630
src/components/map/naver/dron/DronMarker.js

@ -1,630 +0,0 @@
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 naver = props.naver;
let map = props.map;
let CustomOverlay;
let infoWindow;
// const infowindowOpen = data => {
// const content = `
// <div class="dblock-box">
// <div class="dblock-ti">
// <span>${data?.id}</span>
// </div>
// <div class="dblock-txt>
// <div class="dblock-txt-list">
// <div>
// <span style="width: 250px; display: inline-block;">${
// data?.speed
// }${data?.speedType} | ${data?.elev}${data?.elevType} | ${
// data?.heading
// }</span>
// <span style="width: 250px; display: inline-block;">${(data?.coord._lat).toFixed(
// 6
// )} | ${(data?.coord._lng).toFixed(6)}</span>
// </div>
// </div>
// </div>
// </div>
// `;
// 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: `<img src="${imageUrl}" alt="" style="transform: rotate(${clickMarker.gps.heading}deg)">`,
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: `<img src="${imageUrl}" alt="" style="transform: rotate(${clickMarker.gps.heading}deg)">`,
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: `<img id=${id} src="${markerOption.url}" alt="" style="transform: rotate(${gps.heading}deg);">`,
origin: markerOption.origin,
anchor: markerOption.anchor
},
gps: gps
});
marker.setMap(props.map);
dispatch(controlGpFlightPlanAction.request(marker.id)); //예상경로
// dispatch(controlGpHisAction.request({ id: marker.controlId })); //진행경로;
/** drone 상세보기 */
naver.maps.Event.addListener(marker, 'click', function (e) {
handlerDronClick(marker.controlId, marker.id);
});
// naver.maps.Event.addListener(marker, 'mouseover', function (e) {
// const data = {};
// data.id = marker.id;
// data.speed = marker.gps?.speed;
// data.speedType = marker.gps?.speedType;
// data.elev = marker.gps?.elev;
// data.elevType = marker.gps?.elevType;
// data.heading = marker.gps?.heading;
// data.coord = marker.position;
// infowindowOpen(data);
// });
naver.maps.Event.addListener(marker, 'mouseout', function (e) {
if (infoWindow) {
infoWindow.close();
}
});
// naver.maps.Event.addListener(map, 'zoom_changed', function (zoom) {
// const a = document.getElementsByClassName('dblock-box');
// for (let i = 0; i < a.length; i++) {
// if (zoom <= 9) {
// a[i].style.display = 'none';
// } else {
// a[i].style.display = 'block';
// a[i].style.width = `${zoom * 10 + 20}px`;
// a[i].style.fontSize = `${zoom}px`;
// }
// }
// // console.log(document.getElementsByClassName('dblock-box'));
// // document.querySelector('.dblock-box').style.width = `${zoom * 10}px`;
// // document.querySelector('.dblock-box').style.fontSize = `${zoom}px`;
// // document.querySelector('.dblock-ti').style.fontSize = `${zoom}px`;
// });
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);
};
const removeInfos = info => {
info.setMap(null);
};
//마커에 위치를 이동한다.
const moveMarkers = (marker, position, gps) => {
const getIcon = marker.getIcon();
marker.setPosition(position);
const warnList = controlGpArcrftWarnList?.filter(
i => i.cntrlId === gps.controlId
);
if (warnList?.length > 0) {
if (warnList[0].controlWarnCd) {
marker.setIcon({
content: `<img ${getIcon.content.substr(
getIcon.content.indexOf('src'),
getIcon.content.indexOf('alt') - 6
)} alt="" style="transform: rotate(${
gps.heading
}deg); filter: invert(16%) sepia(79%) saturate(4975%) hue-rotate(359deg) brightness(104%) contrast(129%)" />`,
anchor: getIcon.anchor
});
} else {
marker.setIcon({
content: `<img ${getIcon.content.substr(
getIcon.content.indexOf('src'),
getIcon.content.indexOf('alt') - 6
)} alt="" style="transform: rotate(${gps.heading}deg); " />`,
anchor: getIcon.anchor
});
}
return;
}
marker.setIcon({
content: `<img ${getIcon.content.substr(
getIcon.content.indexOf('src'),
getIcon.content.indexOf('alt') - 6
)} alt="" style="transform: rotate(${gps.heading}deg); " />`,
anchor: getIcon.anchor
});
};
const moveInfos = (info, position, item, idx) => {
if (info) {
info.setPosition(position, info);
// info._element.html(`<div class="dblock-ti"><span>${info?._id}</span>
// <span>${item?.speed}${item?.speedType} | ${item?.elev}${item?.elevType} | ${item?.heading}</span></div>`);
info._element.html(`
<div class="dblock-ti">
<span>${info?._id}</span>
</div>
<div class="dblock-txt">
<div class="dblock-txt-list">
<span>${item?.elev}M</span>
<span>${item?.speed}km</span>
${
typeof item?.lat === 'number' && typeof item?.lng === 'number'
? `
<span>
${(item?.lat).toFixed(6)} ${(item?.lng).toFixed(6)}
</span>`
: ''
}
</div>
</div>
`);
}
};
//데이터가 없는 마커를 모두 삭제 한다.
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);
if (arrMarkers) {
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 = $(`
<div class="dblock-box">
<div class="dblock-ti">
<span>${marker?.id}</span>
</div>
<div class="dblock-txt">
<div class="dblock-txt-list">
<span>${gps?.elev}M</span>
<span>${gps?.speed}km</span>
${
typeof gps?.lat === 'number' && typeof gps?.lng === 'number'
? `
<span>
${(gps?.lat).toFixed(6)} ${(gps?.lng).toFixed(6)}
</span>`
: ''
}
</div>
</div>
</div>
`);
// this._element = $(`
// <div class="tooltip-box" style="width: 150px;">
// <div class="tooltip-ti">
// <span>${marker?.id}</span>
// </div>
// <div class="tooltip-txt>
// <div class="tooltip-txt-list">
// <div>
// <span style="width: 120px; display: inline-block;">속도: ${gps?.speed}${gps?.speedType}</span>
// </div>
// <div>
// <span style="width: 120px; display: inline-block;">고도: ${gps?.elev}${gps?.elevType}</span>
// </div>
// <div>
// <span style="width: 120px; display: inline-block;">헤딩방향: ${gps?.heading}</span>
// </div>
// </div>
// </div>
// </div>
// `)
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;
}
infoInit(marker, controlGpList[idx], idx);
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;
};

200
src/components/map/naver/dron/DronPlan.js

@ -1,200 +0,0 @@
import { useEffect, useState } from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { controlGpFlightPlanInitAction } from '../../../../modules/control/gp';
import DronToast from './DronToast';
import { toast } from 'react-toastify';
const DronPlan = ({ naver, map }) => {
const dispatch = useDispatch();
const { controlGpList } = useSelector(state => state.controlGpState);
const { controlGpFltPlanList } = useSelector(state => state.controlGpFltPlanState);
const { objectId, isClickObject } = useSelector(state => state.controlMapReducer);
const [area, setArea] = useState(); // 비행 구역 관리
const [buffer, setBuffer] = useState(); // 버퍼 구역 관리
const [controlId, setControlId] = useState(); // 식별번호 저장
useEffect(() => {
if (controlGpFltPlanList) {
init();
}
}, [controlGpFltPlanList])
useEffect(() => {
if (!isClickObject) {
// 관제 종료시 영역 초기화.
clear();
} else {
setControlId(objectId);
}
}, [objectId ,isClickObject]);
useEffect(() => {
// 구역 대상의 드론 데이터가 지도 상에 존재하고 있는지 체크해야 한다. (없을 경우 영역 제거)
if (controlId && isClickObject) {
if (controlGpList) {
const isExist = controlGpList.find(data => data.controlId === controlId)
if(!isExist) {
clear();
}
}
}
}, [controlGpList])
// useEffect(() => {
// if (controlGpContains) {
// if(!controlGpContains.contains) {
// toast.info(<DronToast title={'비정상 상황 알림'} message={'경로 상에 비행 구역을 이탈하였습니다.'}/>, {
// autoClose: 3000,
// hideProgressBar: true,
// position: toast.POSITION.BOTTOM_RIGHT,
// })
// }
// }
// }, [controlGpContains])
/* 비행 구역 그리기. */
const init = () => {
if(area) {
area.setMap(null);
}
/* 좌표 추출 */
const planList = controlGpFltPlanList;
planList.forEach(plan => {
const areaList = plan.areaList;
// 구역 정보는 계획서당 1개만 존재
areaList.forEach(area => {
const coordList = area.coordList; // 기초 좌표
const bufferList = area.bufferCoordList; // 기초 좌표의 버퍼 좌표
const bufferZone = area.bufferZone; // 반경 값
const areaType = area.areaType; // 도형 타입
const paths = [];
coordList.forEach((coord) => {
const path = new naver.maps.LatLng(coord.lat, coord.lon)
paths.push(path);
});
clear();
if (areaType === 'LINE') {
polyline(paths, bufferList);
}
if (areaType === 'POLYGON') {
polygon(paths);
}
if (areaType === 'CIRCLE') {
circle(paths, bufferZone);
}
});
})
}
/* Polyline Create */
const polyline = (paths, bufferList) => {
if (paths && paths.length > 1) {
const line = new naver.maps.Polyline({
strokeLineCap: 'round',
strokeLineJoin: 'round',
strokeColor: '#283046',
strokeWeight: 1,
strokeOpacity: 0.5,
path: paths,
map: map
});
setArea(line);
}
if (bufferList && bufferList.length > 1) {
const paths = [];
bufferList.forEach((buffer) => {
const path = new naver.maps.LatLng(buffer.lat, buffer.lon)
paths.push(path);
});
const lineBuffer = new naver.maps.Polygon({
strokeColor: '#283046',
strokeOpacity: 1,
fillColor: '#8a1c05',
fillOpacity: 0.1,
paths: paths,
map: map
});
setBuffer(lineBuffer);
}
}
/* Polygon Create */
const polygon = (paths) => {
if (paths && paths.length > 1) {
const poly = new naver.maps.Polygon({
strokeColor: '#283046',
strokeOpacity: 1,
fillColor: '#8a1c05',
fillOpacity: 0.1,
paths: paths,
map: map
});
setArea(poly);
}
}
/* Circle Create */
const circle = (paths, bufferZone) => {
if (paths[0].lat !== 0 && paths[0].lon !== 0) {
const circle = new naver.maps.Circle({
strokeColor: '#283046',
strokeOpacity: 1,
fillColor: '#8a1c05',
fillOpacity: 0.1,
center: paths[0],
radius: bufferZone,
map: map,
clickable: true
});
setArea(circle);
}
}
/* 구역 초기화 */
const clear = () => {
if(area) {
area.setMap(null);
setArea();
if(buffer) {
buffer.setMap(null);
setBuffer();
}
dispatch(controlGpFlightPlanInitAction());
}
}
return null;
}
export default DronPlan;

99
src/components/map/naver/dron/DronToast.js

@ -1,99 +0,0 @@
import React, { useEffect, useState } from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { Fragment } from 'react';
import { toast } from 'react-toastify';
import Avatar from '../../../../@core/components/avatar';
import { Bell, Check, X, AlertTriangle, Info } from 'react-feather';
import {
controlGpDtlAction,
controlGpFlightPlanAction
} from '../../../../modules/control/gp';
import {
objectClickAction,
objectUnClickAction
} from '../../../../modules/control/map/actions/controlMapActions';
import 'react-toastify/dist/ReactToastify.css';
import useAudio from '../../../../utility/hooks/useAudio';
import warning from '../../../../assets/sounds/warning.mp3';
const DronToast = () => {
const dispatch = useDispatch();
const [playing, toggle] = useAudio(warning);
const { controlGpArcrftWarnList } = useSelector(
state => state.controlGpLogState
);
const [toastId, setToastId] = useState();
let warningList = [];
useEffect(() => {
if (controlGpArcrftWarnList) {
if (!toastId) {
for (let i = 0; i < controlGpArcrftWarnList.length; i++) {
if (controlGpArcrftWarnList[i].controlWarnCd) {
const id = toast.info(
toastRender(
`${controlGpArcrftWarnList[i].idntfNum} 비정상 상황 알림`,
`경로 상에 비행 구역을 이탈했습니다.`
),
{
autoClose: false,
hideProgressBar: true,
position: toast.POSITION.BOTTOM_RIGHT,
onClick: () => {
handleNotiClick(
controlGpArcrftWarnList[i].cntrlId,
controlGpArcrftWarnList[i].idntfNum
);
// setToastId(null);
},
onClose: () => {
// setIs(true);
toggle(false);
setToastId(null);
}
}
);
setToastId(id);
break;
}
}
}
for (let i = 0; i < controlGpArcrftWarnList.length; i++) {
warningList.push(controlGpArcrftWarnList[i].controlWarnCd);
}
warningList.find(i => i) ? toggle(true) : toggle(false);
}
}, [controlGpArcrftWarnList]);
const handleNotiClick = (controlId, idntfNum) => {
dispatch(objectClickAction(controlId));
dispatch(controlGpDtlAction.request(controlId));
dispatch(controlGpFlightPlanAction.request(idntfNum));
};
const toastRender = (title, message) => {
return (
<Fragment>
<div className='toastify-header'>
<div className='title-wrapper'>
<Avatar size='sm' color='info' icon={<Info size={10} />} />
<h6 className='text-info ml-50 mb-0' style={{ fontSize: 'small' }}>
{title}
</h6>
</div>
</div>
<div className='toastify-body'>
<span>{message}</span>
</div>
</Fragment>
);
};
return null;
};
export default DronToast;

66
src/components/map/naver/dron/NewDronHistroy.js

@ -1,66 +0,0 @@
import { object } from 'prop-types';
import { useEffect, useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { controlGpHisAction } from '../../../../modules/control/gp';
export const NewDronHistory = props => {
const dispatch = useDispatch();
const { controlGpHistory } = useSelector(state => state.controlGpHisState);
const { controlGpList } = useSelector(state => state.controlGpState);
// const { objectId, isClickObject } = useSelector(
// state => state.controlMapReducer
// );
// const [arrHistory, setArrHistory] = useState([]);
let naver = props.naver;
let polyline = [];
let polylinePath = [[]];
const [arrHistory, setArrHistory] = useState([]);
const [controlIdArr, setControlIdArr] = useState([]);
useEffect(() => {
if (controlGpList) {
const listArr = controlGpList.map(gpList => {
return gpList.objectId;
});
if (controlIdArr != listArr) {
setControlIdArr(listArr);
const diff = controlIdArr.filter(list => !listArr.includes(list));
if (diff.length > 0) console.log(diff);
}
// console.log(controlGpList, '>>>>');
}
}, [controlGpList]);
useEffect(() => {
if (controlGpHistory) {
// const tt = controlGpHistory[0].objectId;
// console.log(tt);
historyInit();
}
}, [controlGpHistory]);
const historyInit = () => {
const hisList = controlGpHistory;
const line = new naver.maps.Polyline({
clickable: false,
strokeColor: '#ff4961',
strokeStyle: 'solid',
strokeOpacity: 5,
strokeWeight: 1.5
});
hisList.map(item => {
if (item.lat > 0 && item.lng > 0) {
const position = new naver.maps.LatLng(item.lat, item.lng);
polylinePath.push(position);
}
});
// line.setPath(poly)
};
return null;
};

131
src/components/map/naver/dron/NewDronPlan.js

@ -1,131 +0,0 @@
import { useEffect, useState } from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { controlGpFlightPlanInitAction } from '../../../../modules/control/gp';
const NewDronPlan = ({ naver, map }) => {
const dispatch = useDispatch();
const { controlGpList } = useSelector(state => state.controlGpState);
const { controlGpFltPlanList } = useSelector(
state => state.controlGpFltPlanState
);
const [areaArr, setAreaArr] = useState([]);
const [bufferArr, setBufferArr] = useState([]);
const [controlIdArr, setControlIdArr] = useState([]);
useEffect(() => {
if (controlGpFltPlanList) {
planInit();
}
}, [controlGpFltPlanList]);
useEffect(() => {
if (controlGpList) {
const listArr = controlGpList.map(gpList => {
return gpList.objectId;
});
if (controlIdArr != listArr) {
setControlIdArr(listArr);
const diff = controlIdArr.filter(list => !listArr.includes(list));
if (diff) clear(diff);
}
}
}, [controlGpList]);
const planInit = () => {
const planList = controlGpFltPlanList;
planList.forEach(plan => {
const areaList = plan.areaList;
areaList.forEach(area => {
const coordList = area.coordList; // 기초 좌표
const bufferList = area.bufferCoordList; // 기초 좌표의 버퍼 좌표
const bufferZone = area.bufferZone; // 반경 값
const areaType = area.areaType; // 도형 타입
const paths = [];
coordList.forEach(coord => {
const path = new naver.maps.LatLng(coord.lat, coord.lon);
paths.push(path);
});
const idntfNum = plan.arcrftList[0].idntfNum;
if (areaType === 'LINE') {
polyline(paths, bufferList, idntfNum);
}
if (areaType === 'POLYGON') {
//
}
if (areaType === 'CIRCLE') {
//
}
});
});
};
const polyline = (paths, bufferList, idntfNum) => {
if (paths && paths.length > 1) {
const line = new naver.maps.Polyline({
strokeLineCap: 'round',
strokeLineJoin: 'round',
strokeColor: '#283046',
strokeWeight: 1,
strokeOpacity: 0.5,
path: paths,
map: map
});
setAreaArr(prev => [...prev, { idntfNum: idntfNum, line: line }]);
}
if (bufferList && bufferList.length > 1) {
const paths = [];
bufferList.forEach(buffer => {
const path = new naver.maps.LatLng(buffer.lat, buffer.lon);
paths.push(path);
});
const lineBuffer = new naver.maps.Polygon({
strokeColor: '#283046',
strokeOpacity: 1,
fillColor: '#8a1c05',
fillOpacity: 0.1,
paths: paths,
map: map
});
setBufferArr(prev => [
...prev,
{ idntfNum: idntfNum, lineBuffer: lineBuffer }
]);
}
};
const clear = diffArr => {
if (areaArr) {
const clearArea = areaArr
.filter(area => diffArr.includes(area.idntfNum))
.map(obj => obj.line);
const clearBuffer = bufferArr
.filter(buffer => diffArr.includes(buffer.idntfNum))
.map(obj => obj.lineBuffer);
clearArea.map(area => area.setMap(null));
clearBuffer.map(buffer => buffer.setMap(null));
const saveArea = areaArr.filter(area => !diffArr.includes(area.idntfNum));
const saveBuffer = bufferArr.filter(
buffer => !diffArr.includes(buffer.idntfNum)
);
setAreaArr(saveArea);
setBufferArr(saveBuffer);
// dispatch(controlGpFlightPlanInitAction());
}
};
return null;
};
export default NewDronPlan;

170
src/components/map/naver/feature/FeatureAirZone.js

@ -1,170 +0,0 @@
import { useEffect, useState } from 'react';
import { useSelector } from 'react-redux';
import '../../../../assets/css/custom.css';
export const FeatureAirZone = props => {
const mapControl = useSelector(state => state.controlMapReducer);
let infoWindow;
useEffect(() => {
featureAirZoneInit();
featureAirEvent();
}, [mapControl]);
useEffect(() => {
props.poly?.map(air => {
air?.map(a => {
a.setMap(props.map);
});
});
}, [props.poly]);
const infowindowOpen = data => {
const content =
'<div class="tooltip-box">' +
'<div class="tooltip-ti">' +
'<span>' +
data.title +
'</span>' +
'</div>' +
'<div class="tooltip-txt">' +
'<div class="tooltip-txt-list">' +
// '<span class="ti">설명</span>' +
'<span>' +
data.description +
'</span>' +
'</div>' +
// '<div class="tooltip-txt-list">' +
// '<span class="ti">좌표정보</span>' +
// '<span>'+data.coord+'</span>' +
// '</div>' +
'</div>' +
// '<span class="arrow"></span>' +
'</div>';
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)
});
infoWindow.open(props.map, data.coord);
};
const featureAirZoneInit = () => {
let arrGeoJson = [];
// props.map.data.removeGeoJson(props.geoJson);
// let geoJson = originGeoJson;
let useGeoJson = { type: 'FeatureCollection' };
useGeoJson.features = props.features;
props.map.data.removeGeoJson(useGeoJson);
props.features.map(item => {
if (item.properties.type === '0001' && mapControl.area0001) {
arrGeoJson.push(item);
} else if (item.properties.type === '0002' && mapControl.area0002) {
arrGeoJson.push(item);
} else if (item.properties.type === '0003' && mapControl.area0003) {
arrGeoJson.push(item);
} else if (item.properties.type === '0004' && mapControl.area0004) {
arrGeoJson.push(item);
} else if (item.properties.type === '0005' && mapControl.area0005) {
arrGeoJson.push(item);
} else if (item.properties.type === '0006' && mapControl.area0006) {
arrGeoJson.push(item);
}
});
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');
const name = feature.getProperty('name');
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' && name != '김포공항') {
color = '#009cad';
} else if (name === '김포공항') {
color = '#020715';
}
return {
fillColor: name === '김포공항' ? '#ffffff' : color,
opercity: name === '김포공항' ? 0 : 1,
strokeColor: color,
strokeWeight: name === '김포공항' ? 1 : 0.7,
icon: null
};
});
// const coordzip = [];
// let tt = 0;
// for (let i = 0; i <= 180; i++) {
// const coord1 = new naver.maps.EPSG3857.getDestinationCoord(
// new naver.maps.LatLng(33.3943517, 126.7142598),
// tt,
// 9300
// );
// coordzip.push(coord1);
// tt += 2;
// }
// console.log(coordzip);
// console.log(tt);
};
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'
});
infowindowOpen(data);
});
props.map.data.addListener('mouseout', function (e) {
props.map.data.revertStyle();
if (infoWindow) {
infoWindow.close();
}
});
};
return null;
};

23
src/components/map/naver/search/NaverMapSearch.js

@ -1,23 +0,0 @@
import { useEffect } from 'react';
export const NaverMapSearch = props => {
useEffect(() => {
props.naver.maps.Service.geocode(
{
address: '산곡동'
},
function (status, response) {
if (status !== naver.maps.Service.Status.OK) {
return alert('Something wrong!');
}
var result = response.result, // 검색 결과의 컨테이너
items = result.items; // 검색 결과의 배열
// do Something
}
);
});
return null;
};
Loading…
Cancel
Save