import { AntiDebug } from '../../anti_debugging.js'; let antiDebug = new AntiDebug(); // import {HMCesium} from 'http://gsim.hanmaceng.co.kr:5151/data/lib2_origin/hmCesium.min.js'; let hmCesium = new HMCesium('mapContainer', // Cesium widget을 포함할 DOM 요소나 ID { // terrainUrl : 'http://gsim.hanmaceng.co.kr:5151/terrain/world_1deg', terrainUrl : 'http://gsim.hanmaceng.co.kr:4040/terrain/total_', imageryUrl : [ ['URL',"https://a.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}.png"], ['WMTS','https://api.vworld.kr/req/wmts/1.0.0/729B62A2-3E48-3E62-B180-7EF5EA3C07F4/Base/{TileMatrix}/{TileRow}/{TileCol}.png'], ['WMTS','https://api.vworld.kr/req/wmts/1.0.0/729B62A2-3E48-3E62-B180-7EF5EA3C07F4/Satellite/{TileMatrix}/{TileRow}/{TileCol}.jpeg'], ['WMTS','https://api.vworld.kr/req/wmts/1.0.0/729B62A2-3E48-3E62-B180-7EF5EA3C07F4/Hybrid/{TileMatrix}/{TileRow}/{TileCol}.png'], ['URL',"https://mt1.google.com/vt/lyrs=y&x={x}&y={y}&z={z}&hl=en&scale=2&apistyle=s.e:l.i|p.v:off"], ['URL',"https://mt1.google.com/vt/lyrs=s&x={x}&y={y}&z={z}&hl=en&scale=2&apistyle=s.e:l.i|p.v:off"], ['URL',"https://a.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png"], ['URL',"https://mt1.google.com/vt/lyrs=m&x={x}&y={y}&z={z}&hl=en&scale=2&apistyle=s.e:l.i|p.v:off"], ['URL',"https://a.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}.png"] ], setView:[126.72219913, 38.0632799256, 12283626, 6.28, -1.569], // flyTo:[126.72219913, 38.0632799256, 1445272, 6.28, -1.569], flyTo:[127.52102339658776, 36.670851294571314, 1060379.6088309984, 6.28, -1.569], mapMode : '3D', rotate2D : false, // mapEmphasize : { // restrictCamera : true, //bool // true/false를 통해 카메라를 제한된 구역 안에서만 움직일 수 있게 해놓는다 // center : [126.7123087, 36.92329764, 0],//lon, lat, height // 카메라의 중심점 설정 // range : 1500,//전체 폴리곤 범위 //default : 1500 // 카메라가 움직일 수 있는 전체 영역을 지정한다. // holeRange : 60,//강조 구역 범위 //단위 : km, default : 30 // empMap에 들어가보면 holeRange에 *1000이 되어있다. Cesium의 거리 unit은 m이기 때문에 km인것이다. // } }, { //dom_option slider : document.getElementById('slider'), mouseInfo: document.querySelector('.footer-left'), }, { //function_option } ); async function initialize(){ if(hmCesium.makerLayers){ for(let i = 0; i < hmCesium.makerLayers.length; i++){ removeLayer(hmCesium.makerLayers[i]._name); } } //유저 정보 넣기 await getUser(); hmCesium.makerLayers = []; hmCesium.labelArray = []; //리스트 그리기 await drawList(); await drawBookMarkList(); // hmCesium.billArray = []; } initialize(); ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////*** 유저 정보 관련 ***/////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// async function getUser(){ let authStatusRes = await axios.get('/auth/status'); hmCesium.user = authStatusRes.data.user; if(!hmCesium.user.dept.includes('기술개발') && hmCesium.user.permission == null){ document.getElementById('project-stat').style.display = 'none'; } if(hmCesium.user.bookmark && hmCesium.user.bookmark != null && typeof hmCesium.user.bookmark != 'object'){ hmCesium.user.bookmark = JSON.parse(hmCesium.user.bookmark); } document.getElementById('user-info').innerHTML = `${hmCesium.user.user_nm} ${hmCesium.user.position}`; } //상단 프로젝트수행현황 document.getElementById('project-stat').addEventListener('click',async()=>{ // window.open(`/projectStatus`, '', `width=${screen.availWidth}, height=${screen.availHeight}, fullscreen=yes ,location=no`); let projectStat = window.open(`/projectStatus`, '_blank'); if(projectStat){ setTimeout(()=>{ let user = hmCesium.user; user.message = `projectStatusMessage`; projectStat.postMessage(user, window.location.origin); },500); } }) ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////*** 유저 정보 관련 END ***////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////*** 리스트 관련 ***/////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //메뉴 변경부분 const tabButtons = document.querySelectorAll(".list__tabs_button"); const tabContents = document.querySelectorAll(".list__contents"); tabButtons.forEach(button => { button.addEventListener("click", () => { tabButtons.forEach(btn => btn.classList.remove("--tab__active")); button.classList.add("--tab__active"); const target = button.getAttribute("data-tab"); tabContents.forEach(content => { content.style.display = (content.id === target) ? "block" : "none"; }); // 전체 등록 레이어 = hmCesium.makerLayers if(target == 'bookmark-list'){//북마크 넘어갈때 for(let i = 0 ; i < hmCesium.makerLayers.length; i++){ // hmCesium.makerLayers[i].show = false; if(hmCesium.makerLayers[i]._name.includes('bookmark-')) hmCesium.makerLayers[i].show = true; else hmCesium.makerLayers[i].show = false; } }else{//토탈 넘어올때 // let idArray = []; // let eles = document.querySelectorAll('#total-list details[open]'); // for(const ele of eles){ // idArray.push(ele.id); // } // for(let i = 0 ; i < hmCesium.makerLayers.length; i++){ // if(idArray.includes(hmCesium.makerLayers[i]._name)){ // hmCesium.makerLayers[i].show = true; // } // } for(let i = 0 ; i < hmCesium.makerLayers.length; i++){ if(!hmCesium.makerLayers[i]._name.includes('bookmark-')) hmCesium.makerLayers[i].show = true; else hmCesium.makerLayers[i].show = false; } } }); }); //리스트 그리기 async function drawList(){ let allList = await getAllList(); // console.log(allList); //전체 리스트 let totalList = document.querySelector('#total-list .list__contents_aria'); //전체 리스트 만들기 for(let i = 0; i < Object.keys(allList).length; i++){ let details = document.createElement('details'); details.classList.add('list__contents_aria_group'); details.id = `${Object.keys(allList)[i]}`; let html = `

${Object.keys(allList)[i]}

${getDepth1Count(Object.keys(allList)[i])}건
`; for(let j = 0; j < Object.keys(allList[Object.keys(allList)[i]]).length; j++){ html += `

${Object.keys(allList[Object.keys(allList)[i]])[j]}

`; }; details.innerHTML = html; // ul 안에 li가 없는 경우 totalList에 추가 안함 if (details.querySelectorAll('.list__contents_aria_group_body_list_item').length > 0) { totalList.appendChild(details); details.querySelectorAll('li').forEach(ele=>{ ele.addEventListener('click', async e=>{ let depth1 = ele.id.split('__')[0].replace('list-', ''); let depth2 = ele.id.split('__')[1]; let depth3 = ele.id.split('__')[2]; selectProject(depth1, depth2, depth3); }) // ele.querySelector('i').addEventListener('click', async e=>{ // toggleBookmark(e.target); // e.stopPropagation(); // }) }) details.open = true; await drawIcon(Object.keys(allList)[i]); let layer = changeLayer(`${Object.keys(allList)[i]}`); layer.show = document.getElementById('bookmark-list').style.display != 'block'; //depth1 선택(펼치기) 이벤트 details.querySelector('summary').addEventListener('click', async e=>{ if(!details.open){ //펼치기 let car3Array =[]; let centerPosition = new Cesium.Cartesian3(0,0,0); let maxDist = 0; for(let j = 0; j < Object.keys(allList[Object.keys(allList)[i]]).length; j++){ let depth2 = Object.keys(allList[Object.keys(allList)[i]])[j]; for(let k = 0; k < Object.keys(allList[Object.keys(allList)[i]][depth2]).length; k++){ let depth3 = Object.keys(allList[Object.keys(allList)[i]][depth2])[k]; let project = allList[Object.keys(allList)[i]][depth2][depth3]; let car3 = Cesium.Cartesian3.fromDegrees(project.lon, project.lat); Cesium.Cartesian3.add(centerPosition, car3,centerPosition); car3Array.push(car3); } } Cesium.Cartesian3.divideByScalar(centerPosition, car3Array.length, centerPosition); for(let i = 1; i < car3Array.length; i++){ if(maxDist < Cesium.Cartesian3.distance(centerPosition, car3Array[i])){ maxDist = Cesium.Cartesian3.distance(centerPosition, car3Array[i]); } } if(car3Array.length == 1){ maxDist = 5000; } let carto = Cesium.Cartographic.fromCartesian(centerPosition); let option = { location : [Cesium.Math.toDegrees(carto.longitude), Cesium.Math.toDegrees(carto.latitude), (maxDist < 1000)?5500:maxDist*5, 6.28, -1.57] } hmCesium.camera_flyTo(option); //아이콘 그리기 drawIcon(Object.keys(allList)[i]); }else{ //닫기 await removeLayer(Object.keys(allList)[i]); } }) } } } //전체 리스트 가져오기 async function getAllList(){ let params = { steps : getSteps(), type : getTypes(), search : document.getElementById('search-param').value.toUpperCase(), category : 'bimproject', } let res = await axios.get(`/gsim/getAllList`, {params : params}); let list = res.data.data; let result = {}; //전체 리스트 만들기 for(let i = 0; i < list.length; i++){ if(!result[`${list[i].large_class}`]){ result[`${list[i].large_class}`] = {}; } if(!result[`${list[i].large_class}`][`${list[i].mid_class}`]){ result[`${list[i].large_class}`][`${list[i].mid_class}`] = []; } if(!result[`${list[i].large_class}`][`${list[i].mid_class}`][`${list[i].short_nm}`]){ result[`${list[i].large_class}`][`${list[i].mid_class}`][`${list[i].short_nm}`] = list[i]; } } hmCesium.allList = result; return result; } function getSteps(){ let result = []; if(document.getElementById('step-done').checked) result.push('done'); if(document.getElementById('step-active').checked) result.push('active'); if(document.getElementById('step-stop').checked) result.push('stop'); if(document.getElementById('step-wait').checked) result.push('wait'); // if(document.getElementById('step-bid').checked) result.push('bid'); // if(document.getElementById('step-support').checked) result.push('support'); if(result.length == 0) result.push(' '); return result; } function getTypes(){ let result = []; if(document.getElementById('step-construction').checked) result.push('construction'); if(document.getElementById('step-design').checked) result.push('design'); if(document.getElementById('step-surgest').checked) result.push('surgest'); if(document.getElementById('step-research').checked) result.push('research'); if(document.getElementById('task-support').checked) result.push('support'); if(document.getElementById('task-center').checked) result.push('center'); if(document.getElementById('task-survey').checked) result.push('survey'); if(result.length == 0) result.push(' '); return result; } //depth1 count function getDepth1Count(depth1){ let list = hmCesium.allList[depth1]; let result = 0; for(let i = 0 ; i < Object.keys(list).length; i++){ for(let j = 0; j < Object.keys(list[Object.keys(list)[i]]).length; j++){ result ++; } } return result; } //bookmark count function getBookmarkCount(depth1){ let list = getBookMarkList()[depth1]; let result = 0; for(let i = 0 ; i < Object.keys(list).length; i++){ for(let j = 0; j < Object.keys(list[Object.keys(list)[i]]).length; j++){ result ++; } } return result; } // step, type 한글로 변경 function stepType2Korean(param){ let result = undefined; switch(param){ case 'done': result = '완료'; break; case 'active': result = '진행'; break; case 'stop': result = '중지'; break; case 'wait': result = '대기'; break; case 'construction': result = '시공'; break; case 'design': result = '설계'; break; case 'surgest': result = '제안'; break; case 'research': result = '연구'; break; case 'support': result = '지원'; break; case 'center': result = '센터'; break; case 'survey': result = '측량'; break; } return result; } function getBookMarkList(){ let bookmarkList = {}; if(!hmCesium.user.bookmark) return bookmarkList; for(let i = 0; i < Object.keys(hmCesium.allList).length; i++){ if(hmCesium.user.bookmark[Object.keys(hmCesium.allList)[i]] && Object.keys(hmCesium.user.bookmark[Object.keys(hmCesium.allList)[i]]).length > 0 ){ bookmarkList[Object.keys(hmCesium.allList)[i]] = {}; for(let j = 0; j < Object.keys(hmCesium.allList[Object.keys(hmCesium.allList)[i]]).length; j ++){ if(hmCesium.user.bookmark[Object.keys(hmCesium.allList)[i]][Object.keys(hmCesium.allList[Object.keys(hmCesium.allList)[i]])[j]] && Object.keys(hmCesium.user.bookmark[Object.keys(hmCesium.allList)[i]][Object.keys(hmCesium.allList[Object.keys(hmCesium.allList)[i]])[j]]).length > 0){ bookmarkList[Object.keys(hmCesium.allList)[i]][Object.keys(hmCesium.allList[Object.keys(hmCesium.allList)[i]])[j]] = {}; for(let k = 0; k < Object.keys(hmCesium.user.bookmark[Object.keys(hmCesium.allList)[i]][Object.keys(hmCesium.allList[Object.keys(hmCesium.allList)[i]])[j]]).length; k ++){ bookmarkList[Object.keys(hmCesium.allList)[i]][Object.keys(hmCesium.allList[Object.keys(hmCesium.allList)[i]])[j]][Object.keys(hmCesium.user.bookmark[Object.keys(hmCesium.allList)[i]][Object.keys(hmCesium.allList[Object.keys(hmCesium.allList)[i]])[j]])[k]] = hmCesium.allList[Object.keys(hmCesium.allList)[i]][Object.keys(hmCesium.allList[Object.keys(hmCesium.allList)[i]])[j]][Object.keys(hmCesium.user.bookmark[Object.keys(hmCesium.allList)[i]][Object.keys(hmCesium.allList[Object.keys(hmCesium.allList)[i]])[j]])[k]]; } } } if(Object.keys(bookmarkList[Object.keys(hmCesium.allList)[i]]).length == 0){ delete bookmarkList[Object.keys(hmCesium.allList)[i]]; } } } return bookmarkList; } //북마크 그리기 async function drawBookMarkList(isEdit = false){ //이전 북마크 아이콘 삭제 for(let i = 0; i < hmCesium.makerLayers.length; i++){ if(hmCesium.makerLayers[i]._name.includes('bookmark-')){ removeLayer(hmCesium.makerLayers[i]._name); } } let old_bookmarkList = []; if(isEdit){ let old_list_dom = document.querySelectorAll(`#bookmark-list .list__contents_aria details[open]`); old_list_dom.forEach((dom) => old_bookmarkList.push(dom.id)); } let bookmarkList = getBookMarkList(); hmCesium.user.bookmark = bookmarkList; //북마크 추가된 전체리스트는 북마크 체크 표시 for(let depth1 of Object.keys(bookmarkList)){ for(let depth2 of Object.keys(bookmarkList[depth1])){ for(let depth3 of Object.keys(bookmarkList[depth1][depth2])){ // console.log(`list-${depth1}__${depth2}__${depth3}`); document.getElementById(`list-${depth1}__${depth2}__${depth3}`)?.querySelector('i')?.classList.add('--bookmark__check'); } } } let div = document.querySelector('#bookmark-list .list__contents_aria'); div.innerHTML = ''; for(let i = 0; Object.keys(bookmarkList).length > i; i++){ let details = document.createElement('details'); details.classList.add('list__contents_aria_group'); details.id = `${Object.keys(bookmarkList)[i]}`; let html = `

${Object.keys(bookmarkList)[i]}

${getBookmarkCount(Object.keys(bookmarkList)[i])}건
`; for(let j = 0; j < Object.keys(bookmarkList[Object.keys(bookmarkList)[i]]).length; j++){ html += `

${Object.keys(bookmarkList[Object.keys(bookmarkList)[i]])[j]}

`; }; details.innerHTML = html; div.appendChild(details); details.querySelectorAll('li').forEach(ele=>{ ele.addEventListener('click', async e=>{ let depth1 = ele.id.split('__')[0].replace('bookmark-', ''); let depth2 = ele.id.split('__')[1]; let depth3 = ele.id.split('__')[2]; selectProject(depth1, depth2, depth3); }) ele.querySelector('i').addEventListener('click', async e=>{ toggleBookmark(e.target); e.stopPropagation(); }) }) details.open = true; await drawIcon(Object.keys(bookmarkList)[i], true); let layer = changeLayer(`bookmark-${Object.keys(bookmarkList)[i]}`); layer.show = document.getElementById('bookmark-list').style.display == 'block'; //depth1 선택(펼치기) 이벤트 details.querySelector('summary').addEventListener('click', async e=>{ if(!details.open){ //펼치기 let car3Array =[]; let centerPosition = new Cesium.Cartesian3(0,0,0); let maxDist = 0; for(let j = 0; j < Object.keys(bookmarkList[Object.keys(bookmarkList)[i]]).length; j++){ let depth2 = Object.keys(bookmarkList[Object.keys(bookmarkList)[i]])[j]; for(let k = 0; k < Object.keys(bookmarkList[Object.keys(bookmarkList)[i]][depth2]).length; k++){ let depth3 = Object.keys(bookmarkList[Object.keys(bookmarkList)[i]][depth2])[k]; let project = bookmarkList[Object.keys(bookmarkList)[i]][depth2][depth3]; let car3 = Cesium.Cartesian3.fromDegrees(project.lon, project.lat); Cesium.Cartesian3.add(centerPosition, car3,centerPosition); car3Array.push(car3); } } Cesium.Cartesian3.divideByScalar(centerPosition, car3Array.length, centerPosition); for(let i = 1; i < car3Array.length; i++){ if(maxDist < Cesium.Cartesian3.distance(centerPosition, car3Array[i])){ maxDist = Cesium.Cartesian3.distance(centerPosition, car3Array[i]); } } if(car3Array.length == 1){ maxDist = 5000; } let carto = Cesium.Cartographic.fromCartesian(centerPosition); let option = { location : [Cesium.Math.toDegrees(carto.longitude), Cesium.Math.toDegrees(carto.latitude), (maxDist < 100)?550:maxDist*5, 6.28, -1.57] } hmCesium.camera_flyTo(option); //아이콘 그리기 drawIcon(Object.keys(bookmarkList)[i], true); }else{ //닫기 await removeLayer(Object.keys(bookmarkList)[i], true); } }) } //이전 열린목록 살리기 if(isEdit){ for(let i = 0; i < old_bookmarkList.length; i++){ if(document.querySelector(`#bookmark-list .list__contents_aria details#${old_bookmarkList[i]}`)){ document.querySelector(`#bookmark-list .list__contents_aria details#${old_bookmarkList[i]}`).open = true; drawIcon(old_bookmarkList[i], true); let layer = changeLayer(`bookmark-${old_bookmarkList[i]}`); layer.show = document.getElementById('bookmark-list').style.display == 'block'; } } } } //북마크 추가삭제 async function toggleBookmark(ele){ let parentId = ele.parentElement.id; let depth1 = parentId.split('__')[0].replace('bookmark-', '').replace('list-', ''); let depth2 = parentId.split('__')[1]; let depth3 = parentId.split('__')[2]; ele.classList.toggle('--bookmark__check'); if(ele.classList.contains('--bookmark__check')){ if(!hmCesium.user.bookmark || hmCesium.user.bookmark == null ||hmCesium.user.bookmark == '') hmCesium.user.bookmark = {}; if(!hmCesium.user.bookmark[depth1]) hmCesium.user.bookmark[depth1] = {}; if(!hmCesium.user.bookmark[depth1][depth2]) hmCesium.user.bookmark[depth1][depth2] = {}; if(!hmCesium.user.bookmark[depth1][depth2][depth3]) hmCesium.user.bookmark[depth1][depth2][depth3] = hmCesium.allList[depth1][depth2][depth3]; }else{ delete hmCesium.user.bookmark[depth1][depth2][depth3]; if(Object.keys(hmCesium.user.bookmark[depth1][depth2]).length == 0) delete hmCesium.user.bookmark[depth1][depth2]; if(Object.keys(hmCesium.user.bookmark[depth1]).length == 0) delete hmCesium.user.bookmark[depth1]; document.getElementById(`list-${depth1}__${depth2}__${depth3}`).querySelector('i').classList.remove('--bookmark__check'); } let params = { bookmark : JSON.stringify(hmCesium.user.bookmark) } axios.get('/gsim/updateBookmark',{params : params}); //북마크 리스트 다시그리기 drawBookMarkList(true); } //프로젝트 검색 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////*** 리스트 관련 END ***////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////*** 지도조작 ***/////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //아이콘 그리기 async function drawIcon(depth1, isBookmark = false){ let layerName = depth1; if(isBookmark) layerName = 'bookmark-' + depth1; let layer = changeLayer(layerName, true); if(!checkLayer(layerName)) { hmCesium.makerLayers.push(layer); } // 이미 그려진 아이콘 전체 삭제 layer.entities.removeAll(); let totalList = hmCesium.allList; if(isBookmark) totalList = hmCesium.user.bookmark; let list = totalList[depth1]; for(let i = 0; i < Object.keys(list).length; i ++){ for(let j = 0; j < Object.keys(list[Object.keys(list)[i]]).length; j ++){ let project = list[Object.keys(list)[i]][Object.keys(list[Object.keys(list)[i]])[j]]; let stepTag = stepType2Korean(project.step); let typeTag = stepType2Korean(project.project_type); let border = ``, color=``; switch(stepTag){ case '진행': border = `#FAA59E`; color=`#F21D0D`; break; case '중지': border = `#9ADFFE`; color=`#03AEFC`; break; case '완료': border = `#C3CFD5`; color=`#688897`; break; case '대기': border = `#B8E0B9`; color=`#4DB251`; break; } let bill = { // html : `
//
//

// ${project.short_nm}

//
//
// ${stepTag}
//
//
//
//
//
`, html : `
${typeTag}

${project.short_nm}

${stepTag}
`, position : [project.lon, project.lat], step : project.step, name : project.short_nm, path : `${project.large_class}__${project.mid_class}__${project.short_nm}`, } loadBillboard(bill, layer); } } hmCesium.viewer.scene.render(); } async function getProjectPath(name){ let list = document.getElementById('total-list').querySelectorAll('li'); for(let i = 0 ; i < list.length; i ++){ if(list[i].id.includes(name)) return list[i].id; } } //hmCesium.makerLayers 중복체크 function checkLayer(name){ for(let i = 0; i < hmCesium.makerLayers.length; i++){ if(hmCesium.makerLayers[i]._name == name){ return true; } } return false; } async function loadBillboard(json, layer) { const container = document.createElement('div'); container.style.position = 'absolute'; container.style.left = '-9999px'; container.style.top = '-9999px'; container.style.visibility = 'hidden'; container.style.display = 'inline-block'; container.style.width = 'auto'; container.innerHTML = json.html; document.body.appendChild(container); await new Promise(resolve => setTimeout(resolve, 200)); const innerElement = container.querySelector('.point-title'); const elementRect = innerElement ? innerElement.getBoundingClientRect() : container.getBoundingClientRect(); const contentWidth = Math.max( Math.ceil(elementRect.width), innerElement ? innerElement.scrollWidth : container.scrollWidth ); const contentHeight = Math.max( Math.ceil(elementRect.height), innerElement ? innerElement.scrollHeight : container.scrollHeight ); const horizontalPadding = 40; const verticalPadding = 24; const width = contentWidth + horizontalPadding; const height = contentHeight + verticalPadding; const svgData = `
${container.innerHTML}
`; const encodedSvg = btoa(unescape(encodeURIComponent(svgData))); const dataUrl = `data:image/svg+xml;base64,${encodedSvg}`; const position = Cesium.Cartesian3.fromDegrees(json.position[0], json.position[1], 0); const testImg = new Image(); testImg.onload = function() { const label = layer.entities.add({ position: position, name: json.name, billboard: { image: dataUrl, horizontalOrigin: Cesium.HorizontalOrigin.CENTER, verticalOrigin: Cesium.VerticalOrigin.BOTTOM, // BOTTOM으로 변경 width: width, height: height, pixelOffset: new Cesium.Cartesian2(0, -3), heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 250_000), show: true } }); label.projectPath = json.path; hmCesium.labelArray.push(label); const bill = layer.entities.add({ position: position, name: json.name, billboard: { image: `/index/img-onpremise/icon-location-${json.step}.svg`, horizontalOrigin: Cesium.HorizontalOrigin.CENTER, verticalOrigin: Cesium.VerticalOrigin.CENTER, heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, show: true } }); bill.__label = label; document.body.removeChild(container); }; testImg.onerror = function() { console.error('SVG 이미지 로드 실패'); document.body.removeChild(container); }; testImg.src = dataUrl; } function hoverProject(picked){ for(let i = 0 ; i < hmCesium.labelArray.length; i++){ if(hmCesium.labelArray[i] == picked || hmCesium.labelArray[i]._name == picked._name){ hmCesium.labelArray[i]._billboard.distanceDisplayCondition = new Cesium.DistanceDisplayCondition(); }else{ hmCesium.labelArray[i]._billboard.distanceDisplayCondition = new Cesium.DistanceDisplayCondition(0,150_000); } } } //이벤트 핸들러 겹쳐서 새로 생성 //마우스 무브 이벤트 let newHandler = new Cesium.ScreenSpaceEventHandler(hmCesium.viewer.scene.canvas); newHandler.setInputAction(ThrottleTimer((movement)=>{ let pickedObject = hmCesium.viewer.scene.pick(movement.endPosition); if(pickedObject){ hoverProject(pickedObject.id); }else{ for(let i = 0; i < hmCesium.labelArray.length; i++){ hmCesium.labelArray[i]._billboard.distanceDisplayCondition = new Cesium.DistanceDisplayCondition(0,150_000); } } },100),Cesium.ScreenSpaceEventType.MOUSE_MOVE); //마우스 클릭 이벤트 newHandler.setInputAction((e)=>{ let pickedObject = hmCesium.viewer.scene.pick(e.position); if(pickedObject){ let entity; if(pickedObject.id.__label) entity = pickedObject.id.__label; else entity = pickedObject.id; let project = entity.projectPath; selectProject(project.split('__')[0],project.split('__')[1],project.split('__')[2]); } },Cesium.ScreenSpaceEventType.LEFT_CLICK); //아이콘 레이어 삭제하기 async function removeLayer(depth2, isBookmark = false){ if(isBookmark) depth2 = 'bookmark-' + depth2; let layer = changeLayer(depth2); hmCesium.viewer.dataSources.remove(layer); for(let i = 0 ; i < hmCesium.labelArray.length; i++){ if(hmCesium.labelArray[i].entityCollection._owner._name == depth2){ hmCesium.labelArray.splice(hmCesium.labelArray.indexOf(hmCesium.labelArray[i]),1); i--; } } for(let i = 0; i < hmCesium.makerLayers.length; i++){ if(hmCesium.makerLayers[i]._name == depth2){ hmCesium.makerLayers[i].entities.removeAll(); hmCesium.makerLayers.splice(hmCesium.makerLayers.indexOf(hmCesium.makerLayers[i]),1); i--; } } hmCesium.viewer.scene.render(); } //리스트, 마커 클릭 이벤트 - 화면 이동 및 gsimViewer 연결 async function selectProject(depth1, depth2, depth3){ let project = hmCesium.allList[depth1][depth2][depth3]; let project_id = project.project_id; let maxDist = 250000; let option = { location : [project.lon, project.lat, maxDist, 6.28, -1.57], duration : 1.5, complete : function(){ let href = `/${project_id}/archive`; window.location.href = href; } } hmCesium.camera_flyTo(option); } //레이어 변경 function changeLayer(name, bMake = false){ let viewer = hmCesium.viewer; let layer = viewer.dataSources.getByName(name); if(layer.length == 0){ if(bMake){ layer = new Cesium.CustomDataSource(name); viewer.dataSources.add(layer); }else{ return undefined; } }else{ layer = layer[0]; } return layer; } //throttle function ThrottleTimer(fn, delay){ let timer; return function(){ if(!timer){ timer = setTimeout(()=>{ timer = null; fn.apply(this, arguments); },delay); } } } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////*** 지도조작 END ***////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////*** 기본지도 (우측하단) ***/////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // 기본지도창 on/off document.getElementById('baseMap-btn').addEventListener('click', (e)=>{ document.getElementById('baseMap-btn').classList.toggle('on'); if(document.getElementById('baseMap-modal').style.display == 'none'){ document.getElementById('baseMap-modal').style.display = 'flex'; }else{ document.getElementById('baseMap-modal').style.display = 'none'; } }); //기본 지도창 닫기 document.querySelector('#baseMap-modal .icon').addEventListener('click',()=>{ document.getElementById('baseMap-modal').style.display = 'none'; }) //baseMap 변경 document.querySelectorAll('#baseMap-modal input').forEach(ele=>{ ele.addEventListener('change', (e)=>{ let value = e.target.value; changeBaseMap(value); }) }); function changeBaseMap(value){ let index = 0; switch(value){ case 'vworld-hybrid': index = 3; break; case 'vworld-satellite': index = 2; break; case 'vworld-normal': index = 1; break; case 'google-hybrid': index = 4; break; case 'google-satellite': index = 5; break; case 'google-normal': index = 7; break; case 'carto-normal': index = 0; break; case 'carto-light': index = 6; break; case 'carto-dark': index = 8; break; } hmCesium.changeBaseMap(index); if(index == 3){ hmCesium.hmUtil.baseMap[2].show = true; } } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////*** 기본지도 (우측하단) END ***////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////*** footer (mouseInfo) ***/////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // 토목좌표 설정 document.getElementById('gcs2').addEventListener('change', () => { if(document.querySelector('input[name="pcs"]')) document.querySelector('input[name="pcs"]').checked = true; document.querySelectorAll('input[name="pcs"]').forEach((radio) => { radio.disabled = false; let label = radio.closest('label'); label.style.opacity = '100%'; label.style.cursor = 'pointer'; }); hmCesium.change_coordiUnit(document.querySelector('input[name="pcs"]:checked').id); }); // 좌표 변환 설정 document.querySelectorAll('input[name="pcs"]').forEach((radio) => { radio.addEventListener('change', () => { hmCesium.change_coordiUnit(radio.id); }); }); // 위경도 설정 document.getElementById('gcs1').addEventListener('change', (e) => { if (e.target.checked) { hmCesium.change_coordiUnit('4326'); } document.querySelectorAll('input[name="pcs"]').forEach((radio) => { radio.disabled = true; radio.checked = false; let label = radio.closest('label'); label.style.opacity = '25%'; label.style.cursor = 'not-allowed'; }); }); // 모달열기 document.querySelector('.coordinate p').addEventListener('click', () => { if(document.getElementById('select-coordi').style.display == 'none'){ document.getElementById('select-coordi').style.display = 'block'; }else{ document.getElementById('select-coordi').style.display = 'none'; } }); // 모달닫기 document.getElementById('select-coordi-close').addEventListener('click', () => { document.getElementById('select-coordi').style.display = 'none'; }); // let keys = Object.keys(hmCesium.main.model); // let lastKey = keys[keys.length-1]; // //모델 설정 후 좌표 바꾸기 // if(hmCesium.main.model[lastKey].projection != '4326'){ // document.getElementById('gcs2').click(); // document.getElementById(hmCesium.main.model[lastKey].projection).click(); // } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////*** footer (mouseInfo) END ***////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////*** step (진행상태) ***/////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// document.getElementById('step-btn').addEventListener('click', ()=>{ document.getElementById('step-btn').classList.toggle('on'); if(document.getElementById('step-btn').classList.contains('on')){ document.getElementById('step-modal').style.display = 'block'; }else{ document.getElementById('step-modal').style.display = 'none'; } }) document.getElementById('step-modal-close').addEventListener('click', ()=>{ document.getElementById('step-modal').style.display = 'none'; document.getElementById('step-btn').classList.remove('on'); }) document.querySelectorAll('#step-modal input').forEach(ele=>{ ele.addEventListener('change', async ()=>{ let list = document.getElementById('total-list'); const search = list.firstElementChild; if(list.lastElementChild && list.lastElementChild !== search){ // list.removeChild(list.lastElementChild); list.lastElementChild.innerHTML= ''; } for(let i = 0; i < hmCesium.makerLayers.length; i++){ await removeLayer(hmCesium.makerLayers[i]._name); i--; } initialize(); }) }) document.getElementById('search-param').addEventListener('keydown',async (e)=>{ if(e.key == 'Enter' || e.keyCode == 13){ let list = document.getElementById('total-list'); const search = list.firstElementChild; if(list.lastElementChild && list.lastElementChild !== search){ // list.removeChild(list.lastElementChild); list.lastElementChild.innerHTML= ''; } for(let i = 0; i < hmCesium.makerLayers.length; i++){ await removeLayer(hmCesium.makerLayers[i]._name); i--; } await initialize(); // if(document.getElementById('search-param').value != ''){ // document.getElementById('total-list').querySelectorAll('li').forEach(ele=>{ele.click();}); // } } }) ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////*** step (진행상태) END ***////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /* JSON 생성용 함수 */ //각 path별 listJSON 업데이트 async function updateListJson(depth1, depth2){ let params = { projectCode : `${depth1}++${depth2}`, } let res = await axios.get('/gsim/makeTreeJson',{params: params}); console.log(res.data.data); } //전체 리스트 업데이트 async function updateAll(){ // let listDom = document.getElementById('total-list').querySelectorAll('li'); // listDom.forEach(async ele=>{ // let depth1 = ele.id.split('__')[0]; // let depth2 = ele.id.split('__')[1]; // await updateListJson(depth1, depth2); // }) // 실제 폴더목록 불러오는 형태로 변경 let list = await getDepth2(); let depth1 = Object.keys(list); for(let i = 0; i < depth1.length; i++){ let depth2 = list[depth1[i]]; for(let j = 0 ; j < depth2.length; j++){ await updateListJson(depth1[i], depth2[j]); } } } //개별 gsim생성 async function makeGSIM(depth1, depth2, depth3){ let params = { projectCode : `${depth1}++${depth2}++${depth3}`, } let res = await axios.get(`/gsim/makeTotalJson`, {params : params}); console.log(res); } //depth2 gsim 생성 async function makeGroupGSIM(depth1, depth2){ let obj = await getDepth3(depth1, depth2); let depth3 = Object.keys(obj); for(let i = 0; i < depth3.length; i++){ makeGSIM(depth1, depth2, depth3[i]); } } //전체 리스트 gsim 생성 async function makeAllGSIM(){ let list = await getDepth2(); let depth1 = Object.keys(list); for(let i = 0 ; i < depth1.length; i++){ let depth2 = list[depth1[i]]; for(let j = 0 ; j < depth2.length; j ++){ makeGroupGSIM(depth1[i], depth2[j]); } } } //수동을 위한 전역화 window.updateList = updateListJson; window.updateAll = updateAll; window.makeGSIM = makeGSIM; window.makeGroupGSIM = makeGroupGSIM; window.makeAllGSIM = makeAllGSIM; ///////test // hmCesium.viewer.screenSpaceEventHandler.setInputAction(e=>{ // const pickedObject = hmCesium.viewer.scene.pick(e.endPosition,1,1); // let position; // if((pickedObject && pickedObject instanceof Cesium.Entity && pickedObject.id.position) || (pickedObject && pickedObject.id instanceof Cesium.Entity && pickedObject.id.position)){ // position = pickedObject.id.position._value;//entity는 picking위치를 알 수 없어서 entity위치로 대체 // if(!position) position = hmCesium.viewer.scene.pickPosition(e.endPosition); // }else if(pickedObject){//3dtiles // position = hmCesium.viewer.scene.pickPosition(e.endPosition); // }else{ // const ray = hmCesium.viewer.scene.camera.getPickRay(e.endPosition); // position = hmCesium.viewer.scene.globe.pick(ray, hmCesium.viewer.scene); // } // if(position){ // if(hmCesium.domManager.epsg == '4326'){ // let carto = Cesium.Cartographic.fromCartesian(position); // var latitude = Cesium.Math.toDegrees(carto.latitude); // var longitude = Cesium.Math.toDegrees(carto.longitude); // document.getElementById('latitude').innerHTML = ` 위도 : ${latitude.toFixed(4)}  `; // document.getElementById('longitude').innerHTML = ` 경도 : ${longitude.toFixed(4)}  `; // }else{ // let descartes = hmCesium.hmUtil.getEPSGCoordinate(hmCesium.domManager.epsg, position); // document.getElementById('latitude').innerHTML = ` X : ${descartes[0].toFixed(4)}  `; // document.getElementById('longitude').innerHTML = ` Y : ${descartes[1].toFixed(4)}  `; // } // } // },Cesium.ScreenSpaceEventType.MOUSE_MOVE); document.getElementById('logout-btn').addEventListener('click',async ()=>{ await axios.get(`/auth/logout`); window.location.href = `/`; })