diff --git a/package.json b/package.json index b292c85b..de9181fb 100644 --- a/package.json +++ b/package.json @@ -47,7 +47,7 @@ "html-to-draftjs": "1.5.0", "http-proxy-middleware": "^2.0.1", "intl-messageformat": "7.8.4", - "jquery": "3.5.1", + "jquery": "^3.5.1", "js-cookie": "^3.0.0", "jsonwebtoken": "8.5.1", "jwt-decode": "^3.1.2", diff --git a/src/assets/css/custom.css b/src/assets/css/custom.css index c6f1fbcd..0f44874d 100644 --- a/src/assets/css/custom.css +++ b/src/assets/css/custom.css @@ -245,6 +245,17 @@ h1.logo span{display:block;color:#f4f4f4;font-weight:bold;letter-spacing:2px;fon /* fligth path draw */ .left-menu-nav li .check{background-color: #283046; font-size:0.9rem; color: white; width:70px; border: 0px;} +.left-menu-nav.test{position: relative; z-index: 1; cursor: pointer; float: left; display: block; margin: 0px; padding: 0px; width: 28px; height: 28px; list-style: none; box-sizing: content-box !important; background: rgb(255, 255, 255);} +.left-menu-nav .test .btn-stop{margin-left:25px; width: 28px; height: 28px; display: block; border: 0px solid transparent; box-sizing: content-box !important;} +.left-menu-nav .test .btn-use{margin-left:20px; width: 35px; height: 35px; display: block; border: 0px solid transparent; box-sizing: content-box !important; background-color: #009cad;} + +.measure-control{position:absolute; z-index:100;} + +.control-btn{margin-left: 7px; border-bottom: solid 1px #283046; margin-bottom:5px;} +.buffer-input{text-align: center; border-radius: 100px; border: 1px solid #283046; width: 70px; margin-left: 5px;} +.buffer-btn{text-align: center; border-radius: 100px; border: 1px solid #283046; width: 30px; margin-left: 5px;} + + /*메인-알림*/ .notice{width:650px;height:45px;overflow:hidden;position:absolute;left:50%;top:20px;transform: translate(-50%,0px);background:#283046;display:flex;font-size:0.9375rem;color:#f4f4f4;padding:0px 20px;border-radius:30px;} diff --git a/src/components/basis/flight/plan/FlightPlanAreaForm.js b/src/components/basis/flight/plan/FlightPlanAreaForm.js index 2de40024..50ef0011 100644 --- a/src/components/basis/flight/plan/FlightPlanAreaForm.js +++ b/src/components/basis/flight/plan/FlightPlanAreaForm.js @@ -1,20 +1,24 @@ -import React from 'react'; +import React, { useState, useEffect } from 'react'; +import classnames from 'classnames'; import { Card, CardBody, Col, FormGroup, + FormFeedback, Input, Label, Row, - Button + Button, + Form } from 'reactstrap'; -const FlightPlanAreaForm = () => { + +const FlightPlanAreaForm = (props) => { return ( - +
@@ -28,57 +32,22 @@ const FlightPlanAreaForm = () => {
-
+
- - - -
-
- - - - - - - - -
-
- - - - - + placeholder='' + innerRef={props.data} + /> @@ -89,33 +58,55 @@ const FlightPlanAreaForm = () => {
-
+
- +
+ + 확인 + + + props.setModal({ ...props.modal, isOpen: !props.modal.isOpen }) + } + > + 취소 + - -
+
) diff --git a/src/components/modal/FormModal.js b/src/components/basis/flight/plan/FlightPlanAreaModal.js similarity index 50% rename from src/components/modal/FormModal.js rename to src/components/basis/flight/plan/FlightPlanAreaModal.js index 5c7f92f2..3bcee8fa 100644 --- a/src/components/modal/FormModal.js +++ b/src/components/basis/flight/plan/FlightPlanAreaModal.js @@ -1,6 +1,11 @@ +import { useState } from 'react'; import { Button, Modal, ModalHeader, ModalBody, ModalFooter } from 'reactstrap'; +import FlightPlanAreaContainer from '../../../../containers/basis/flight/plan/FlightPlanAreaContainer'; + +export const FlightPlanAreaModal = props => { + + const [onSubmit, setOnSubmit] = useState(false); -export const FormModal = props => { return (
{ {props.modal.title} - {props.modal.contents} + - + {/* - + */}
); diff --git a/src/components/basis/flight/plan/FlightPlanForm.js b/src/components/basis/flight/plan/FlightPlanForm.js index 8a758b86..2df3b01c 100644 --- a/src/components/basis/flight/plan/FlightPlanForm.js +++ b/src/components/basis/flight/plan/FlightPlanForm.js @@ -44,7 +44,7 @@ const FlightPlanForm = (props) => { - + { - + { placeholder='' /> - + + + +
+ - + { /> - - + { placeholder='' /> - - -
+ + + + -
+ {/*
- + { - + { -
+
*/}
@@ -273,7 +277,8 @@ const FlightPlanForm = (props) => { id='ownerNm' name='ownerNm' size='sm' - placeholder='' + placeholder='' + readOnly /> @@ -287,7 +292,8 @@ const FlightPlanForm = (props) => { id='ownerNm' name='ownerNm' size='sm' - placeholder='' + placeholder='' + readOnly /> @@ -305,7 +311,8 @@ const FlightPlanForm = (props) => { id='ownerNm' name='ownerNm' size='sm' - placeholder='' + placeholder='' + readOnly /> @@ -320,7 +327,8 @@ const FlightPlanForm = (props) => { id='ownerNm' name='ownerNm' size='sm' - placeholder='m' + placeholder='m' + readOnly />
@@ -329,7 +337,8 @@ const FlightPlanForm = (props) => { id='ownerNm' name='ownerNm' size='sm' - placeholder='ft' + placeholder='ft' + readOnly />
diff --git a/src/components/mapDraw/naver/NaverMap.js b/src/components/mapDraw/naver/NaverMap.js index 6b32d000..0562a90f 100644 --- a/src/components/mapDraw/naver/NaverMap.js +++ b/src/components/mapDraw/naver/NaverMap.js @@ -1,18 +1,15 @@ import React, { useEffect, useState } from 'react'; -import { useSelector } from 'react-redux'; -import dronicon from '../../../assets/control/icon/drone.png'; -import { DronMarker } from './dron/DronMarker'; -import { DronHistory } from './dron/DronHistory'; import NaverMapControl from './NaverMapControl'; -import { NaverMapSearch } from './search/NaverMapSearch'; import { FeatureAirZone } from './feature/FeatureAirZone'; -import { DrawPath } from './draw/DrawPath'; import { DrawMap } from './draw/DrawMap'; +import { JQueryDraw } from './draw/JQueryDraw'; import geoJson from '../geojson/airArea.json'; import SensorZone from "./sensor/SensorZone"; +import $ from 'jquery'; + export const NaverCustomMap = () => { const naver = window.naver; // let map; @@ -26,14 +23,8 @@ export const NaverCustomMap = () => { useEffect(() => { NaverMapInit(); - // console.log(map); - // console.log(features); - // setIsMapLoad(true); }, []); - // useEffect(() => { - // console.log('==============11111==================', mapObject); - // }, [mapObject]); const removeArrMarkers = arrData => { arrMarkers = arrData; @@ -46,7 +37,7 @@ export const NaverCustomMap = () => { zoomControl: true, // mapTypeId: naver.maps.MapTypeId.HYBRID, zoomControlOptions: { - position: naver.maps.Position.TOP_LEFT, + position: naver.maps.Position.LEFT_CENTER, style: naver.maps.ZoomControlStyle.SMALL } @@ -56,19 +47,24 @@ export const NaverCustomMap = () => { }; return ( - <> -
+
+
+ {/* 제이쿼리로 그리기 */} + +
+ {mapObject != null ? ( <> - + + {/* 그리기 도구 모음 불러오는 거 */} ) : null} {/* */} - +
); }; diff --git a/src/components/mapDraw/naver/draw/DrawMap.js b/src/components/mapDraw/naver/draw/DrawMap.js index 6b0ea4fc..3e6b12ee 100644 --- a/src/components/mapDraw/naver/draw/DrawMap.js +++ b/src/components/mapDraw/naver/draw/DrawMap.js @@ -1,38 +1,57 @@ import { useEffect, useState } from "react"; -import { render } from "react-dom"; -import { BiCaretLeftCircle } from "react-icons/bi"; import { useSelector } from "react-redux"; export const DrawMap = props => { const {naver} = props; const {map} = props; - const [check, setCheck] = useState([]); + const [drawing, setDrawing] = useState(); + const [overlay, setOverlay] = useState([]); const {drawCheck} = useSelector(state => state.controlMapReducer); + useEffect(() => { + removeOverlay(); + }, [overlay]); useEffect(() => { init(); }, [drawCheck]); + + const removeOverlay = () => { + if(overlay.length >= 2) { + drawing.removeDrawing(overlay[0]); + setOverlay(prev => ([prev[overlay.length-1]])); + } + } + const init = () => { - removeDraw(); + initRemove(); + removeDrawManager(); } - const removeDraw = () => { - check.forEach(prev => prev.setMap(null)); - drawSetting(); + const initRemove = () => { + if(overlay) { + overlay.forEach(prev => drawing.removeDrawing(prev)); + setOverlay([]); + } } + const removeDrawManager = () => { + if(drawing) { + drawing.setMap(null); + } + drawSetting(); + } const drawSetting = () => { if(drawCheck) { + // debugger; let drawingManager = new naver.maps.drawing.DrawingManager({ drawingControl: [ naver.maps.drawing.DrawingMode.POLYLINE, naver.maps.drawing.DrawingMode.POLYGON, - naver.maps.drawing.DrawingMode.ELLIPSE, - naver.maps.drawing.DrawingMode.RECTANGLE + naver.maps.drawing.DrawingMode.ELLIPSE ], drawingControlOptions: { position: naver.maps.Position.LEFT_CENTER, @@ -52,21 +71,15 @@ export const DrawMap = props => { strokeWeight: 2, } }, - rectangleOptions: { - fillColor: '#ff0000', - fillOpacity: 0.3, - strokeWeight: 2, - strokeColor: '#ff0000' - }, ellipseOptions: { fillColor: '#ff25dc', fillOpacity: 0.3, strokeWeight: 2, strokeColor: '#ff25dc' }, - polylineOptions: { // 화살표 아이콘 계열 옵션은 무시됩니다. + polylineOptions: { strokeColor: '#222', - strokeWeight: 2 + strokeWeight: 10 }, polygonOptions: { fillColor: '#ffc300', @@ -75,12 +88,28 @@ export const DrawMap = props => { strokeColor:'#ffc300' } }); + + // console.log(drawingManager.) + + addEvent(drawingManager); drawingManager.setMap(map); - setCheck(prev => ([...prev, drawingManager])); + setDrawing(drawingManager); } } + const addEvent = (drawingManager) => { + drawingManager.addListener('drawing_added', function(overlay) { + console.log(overlay) + if(overlay.OVERLAY_TYPE === 'Polygon') { + console.log(overlay.paths._array[0]._array) + } else if(overlay.OVERLAY_TYPE === 'Ellipse') { + console.log(overlay.bounds) + } + setOverlay(prev=> ([...prev, overlay])); + }); + } + return null; }; diff --git a/src/components/mapDraw/naver/draw/DrawPath.js b/src/components/mapDraw/naver/draw/DrawPath.js deleted file mode 100644 index f8326ed4..00000000 --- a/src/components/mapDraw/naver/draw/DrawPath.js +++ /dev/null @@ -1,154 +0,0 @@ -import { useEffect, useState } from "react"; -import { BiCaretLeftCircle } from "react-icons/bi"; -import { useSelector } from "react-redux"; - -export const DrawPath = props => { - const {naver} = props; - const {map} = props; - const {drawType} = useSelector(state => state.controlMapReducer); - - let linePath = ([]); - let circleCenter = ''; - - const [eventGroup, setEventGroup] = useState([]); - const [polylines, setPolylines] = useState([]); - const [circleLayers, setCircleLayers] = useState([]); - - useEffect(() => { - // drawSetting(); - }, []); - - useEffect(() => { - init(); - }, [drawType]); - - useEffect(() => { - }, [eventGroup]); - - useEffect(() => { - moveCircle(); - }, [circleLayers]); - - const init = () => { - removeEvent(); - removeLayers(); - } - - const drawSetting = () => { - const drawingManager = new naver.maps.drawing.DrawingManager({ - drawingControl: [ - naver.maps.drawing.DrawingMode.POLYLINE, - naver.maps.drawing.DrawingMode.POLYGON, - naver.maps.drawing.DrawingMode.ELLIPSE, - naver.maps.drawing.DrawingMode.RECTANGLE - ], - drawingControlOptions: { - position: naver.maps.Position.LEFT_CENTER, - style: naver.maps.drawing.DrawingStyle.VERTICAL - } - }); - drawingManager.setMap(map); - } - - const removeEvent = () => { - eventGroup.forEach(prev => naver.maps.Event.removeListener(prev)); - // eventGroup.forEach(prev => console.log(prev)); - // const test = eventGroup.find(prev=> prev='drawingManager'); - // if(test) { - // test.setMap(null); - // } - setEventGroup([]); - addEvent(); - } - - const removeLayers = () => { - if(polylines) { - polylines.forEach(prev => prev.setMap(null)); - setPolylines([]); - }; - if(circleLayers) { - circleLayers.forEach(prev => prev.setMap(null)); - setCircleLayers([]); - }; - linePath = []; - // circleCenter = ''; - } - - const addEvent = () => { - let addClick = naver.maps.Event.addListener(map, 'click', function(e) { - // debugger; - if(drawType) { - linePath.push(e.coord); - circleCenter = e.coord; - startDraw(); - } else { - // console.log('1'); - } - }); - - // let escDown = naver.maps.Event.addListener(map, 'keydown', function(e) { - // const keyboardEvent = e.keyboardEvent, - // keyCode = keyboardEvent.keyCode || keyboardEvent.which; - - // const ESC = 27; - // if(keyCode === ESC) { - // keyboardEvent.preventDefault(); - // // removeLayers(); - // } - // }); - - - setEventGroup(prev => ([...prev, addClick])); - } - - const startDraw = () => { - if(drawType === 'LINE') { - createPolyline(); - } else if(drawType === 'CIRCLE') { - createCircle(); - } - } - - const createPolyline = () => { - if(linePath.length >= 2) { - const polyline = new naver.maps.Polyline({ - path: linePath, - strokeColor: '#ff0000', - strokeWeight: 2, - strokeOpacity: 0.5, - map: map - }); - linePath.shift(); - setPolylines(prev => ([...prev, polyline])); - } - } - - const createCircle = () => { - const circle = new naver.maps.Circle({ - center: circleCenter, - strokeColor: '#283046', - strokeWeight: 1, - strokeOpacity: 0.8, - fillColor: '#0000ff', - fillOpacity: 0.2, - radius: 150, - clickable: false, - map: map - }); - // circleCenter = ''; - setCircleLayers(prev => ([...prev, circle])); - } - - const moveCircle = () => { - if(circleLayers.length >= 2) { - circleLayers[0].setMap(null); - setCircleLayers(prev => ([prev[circleLayers.length-1]])); - } - // else { - // console.log(circleLayers); - // } - } - - return null; -}; - diff --git a/src/components/mapDraw/naver/draw/JQueryDraw.js b/src/components/mapDraw/naver/draw/JQueryDraw.js new file mode 100644 index 00000000..243cd1c4 --- /dev/null +++ b/src/components/mapDraw/naver/draw/JQueryDraw.js @@ -0,0 +1,496 @@ +import $ from 'jquery'; +import { useEffect } from 'react'; +import { useSelector } from 'react-redux'; +import '../../../../assets/css/custom.css'; +import { CustomInput } from 'reactstrap'; + +export const JQueryDraw = props => { + const {naver} = props; + const {map} = props; + + const { drawType } = useSelector(state => state.controlMapReducer); + + + var Measure = function(buttons) { + this.$btnLine = buttons.line; + this.$btnPolygon = buttons.polygon; + this.$btnCircle = buttons.circle; + + this._mode = null; + + this._bindDOMEvents(); + }; + + $.extend( + Measure.prototype,{ + constructor: Measure, + + setMap: function(map) { + console.log('setMap') + if (this.map) { + this._unbindMap(this.map); + } + + this.map = map; + + if (map) { + this._bindMap(map); + } + }, + + startMode: function(mode) { + console.log('startMode') + if (!mode) return; + + if (mode === 'line') { + this._startDistance(); + } if (mode === 'polygon') { + this._startArea(); + } if (mode === 'circle') { + this._startCircle(); + } + }, + + _startDistance: function() { + console.log('startDistance') + var map = this.map; + this._distanceListeners = [ + naver.maps.Event.addListener(map, 'click', this._onClickDistance.bind(this)) + ]; + }, + + _startArea: function() { + console.log('startArea') + var map = this.map; + + this._areaListeners = [ + naver.maps.Event.addListener(map, 'click', this._onClickArea.bind(this)), + naver.maps.Event.addListener(map, 'rightclick', this._finishArea.bind(this)) + ]; + + $(document).on('mousemove.measure', this._onMouseMoveArea.bind(this)); + }, + + _startCircle: function() { + console.log('startCircle') + var map = this.map; + this._circleListeners = [ + naver.maps.Event.addListener(map, 'click', this._onClickCircle.bind(this)), + naver.maps.Event.addListener(map, 'rightclick', this._finishCircle.bind(this)) + ]; + }, + + _finishDistance: function() { + console.log('finishDistance') + naver.maps.Event.removeListener(this._distanceListeners); + delete this._distanceListeners; + + $(document).off('mousemove.measure'); + + if (this._guideline) { + this._guideline.setMap(null); + delete this._guideline; + } + + if (this._polyline) { + console.log(this._polyline.getPath()) + + this._bufferPolygon = new naver.maps.Polygon({ + + }) + + // this._polygon = new naver.maps.Polygon({ + // strokeColor: '#00f', + // strokeOpacity: 0.6, + // strokeWeight: 2, + // fillColor: '#00f', + // fillOpacity: 0.3, + // paths: [coord], + // map: map + // }); + + + // 이거 하면 그동안 한거 싹 사라짐 -> 얘를 통해서 drawType이 바뀌면 다 날라가는 걸로 해보면 될듯 + // this._polyline.setMap(null) + delete this._polyline; + } + //onfocus()의 반대기능 = blur() + this.$btnLine.removeClass('control-on').blur(); + + this._mode = null; + }, + + _finishArea: function() { + console.log('finishArea') + naver.maps.Event.removeListener(this._areaListeners); + delete this._areaListeners; + + $(document).off('mousemove.measure'); + + if (this._polygon) { + var path = this._polygon.getPath(); + path.pop(); + + delete this._polygon; + } + + this.$btnPolygon.removeClass('control-on').blur(); + + this._mode = null; + }, + + _finishCircle: function() { + console.log('finishCircle') + + naver.maps.Event.removeListener(this._circleListeners); + delete this._circleListeners; + + $(document).off('mousemove.measure'); + + if(this._guidecircle) { + this._guidecircle.setMap(null); + this._radius.setMap(null); + delete this._raidus; + delete this._guidecircle; + } + + if (this._circle) { + // this._circle.setMap(null); + delete this._circle; + } + + this.$btnCircle.removeClass('control-on').blur(); + + // delete this._lastDistance; + this._mode = null; + }, + + finishMode: function(mode) { + console.log('finishMode') + if (!mode) return; + + if (mode === 'line') { + this._finishDistance(); + } if (mode === 'polygon') { + this._finishArea(); + } if (mode === 'circle') { + this._finishCircle(); + } + }, + + _onClickDistance: function(e) { + console.log('onClickDistance') + var map = this.map, + coord = e.coord; + + console.log(coord, '클릭좌표1'); + + if (!this._polyline) { + // 임시로 보여줄 점선 폴리라인을 생성합니다. + this._guideline = new naver.maps.Polyline({ + strokeColor: '#db4040', + strokeWeight: 5, + strokeStyle: [4, 4], + strokeOpacity: 0.4, + path: [coord], + map: map + }); + + $(document).on('mousemove.measure', this._onMouseMoveDistance.bind(this)); + this._distanceListeners.push(naver.maps.Event.addListener(map, 'rightclick', this._finishDistance.bind(this))); + + // 실제 거리재기에 사용되는 폴리라인을 생성합니다. + this._polyline = new naver.maps.Polyline({ + strokeLineCap: 'round', + strokeLineJoin: 'round', + strokeColor: '#db4040', + strokeWeight: 5, + strokeOpacity: 1, + path: [coord], + map: map + }); + + this._test = new naver.maps.Polyline({ + // path: [[126.6047916, 37.5237865], [126.6047719, 37.5237832]], + path: [[126.6048449, 37.5237486], [126.6047340, 37.5237299]], + map: map, + strokeweight: 5, + strokeOpacity: 1, + strokeColor: '#db4040' + }) + console.log(this._test.getDistance()); + + } else { + this._guideline.setPath([e.coord]); + this._polyline.getPath().push(coord); + } + }, + + _onMouseMoveDistance: function(e) { + console.log('onMouseMoveDistance') + var map = this.map, + proj = this.map.getProjection(), + coord = proj.fromPageXYToCoord(new naver.maps.Point(e.pageX, e.pageY)), + path = this._guideline.getPath(); + + // console.log(coord, '실시간 좌표') + if (path.getLength() === 2) { + //맨 뒷 값 삭제 = 기존클릭좌표만 남겨둬라 = 실시간으로 좌표들어가야 하니까 + path.pop(); + } + + // [기존 클릭 좌표, 실시간 좌표] + path.push(coord); + }, + + _onClickArea: function(e) { + console.log('onClickArea') + var map = this.map, + coord = e.coord; + + if (!this._polygon) { + this._polygon = new naver.maps.Polygon({ + strokeColor: '#00f', + strokeOpacity: 0.6, + strokeWeight: 2, + fillColor: '#0000ff', + fillOpacity: 0.1, + paths: [coord], + map: map + }); + } else { + this._polygon.getPath().push(coord); + } + }, + + _onMouseMoveArea: function(e) { + console.log('onMouseMoveArea') + if (!this._polygon) return; + + var map = this.map, + proj = this.map.getProjection(), + coord = proj.fromPageXYToCoord(new naver.maps.Point(e.pageX, e.pageY)), + path = this._polygon.getPath(); + + if (path.getLength() >= 2) { + path.pop(); + } + + path.push(coord); + }, + + _onClickCircle: function(e) { + console.log('onClickCircle') + var map = this.map, + coord = e.coord; + + if(!this._circle) { + + //가이드 라인 + this._radius = new naver.maps.Polyline({ + // strokeColor: '#db4040', + // strokeWeight: 2, + strokeStyle: [4, 4], + strokeOpacity: 0.6, + path: [coord], + map: map + }); + this._lastDistance = this._radius.getDistance(); + + // 임시로 보여줄 원형 + this._guidecircle = new naver.maps.Circle({ + // strokeColor: '#283046', + // strokeWeight: 2, + strokeOpacity: 0.8, + strokeStyle: [4, 4], + fillColor: '#0000ff', + fillOpacity: 0.1, + center: coord, + radius: this._lastDistance, + map: map + }); + + $(document).on('mousemove.measure', this._onMouseMoveCircle.bind(this)); + this._circleListeners.push(naver.maps.Event.addListener(map, 'rightclick', this._finishCircle.bind(this))); + + // 실제 사용되는 원형 + this._circle = new naver.maps.Circle({ + // strokeColor: '#283046', + // strokeWeight: 2, + strokeOpacity: 0.8, + fillColor: '#0000ff', + fillOpacity: 0.1, + center: coord, + radius: this._lastDistance, + map: map + }); + + } else { + // this._guidecircle.setCenter(e.coord); + // this._circle.setCenter(coord); + // if(this._radius.getPath().length() === 2) { + // this._radius.getPath().pop(); + // } + + // this._radius.getPath().push(coord); + + var distance = this._radius.getDistance(); + this._lastDistance = distance; + this._circle.setRadius(this._lastDistance); + + + } + }, + + _onMouseMoveCircle: function(e) { + console.log('onMouseMoveCircle') + if(!this._circle) return; + + var map = this.map, + proj = this.map.getProjection(), + coord = proj.fromPageXYToCoord(new naver.maps.Point(e.pageX, e.pageY)), + path = this._radius.getPath(), + center = this._guidecircle.getCenter(), //LatLng으로 나옴 + r = proj.getDistance(coord, center); + + if(path.getLength() === 2) { + path.pop(); + } + path.push(coord); + this._guidecircle.setRadius(r); + }, + + _bindMap: function(map) { + console.log('bindMap') + }, + + _unbindMap: function() { + console.log('unbindMap') + this.unbindAll(); + }, + + _bindDOMEvents: function() { + console.log('bindDOMEvents') + this.$btnLine.on('click.measure', this._onClickButton.bind(this, 'line')); + this.$btnPolygon.on('click.measure', this._onClickButton.bind(this, 'polygon')); + this.$btnCircle.on('click.measure', this._onClickButton.bind(this, 'circle')); + }, + + _onClickButton: function(newMode, e) { + //newMode는 방금 클릭한 값(line, polygon, circle...) + console.log('onClickButton') + e.preventDefault(); + + var btn = $(e.target), + map = this.map, + mode = this._mode; + //this._mode는 클릭하기 전 값(첫 클릭이면 null) + + if (btn.hasClass('control-on')) { + console.log('remove') + btn.removeClass('control-on'); + } else { + console.log('add') + btn.addClass('control-on'); + } + + this._clearMode(mode); + + if (mode === newMode) { + this._mode = null; + return; + } + + this._mode = newMode; + + this.startMode(newMode); + }, + + _clearMode: function(mode) { + console.log('clearMode') + if (!mode) return; + + if (mode === 'line') { + if (this._polyline) { + this._polyline.setMap(null); + delete this._polyline; + } + + this._finishDistance(); + } else if (mode === 'polygon') { + if (this._polygon) { + this._polygon.setMap(null); + delete this._polygon; + } + + this._finishArea(); + } else if (mode === 'circle') { + if (this._circle) { + this._circle.setMap(null); + delete this._circle; + } + + this._finishCircle(); + } else if(mode === 'CIRCLE') { + if(this._circle) { + this._circle.setMap(null); + delete this._circle; + } + } + } + }); + + // id랑 매치시켜서 옵션 지정함 + var measures = new Measure({ + line: $('#line'), + polygon: $('#polygon'), + circle: $('#circle') + }); + + measures.setMap(map); + + return( + <> +
+ +
+ + ) + +}; + diff --git a/src/containers/basis/flight/plan/FlightPlanAreaContainer.js b/src/containers/basis/flight/plan/FlightPlanAreaContainer.js index 1e2cecd1..39dc57ec 100644 --- a/src/containers/basis/flight/plan/FlightPlanAreaContainer.js +++ b/src/containers/basis/flight/plan/FlightPlanAreaContainer.js @@ -1,29 +1,53 @@ import React, { useEffect, useState } from 'react'; +import { useForm } from 'react-hook-form'; +import {useHistory} from 'react-router-dom'; import { useDispatch, useSelector } from 'react-redux'; import FlightPlanAreaForm from '../../../../components/basis/flight/plan/FlightPlanAreaForm'; -import { Button, Col, Row } from 'reactstrap'; +import {Col, Row, Form } from 'reactstrap'; import * as Actions from '../../../../modules/basis/flight/actions/basisFlightAction'; import FlightPlanAreaMap from '../../../../components/basis/flight/plan/FlightPlanAreaMap'; +import * as yup from 'yup'; +import { yupResolver } from '@hookform/resolvers/yup'; - -const FlightPlanAreaContainer = () => { +const FlightPlanAreaContainer = (props) => { const dispatch = useDispatch(); + const history = useHistory(); + const { areaList } = useSelector(state => state.flightState); - const [airArea, setAirArea] = useState(null); + const validSchema = yup.object().shape({ + }); + + const { register, getValues, setValue, errors, handleSubmit } = useForm({ + defaultValues: { + coodinates: [], + radius: '', + altitude_m: '', + altitude_ft: '', + }, + resolver: yupResolver(validSchema) + }); + - const getAriAreaList = () => { + const getAirAreaList = () => { dispatch(Actions.AREA_LIST.request()); } + const createAirArea = async data => { + dispatch(Actions.FLIGHT_PLAN_AREA.request(data)); + + props.setModal({ ...props.modal, isOpen: !props.modal.isOpen }); + props.setOnSubmit(false); + } + useEffect(() => { - getAriAreaList(); + getAirAreaList(); }, []); useEffect(() => { setAirArea(areaList); - }, [areaList]) + }, [areaList]) return ( @@ -34,8 +58,14 @@ const FlightPlanAreaContainer = () => { /> ) : null} - - + + diff --git a/src/containers/basis/flight/plan/FlightPlanDetailContainer.js b/src/containers/basis/flight/plan/FlightPlanDetailContainer.js index 99809ec6..3df9a61e 100644 --- a/src/containers/basis/flight/plan/FlightPlanDetailContainer.js +++ b/src/containers/basis/flight/plan/FlightPlanDetailContainer.js @@ -1,18 +1,38 @@ -import React, {useState} from 'react'; +import React, {useEffect, useState} from 'react'; import FlightPlanForm from '../../../../components/basis/flight/plan/FlightPlanForm'; import { CustomDetailLayout } from '../../../../components/layout/CustomDetailLayout'; -import { FormModal } from '../../../../components/modal/FormModal'; +import { FlightPlanAreaModal } from '../../../../components/basis/flight/plan/FlightPlanAreaModal'; import FlightPlanAreaContainer from './FlightPlanAreaContainer'; - +import {useHistory} from 'react-router-dom'; +import { useDispatch, useSelector } from 'react-redux'; +import * as yup from 'yup'; +import { yupResolver } from '@hookform/resolvers/yup'; +import * as Actions from '../../../../modules/basis/flight/actions/basisFlightAction'; +import { useForm } from 'react-hook-form'; const FlightPlanDetailContainer = () => { + const dispatch = useDispatch(); + const history = useHistory(); + + const { flightPlanArea } = useSelector(state => state.flightState); + const [areaInfo, setAreaInfo] = useState(); const [modal, setModal] = useState({ isOpen: false, - title: '', - contents: '', + title: '', }); - + /* Form Validation Checking */ + const validSchema = yup.object().shape({ + }); + const {} = useForm({ + defaultValues: { + coodinates: [], + radius: '', + altitude_m: '', + altitude_ft: '', + }, + resolver: yupResolver(validSchema) + }) const saveFlightPlanArea = () => { console.log('비행 구역 설정 저장'); @@ -21,20 +41,24 @@ const FlightPlanDetailContainer = () => { const openModal = () => { setModal({ isOpen: true, - title: '비행 구역 설정', - contents: + title: '비행 구역 설정', }); } + useEffect(() => { + setAreaInfo(flightPlanArea); + }, [flightPlanArea]); + return ( - ) diff --git a/src/modules/basis/flight/actions/basisFlightAction.ts b/src/modules/basis/flight/actions/basisFlightAction.ts index f7cd37cc..402a7ba8 100644 --- a/src/modules/basis/flight/actions/basisFlightAction.ts +++ b/src/modules/basis/flight/actions/basisFlightAction.ts @@ -1,6 +1,6 @@ import { AxiosError } from 'axios'; import { createAsyncAction, ActionType} from 'typesafe-actions'; -import { FlightAreaData } from '../models/basisFlightModel'; +import { FlightAreaData, FlightPlanArea } from '../models/basisFlightModel'; // 공역 조회 @@ -8,14 +8,26 @@ const AREA_LIST_REQUEST = 'basis/flight/area/LIST_REQUEST'; const AREA_LIST_SUCCESS = 'basis/flight/area/LIST_SUCCESS'; const AREA_LIST_FAILURE = 'basis/flight/area/LIST_FAILURE'; +// 비행 구역 설정 +const FLIGHT_PLAN_AREA_REQUEST = 'basis/flight/plan/area/LIST_REQUEST'; +const FLIGHT_PLAN_AREA_SUCCESS = 'basis/flight/plan/area/LIST_SUCCESS'; +const FLIGHT_PLAN_AREA_FAILURE = 'basis/flight/plan/area/LIST_FAILURE'; + export const AREA_LIST = createAsyncAction( AREA_LIST_REQUEST, AREA_LIST_SUCCESS, AREA_LIST_FAILURE )(); +export const FLIGHT_PLAN_AREA = createAsyncAction( + FLIGHT_PLAN_AREA_REQUEST, + FLIGHT_PLAN_AREA_SUCCESS, + FLIGHT_PLAN_AREA_FAILURE +)(); + const actions = { - AREA_LIST + AREA_LIST, + FLIGHT_PLAN_AREA }; export type FlightAction = ActionType; \ No newline at end of file diff --git a/src/modules/basis/flight/models/basisFlightModel.ts b/src/modules/basis/flight/models/basisFlightModel.ts index 3880268e..abcedbcc 100644 --- a/src/modules/basis/flight/models/basisFlightModel.ts +++ b/src/modules/basis/flight/models/basisFlightModel.ts @@ -1,11 +1,21 @@ export interface FlightState { areaList: FlightAreaData | undefined + flightPlanArea: FlightPlanArea | undefined } export interface FlightAreaData { areaList: [] } +export interface FlightPlanArea { + address : '', + coordinates : '', + redius : '', + altitude_m : '', + altitude_ft : '', +} + export const initFlight = { - areaList: undefined + areaList: undefined, + flightPlanArea: undefined }; \ No newline at end of file diff --git a/src/modules/basis/flight/reducers/basisFlightReducer.ts b/src/modules/basis/flight/reducers/basisFlightReducer.ts index 32ad54b5..708445ad 100644 --- a/src/modules/basis/flight/reducers/basisFlightReducer.ts +++ b/src/modules/basis/flight/reducers/basisFlightReducer.ts @@ -12,4 +12,10 @@ export const flightReducer = createReducer ( const {data} = action.payload; draft.areaList = data; }) -) ; \ No newline at end of file +) +.handleAction(Actions.FLIGHT_PLAN_AREA.request, (state, action) => + produce(state, draft => { + const data = action.payload; + draft.flightPlanArea = data; + }) +) \ No newline at end of file diff --git a/src/modules/basis/flight/sagas/basisFlightSaga.ts b/src/modules/basis/flight/sagas/basisFlightSaga.ts index 9676eaa8..82362ef7 100644 --- a/src/modules/basis/flight/sagas/basisFlightSaga.ts +++ b/src/modules/basis/flight/sagas/basisFlightSaga.ts @@ -38,6 +38,24 @@ function* listAreaSaga(action: ActionType) { } } +function* createFlightPlanArea(action: ActionType) { + try { + const data = action.payload; + + yield put( + Actions.FLIGHT_PLAN_AREA.success({ + data: data + }) + ) + + } catch (error: any) { + yield put( + Actions.FLIGHT_PLAN_AREA.failure(error) + ) + } +} + export function* flightSaga() { yield takeEvery(Actions.AREA_LIST.request, listAreaSaga); + yield takeEvery(Actions.FLIGHT_PLAN_AREA.request, createFlightPlanArea); } \ No newline at end of file diff --git a/src/views/testDraw/main/ControlMainDraw.js b/src/views/testDraw/main/ControlMainDraw.js index 55410aca..87d149a9 100644 --- a/src/views/testDraw/main/ControlMainDraw.js +++ b/src/views/testDraw/main/ControlMainDraw.js @@ -1,12 +1,8 @@ import React, { useEffect, useState } from 'react'; - import '../../../assets/css/custom.css'; import logo from '../../../assets/images/pal_logo.png'; - import { Sun, Map, Bell, Check } from 'react-feather'; - import { AiOutlinePoweroff } from 'react-icons/ai'; - import { ReactComponent as DroneMenuIcon } from '../../../assets/images/drone_menu_icon.svg'; import ControlAlarmNotice from '../alarm/ControlAlarmNotice'; @@ -99,45 +95,54 @@ const ControlMainDraw = () => { - - {/* pathDraw Test */} + + + {/* 네이버 그리기 도구모음 */}
  • handlerDrawType('CIRCLE')} - value={mapControl.drawType === 'CIRCLE' ? 'check' : 'CIRCLE'} + onClick={e => handlerDrawCheck(!mapControl.drawCheck)} + value={mapControl.drawCheck === true ? 'IN USE' : 'STOP'} /> +
  • +
+ + {/* 제이쿼리로 그리기(기능 연결 중) */} + {/*
    +
  • handlerDrawType('LINE')} - value={mapControl.drawType === 'LINE' ? 'check' : 'LINE'} - />
    + /> + handlerDrawType('POLYGON')} + /> + handlerDrawType('CIRCLE')} + /> handlerDrawType('')} - value={mapControl.drawType === '' ? 'check' : 'X'} - /> -
  • -
- -
    -
  • - handlerDrawCheck(!mapControl.drawCheck)} - value={mapControl.drawCheck === true ? 'IN USE' : 'STOP'} - /> + value={mapControl.drawType === '' ? 'STOP' : 'IN USE'} + />
  • -
+ */}