diff --git a/src/components/map/naver/NaverMap.js b/src/components/map/naver/NaverMap.js index b791fa9..4fb47ae 100644 --- a/src/components/map/naver/NaverMap.js +++ b/src/components/map/naver/NaverMap.js @@ -11,6 +11,7 @@ import NewDronPlan from './dron/NewDronPlan'; import { NewDronHistory } from './dron/NewDronHistroy'; import DronToast from './dron/DronToast'; import SensorZone from './sensor/SensorZone'; +import ControlDraw from './draw/ControlDraw'; export const NaverCustomMap = () => { const dispatch = useDispatch(); @@ -126,7 +127,8 @@ export const NaverCustomMap = () => { useEffect(() => { NaverMapInit(); - airPort?.map(air => polyArea(air)); + // airPort?.map(air => polyArea(air)); + airPort?.map((air, idx) => polyArea(air, idx)); }, []); useEffect(() => { @@ -198,11 +200,11 @@ export const NaverCustomMap = () => { setArrPolyline([...arrPolyline, line]); }; - const polyArea = air => { + const polyArea = (air, idx) => { //격자 공역 const polyArr = []; const radius = air.buffer; - const position = air.center; + const position = air.center; //공역 센터 const color = '#000'; const opacity = 0.7; @@ -215,6 +217,8 @@ export const NaverCustomMap = () => { // buffer += 2000; buffer += 1000; + //EPSG3857.getDestinationCoord + //지정한 좌표에서 북쪽을 기준으로 각도와 거리만큼 떨어진 위치의 좌표 반환 const coord = new naver.maps.EPSG3857.getDestinationCoord( position, angle, @@ -308,6 +312,8 @@ export const NaverCustomMap = () => { + + {/* state.controlMapReducer); + + const naver = props.naver; + const map = props.map; + let mode; + + const [mapClickEvent, setMapClickEvent] = useState(); + const [circleArr, setCircleArr] = useState([]); + + const [up, setUp] = useState(false); + + useEffect(() => { + if (up) { + const delay = 100; + const timer = setTimeout(() => { + createMapClick(); + setUp(false); + }, delay); + + return () => { + clearTimeout(timer); + }; + } + }, [up]); + + useEffect(() => { + drawInit(); + }, [mapControl.ctrlDrawType]); + + const drawInit = () => { + removeMapClick(); + if (mapControl.ctrlDrawType === 'CIRCLE') { + onClickButton('CIRCLE'); + } else if (mapControl.ctrlDrawType === 'RESET') { + onClickReset(); + } + }; + + const onClickButton = newMode => { + removeMapClick(); + if (mode === newMode) { + mode = null; + return; + } + + // startMode(newMode); + if (!newMode) return; + + createMapClick(); + }; + + const onClickReset = () => { + console.log('초기화 진행'); + circleArr.map(circle => circle.setMap(null)); + setCircleArr([]); + + removeMapClick(); + }; + + const removeMapClick = () => { + $(document).off('mousemove.measure'); + $(document).off('mouseup.measure'); + + // naver.maps.Event.clearInstanceListeners(map); + naver.maps.Event.removeListener(mapClickEvent); + setMapClickEvent(); + }; + + const createMapClick = () => { + setMapClickEvent( + naver.maps.Event.addListener(map, 'click', function (e) { + onClickCircle(e); + }) + ); + }; + + const onClickCircle = e => { + const coord = e.coord; + + const circle = new naver.maps.Circle({ + strokeColor: '#283046', + strokeOpacity: 1, + fillColor: '#7367F0', + fillOpacity: 0.1, + center: coord, + radius: 100, + map: map, + clickable: true + }); + setCircleArr(prev => [...prev, circle]); + + naver.maps.Event.addListener(circle, 'mousedown', function () { + onMouseDown(circle); + }); + setUp(false); + }; + + const onMouseDown = circle => { + map.setOptions({ + draggable: false, + pinchZoom: false, + scrollWheel: false, + keyboardShortcuts: false, + disableDoubleTapZoom: true, + disableDoubleClickZoom: true, + disableTwoFingerTapZoom: true + }); + + $(document).on('mousemove.measure', function (e) { + onMouseMove(e, circle); + }); + + $(document).on('mouseup.measure', function (e) { + onMouseUp(); + }); + }; + + const onMouseMove = (e, circle) => { + const proj = map.getProjection(); + const coord = proj.fromPageXYToCoord( + new naver.maps.Point(e.pageX, e.pageY) + ); + + const center = circle.getCenter(); + const r = proj.getDistance(coord, center); + + circle.setRadius(r); + }; + + const onMouseUp = () => { + map.setOptions({ + draggable: true, + pinchZoom: true, + scrollWheel: true, + keyboardShortcuts: true, + disableDoubleTapZoom: false, + disableDoubleClickZoom: false, + disableTwoFingerTapZoom: false + }); + + removeMapClick(); + setUp(true); + }; + + return null; +} diff --git a/src/modules/control/map/actions/controlMapActions.ts b/src/modules/control/map/actions/controlMapActions.ts index 6b8e0a3..be85343 100644 --- a/src/modules/control/map/actions/controlMapActions.ts +++ b/src/modules/control/map/actions/controlMapActions.ts @@ -2,12 +2,12 @@ export const mapTypeChangeAction = (value: any) => dispatch => dispatch({ type: 'MAP_TYPE_CHANGE', value }); - // draw 옵션 변경 Action +// draw 옵션 변경 Action export const drawTypeChangeAction = (value: any) => dispatch => -dispatch({type: 'DRAW_TYPE_CHANGE', value}); + dispatch({ type: 'DRAW_TYPE_CHANGE', value }); export const drawCheckAction = (value: any) => dispatch => -dispatch({type: 'DRAW_CHECK', value}); + dispatch({ type: 'DRAW_CHECK', value }); // 드론체 클릭 시 Action export const objectClickAction = (value: any) => dispatch => @@ -20,4 +20,7 @@ export const areaClickAction = (value: any) => dispatch => dispatch({ type: 'AREA_CLICK', value }); export const sensorClickAction = (value: any) => dispatch => - dispatch({type: 'SENSOR_CLICK', value}) + dispatch({ type: 'SENSOR_CLICK', value }); + +export const ctrlDrawTypeChangeAction = (value: any) => dispatch => + dispatch({ type: 'CTRL_DRAW_TYPE_CHANGE', value }); diff --git a/src/modules/control/map/reducers/controlMapReducer.ts b/src/modules/control/map/reducers/controlMapReducer.ts index 116007a..57d6457 100644 --- a/src/modules/control/map/reducers/controlMapReducer.ts +++ b/src/modules/control/map/reducers/controlMapReducer.ts @@ -13,19 +13,21 @@ const initialState = { drawType: null, + ctrlDrawType: null, + drawCheck: '' }; const controlReducerReducer = (state = initialState, action) => { switch (action.type) { case 'MAP_TYPE_CHANGE': - return {...state, mapType: action.value}; + return { ...state, mapType: action.value }; - case 'OBJECT_CLICK': - return {...state, objectId: action.value, isClickObject: true}; + case 'OBJECT_CLICK': + return { ...state, objectId: action.value, isClickObject: true }; case 'OBEJCT_UN_CLICK': - return {...state, isClickObject: false}; + return { ...state, isClickObject: false }; case 'AREA_CLICK': if (action.value === '0001') { @@ -67,7 +69,7 @@ const controlReducerReducer = (state = initialState, action) => { return { ...state, sensor: action.value - } + }; break; default: return state; @@ -78,6 +80,12 @@ const controlReducerReducer = (state = initialState, action) => { drawType: action.value }; + case 'CTRL_DRAW_TYPE_CHANGE': + return { + ...state, + ctrlDrawType: action.value + }; + case 'DRAW_CHECK': return { ...state, diff --git a/src/views/control/main/ControlMain.js b/src/views/control/main/ControlMain.js index 9cbdfe7..5b37c8e 100644 --- a/src/views/control/main/ControlMain.js +++ b/src/views/control/main/ControlMain.js @@ -19,7 +19,7 @@ import { import { AiOutlinePoweroff, AiOutlineExclamation } from 'react-icons/ai'; import { IoAlertOutline } from 'react-icons/io5'; import { ReactComponent as DroneMenuIcon } from '../../../assets/images/drone_menu_icon.svg'; -import { Card } from 'reactstrap'; +import { Card, Button } from 'reactstrap'; import ControlAlarmNotice from '../alarm/ControlAlarmNotice'; import ControlReportList from '../report/ControlReportList'; import ControlReportDetail from '../report/ControlReportDetail'; @@ -30,7 +30,10 @@ import WebsocketClient from '../../../components/websocket/WebsocketClient'; import { useDispatch, useSelector } from 'react-redux'; import { controlweatherAction } from '../../../modules/control/gp/actions/controlGpAction'; import * as Actions from '../../../modules/account/login/actions/authAction'; -import { objectUnClickAction } from '../../../modules/control/map/actions/controlMapActions'; +import { + ctrlDrawTypeChangeAction, + objectUnClickAction +} from '../../../modules/control/map/actions/controlMapActions'; const ControlMain = () => { const dispatch = useDispatch(); @@ -149,6 +152,11 @@ const ControlMain = () => { } else return ; } } + + const handlerDrawType = val => { + dispatch(ctrlDrawTypeChangeAction(val)); + }; + return ( <> @@ -295,6 +303,22 @@ const ControlMain = () => { +
+ handlerDrawType('CIRCLE')} + > + Circle + + handlerDrawType('RESET')} + > + 초기화 + +
{oepnReportList ? (