Kaynağa Gözat

update 2024-10-23

junggilpark 9 ay önce
ebeveyn
işleme
954948fdaa

+ 1 - 1
conf/tsi-sig-server.pid

@@ -1 +1 @@
-2916
+28324

+ 7 - 0
src/main/java/com/tsi/sig/server/controller/MainController.java

@@ -72,6 +72,7 @@ public class MainController {
     @RequestMapping(value = "/getTreeListFrame.do")
     public String getTreeListFrame(Locale locale, Model model, HttpServletRequest request, HttpServletResponse response) throws Exception {
         //log.info("CALL.........................................: getTreeListFrame");
+        model.addAttribute("center", this.mainService.getCenterCode());
         return "treeListFrame";
     }
 
@@ -162,4 +163,10 @@ public class MainController {
     public List<EvpServiceVo> getEvpHistory(@RequestParam HashMap<String,Object> paramMap) throws Exception {
         return mainService.getEvpHistoryList(paramMap);
     }
+
+    @RequestMapping(value = "/getCenterCode.do", method = RequestMethod.POST)
+    @ResponseBody
+    public List<EvpCenterVo> getCenterCode() throws Exception {
+        return mainService.getCenterCode();
+    }
 }

+ 1 - 0
src/main/java/com/tsi/sig/server/mapper/MainMapper.java

@@ -21,4 +21,5 @@ public interface MainMapper {
     List<EvpEventVo> getEvpEventList(Map<String, Object> paramMap);
     List<EvpSignalVo> getEvpSignalCurrList(Map<String, Object> paramMap);
     List<EvpEventVo> getEvpEventCurrList(Map<String, Object> paramMap);
+    List<EvpCenterVo> getEvpCenterCode();
 }

+ 10 - 3
src/main/java/com/tsi/sig/server/service/MainService.java

@@ -212,13 +212,20 @@ public class MainService {
 
     public List<EvpServiceVo> getEvpHistoryList(Map<String, Object> paramMap) {
         List<EvpServiceVo> result = this.mainMapper.getEvpHistoryList(paramMap);
+
         if (result != null && result.size() > 0) {
             for (EvpServiceVo vo : result) {
-                vo.setRouteList(this.mainMapper.getEvpRouteList(paramMap));
-                vo.setPhaseList(this.mainMapper.getEvpSignalList(paramMap));
-                vo.setEventList(this.mainMapper.getEvpEventList(paramMap));
+                Map<String, Object> param = new HashMap<>();
+                param.put("serviceId", vo.getServiceId());
+                vo.setRouteList(this.mainMapper.getEvpRouteList(param));
+                vo.setPhaseList(this.mainMapper.getEvpSignalList(param));
+                vo.setEventList(this.mainMapper.getEvpEventList(param));
             }
         }
         return result;
     }
+
+    public List<EvpCenterVo> getCenterCode() {
+        return this.mainMapper.getEvpCenterCode();
+    }
 }

+ 13 - 0
src/main/java/com/tsi/sig/server/vo/EvpCenterVo.java

@@ -0,0 +1,13 @@
+package com.tsi.sig.server.vo;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+
+@Data
+public class EvpCenterVo {
+    @JsonProperty("center_id")
+    private Long centerId;
+
+    @JsonProperty("center_nm")
+    private String centerNm;
+}

+ 16 - 21
src/main/resources/mybatis/mapper/main.xml

@@ -68,28 +68,16 @@
 			   OCR_NO,
 			   OCR_TYPE,
 			   SERVICE_DIST,
-			   STATUS_CD,
-			   IF(STATUS_CD = 1,  '진행중',
-			   IF(STATUS_CD = 2,  '정상종료',
-			   IF(STATUS_CD = 3,  '취소-아직 통과하지 않은 교차로 존재',
-			   IF(STATUS_CD = 4,  '센터강제종료-운영자가 서비스를 강제 종료',
-			   IF(STATUS_CD = 5,  '비정상종료-서비스가 존재하지 않음',
-			   IF(STATUS_CD = 6,  '서비스 시작 실패',
-			   IF(STATUS_CD = 7,  '비정상정료-앱서버에 에러 발생',
-			   IF(STATUS_CD = 8,  '비정상종료-일정시간 앱에서 위치 및 속도 정보가 오지 않음',
-			   IF(STATUS_CD = 9,  '자동종료-경로이탈',
-			   IF(STATUS_CD = 10, '자동종료-경로진입 가능시간 초과',
-			   IF(STATUS_CD = 11, '자동종료-정차가능시간 초과',
-			   IF(STATUS_CD = 12, '취소',
-			   IF(STATUS_CD = 13, '실패-서비스 제어 요청',
-			   IF(STATUS_CD = 14, '실패-서비스 가능 교차로가 존재하지 않음',
-			   IF(STATUS_CD = 15, '자동종료', '-'
-			   ))))))))))))))) AS STATUS_DESC
+			   STATUS_CD
 		FROM tb_evp_service
-		<if test="serviceId != null and !serviceId.equals('')">
-			WHERE SERVICE_ID = #{serviceId}
-		</if>
-		ORDER BY CLCT_DT
+			WHERE DATE_FORMAT(clct_dt, '%Y-%m-%d %h:%i:%s') BETWEEN #{start} AND #{end}
+			<if test="!'ALL'.equals(region)">
+				AND LEFT(service_id, 3) = #{region}
+			</if>
+			<if test="serviceId != null and !serviceId.equals('')">
+				AND SERVICE_ID = #{serviceId}
+			</if>
+		ORDER BY CLCT_DT, SERVICE_ID
 	</select>
 
 	<select id="getEvpRouteList" parameterType="java.util.HashMap" resultType="com.tsi.sig.server.vo.EvpRouteVo">
@@ -342,4 +330,11 @@
 		  AND cur_lng BETWEEN 125.06666667 AND 131.87222222
 		ORDER BY clct_dt
 	</select>
+	<select id="getEvpCenterCode" resultType="com.tsi.sig.server.vo.EvpCenterVo">
+		SELECT
+		    center_id,
+			center_nm
+		  FROM tb_evp_center
+		 WHERE use_yn = 'Y'
+	</select>
 </mapper>

+ 35 - 13
src/main/resources/static/css/main.css

@@ -1229,6 +1229,7 @@ div.popState dl.jaywork dd strong.rblue {color:#607cd4; text-align:right;}
     top: 0;
     left: 0;
 }
+#historyList table tbody td,
 #evp-cur-list table tbody td {
     font-size: 12px;
     text-align: center;
@@ -1237,9 +1238,12 @@ div.popState dl.jaywork dd strong.rblue {color:#607cd4; text-align:right;}
     height: 22px;
     line-height: 22px;
 }
+
+#historyList table tbody tr:nth-child(even) td,
 #evp-cur-list table tbody tr:nth-child(even) td {
     background-color: #3c3c3c;
 }
+#historyList table tbody tr:nth-child(odd) td,
 #evp-cur-list table tbody tr:nth-child(odd) td {
     background-color:#292828;
 }
@@ -3468,21 +3472,31 @@ cursor: pointer;border: 1px solid #ebebeb;border-bottom-color: #e2e2e2;border-ra
         float: left;
     }
 }
-/*:root {*/
-/*    --map-tiles-filter: brightness(0.6) invert(1) contrast(3) hue-rotate(200deg) saturate(0.3) brightness(0.7);*/
-/*}*/
-/*#map img{*/
+
+.play-box {
+    width: 100%;
+    height: 38px;
+    background-color: #212121;
+}
+#pause.on,
+#stop.on,
+#play.on {
+    cursor: pointer;
+}
+.play-box > div {
+    width: 100%;
+    height: 100%;
+    display: flex;
+    justify-content: flex-end;
+    padding: 5px 20px;
+    color: #b2b2b2;
+    gap: 5px;
+    box-sizing: border-box;
+    align-items: center;
+}
+
 #map img{
-   /*filter : brightness(0.7);*/
-    /*opacity: 0.9 !important;*/
-    /*filter: contrast(0.7);*/
     filter: brightness(0.6) invert(0.8) contrast(2) hue-rotate(180deg) saturate(0) brightness(0.7);
-    /*filter: brightness(0.6) invert(1) contrast(4) hue-rotate(180deg) saturate(0) brightness(0.7);*/
-    /*filter: invert(1) saturate(0.3) brightness(0.7);*/
-    /*filter: invert(100%) hue-rotate(180deg) brightness(120%) contrast(72.5%);*/
-    /*-webkit-filter: invert(100%) hue-rotate(180deg) brightness(120%) contrast(72.5%);*/
-    /*-moz-filter: invert(100%) hue-rotate(180deg) brightness(120%) contrast(72.5%);*/
-    /*transition: 0.2s ease-out;*/
 }
 
 #start_time, #end_time,
@@ -3506,6 +3520,13 @@ cursor: pointer;border: 1px solid #ebebeb;border-bottom-color: #e2e2e2;border-ra
     margin-right: 20px;
     margin-left: auto;
 }
+.evp_legend {
+    position: absolute;
+    bottom: 230px;
+    right: 50px;
+    z-index: 20;
+    display: none;
+}
 /*#map button, */
 #map > div:nth-child(7),
 select#region,
@@ -3526,6 +3547,7 @@ img[src="images/logout.png"]{
 #map .wideMap img,
 #map .upDownMap img,
 #map img[src="/images/evp_arr.svg"],#map img[src="images/TrafficLight25.png"],
+#map img[src="/images/evp_legend.png"],
 #map img[src="/images/car.svg"],
 #map img[src="images/sig1.png"],
 #map img[src="images/sig2.png"],

BIN
src/main/resources/static/images/evp_legend2.png


BIN
src/main/resources/static/images/pause.png


BIN
src/main/resources/static/images/pause_on.png


BIN
src/main/resources/static/images/play.png


BIN
src/main/resources/static/images/play_on.png


BIN
src/main/resources/static/images/stop.png


BIN
src/main/resources/static/images/stop_on.png


+ 42 - 13
src/main/resources/static/js/map.js

@@ -153,8 +153,25 @@ function init() {
     }
 
     function drawEvp(serviceId) {
-       if (serviceId) {
-           const iframe = $('#iframeTreeList').contents();
+
+        if (serviceId) {
+           const $iframe = $('#iframeTreeList');
+           const iframe = $iframe.contents();
+           const iframeContent = $iframe.get(0).contentWindow;
+           const iframeMap = iframeContent._historyMap;
+           if (iframeMap && iframeMap.size) {
+               iframeMap.forEach((obj)=>{
+                   if (obj.get('draw')) {
+                       obj.get('draw').clear();
+                       obj.set('draw', null);
+                   }
+               });
+               if (iframeContent.interval) {
+                   clearInterval(iframeContent.interval);
+                   iframeContent.interval = null;
+                   iframeContent.cnt = 0;
+               }
+           }
            if (!iframe.find('.tr_'+ serviceId + '.on').length) {
                iframe.find('tr.on').removeClass('on');
                iframe.find('.tr_'+ serviceId).addClass('on');
@@ -313,6 +330,14 @@ function emergencyHistoryCallBack(data) {
     }
 }
 
+function drawHistory(data) {
+    return new EmergencyObj(data);
+}
+
+function createSig(data) {
+    return new EmergencySig(data);
+}
+
 function setEmergencyCurr(car, sigMap, road, arrive, dataMap) {
     const sigArr   = dataMap.get('sig');
     const eventObj = dataMap.get('event')
@@ -1636,7 +1661,7 @@ class EmergencyObj{
 
     init() {
         this.road = new EmergencyRoadObj(this.route_list);
-        this.road.setBound();
+        this.setBound();
         if (this.phase_list && this.phase_list.length) {
             this.phase_list.forEach((obj)=>{
                 const sig = new EmergencySig(obj);
@@ -1694,13 +1719,14 @@ class Ring{
         this.head_angle = head_angle;
         this.end_angle = end_angle;
         this.state = state;
+        this.polyLine = null;
         this.init();
     }
 
     init() {
-            const headPosition = getKakaoPosition(this.head_lng, this.head_lat);
-            const midPosition = getKakaoPosition(this.mid_lng, this.mid_lat);
-            const endPosition = getKakaoPosition(this.end_lng, this.end_lat);
+            const headPosition = getKakaoPosition(this.head_lat, this.head_lng);
+            const midPosition = getKakaoPosition(this.mid_lat, this.mid_lng);
+            const endPosition = getKakaoPosition(this.end_lat, this.end_lng);
             let stateColor = '#FF0000';
             if (!isNaN(Number(this.state))) {
                 stateColor = stateMap.get(Number(this.state));
@@ -1800,7 +1826,8 @@ class EmergencySig{
             stateColor = stateMap.get(Number(this.state));
         }
         const position = getKakaoPosition(this.lat, this.lng);
-        if (!sigMap.get(this.service_id + '_' + this.sep_no)) {
+
+        if (!sigMap.get(this.service_id + '_' + this.seq_no)) {
             this.circle = new kakao.maps.Circle({
                 center : position,  // 원의 중심좌표 입니다
                 radius: 60, // 미터 단위의 원의 반지름입니다
@@ -1839,7 +1866,7 @@ class EmergencySig{
                 head_lng : data.a_head_lng,
                 mid_lat : data.a_mid_lat,
                 mid_lng : data.a_mid_lng,
-                end_lag : data.a_end_lat,
+                end_lat : data.a_end_lat,
                 end_lng : data.a_end_lng,
                 head_angle : data.a_head_angle,
                 end_angle : data.a_end_angle,
@@ -1856,7 +1883,7 @@ class EmergencySig{
                 head_lng   : data.b_head_lng,
                 mid_lat    : data.b_mid_lat,
                 mid_lng    : data.b_mid_lng,
-                end_lag    : data.b_end_lat,
+                end_lat    : data.b_end_lat,
                 end_lng    : data.b_end_lng,
                 head_angle : data.b_head_angle,
                 end_angle  : data.b_end_angle,
@@ -1988,10 +2015,12 @@ class EmergencyRoadObj{
     }
 
     setBound() {
-        const bounds = new kakao.maps.LatLngBounds();
-        bounds.extend(this.kakaoPathArr[0]);
-        bounds.extend(this.kakaoPathArr[this.pathArr.length - 1]);
-        map.setBounds(bounds);
+        if (this.kakaoPathArr.length > 0) {
+            const bounds = new kakao.maps.LatLngBounds();
+            bounds.extend(this.kakaoPathArr[0]);
+            bounds.extend(this.kakaoPathArr[this.pathArr.length - 1]);
+            map.setBounds(bounds);
+        }
     }
 }
 

+ 1 - 0
src/main/webapp/WEB-INF/jsp/main.jsp

@@ -160,6 +160,7 @@
                 <div class="coord-btn" onclick="moveToPosition()">이동</div>
             </div>
         </div>
+        <div class="evp_legend"><img alt="긴급차량우선신호 범례" src="/images/evp_legend2.png" width="178" height="50"></div>
     </div>
     <!-- 로드뷰 -->
     <div id="rvWrapper">

+ 255 - 6
src/main/webapp/WEB-INF/jsp/treeListFrame.jsp

@@ -51,15 +51,20 @@
             <div>
                 <div>지역</div>
                 <select id="region">
-                    <option value="all" selected>전체</option>
+                    <option value="ALL" selected>전체</option>
+                    <c:if test="${fn:length(center) != 0}">
+                        <c:forEach var="item" items="${center}">
+                            <option value="${item.centerId}">${item.centerNm}</option>
+                        </c:forEach>
+                    </c:if>
                 </select>
             </div>
             <div>
-                <div>검색시작일</div>
+                <div>검색시작</div>
                 <input type="date" id="start" autocomplete="false"/><input type="time" id="start_time">
             </div>
             <div>
-                <div>검색종료</div>
+                <div>검색종료</div>
                 <input type="date" id="end" autocomplete="false" /><input type="time" id="end_time">
             </div>
         </div>
@@ -82,7 +87,14 @@
             </tbody>
         </table>
     </div>
-    <div></div>
+    <div class="play-box">
+        <div>
+            <div>시뮬레이션 재생/멈춤</div>
+            <img id="play" onclick="playSimulation()" src="/images/play.png" alt="시뮬레이션 재생버튼" width="24px">
+            <img id="pause" onclick="pauseSimulation()" src="/images/pause.png" alt="시뮬레이션 멈춤버튼" width="24px">
+            <img id="stop" onclick="stopSimulation()" src="/images/stop.png" alt="시뮬레이션 초기화버튼" width="24px">
+        </div>
+    </div>
     <div class="treeLoading"><img src="/css/themes/classic/throbber.gif"/></div>
 </div>
 <script type="text/javascript" src="${contextRoot }/js/common/moment.js"></script>
@@ -116,6 +128,10 @@
     const $startTime = $('#start_time');
     const $end       = $('#end');
     const $endTime   = $('#end_time');
+    var _historyMap = new Map();
+
+    var interval = null;
+    var cnt = 0;
 
     $start.val(getDateToStr(new Date()));
     $end.val(getDateToStr(new Date()));
@@ -668,19 +684,29 @@
         $('.searchBox').css('display', 'flex');
         $('.historyBox').css('display', 'none');
         $('.leftMenu .evp-cur').hide();
+        $('.evp_legend', parent.document).hide();
+        unsetEvpCurr();
+
+        if (_historyMap && _historyMap.size) {
+            _historyMap.forEach((obj)=> {if (obj.get('draw')) obj.get('draw').clear()});
+            _historyMap.clear();
+            $('.history-table tr.on').removeClass('on');
+        }
+    }
+
+    function unsetEvpCurr() {
         if (window.parent._EmergencyMap && window.parent._EmergencyMap.size) {
             window.parent._EmergencyMap.forEach((obj)=> obj.clear());
             window.parent._EmergencyMap.clear();
             $('.evp-table tr.on').removeClass('on');
             window.parent._isClick = null;
         }
-
     }
 
     function goEvpMenu() {
         $('.tabs > li').eq(1).addClass('on');
         $('.tabs > li').eq(0).removeClass('on');
-
+        $('.evp_legend', parent.document).show();
         // $('.treeLoading').show();
         $('#historyList').show();
         $('#intTree').hide();
@@ -690,7 +716,230 @@
     }
 
     function searchHistoryData() {
+        const $region       = $('#region');
+        const regionVal    = $region.val();
+        const startVal     = $start.val();
+        const endVal       = $end.val();
+        const startTimeVal = $startTime.val();
+        const endTimeVal   = $endTime.val();
+        if (!startVal) {
+            alert('검색시작 년월일을 입력해주세요');
+            return $start.focus();
+        }
+        if (!startTimeVal) {
+            alert('검색시작 시간을 입력해주세요');
+            return $startTime.focus();
+        }
+        if (!endVal) {
+            alert('검색종료 년월일을 입력해주세요');
+            return $end.focus();
+        }
+
+        if (!endTimeVal) {
+            alert('검색종료 시간을 입력해주세요');
+            return $endTime.focus();
+        }
+
+        const param = {
+            start : startVal + ' ' + startTimeVal + ':00',
+            end : endVal + ' ' + endTimeVal + ':59',
+            region : regionVal
+        }
+        if (param.start > param.end) {
+            alert('검색시작 일시가 종료 일시 보다 큽니다.');
+            return $end.focus();
+        }
+        window.parent.requestService('getEvpHistory.do', param, (rec)=>{
+            const $historyTable = $('.history-table');
+            let str = '<tr><td colspan="3" class="empty-history">조회된 내용이 없습니다.</td></tr>'
+            _historyMap.clear();
+            if (rec && rec.length) {
+                str = '';
+                for (let history of rec) {
+                     _historyMap.set(history.service_id, new Map());
+                    const {event_list, phase_list} = history;
+
+                    const dateMap = new Map();
+                    if (event_list.length && phase_list.length) {
+                        event_list.forEach((eventObj)=>{
+                            dateMap.set(eventObj.clct_dt, new Map());
+                            dateMap.get(eventObj.clct_dt).set('event', eventObj);
+                            dateMap.get(eventObj.clct_dt).set('sig', []);
+                        });
+
+                        phase_list.forEach((obj)=>{
+                            if (!dateMap.get(obj.clct_dt)) {
+                                dateMap.set(obj.clct_dt, new Map());
+                                dateMap.get(obj.clct_dt).set('event', null);
+                                dateMap.get(obj.clct_dt).set('sig', []);
+                            }
+                            dateMap.get(obj.clct_dt).get('sig').push(obj);
+                        });
+
+                        if (dateMap.size) {
+                            history.event_list = [];
+                            history.phase_list = [];
+                            const dateArr = Array.from(dateMap.keys()).sort();
+                            let beforeSig;
+                            let beforeEvent;
+
+                            for (let date of dateArr) {
+                                const objMap = dateMap.get(date);
+                                if (objMap.get('event') === null && beforeEvent === undefined) {
+                                    beforeEvent = event_list[0];
+                                }
+                                else if (objMap.get('event')){
+                                    beforeEvent = objMap.get('event');
+                                }
+                                beforeEvent.clct_dt = date;
+
+                                if (objMap.get('sig').length === 0 && beforeSig === undefined) {
+                                    beforeSig = dateMap.get(phase_list[0].clct_dt).get('sig');
+                                }
+                                else if (objMap.get('sig').length) {
+                                    beforeSig = objMap.get('sig');
+                                }
+
+                                beforeSig.forEach((obj)=>{
+                                    obj.clct_dt = date;
+                                })
+
+                                history.event_list.push(beforeEvent);
+                                history.phase_list.push(beforeSig);
+                            }
+                        }
+                    }
+                     _historyMap.get(history.service_id).set('obj', history);
+                     _historyMap.get(history.service_id).set('draw', null);
+                    str += `<tr class="hs_\${history.service_id}" onclick="drawHistory('\${history.service_id}')"><td>\${history.clct_dt}</td><td>\${history.service_id}</td><td>\${history.service_nm}</td></tr>`;
+                }
+            }
+            $historyTable.html(str);
+        }, true);
+    }
+
+    function drawHistory(serviceId) {
+        unsetEvpCurr();
+        if (_historyMap.size) {
+            _historyMap.forEach((obj, key)=>{
+                const beforeDraw = obj.get('draw');
+                if (beforeDraw && serviceId !== key) {
+                    beforeDraw.clear();
+                    obj.set('draw', null);
+                }
+            })
+            if (_historyMap.get(serviceId).get('draw')) {
+                return;
+            }
+            else {
+                if (interval) {
+                    clearInterval(interval);
+                    interval = null;
+                    cnt = 0;
+                }
+            }
+        }
+
+        const obj = _historyMap.get(serviceId).get('obj');
+        $('#historyList tr.on').removeClass('on');
+        $('.hs_' + serviceId).addClass('on');
+        const drawObj = {...obj};
+        const {event_list, phase_list} = obj;
+
+        if (event_list && event_list.length) drawObj.event_list = [drawObj.event_list[0]];
+        if (phase_list && phase_list.length) drawObj.phase_list = phase_list[0];
+
+        const draw = window.parent.drawHistory(drawObj);
+        _historyMap.get(serviceId).set('draw', draw);
+        imageOnOff('play', true);
+        imageOnOff('stop', false);
+        imageOnOff('pause', false);
+    }
+
+    function imageOnOff(name, isOn) {
+        const el = $('#' + name);
+        const eventName = isOn ? 'addClass' : 'removeClass';
+        el[eventName]('on');
+
+        if (el.attr('src') === getImageName(name, !isOn)) {
+            el.attr('src', getImageName(name, isOn));
+        }
+    }
+
+    function getImageName(name, isOn) {
+        let imgName = '/images/' + name;
+        const onName = '_on';
+        const extName = '.png';
+        if (isOn) {
+            imgName += onName;
+        }
+        return imgName + extName;
+    }
+
+    function playSimulation() {
+        if (!$('#play').hasClass('on')) return;
+
+        const serviceId = $('.history-table tr.on').attr('class').replace(/hs_| on/gi, '');
+        let evp = _historyMap.get(serviceId);
+        let obj = evp.get('obj');
+        let draw = evp.get('draw');
+        if (!draw) {
+            drawHistory(serviceId);
+            draw = evp.get('draw');
+        }
+
+        const { event_list, phase_list } = obj;
+        imageOnOff('stop', true);
+        imageOnOff('pause', true);
+        imageOnOff('play', false);
+        interval = setInterval(()=>{
+            const position = window.parent.getKakaoPosition(event_list[cnt].cur_lat, event_list[cnt].cur_lng);
+            draw.car.moveMarker(position);
+            phase_list[cnt].forEach((sigObj)=>{
+                const evpSig = draw.sig.get(sigObj.service_id + '_' + sigObj.seq_no);
+                if (evpSig === undefined) {
+                    draw.sig.set(sigObj.service_id + '_' + sigObj.seq_no, window.parent.createSig(sigObj));
+                }
+                else {
+                    if (!evpSig.a_ring && !evpSig.b_ring) {
+                        evpSig.createRing(sigObj);
+                    }
+                    else {
+                        const {a_head_lat, a_head_lng, a_mid_lat, a_mid_lng, a_end_lat, a_end_lng,
+                            b_head_lat, b_head_lng, b_mid_lat, b_mid_lng, b_end_lat, b_end_lng} = sigObj;
+                        const aPosition = [
+                            window.parent.getKakaoPosition(a_head_lat, a_head_lng),
+                            window.parent.getKakaoPosition(a_mid_lat, a_mid_lng),
+                            window.parent.getKakaoPosition(a_end_lat, a_end_lng),
+                        ]
+                        const bPosition = [
+                            window.parent.getKakaoPosition(b_head_lat, b_head_lng),
+                            window.parent.getKakaoPosition(b_mid_lat, b_mid_lng),
+                            window.parent.getKakaoPosition(b_end_lat, b_end_lng),
+                        ]
+
+                        // console.log(aPosition, bPosition);
+                        evpSig.a_ring.setPath(aPosition);
+                        evpSig.b_ring.setPath(bPosition);
+                    }
+                    evpSig.setState(sigObj.state);
+                }
+            })
+            cnt++;
+        }, 500);
+    }
+
+    function pauseSimulation() {
+        clearInterval(interval);
+        imageOnOff('pause', false);
+        imageOnOff('play', true);
+    }
 
+    function stopSimulation() {
+        clearInterval(interval);
+        imageOnOff('stop', false);
+        imageOnOff('pause', false);
+        cnt = 0;
     }
 </script>
 </body>