import { currDt } from "/js/utils/common.js"; import { requestGet, apiGet } from "/js/utils/restApi.js"; import { TMapMngr } from "/js/vworld/map-mngr.js"; import { LayerType, LayerIndex } from "/js/vworld/map-const.js"; import { TWebSocket } from "/js/websocket/websocket.js"; import * as MAIN from "./main.js"; export let _mapManager = null; let _webSocket = null; export let _cctvMap = new Map(); export let _vmsMap = new Map(); let _trafficMap = new Map(); const _crdnMap = new Map(); window.$trafficMap = _trafficMap; let _timerFetchFcltStts = null; // 시설물 상태정보 요청 타이머 let _timerFetchTraffic = null; // 교통정보 요청 타이머 let _timerFetchIncdData = null; // 돌발정보 요청 타이머 let _timerWebsocket = null; export let _iceServerMap = new Map(); export const drctMap = new Map(); drctMap.set(1, 0); drctMap.set(2, 90); drctMap.set(3, 180); drctMap.set(4, 270); drctMap.set(5, 45); drctMap.set(6, 135); drctMap.set(7, 225); drctMap.set(8, 315); const requestFetchFcltStts = () => { //console.log(`${nowTime()} requestFetchFcltStts`); if (_timerFetchFcltStts) window.clearTimeout(_timerFetchFcltStts); _timerFetchFcltStts = window.setTimeout(() => fetchFcltStts(), 2 * 60 * 1000); }; const requestFetchTraffic = () => { //console.log(`${nowTime()} requestFetchTraffic`); if (_timerFetchTraffic) window.clearTimeout(_timerFetchTraffic); _timerFetchTraffic = window.setTimeout(() => fetchTraffic(), 5 * 60 * 1000); }; const requestFetchIncdData = () => { //console.log(`${nowTime()} requestFetchIncdData`); if (_timerFetchIncdData) window.clearTimeout(_timerFetchIncdData); _timerFetchIncdData = window.setTimeout(() => fetchIncdData(), 2 * 60 * 1000); }; let _timerFetchUnitStts = null; // 프로세스 상태정보 요청 타이머 const requestFetchUnitStts = () => { //console.log(`${nowTime()} requestFetchUnitStts`); if (_timerFetchUnitStts) window.clearTimeout(_timerFetchUnitStts); _timerFetchUnitStts = window.setTimeout(() => fetchUnitStts(), 2 * 60 * 1000); }; // 웹소켓 초기화 function websocketConnect(clientType) { _webSocket = new TWebSocket(clientType, onSocketReceived, onSocketDisconnected, onSocketError, onSocketConnected); _webSocket.connect(); } function onSocketConnected(AClientType, AMessage) { if (_timerWebsocket != null) { clearTimeout(_timerWebsocket); _timerWebsocket = null; } console.log(`${nowTime()} onSocketConnected, ${AClientType}, `, AMessage); } function onSocketReceived(AClientType, AMessage) { // console.log(`${nowTime()} onSocketReceived, ${AClientType}, `, AMessage); const command = AMessage.command; const jsonData = AMessage.data; if (command === "itsFcltStts" || command === "bisFcltStts") { updateFcltStts(jsonData); //if (command === "bisFcltStts") { //const sttsArray = Array.from( _sttsMap.values() ); MAIN.updateFcltStts(_sttsMap); //} requestFetchFcltStts(); } else if (command === "itsUnitStts" || command === "bisUnitStts") { if (command === "itsUnitStts") { MAIN.updateUnitStts(jsonData); //ITS 프로세스 } //if (command === "bisUnitStts") { requestFetchUnitStts(); //} } else if (command === "traffic") { // 소통정보 가공완료 fetchTraffic(); } else if (command === "form-save") { // VMS 메시지 생성 저장 } else if ( command === "fcltUserMsg" ) { getDataAsync('/api/facility/tb_user_msg/list/notify/' + encodeURIComponent(window.$userId), (jsonData)=>{ if (jsonData && jsonData.length > 0){ MAIN.drawMsgView(jsonData); } }, null, null, true); } } function connectToWebSocket() { if (_timerWebsocket != null) { clearTimeout(_timerWebsocket); _timerWebsocket = null; } websocketConnect('op') } //소켓이 끊어 졌을때 다시 실행 function onSocketDisconnected(AClientType, AMessage) { console.log(`${nowTime()} onSocketDisconnected, ${AClientType}, `, AMessage); if (_timerWebsocket != null) { clearTimeout(_timerWebsocket); _timerWebsocket = null; } _timerWebsocket = setTimeout(connectToWebSocket, 5000); } function onSocketError(AClientType, AMessage) { console.log(`${nowTime()} onSocketError, ${AClientType}, `, AMessage); } function FcltStts(type) { this.type = type; this.total = 0; this.normal = 0; this.error = 0; this.collect = 0; this.objLists = new Array(); } export const _sttsMap = new Map(); _sttsMap.set("CCTV", new FcltStts("CCTV")); _sttsMap.set("VMS", new FcltStts("VMS")); _sttsMap.set("VDS", new FcltStts("VDS")); _sttsMap.set("DSRC", new FcltStts("DSRC")); _sttsMap.set("SIG", new FcltStts("신호제어기")); _sttsMap.set("CCAM", new FcltStts("교차로카메라")); _sttsMap.set("WCAM", new FcltStts("웹카메라")); //_sttsMap.set("BIT", new FcltStts("BIT")); export function doMap() { // 지도객체 먼저 생성 하여야 함 _mapManager = new TMapMngr("map", "tooltip"); connectToWebSocket(); _mapManager.onMapMoveEndFunc = onMapMoveEndFunc; // 지도 이동/줌 변경 이벤트 반환 _mapManager.onMouseClickFunc = onMouseClickFunc; // 객체 마우스 클릭 이벤트 반환 _mapManager.onContextMenuFunc = onContextMenuFunc; // 객체 컨텍스트 이벤트 반환 //_mapManager.onSelectObjFunc = onSelectObjFunc; // 객체 선택 이벤트 반환 //_mapManager.onFcltDragEndFunc = onFcltDragEndFunc; // 객체(시설물) 편집시 객체 이동후 좌표 반환 // 지도 초기화설정 _mapManager.showTrafficTooltip(false); _mapManager.setSelectMode(true); _mapManager.toggleBaseMap(true); requestGet('/api/database/code/cmmn-cd/LTC', (jsonData) => {_mapManager.setTrafficGradDesc(jsonData);}); } function onMapMoveEndFunc(AZoom, ACenterX, ACenterY, ALeft, ABottom, ARight, ATop) { //console.log(`${nowTime()} onMapMoveEndFunc, ${AZoom}, ${ACenterX}, ${ACenterY}, ${ALeft}, ${ABottom}, ${ARight}, ${ATop}`); $('.cctv-right-btn-click').remove(); $('.vms-right-btn-click').remove(); } function onMouseClickFunc(ALyrIdx, ALyrName, ANmbr, ACoordX, ACoordY, X, Y) { //console.log(`${nowTime()} onMouseClickFunc, ${ALyrIdx}, ${ALyrName}, ${ANmbr}, ${ACoordX}, ${ACoordY}, ${X}, ${Y}`); if (ALyrIdx === -1) { $('.cctv-right-btn-click').remove(); $('.vms-right-btn-click').remove(); } // const obj = _mapManager.findLayerObject(ALyrIdx, ANmbr); // if (!obj) { // return; // } if (ALyrName === "VMS") { } else if (ALyrName === "CCTV") { } // else if (ALyrName === "BIT") { // } let option = 'width = 580, height = 550, top = 200, left = 674, resizable=no, scrollbars=no'; if (ALyrIdx >= LayerIndex.Link1 && ALyrIdx <= LayerIndex.Link5) { window.open('./detail-traffic-pop-up.html?id=' + encodeURIComponent(ANmbr) + '&type=link', '구간선택', option); } else if (ALyrIdx >= LayerIndex.Ifsc1 && ALyrIdx <= LayerIndex.Ifsc5) { window.open('./detail-traffic-pop-up.html?id=' + encodeURIComponent(ANmbr) + '&type=ifsc', '구간선택', option); } else if (ALyrIdx >= LayerIndex.Road1 && ALyrIdx <= LayerIndex.Road5) { window.open('./detail-traffic-pop-up.html?id=' + encodeURIComponent(ANmbr) + '&type=road', '구간선택', option); } } function onContextMenuFunc(ALyrIdx, ALyrName, ANmbr, ACoordX, ACoordY, X, Y) { //console.log(`${nowTime()} onContextMenuFunc, ${ALyrIdx}, ${ALyrName}, ${ANmbr}, ${ACoordX}, ${ACoordY}, ${X}, ${Y}`); $('.cctv-right-btn-click').remove(); $('.vms-right-btn-click').remove(); //cctv 우클릭 이벤트 if (ALyrIdx === LayerIndex.Cctv || ALyrIdx === LayerIndex.WCam || ALyrIdx === LayerIndex.CCam) { const cctvObj = _mapManager.findLayerObject(ALyrIdx, ANmbr); let type; switch (ALyrIdx) { case LayerIndex.Cctv: type = 'CCTV'; break; case LayerIndex.WCam: type = '웹카메라'; break; case LayerIndex.CCam: type = '교차로카메라'; break; } if (cctvObj) { let div = $(`
[${type}] ${cctvObj.ID} - ${cctvObj.NAME}
카메라 영상
`); $('body').append(div); if ($('#drawer')[0].offsetWidth - X < div[0].offsetWidth){ div.css('left', $('#drawer')[0].offsetWidth - div[0].offsetWidth + 12); } else { div.css('left', X); } if ($('#drawer')[0].offsetHeight - Y < div[0].offsetHeight){ div.css('top', $('#drawer')[0].offsetHeight - div[0].offsetHeight + 59); } else { div.css('top', Y); } $(div).children().eq(0).children().eq(1).on('click',function(e){ $('.cctv-right-btn-click').remove(); const cctvBox = $('#' + cctvObj.ID); if (cctvBox.length > 0) { return cctvBox.mousedown(); } newCamCtrl(createVideoIframe, cctvObj, X, Y); }) } } //vms 우클릭 이벤트 else if (ALyrIdx === LayerIndex.Vms) { const vmsObj = _mapManager.findLayerObject(ALyrIdx, ANmbr); if (vmsObj) { let div = $(`
[VMS] ${vmsObj.ID} - ${vmsObj.NAME}
카메라 영상
표출메시지
`); $('body').append(div); if ($('#drawer')[0].offsetWidth - X < div[0].offsetWidth){ div.css('left', $('#drawer')[0].offsetWidth - div[0].offsetWidth + 12); } else { div.css('left', X); } if ($('#drawer')[0].offsetHeight - Y < div[0].offsetHeight){ div.css('top', $('#drawer')[0].offsetHeight - div[0].offsetHeight + 59); } else { div.css('top', Y); } if (!_cctvMap.get(vmsObj.ID)){ _cctvMap.set(vmsObj.ID, new Map()); } if (!_vmsMap.get(vmsObj.ID)){ _vmsMap.set(vmsObj.ID, new Map()); } // 카메라 영상 클릭 이벤트 $(div).children().eq(0).children().eq(1).on('click',function(){ $('.vms-right-btn-click').remove(); let src = vmsObj.strmHttpAddr; camCtrl(_cctvMap, createVideoDiv, vmsObj, src, X, Y, true); }); //표출메시지 클릭 이벤트 $(div).children().eq(0).children().eq(2).on('click',function(){ $('.vms-right-btn-click').remove(); if(!_vmsMap.get(vmsObj.ID).get('div')){ vmsMessageCtrl(vmsObj,X, Y); } }) } } } /** * 표출메시지 이벤트 * @param {*} obj vms 객체 * @param {*} X 마우스 X 좌표 * @param {*} Y 마우스 Y 좌표 */ export function vmsMessageCtrl(obj, X, Y){ let vmsData = []; //vms 데이터 수신 getData('/api/vms/common/vms-form/dspl-prst', vmsData, {id:obj.NMBR}); if (vmsData[0] && vmsData[0].length > 0) { vmsData = vmsData[0]; //vms 이미지 데이터 let msgs = vmsData[0].msgs; //현재 시각 let now = "제공시각 - " + nowTime(); //이미지 높이에 따른 박스 높이 let height = vmsData[0].vms_hght + 80; //이미지 높이 let imgBoxHeight = vmsData[0].vms_hght; //이미지 넓이에 따른 박스 넓이 let width = vmsData[0].vms_wdth + 20; //vms div 생성 let vmsDiv = createMessageDiv(obj, now, vmsData[0].cmnc_stts_desc); let vmsLeft = X; let vmsTop = Y; $('body').append(vmsDiv); vmsDiv.children().eq(1).css('height', imgBoxHeight); vmsDiv.children().eq(1).children().eq(0).css({height: imgBoxHeight, width: width - 20}); if ($('#drawer')[0].offsetWidth - X < width){ vmsLeft = $('#drawer')[0].offsetWidth - width + 12; } if ($('#drawer')[0].offsetHeight - Y < height){ vmsTop = $('#drawer')[0].offsetHeight - height + 59; } vmsDiv.css({left:vmsLeft, top:vmsTop, height: height}); let imgPosition = vmsDiv.children().eq(1).children().eq(0); let phaseNumPosition = vmsDiv.children().eq(2).children().eq(0); let intervalNumPosition = vmsDiv.children().eq(2).children().eq(1); let closePosition = vmsDiv.children().eq(0).children().eq(0); let vmsInfo = _vmsMap.get(obj.ID); vmsInfo.set('div', vmsDiv); setVmsInterval(msgs, imgPosition, phaseNumPosition, intervalNumPosition, 0, obj.ID); //vmsInfo.set('intervalArr', intervalArr); $('.vms-box').draggable({ containment: "body" }); //dragEvent(vmsDiv, 'vms-box'); closePosition.on('click', function(){ clearTimeout(vmsInfo.get('interval')); vmsInfo.get('div').remove(); vmsInfo.delete('div'); }); } else { //현재 시각 let now = '표출메시지가 없습니다.'; //이미지 높이에 따른 박스 높이 let height = 144; //이미지 높이 let imgBoxHeight = 64; //이미지 넓이에 따른 박스 넓이 let width = 404; //vms div 생성 let vmsDiv = createMessageDiv(obj, now); let vmsLeft = X; let vmsTop = Y; $('body').append(vmsDiv); vmsDiv.children().eq(1).css('height', imgBoxHeight); vmsDiv.children().eq(1).children().eq(0).css({height: imgBoxHeight, width: width - 20}); if ($('#drawer')[0].offsetWidth - X < width){ vmsLeft = $('#drawer')[0].offsetWidth - width + 12; } if ($('#drawer')[0].offsetHeight - Y < height){ vmsTop = $('#drawer')[0].offsetHeight - height + 59; } vmsDiv.css({left:vmsLeft, top:vmsTop, width:width, height: height}); let imgPosition = vmsDiv.children().eq(1).children().eq(0); let closePosition = vmsDiv.children().eq(0).children().eq(0); imgPosition.css('background-color', 'black'); let vmsInfo = _vmsMap.get(obj.ID); vmsInfo.set('div', vmsDiv); //dragEvent(vmsDiv, 'vms-box'); $('.vms-box').draggable({ containment: "body" }); closePosition.on('click', function(){ vmsInfo.get('div').remove(); vmsInfo.delete('div'); }); } } /** * vms 이미지 인터벌 * @param {*} value vms 데이터 * @param {*} position vms 이미지 위치 * @param {*} phase phase 번호 텍스트 위치 * @param {*} num 카운트 텍스트 위치 */ export function setVmsInterval(data, position, phase, num, idx, id){ if (data[idx]) { $(position).prop('src', 'data:image/png;base64,'+ data[idx].vms_dspl_msg_imag); let time = data[idx].dspl_hh; let intervalNum = data[idx].dspl_hh; idx++; $(num).text(intervalNum--); $(phase).text(idx + '/' + data.length); let timeInterval = setInterval(()=>{ $(num).text(intervalNum--); if(intervalNum === 0){ clearInterval(timeInterval); } }, 1000); if(idx === data.length){ idx = 0; } let interval = setTimeout(() => { window.clearTimeout(interval); setVmsInterval(data, position, phase, num, idx, id); }, time * 1000); _vmsMap.get(id).set('interval', interval); } } /** * 시설물 클릭 시 카메라 영상 생성 및 이동 이벤트 * @param {*} map 해당 맵 객체 * @param {*} obj 해당 시설물 객체 * @param {*} src 영상 소스 * @param {*} X X좌표 * @param {*} Y Y좌표 */ export async function newCamCtrl(method, obj, X, Y){ let cctvBox = method(obj); $("body").append(cctvBox); let cctvLeft = X; let cctvTop = Y; const drawer = $('#drawer'); const dragBox = $('#' + obj.ID); if (drawer[0].offsetWidth - X < cctvBox[0].offsetWidth){ cctvLeft = drawer[0].offsetWidth - cctvBox[0].offsetWidth + 12; } if (drawer[0].offsetHeight - Y < cctvBox[0].offsetHeight){ cctvTop = drawer[0].offsetHeight - cctvBox[0].offsetHeight + 59; } dragBox.css({left:cctvLeft, top:cctvTop}); dragBox.draggable({ containment: "body", handle: '.cctv-box-title' }); dragBox.children().eq(0).children().eq(0).on('click',function(){ cctvBox.remove(); }); dragBox.on('mousedown', ()=>{ const cctvBoxArr = $('.cctv-box'); if (cctvBoxArr.length > 1) { let maxZ = Math.max(...cctvBoxArr.map((_, el) => +$(el).css('z-index') || 0).get()); if (maxZ === 100 || maxZ > Number(dragBox.css('z-index'))) { maxZ++; } dragBox.css('z-index', maxZ); } }) } /** * 시설물 클릭 시 카메라 영상 생성 및 이동 이벤트 * @param {*} map 해당 맵 객체 * @param {*} obj 해당 시설물 객체 * @param {*} src 영상 소스 * @param {*} X X좌표 * @param {*} Y Y좌표 */ export function camCtrl(map, method, obj, src, X, Y, vmsTrue){ let cctvBox = method(obj); $("body").append(cctvBox); let cctvLeft = X; let cctvTop = Y; if ($('#drawer')[0].offsetWidth - X < cctvBox[0].offsetWidth){ cctvLeft = $('#drawer')[0].offsetWidth - cctvBox[0].offsetWidth + 12; } if ($('#drawer')[0].offsetHeight - Y < cctvBox[0].offsetHeight){ cctvTop = $('#drawer')[0].offsetHeight - cctvBox[0].offsetHeight + 59; } cctvBox.css({left:cctvLeft, top:cctvTop}); let cctvInfo = map.get(obj.ID); cctvInfo.set('div', cctvBox); let player = webRtcConnector(obj, $('#' + obj.ID).children().eq(1).children().eq(0), 'video' + obj.ID, vmsTrue); if (player) { cctvInfo.set('video', player); $('#video' + obj.ID).on('dblclick', function (){ if (cctvBox.css('width') === '350px') { cctvBox.css('width', 700); cctvBox.css('height', 600); } else { cctvBox.css('width', 350); cctvBox.css('height', 300); } }) } cctvBox.children().eq(0).children().eq(0).on('click',function(){ cctvBox.remove(); if (cctvInfo.get('video')) { cctvInfo.get('video').Stop(); } }); cctvBox.draggable({ containment: "body", handle : ".cctv-box-title" }); //dragEvent(cctvBox, 'cctv-box'); } /** * 카메라 영상 div 생성 * @param {*} obj 데이터 객체 * @returns 생성 div */ export function createVideoIframe(obj){ const iceInfo = _iceServerMap.get(obj.rtc_svr_ip); if (iceInfo) { const {svr_ip, svr_prot, svr_port, svr_id, svr_pswd} = iceInfo obj.local_ice_svr = svr_prot + ":" + svr_ip + ":" + svr_port; obj.local_ice_id = svr_id; obj.local_ice_pswd = svr_pswd; } const {ID, NAME, local_ice_id, local_ice_svr, local_ice_pswd, rtc_id, rtc_svr_ip, rtc_svr_port} = obj; const objInfo = {ID, NAME, local_ice_id, local_ice_svr, local_ice_pswd, rtc_id, rtc_svr_ip, rtc_svr_port}; const objStr = encodeURIComponent(JSON.stringify(objInfo)); let title = ID + ' - ' + NAME; if (obj.lyrInfo.lyrName === '교차로카메라') { title = obj.NMBR + ' - ' + NAME; } let div = $(`
${title} X
`); return div; } /** * 카메라 영상 div 생성 * @param {*} obj 데이터 객체 * @returns 생성 div */ export function createVideoDiv(obj){ let div = $(`
${obj.ID} - ${obj.NAME} X
`); return div; } function webRtcConnector(obj, videoBox, id, vmsTrue){ //let { web_rtc_svr_ip, web_rtc_svr_port, web_rtc_id } = obj; let { rtc_svr_ip, rtc_svr_port, rtc_id } = obj; if (vmsTrue) { rtc_svr_ip = obj.web_rtc_svr_ip; rtc_svr_port = obj.web_rtc_svr_port; rtc_id = obj.web_rtc_id; } let isNull = nullArrChecker([rtc_svr_ip, rtc_svr_port, rtc_id]); if (!isNull) { videoBox.css('cursor', 'pointer'); videoBox.append($(``)) let video; if (rtc_id.includes('vms-')) { video = new WebRtcPlayer(id, rtc_svr_ip, rtc_svr_port, rtc_id); } else { video = new HiVeWebRtcPlayer(id, rtc_svr_ip, rtc_svr_port, rtc_id); } video.Play(); return video; } else { videoBox.css('background-color', ''); videoBox.append($(`
영상 스트리밍 정보를 확인해주세요.

WEB RTC IP
:
${rtc_svr_ip}
WEB RTC PORT
:
${rtc_svr_port}
WEB RTC ID
:
${rtc_id}
`)) } } /** * 메시지 표출 div 생성 * @param {*} obj 데이터 객체 * @param {*} now 현재 시각 * @returns 생성 div */ export function createMessageDiv(obj, now, cmncSttsDesc){ const procClass = cmncSttsDesc === "통신두절" || !cmncSttsDesc ? 't-red' : ''; let div = $(`
${obj.ID} - ${obj.NAME}   X
${now}   
`); return div; } /** * 드래그 이벤트 * @param {*} position 드래그 상자 위치 */ export function dragEvent(position, classNm){ $(position).on('mousedown', function(){ for (let ii = 0; ii < $('.' + classNm).length; ii++ ){ $($('.' + classNm)[ii]).css('z-index', '100'); }; $(position).css('z-index', '101'); }) position.on("dragstart", function(ev){ let offsetX = ev.offsetX; let offsetY = ev.offsetY; $('#drawer').off('drop'); $('#drawer').off('dragover'); $('#drawer').on('dragover', function(ev){ ev.preventDefault(); }) $('#drawer').on('drop',function(ev){ ev.preventDefault(); $(position).css({left : ev.clientX - offsetX, top : ev.clientY - offsetY}); }) }); } function setTranslate(xPos, yPos, el) { el.style.transform = "translate3d(" + xPos + "px, " + yPos + "px, 0)"; } function onSelectObjFunc(ALyrIdx, ALyrName, ANmbr, ACoordX, ACoordY, X, Y) { //console.log(`${nowTime()} onSelectObjFunc, ${ALyrIdx}, ${ALyrName}, ${ANmbr}, ${ACoordX}, ${ACoordY}, ${X}, ${Y}`); } function onFcltDragEndFunc(ALyrIdx, ALyrName, ANmbr, ACoordX, ACoordY) { //console.log(`${nowTime()} onFcltDragEndFunc, ${ALyrIdx}, ${ALyrName}, ${ANmbr}, ${ACoordX}, ${ACoordY}`); } export function loadingData() { fetchBaseData(); fetchFcltData(); fetchUnitStts(); fetchIncdData(); // 돌발정보 요청 //fetchFcltStts(); } /** * Promise.all 사용해서 하나라도 오류가 발생하면 다음 함수가 실행되지 않도록 한다. * 개별 오류 catch 하면 다음 작업에서 계속 오류가 발생(객체를 찾지 못함)하기 때문에 * 아예 다음작업이 수행되지 않도록 catch 를 한번 만 잡는다. * 즉, 오류가 발생하면 그냥 오류 발생 후 다음 작업이 진행되지 않도록 한다. */ async function fetchBaseData() { //console.time("***** fetchBaseData: "); const node = apiGet("/api/database/node/list"); // 노드정보 요청 const link = apiGet("/api/database/link/list"); // 링크정보 요청 const ifsc = apiGet("/api/database/ifsc/list"); // 링크정보 요청 const road = apiGet("/api/database/road/list"); // 도로정보 요청 Promise.all([node, link, ifsc, road]) .then((results) => Promise.all(results.map((r) => r.json()))) .then((values) => { //console.log(`${nowTime()} BaseData, NODE(${values[0].length}), LINK(${values[1].length}), IFSC(${values[2].length}), ROAD(${values[3].length})`); _mapManager.makeLayer(LayerIndex.Node, values[0]); _mapManager.makeTrafficObject(LayerType.LINK, values[1]); _mapManager.makeTrafficObject(LayerType.IFSC, values[2]); _mapManager.makeTrafficObject(LayerType.ROAD, values[3]); _trafficMap.set('node', values[0]); _trafficMap.set('link', values[1]); _trafficMap.set('ifsc', values[2]); _trafficMap.set('road', values[3]); fetchTraffic(); fetchBaseVrtx(); }) .catch((err) => { console.error(`${nowTime()} Error in fetchBaseData ${err}`); setTimeout(()=>fetchBaseData(), 30000); }) //.finally(() => console.timeEnd("***** fetchBaseData: ")); } async function fetchTraffic() { //console.time("***** fetchTraffic: "); const link = apiGet("/api/manage/main/traffic/link"); // 링크소통정보 요청 const ifsc = apiGet("/api/manage/main/traffic/ifsc"); // 정보제공구간정보 요청 const road = apiGet("/api/manage/main/traffic/road"); // 도로소통정보 요청 // 결측구간, 반복정체구간은 async 로 조회한다. requestGet("/api/manage/main/syst-opr/miss-link-traf", recvMissLinkTraf); requestGet("/api/manage/main/syst-opr/repeat-congest", recvRepeatCongest); Promise.all([link, ifsc, road]) .then((results) => Promise.all(results.map((r) => r.json()))) .then((values) => { //console.log(`${nowTime()} Traffic, LINK(${values[0].length}), IFSC(${values[1].length}), ROAD(${values[2].length})`); _mapManager.updateTrafficObject(LayerType.LINK, values[0]); _mapManager.updateTrafficObject(LayerType.IFSC, values[1]); _mapManager.updateTrafficObject(LayerType.ROAD, values[2]); }) .catch((err) => { console.error(`Error in fetchTraffic ${err}`); setTimeout(()=>fetchTraffic(), 30000); }) //.finally(() => ); // 요청시간을 기준으로 교통정보 요청 타이머 리셋 requestFetchTraffic(); } function recvMissLinkTraf(jsonData) { MAIN.updateMissLinkTraf(jsonData); } function recvRepeatCongest(jsonData) { MAIN.updateRepeatCongest(jsonData); } async function fetchBaseVrtx() { //console.time("***** fetchBaseVrtx: "); // 버텍스를 표출할 레벨을 설정한다. _mapManager.setLayerVisible(LayerIndex.Link1, 16); _mapManager.setLayerVisible(LayerIndex.Link2, 17, 18, 19); _mapManager.setLayerVisible(LayerIndex.Ifsc1, 14); _mapManager.setLayerVisible(LayerIndex.Ifsc2, 15); _mapManager.setLayerVisible(LayerIndex.Road1, 10); _mapManager.setLayerVisible(LayerIndex.Road2, 11, 12, 13); //console.error("***** fetchBaseVrtx_1: "); //const link1 = apiGet("/api/manage/main/map/vrtx/link/1"); // 버텍스정보 요청(1 => 16) const link2 = apiGet("/api/manage/main/map/vrtx/link/2"); // 버텍스정보 요청(2 => 17,18,19) //const ifsc3 = apiGet("/api/manage/main/map/vrtx/ifsc/3"); // 버텍스정보 요청(3 => 15) const ifsc4 = apiGet("/api/manage/main/map/vrtx/ifsc/4"); // 버텍스정보 요청(4 => 14) //const road5 = apiGet("/api/manage/main/map/vrtx/road/5"); // 버텍스정보 요청(5 => 13) const road6 = apiGet("/api/manage/main/map/vrtx/road/6"); // 버텍스정보 요청(6 => 10, 11, 12) //Promise.all([link1, link2, ifsc3, ifsc4, road5, road6]) //Promise.all([link2, ifsc4, road6]) Promise.all([link2, ifsc4, road6]) .then((results) => Promise.all(results.map((r) => r.json()))) .then((values) => { _mapManager.makeLayer(LayerIndex.Link1, values[0]); _mapManager.makeLayer(LayerIndex.Link2, values[0]); _mapManager.makeLayer(LayerIndex.Ifsc1, values[1]); _mapManager.makeLayer(LayerIndex.Ifsc2, values[1]); _mapManager.makeLayer(LayerIndex.Road1, values[2]); _mapManager.makeLayer(LayerIndex.Road2, values[2]); _trafficMap.set('link1', values[0]); _trafficMap.set('link2', values[0]); _trafficMap.set('ifsc1', values[1]); _trafficMap.set('ifsc2', values[1]); _trafficMap.set('road1', values[2]); _trafficMap.set('road2', values[2]); }) .catch((err) => { console.error(`Error in fetchBaseVrtx ${err}`); setTimeout(()=>fetchBaseVrtx(), 30000); }) .finally(() => { }); } async function fetchFcltData() { //console.time("***** fetchFcltData: "); const cctv = apiGet("/api/cctv/common/cctv-list"); // CCTV const vms = apiGet("/api/vms/common/vms-list"); // VMS const vds = apiGet("/api/vds/common/vds-list"); // VDS const dsrc = apiGet("/api/rse/tb_rse_ctlr"); // RSE const sig = apiGet("/api/scrs/tb_sc_sgnl_ctlr"); // 신호제어기(SIG) const ccam = apiGet("/api/scrs/tb_sc_ixr_cmra_mngm/list"); // 교차로 카메라 const wcam = apiGet("/api/wcam/manager/info"); // 교차로 카메라 const iceServer = apiGet("/api/database/strm_ice_svr"); // 교차로 카메라 Promise.all([cctv, vms, vds, dsrc, sig, ccam, wcam, iceServer]) .then((results) => Promise.all(results.map((r) => r.json()))) .then((values) => { // console.log( // //`${nowTime()} FcltData, CCTV(${values[0].length}), VMS(${values[1].length}), VDS(${values[2].length}), PARK(${values[3].length}), BIT(${values[4].length})` // `${nowTime()} FcltData, CCTV(${values[0].length}), VMS(${values[1].length}), VDS(${values[2].length})` // ); _mapManager.makeLayer(LayerIndex.Cctv, values[0]); _mapManager.makeLayer(LayerIndex.Vms, values[1]); _mapManager.makeLayer(LayerIndex.Vds, values[2]); _mapManager.makeLayer(LayerIndex.Dsrc, values[3]); _mapManager.makeLayer(LayerIndex.Sig, values[4]); _mapManager.makeLayer(LayerIndex.WCam, values[6]); values[7].map((obj)=>{ _iceServerMap.set(obj.svr_ip, obj); }) // values[5].map((obj)=>{ // let deg = drctMap.get(obj.drct_dvsn_cd); // const crdn = getDestinationPoint(obj.cmra_y_crdn, obj.cmra_x_crdn, deg, 25); // obj.cmra_y_crdn = crdn[1]; // obj.cmra_x_crdn = crdn[0]; // _crdnMap.set(obj.cmra_id, [obj.cmra_x_crdn, obj.cmra_y_crdn]); // }); _mapManager.makeLayer(LayerIndex.CCam, values[5]); fetchFcltStts(); }) .catch((err) => { console.error(`Error in fetchFcltData ${err}`); setTimeout(()=>fetchFcltData(), 30000); $('.loading-box').css('display','none'); }) //.finally(() => console.timeEnd("***** fetchFcltData: ")); } // 시설물 상태정보 요청(타이머 또는 웹소켓에 의해 실행됨) async function fetchFcltStts() { // console.log("***** fetchFcltStts: "); const its = apiGet("/api/common/stts/total"); // ITS 상태정보 요청 //const bit = apiGet("/api/bis/stts/bit/total"); // BIT 상태정보 요청 //Promise.all([its, bit]) Promise.all([its]) .then((results) => Promise.all(results.map((r) => r.json()))) .then((values) => { //console.log(`${nowTime()} FcltStts, ITS(${values[0].fclt_list.length}))`); //console.log(`${nowTime()} FcltStts, ITS(${values[0].fclt_list.length}), BIT(${values[1].fclt_list.length})`); updateFcltStts(values[0]); MAIN.updateFcltStts(_sttsMap); }) .catch((err) => { console.error(`Error in fetchFcltStts ${err}`); setTimeout(()=>fetchFcltStts(), 30000); }) .finally(() => $('.loading-box').css('display','none')); //.finally(() => console.timeEnd("***** fetchFcltStts: ")); // 요청시간을 기준으로 상태정보 요청 타이머 리셋 requestFetchFcltStts(); } function updateFcltStts(jsonData) { jsonData.fclt_list.forEach((el) => { let lyrInfo = null; const stts = _sttsMap.get(el.fclt_type); // console.log("stts : ",stts); if (!stts) { return; } let toNumber = true; if (el.fclt_type === "CCTV") { lyrInfo = _mapManager.getLayer(LayerIndex.Cctv); // toNumber = true; } else if (el.fclt_type === "VMS") { lyrInfo = _mapManager.getLayer(LayerIndex.Vms); // toNumber = true; } else if (el.fclt_type === "VDS") { lyrInfo = _mapManager.getLayer(LayerIndex.Vds); // toNumber = true; } else if (el.fclt_type === "DSRC") { lyrInfo = _mapManager.getLayer(LayerIndex.Dsrc); // toNumber = true; } else if (el.fclt_type === "SIG") { lyrInfo = _mapManager.getLayer(LayerIndex.Sig); // toNumber = true; } else if (el.fclt_type === "CCAM") { lyrInfo = _mapManager.getLayer(LayerIndex.CCam); toNumber = false; } else if (el.fclt_type === "WCAM") { lyrInfo = _mapManager.getLayer(LayerIndex.WCam); // toNumber = true; } if (lyrInfo) { stts.total = el.total_cnt; stts.normal = el.normal_cnt; stts.error = el.error_cnt; stts.collect = el.col_err_cnt; stts.objLists = el.fclt_objs; // console.log(`${nowTime()} updateFcltStts: stts: `, stts); el.fclt_objs.forEach((obj) => { const fclt = lyrInfo.findObject(toNumber ? Number(obj.fclt_nmbr) : obj.fclt_nmbr); if (fclt) { fclt.updateStts(obj.stts_cd, obj.updt_dt, obj.fclt_info1, obj.fclt_info2); // if (el.fclt_type === "CCTV" && obj.stts_cd !== "CMS0") { // console.log(`${nowTime()} updateFcltStts: CCTV: `, obj.fclt_nmbr); // } } else { console.warn(`fetchFcltStts: Not Found Object, ${obj.fclt_type}, ${obj.fclt_nmbr}, ${obj.fclt_id}`); } }); } else { console.error(nowTime(), " Unknown Fclt Type: ", el.fclt_type); setTimeout(()=>updateFcltStts(), 30000); } }); } // 센터프로세스 상태정보 요청(타이머 또는 웹소켓에 의해 실행됨) export async function fetchUnitStts() { if (_timerFetchUnitStts) window.clearTimeout(_timerFetchUnitStts); //console.time("***** fetchUnitStts: "); const its = apiGet("/api/common/stts/process/its"); // 센터프로세스 ITS //const bis = apiGet("/api/bis/stts/process"); // 센터프로세스 BIT Promise.all([its]) .then((results) => Promise.all(results.map((r) => r.json()))) .then((values) => { //console.log(`${nowTime()} UnitStts, ITS(${values[0].length}), BIS(${values[1].length})`); //console.log(`${nowTime()} UnitStts, ITS(${values[0].length})`); MAIN.updateUnitStts(values[0]); //ITS 프로세스 //updateUnitStts(values[1]); //BIS 프로세스 }) .catch((err) => { console.error(`Error in fetchUnitStts ${err}`); }) //.finally(() => console.timeEnd("***** fetchUnitStts: ")); // 요청시간을 기준으로 상태정보 요청 타이머 리셋 requestFetchUnitStts(); } // function updateUnitStts(jsonData) { // //console.log("updateUnitStts: ", jsonData); // jsonData.forEach((obj) => { // const runStts = obj.run_sts.slice(-1); // let comStts = obj.com_sts.slice(-1); // let dbStts = obj.db_sts.slice(-1); // if (runStts == "1") { // comStts = "1"; // dbStts = "1"; // } // // const comImg = ""; // // //const dbImg = ""; // // setHtml(".A" + obj.syst_id + "_server", comImg); // // if (comStts == null || comStts == "0" || comStts == "2") { // // windowPop(obj.syst_id); // // } // }); // //MAIN._dataUnitSttsList = jsonData; // MAIN._gridFcltSttsBoard.option("dataSource", jsonData); // } // 돌발정보 수신 function recvIncdData(jsonData) { //console.log(`${nowTime()} recvIncdData: ${jsonData.length} EA.`); _mapManager.makeLayer(LayerIndex.Incd, jsonData); // 레이어 생성 MAIN.updateIncdData(jsonData); //console.timeEnd("***** fetchIncdData: "); } // 돌발정보 수신 function recvAutoIncd(jsonData) { //console.log( `${ nowTime() } recvAutoIncd: ${ jsonData.length } EA.` ); //MAIN.updateAutoIncd(jsonData); } // 돌발정보요청 function fetchIncdData() { //console.time("***** fetchIncdData: "); requestGet("/api/manage/main/syst-opr/incd-ocrr", recvIncdData); // 돌발정보 //requestGet("/api/manage/main/syst-opr/auto-incd", recvAutoIncd); // 시스템 자동 돌발 정보 // 요청시간을 기준으로 돌발정보 요청 타이머 리셋 requestFetchIncdData(); } // 시설물 개별적으로 상태정보 요청 async function fetchFcltSttsIndividual() { const cctv = apiGet("/api/cctv/monitoring/stts"); // CCTV 상태정보 요청 const vms = apiGet("/api/vms/monitoring/stts"); // VMS 상태정보 요청 const vds = apiGet("/api/vds/monitoring/ctlr-stts"); // VDS 상태정보 요청 //const bit = apiGet("/api/bis/stts/bit"); // BIT 상태정보 요청 const rse = apiGet("/api/utis/stts/rse"); // RSE 상태정보 요청 //Promise.all([cctv, vms, vds, rse, bit]) Promise.all([cctv, vms, vds, rse]) .then((results) => Promise.all(results.map((r) => r.json()))) .then((values) => { //console.log(`${nowTime()} CCTV(${values[0].length}), VMS(${values[1].length}), VDS(${values[2].length}), BIT(${values[3].length})`); //console.log(`${nowTime()} CCTV(${values[0].length}), VMS(${values[1].length}), VDS(${values[2].length})`); const cctvStts = recvCctvSttsInfo(values[0]); const vmsStts = recvVmsSttsInfo(values[1]); const vdsStts = recvVdsSttsInfo(values[2]); //const bitStts = recvBitSttsInfo(values[3]); const rseStts = recvRseSttsInfo(values[3]); //console.log(nowTime(), "CCTV: ", cctvStts); //console.log(nowTime(), " VMS: ", vmsStts); //console.log(nowTime(), " VDS: ", vdsStts); //console.log(nowTime(), " BIT: ", bitStts); //console.log(nowTime(), " RSE: ", rseStts); }) .catch((err) => { console.error(`Error in fetchFcltStts ${err}`); }); // 요청시간을 기준으로 시설물 상태정보 요청 타이머 리셋 requestFetchFcltStts(); } function recvNodeInfo(AJsonData) { //console.log("recvNodeInfo: " + AJsonData.length + " EA."); _mapManager.makeLayer(LayerIndex.Node, AJsonData); } function recvLinkInfo(AJsonData) { //console.log("recvLinkInfo: " + AJsonData.length + " EA."); _mapManager.makeTrafficObject(LayerType.LINK, AJsonData); requestGet("/api/manage/main/traffic/link", recvLinkTrafInfo); // 소통정보 요청 requestGet("/api/manage/main/map/vrtx/link/1", recvLinkVrtxInfo, LayerIndex.Link1); // 버텍스정보 요청(1 => 16) requestGet("/api/manage/main/map/vrtx/link/2", recvLinkVrtxInfo, LayerIndex.Link2); // 버텍스정보 요청(2 => 17,18,19) } function recvLinkTrafInfo(AJsonData) { //console.log("recvLinkTrafInfo: " + AJsonData.length + " EA."); _mapManager.updateTrafficObject(LayerType.LINK, AJsonData); } function recvIfscInfo(AJsonData) { //console.log("recvIfscInfo: " + AJsonData.length + " EA."); _mapManager.makeTrafficObject(LayerType.IFSC, AJsonData); requestGet("/api/manage/main/traffic/ifsc", recvIfscTrafInfo); // 소통정보 요청 requestGet("/api/manage/main/map/vrtx/ifsc/3", recvIfscVrtxInfo, LayerIndex.Ifsc1); // 버텍스정보 요청(3 => 14) requestGet("/api/manage/main/map/vrtx/ifsc/4", recvIfscVrtxInfo, LayerIndex.Ifsc2); // 버텍스정보 요청(4 => 15) } function recvIfscTrafInfo(AJsonData) { //console.log("recvIfscTrafInfo: " + AJsonData.length + " EA."); _mapManager.updateTrafficObject(LayerType.IFSC, AJsonData); } function recvRoadInfo(AJsonData) { //console.log("recvRoadInfo: " + AJsonData.length + " EA."); _mapManager.makeTrafficObject(LayerType.ROAD, AJsonData); requestGet("/api/manage/main/traffic/road", recvRoadTrafInfo); // 소통정보 요청 requestGet("/api/manage/main/map/vrtx/road/5", recvRoadVrtxInfo, LayerIndex.Road1); // 버텍스정보 요청(5 => 10, 11, 12) requestGet("/api/manage/main/map/vrtx/road/6", recvRoadVrtxInfo, LayerIndex.Road2); // 버텍스정보 요청(6 => 13) } function recvRoadTrafInfo(AJsonData) { //console.log("recvRoadTrafInfo: " + AJsonData.length + " EA."); _mapManager.updateTrafficObject(LayerType.ROAD, AJsonData); } function recvLinkVrtxInfo(AJsonData, ALyrIdx) { //console.log(`${nowTime()} recvLinkVrtxInfo: ${ALyrIdx}, ${AJsonData.length} EA.`); _mapManager.makeLayer(ALyrIdx, AJsonData); } function recvIfscVrtxInfo(AJsonData, ALyrIdx) { //console.log(`${nowTime()} recvIfscVrtxInfo: ${ALyrIdx}, ${AJsonData.length} EA.`); _mapManager.makeLayer(ALyrIdx, AJsonData); } function recvRoadVrtxInfo(AJsonData, ALyrIdx) { //console.log(`${nowTime()} recvRoadVrtxInfo: ${ALyrIdx}, ${AJsonData.length} EA.`); _mapManager.makeLayer(ALyrIdx, AJsonData); } // CCTV function recvCctvInfo(AJsonData) { //console.log("recvCctvInfo: " + AJsonData.length + " EA."); _mapManager.makeLayer(LayerIndex.Cctv, AJsonData); requestGet("/api/cctv/monitoring/stts", recvCctvSttsInfo); // 상태정보 요청 } // CCTV 상태 function recvCctvSttsInfo(AJsonData) { let stts = new FcltStts(); const lyrInfo = _mapManager.getLayer(LayerIndex.Cctv); if (lyrInfo == null) { return stts; } AJsonData.forEach((el, idx) => { const obj = lyrInfo.findObject(el.nmbr); if (obj) { stts.total++; const sttsCd = el.cmnc_stts_cd.slice(-1); if (Number(sttsCd) == 0) { stts.normal++; } obj.updateStts(el.cmnc_stts_cd, el.updt_dt); } }); stts.error = stts.total - stts.normal; //console.log(`${nowTime()} recvCctvSttsInfo: ${AJsonData.length} EA.`); return stts; } // VMS function recvVmsInfo(AJsonData) { //console.log("recvVmsInfo: " + AJsonData.length + " EA."); _mapManager.makeLayer(LayerIndex.Vms, AJsonData); requestGet("/api/vms/monitoring/stts", recvVmsSttsInfo); // 상태정보 요청 } // VMS 상태 function recvVmsSttsInfo(AJsonData) { let stts = new FcltStts(); const lyrInfo = _mapManager.getLayer(LayerIndex.Vms); if (lyrInfo == null) { return stts; } AJsonData.forEach((el, idx) => { const obj = lyrInfo.findObject(el.nmbr); if (obj) { stts.total++; const sttsCd = el.cmnc_stts_cd.slice(-1); if (Number(sttsCd) == 0) { stts.normal++; } obj.updateStts(el.cmnc_stts_cd, el.updt_dt); } }); stts.error = stts.total - stts.normal; //console.log(`${nowTime()} recvVmsSttsInfo: ${AJsonData.length} EA.`); return stts; } // VDS function recvVdsInfo(AJsonData) { //console.log("recvVdsInfo: " + AJsonData.length + " EA."); _mapManager.makeLayer(LayerIndex.Vds, AJsonData); requestGet("/api/vds/monitoring/ctlr-stts", recvVdsSttsInfo); // 상태정보 요청 } // VDS 상태 function recvVdsSttsInfo(AJsonData) { let stts = new FcltStts(); const lyrInfo = _mapManager.getLayer(LayerIndex.Vds); if (lyrInfo == null) { return stts; } AJsonData.forEach((el, idx) => { const obj = lyrInfo.findObject(el.nmbr); if (obj) { stts.total++; const sttsCd = el.cmnc_stts_cd.slice(-1); if (Number(sttsCd) == 0) { stts.normal++; if (el.coll_cnt == 0) { stts.collect++; } } obj.updateStts(el.cmnc_stts_cd, el.updt_dt); } }); stts.error = stts.total - stts.normal; //console.log(`${nowTime()} recvVdsSttsInfo: ${AJsonData.length} EA.`); return stts; } // RSE function recvRseInfo(AJsonData) { //console.log("recvRseInfo: " + AJsonData.length + " EA."); _mapManager.makeLayer(LayerIndex.Rse, AJsonData); //requestGet("/api/utis/stts/rse", recvRseSttsInfo); // 상태정보 요청 } // RSE 상태 function recvRseSttsInfo(AJsonData) { let stts = new FcltStts(); const lyrInfo = _mapManager.getLayer(LayerIndex.Rse); if (lyrInfo == null) { return stts; } AJsonData.forEach((el, idx) => { const obj = lyrInfo.findObject(el.fclt_id); if (obj) { stts.total++; const sttsCd = el.stts_cd.slice(-1); if (Number(sttsCd) == 0) { stts.normal++; } obj.updateStts(el.stts_cd, el.updt_dt); } }); stts.error = stts.total - stts.normal; //console.log(`${nowTime()} recvRseSttsInfo: ${AJsonData.length} EA.`); // 시설물 상태정보 요청 타이머 설정 //_timerLoadingFcltStts = window.setTimeout(function() { // loadingFcltStts(); //}, (60 * 1000)); return stts; } // Park function recvParkInfo(AJsonData) { //console.log("recvParkInfo: " + AJsonData.length + " EA."); _mapManager.makeLayer(LayerIndex.Park, AJsonData); } // BIT // function recvBitInfo(AJsonData) { // console.log("recvBitInfo: " + AJsonData.length + " EA."); // _mapManager.makeLayer(LayerIndex.Bit, AJsonData); // } // function recvBitSttsInfo(AJsonData) { // let stts = new FcltStts(); // const lyrInfo = _mapManager.getLayer(LayerIndex.Bit); // if (lyrInfo == null) { // return stts; // } // AJsonData.forEach((el, idx) => { // const obj = lyrInfo.findObject(el.fclt_id); // if (obj) { // stts.total++; // const sttsCd = el.stts_cd.slice(-1); // if (Number(sttsCd) == 0) { // stts.normal++; // } // obj.updateStts(el.stts_cd, el.updt_dt); // } // }); // stts.error = stts.total - stts.normal; // console.log(`${nowTime()} recvBitSttsInfo: ${AJsonData.length} EA.`); // 시설물 상태정보 요청 타이머 설정 //_timerLoadingFcltStts = window.setTimeout(function() { // loadingFcltStts(); //}, (60 * 1000)); // return stts; // } window.selectLink = function selectLink(linkId) { const map = _mapManager.getInfo(); let lyrIdx = LayerIndex.Link2; let zoom = map.zoom; if (map.zoom == 16) { lyrIdx = LayerIndex.Link1; } else if (map.zoom >= 17) { lyrIdx = LayerIndex.Link2; } else { zoom = 17; lyrIdx = LayerIndex.Link2; } _mapManager.selectLayerObject(lyrIdx, linkId, zoom); }