샘플 리스트
<!doctype html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html;charset=utf-8"> <title>열섬 3D</title> <style> #cmworld3Canvas { width: 100%; height: 100%; } /* 2020.09.01 추가(주소검색) */ html, body { height: 100%; background: transparent; -webkit-text-size-adjust: none; box-sizing: border-box; background: #fff; -webkit-font-smoothing: antialiased; } body, h1, h2, h3, h4, h5, h6, div, p, span, strong, em, blockquote, pre, address, ul, ol, li, dl, dt, dd, table, th, td, form, fieldset, input, select, label, textarea, img, a { margin: 0; padding: 0; border: 0; } h1, h2, h3, h4, h5, h6 { font-weight: 400; } ul, ol { list-style: none; } .btn_search_open { position: absolute; top: 20px; left: 20px; width: 40px; height: 40px; background: url('./textures/icon_search_open.gif') no-repeat center #5d6778; border-radius: 3px; opacity: 0.8; z-index: 100; } .btn_search_close { position: absolute; top: 20px; left: 300px; background: url('./textures/icon_search_close.gif') no-repeat center #5d6778; width: 20px; height: 40px; border-radius: 0 3px 3px 0; } .btn_search_open:hover { opacity: 1; } .search { position: absolute; left: 20px; top: 10px; width: 300px; background: #fff; display: none; z-index: 100; } .search_area { width: 100%; background: #f8faff; box-shadow: 0 5px 10px rgba(24,52,103,0.2); } .tabs { width: 100%; display: block; font-size: 0; } .tabs li { position: relative; display: inline-block; width: calc(100% / 3); height: 34px; line-height: 34px; text-align: center; font-size: 13px; color: #595959; background: #e5eaf7; cursor: pointer; } .tabs li:after { position: absolute; left: 0; top: 11px; content: ''; display: block; width: 1px; height: 12px; background: #d4dae8; } .tabs li:first-child:after { display: none; } .tabs li.active { background: #f8faff; color: #333; font-weight: 600; } .search_area .form .form_line { width: 100%; font-size: 0; padding: 10px 10px 0 10px; text-align-last: center; } .search_area .form .form_line + .form_line { margin-top: -1px; padding: 0 10px 10px 10px; } .inp_search { width: calc(100% - 60px); border: 1px solid #ced0da; height: 30px; margin-bottom: 10px; font-size: 14px; } .btn_search { display: inline-block; background: url('./textures/icon_search.jpg') no-repeat center #4873c2; width: 32px; height: 30px; vertical-align: top; font-size: 0; margin-left: 0px; } #addrSearchBtn { margin-left: 83px !important; } .search_result { width: 100%; background: #fff; } .sch_result_list { width: 90%; display: block; margin: 0 20px; } .sch_result_list li { display: block; border-bottom: 1px solid #f4f6fc; } .sch_result_list li a { display: block; padding: 12px 0; text-decoration: none; } .sch_result_list li a > h3 { font-size: 14px; color: #5d6778; font-weight: 600; } .sch_result_list li a > span { font-size: 12px; color: #a9afba; } .sch_result_list li a:hover > h3 { color: #3761b0; } .sch_result_list li a:hover > span { color: #595959; } .paginate { width: 100%; margin: 10px 0; display: inline-block; text-align: center; } .paginate > a { display: inline-block; width: 20px; height: 20px; text-align: center; font-weight: 600; line-height: 20px; font-size: 12px; } .paginate > a:hover { font-weight: 600; border-radius: 2px; background: #e5eaf7; } .paginate > strong { display: inline-block; width: 20px; height: 20px; border-radius: 2px; background: #3f69b8; text-align: center; font-size: 12px; color: #fff; line-height: 18px; vertical-align: top; } .paginate .prev { display: inlie-block; color: #999; width: 20px; height: 20px; text-align: center; line-height: 20px; } .paginate .next { display: inlie-block; color: #999; width: 20px; height: 20px; text-align: center; line-height: 20px; } .paginate .prev:hover, .paginate .next:hover { border-radius: 2px; background: #e5eaf7; } #formPopUpAPIDiv label { font-size: 0; } .mnu { right: 10px; top: 140px; z-index: 99; position: absolute; text-align: right; } .mnu a { color: rgb(182, 255, 0); } .dg.a { position: fixed; left: 80px; top: 20px; } </style> <script src="./Cm3WebGL/lib/jquery-2.2.0.min.js"></script> <script src="./Cm3WebGL/cm_compile.js"></script> <script> CMWORLD.Compile.includeCm3Library("./Cm3WebGL/"); </script> <script type="text/javascript" src="./Cm3WebGL/lib/shp.js"></script> <script type="text/javascript" src="./Cm3WebGL/lib/ThreeCSG.js"></script> <script type="text/javascript" src="./Cm3WebGL/lib/proj4.js"></script> <!--<script type="text/javascript" src="./js/floorAreaRatio.min.js"></script>--> <script type="text/javascript" src="./js/floorAreaRatio.js"></script> <script src="./lib/dat.gui.min.js"></script> <!--3D--> <!--<script src="./Cm3WebGL/lib/require.2.1.22.min.js"></script>--> <script language="JavaScript"> var cmworld; var camera, scene; var gui; var terrainEnabled = true; var buildingEnabled = false; var wireFrame = false; var m_AcceptableLayerName = "acceptableLayer"; var m_BuildableLayerName = "buildableLayer"; //용적율 변수 var m_BuildingRates = {}; var m_PNUField = "A1"; var m_CodeField = "CODE"; var m_LandAreaField = "LAND_AREA"; var m_BuildAreaField = "BUILD_AREA"; var wgslatlon; var wgsutm; var utmk; //2020.09.01 추가 $(document).ready(function () { // Search $(".btn_search_close").click(function () { $(".search").fadeOut(300); }); $(".btn_search_open").click(function () { $(".search").fadeIn(300); $('#keyword1').focus(); }); }) //2020.09.01 추가(주소검색) function getSearchUrlJuso() { document.formPopUpAPIDiv.keyword.value = $("#keyword1").val(); document.formPopUpAPIDiv.currentPage.value = '1'; searchUrlJuso(); } function searchUrlJuso() { var url = location.href; var confmKey = "U01TX0FVVEgyMDE5MDMyOTExMDgyNzEwODYxMjE="; // 주소검색 API, // localhost, // U01TX0FVVEgyMDE3MDkzMDIwNTAwMTEwNzM4Njg= // => // cmworld.net var resultType = "10"; // 도로명주소 검색결과 화면 출력내용, 1 : 도로명, 2 : 도로명+지번, 3 : // 도로명+상세건물명, 4 : 도로명+지번+상세건물명 document.formPopUpAPIDiv.confmKey.value = confmKey; document.formPopUpAPIDiv.returnUrl.value = url; document.formPopUpAPIDiv.resultType.value = resultType; $('.sch_result_list').html(""); $('#paggingDiv').html(""); $("#resultList").show(); $("#paggingDiv").show(); var tmp = $("#formPopUpAPIDiv").serialize(); tmp += "&confrmKey=U01TX0FVVEgyMDE3MDkzMDIwNTAwMTEwNzM4NjY="; $.ajax({ url: "https://www.juso.go.kr/addrlink/addrLinkApiJsonp.do", // 인터넷망 type: "post", data: $("#formPopUpAPIDiv").serialize(), dataType: "jsonp", crossDomain: true, success: function (xmlStr) { if (navigator.appName.indexOf("Microsoft") > -1) { var xmlData = new ActiveXObject("Microsoft.XMLDOM"); xmlData.loadXML(xmlStr.returnXml) } else { var xmlData = xmlStr.returnXml; } var errCode = $(xmlData).find("errorCode").text(); var errDesc = $(xmlData).find("errorMessage").text(); document.formPopUpAPIDiv.countPageTot.value = $(xmlData).find("totalCount").text(); if (errCode != "0") { alert(errCode + "=" + errDesc); } else { if (xmlStr != null) { //brailleClickEvent(braileMap_EventType.UserData_검색_Search) //검색 시 통계자료 makeListDivPopup(xmlData); pageMakeDivPopup(); } } }, error: function (xhr, status, error) { alert("에러발생"); } }); } function makeListDivPopup(xmlStr) { var htmlStr = ""; var tr_index = 0; var pageNum = document.formPopUpAPIDiv.currentPage.value; var pageSize = document.formPopUpAPIDiv.countPerPage.value; var totalCnt = document.formPopUpAPIDiv.countPageTot.value; var resultType = $("input:radio[name=resultType]:checked").val(); htmlStr += "<p class='text-guide'>검색 결과 <strong>(" + totalCnt + "건)</strong></p>"; if ($(xmlStr).find("juso").length > 0) { $(xmlStr).find("juso").each(function () { tr_index++; var roadAddr = $(this).find('roadAddr').text().replace('\'', ''); var addrDetail = $(this).find('addrDetail').text().replace(/ /gi, "&nbsp;").replace('&nbsp;&nbsp;', '&nbsp;').replace('\'', ''); var roadAddrPart1 = $(this).find('roadAddrPart1').text().replace(/ /gi, "&nbsp;").replace('&nbsp;&nbsp;', '&nbsp;').replace('\'', ''); var roadAddrPart2 = $(this).find('roadAddrPart2').text().replace(/ /gi, "&nbsp;").replace('&nbsp;&nbsp;', '&nbsp;').replace('\'', ''); var engAddr = $(this).find('engAddr').text().replace('\'', ''); var jibunAddr = $(this).find('jibunAddr').text().replace('\'', ''); var zipNo = $(this).find('zipNo').text().replace(/ /gi, "&nbsp;"); var admCd = $(this).find('admCd').text(); var rnMgtSn = $(this).find('rnMgtSn').text(); var bdMgtSn = $(this).find('bdMgtSn').text(); var detBdNmList = $(this).find('detBdNmList').text(); var udrtYn = $(this).find('udrtYn').text(); var buldMnnm = $(this).find('buldMnnm').text(); var buldSlno = $(this).find('buldSlno').text(); var bdnm = $(this).find('bdnm').text(); var noCnt = ((pageNum - 1) * pageSize) + tr_index; if (roadAddr.length > 33) { jibunAddr = jibunAddr.substr(0, 33) + "..."; } if (detBdNmList.length > 40) { detBdNmList = detBdNmList.substr(0, detBdNmList.substr(0, 40).lastIndexOf(",")) + "..."; } htmlStr += "<li>"; htmlStr += "<a class=\"search-row\" style=\"cursor:pointer\">"; htmlStr += "<input type=\"hidden\" class=\"se_admCd\" value=\"" + admCd + "\" />"; htmlStr += "<input type=\"hidden\" class=\"se_rnMgtSn\" value=\"" + rnMgtSn + "\" />"; htmlStr += "<input type=\"hidden\" class=\"se_udrtYn\" value=\"" + udrtYn + "\" />"; htmlStr += "<input type=\"hidden\" class=\"se_buldMnnm\" value=\"" + buldMnnm + "\" />"; htmlStr += "<input type=\"hidden\" class=\"se_buldSlno\" value=\"" + buldSlno + "\" />"; if (bdnm) { htmlStr += "<h3 class=\"poiNm\">" + bdnm + "</h3>"; htmlStr += "<span>" + roadAddr + "</span>"; } else { htmlStr += "<h3 class=\"poiNm\">" + roadAddr + "</h3>"; htmlStr += "<span>[지번]" + jibunAddr + "</span>"; } htmlStr += "</a>"; htmlStr += "</li>"; }); } else { htmlStr += "<li>"; htmlStr += "<a href=\"#\">"; htmlStr += "<h3 class=\"poiNm\">검색결과가 존재하지 않습니다.</h3>"; // htmlStr+="<span></span>"; htmlStr += "</a>"; htmlStr += "</li>"; } $(".sch_result_list").html(htmlStr); $(function () { if (tr_index > 0) { $(".search-row").click(function (e) { $(".sch_result_list").children("li").removeClass("active"); $(e.currentTarget).parent().addClass("active"); var se_admCd = $(e.currentTarget).find("input.se_admCd").val(); var se_rnMgtSn = $(e.currentTarget).find("input.se_rnMgtSn").val(); var se_udrtYn = $(e.currentTarget).find("input.se_udrtYn").val(); var se_buldMnnm = $(e.currentTarget).find("input.se_buldMnnm").val(); var se_buldSlno = $(e.currentTarget).find("input.se_buldSlno").val(); var poiNm = $(e.currentTarget).find("h3.poiNm").text(); var url = location.href; var se_confmKey = "U01TX0FVVEgyMDE5MDMyOTE0NTQ0NDEwODYxMzE="; // 좌표제공API, // localhost, // U01TX0FVVEgyMDE5MDMyOTE1MTgxNTEwODYxMzI= // => // cmworld.net var se_resultType = "4"; // 도로명주소 검색결과 화면 // 출력내용, 1 : 도로명, 2 // : 도로명+지번, 3 : // 도로명+상세건물명, 4 : // 도로명+지번+상세건물명 $.ajax({ url: "http://www.juso.go.kr/addrlink/addrCoordApiJsonp.do", // 인터넷망 type: "post", data: { confmKey: se_confmKey, admCd: se_admCd, rnMgtSn: se_rnMgtSn, udrtYn: se_udrtYn, buldMnnm: se_buldMnnm, buldSlno: se_buldSlno }, dataType: "jsonp", crossDomain: true, success: function (xmlStr) { if (navigator.appName.indexOf("Microsoft") > -1) { var xmlData = new ActiveXObject("Microsoft.XMLDOM"); xmlData.loadXML(xmlStr.returnXml) } else { var xmlData = xmlStr.returnXml; } var errCode = $(xmlData).find("errorCode").text(); var errDesc = $(xmlData).find("errorMessage").text(); document.formPopUpAPIDiv.countPageTot.value = $(xmlData).find("totalCount").text(); if (errCode != "0") { alert(errCode + "=" + errDesc); } else { if (xmlStr != null) { if ($(xmlData).find("juso").length > 0) { $(xmlData).find("juso").each(function () { var pt = { x: parseFloat($(this).find('entX').text()), y: parseFloat($(this).find('entY').text()) }; var ll = ConvertLatLon(pt); if (120 < ll.x && ll.x < 140 && 30 < ll.y && ll.y < 40) { cmworld.gotoGeo(ll.x, ll.y); } return; }); } } } }, error: function (xhr, status, error) { alert("에러발생"); } }); }); } }); } /* * 페이지 설정하기 10 페이당 페이지 번호 생성 */ function pageMakeDivPopup() { var total = document.formPopUpAPIDiv.countPageTot.value; var paggingStr = ""; var pageNum = document.formPopUpAPIDiv.currentPage.value; $('#totalCnt').text("(총 " + total + "건)"); // 총건수 셋팅 if (total < 1) { } else { var PAGEBLOCK = 5; var pageSize = document.formPopUpAPIDiv.countPerPage.value; var totalPages = Math.floor((total - 1) / pageSize) + 1; var firstPage = Math.floor((pageNum - 1) / PAGEBLOCK) * PAGEBLOCK + 1; if (firstPage <= 0) { firstPage = 1; } var lastPage = firstPage - 1 + PAGEBLOCK; if (lastPage > totalPages) { lastPage = totalPages; } var nextPage = lastPage + 1; var prePage = firstPage - 5; if (firstPage > PAGEBLOCK) { paggingStr += "<a class='skip prev10' href='javascript:goPageDivPopup(" + prePage + ");'>&lt;</a>"; } for (i = firstPage; i <= lastPage; i++) { if (pageNum == i) { paggingStr += "<strong>" + i + "</strong>"; } else { paggingStr += "<a href='javascript:goPageDivPopup(" + i + ");'>" + i + "</a>"; } } if (lastPage < totalPages) { paggingStr += "<a class='skip next' href='javascript:goPageDivPopup(" + nextPage + ");'>&gt;</a>"; } $("#paggingDiv").html(paggingStr); } } /* * 해당 페이지로 화면 이동 * */ function goPageDivPopup(pageNum) { document.formPopUpAPIDiv.currentPage.value = pageNum; pageMakeDivPopup(); searchUrlJuso(); } function getBuildingRates() { m_BuildingRates['UQA111'] = 1.00; m_BuildingRates['UQA112'] = 1.20; m_BuildingRates['UQA121'] = 1.50; m_BuildingRates['UQA122'] = 2.00; m_BuildingRates['UQA123'] = 2.50; m_BuildingRates['UQA130'] = 4.00; m_BuildingRates['UQA210'] = 10.00; m_BuildingRates['UQA220'] = 8.00; m_BuildingRates['UQA230'] = 6.00; m_BuildingRates['UQA240'] = 6.00; m_BuildingRates['UQA310'] = 2.00; m_BuildingRates['UQA320'] = 2.00; m_BuildingRates['UQA330'] = 4.00; m_BuildingRates['UQA410'] = 0.50; m_BuildingRates['UQA420'] = 0.50; m_BuildingRates['UQA430'] = 0.50; } window.onload = function () { var canvas = document.querySelector("#cmworldCanvas"); var siteRoot = CMWORLD.Compile.getSiteRootUrl(); cmworld = new CMWORLD.CmWorld3(canvas, 127, 38, CMWORLD.cm_const.EarthRadius, { toptilespan: 36 }); cmworld.option.worldTimer.setStartDateTime(2015, 7, 12, 14, 0, 0, 0); cmworld.setAmbientColor(0xeeeeee); //var textureOption = { noTexture: true, opacity: 0.5 }; cmworld.addTileImageLayer("base", "http://xdworld.vworld.kr:8080/XDServer3d/requestLayerNode?APIKey=B470EFE5-A211-35EE-A38A-0D5AD519F236&Layer=tile&Level={z}&IDX={x}&IDY={y}", 0, 15, 90, -90, -180, 180, "jpg", false); cmworld.addTerrainLayer("terrain", "http://xdworld.vworld.kr:8080/XDServer3d/requestLayerNode?APIKey=B470EFE5-A211-35EE-A38A-0D5AD519F236&Layer=dem&Level={z}&IDX={x}&IDY={y}", 0, 15, 90, -90, -180, 180, ""); ///cmworld.addReal3DLayer("facility_build", "http://xdworld.vworld.kr:8080/XDServer3d/requestLayerNode?Layer=facility_build&Level={z}&IDX={x}&IDY={y}&APIKey=350E1668-0D3F-348A-A950-7F80174028D5", // "http://xdworld.vworld.kr:8080/XDServer3d/requestLayerObject?APIKey=350E1668-0D3F-348A-A950-7F80174028D5&Layer=facility_build&Level={z}&IDX={x}&IDY={y}&DataFile={f}", "facility_build", 0, 15, 90, -90, -180, 180, "dat", textureOption); cmworld.option.showFPS(true); proj4.defs([ ["WGS_LATLON", "+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs"], ["WGS_UTM52", "+proj=utm +zone=52 +ellps=WGS84 +datum=WGS84 +units=m +no_defs"], ["UTM_K", "+proj=tmerc +lat_0=38 +lon_0=127.5 +k=0.9996 +x_0=1000000 +y_0=2000000 +ellps=GRS80 +units=m +no_defs"] ]); wgslatlon = new proj4.Proj('WGS_LATLON'); wgsutm = new proj4.Proj('WGS_UTM52'); utmk = new proj4.Proj('UTM_K'); cmworld.gotoLookAt(126.91821927160821, 37.55271515842018, 1000, 126.91821927160821, 37.55271515842018, 10); //126.92287806018567, 37.52385624604935, 0); //용적율 설정 getBuildingRates(); // Opacity를 위한 User Interface 용 var params = { Terrain: true, Building: false, Wireframe: false, opacity: 1.0 }; //레이어 목록 gui = new dat.GUI(); var folder = gui.addFolder("Layers"); folder.add(params, 'Terrain').onChange( function (v) { terrainEnabled = v; if (terrainEnabled == true) cmworld.addTerrainScene(); else cmworld.removeTerrainScene(); }); /* 2021.04.11 추가(브이월드 건물 보이기) */ folder.add(params, 'Building').name("건물").onChange( function (v) { buildingEnabled = v; var layer = cmworld.getLayer("facility_build"); var textureOption = { noTexture: true, opacity: 0.5 }; if (v == true) { if (!layer) cmworld.addReal3DLayer("facility_build", "http://xdworld.vworld.kr:8080/XDServer/requestLayerNode?Layer=facility_build&Level={z}&IDX={x}&IDY={y}&APIKey=350E1668-0D3F-348A-A950-7F80174028D5", "http://xdworld.vworld.kr:8080/XDServer/requestLayerObject?APIKey=350E1668-0D3F-348A-A950-7F80174028D5&Layer=facility_build&Level={z}&IDX={x}&IDY={y}&DataFile={f}", "facility_build", 0, 15, 90, -90, -180, 180, "dat", textureOption); } layer = cmworld.getLayer("facility_build"); if (layer) layer.visible = v; }); /* 2021.04.11 추가(브이월드 건물 프레임 보이기) */ folder.add(params, 'Wireframe').name("건물 프레임").onChange( function (v) { wireFrame = v; var layer = cmworld.getLayer("facility_build"); if (buildingEnabled == false) { buildingEnabled = true; var textureOption = { noTexture: true, opacity: 0.5 }; if (!layer) { cmworld.addReal3DLayer("facility_build", "http://xdworld.vworld.kr:8080/XDServer/requestLayerNode?Layer=facility_build&Level={z}&IDX={x}&IDY={y}&APIKey=350E1668-0D3F-348A-A950-7F80174028D5", "http://xdworld.vworld.kr:8080/XDServer/requestLayerObject?APIKey=350E1668-0D3F-348A-A950-7F80174028D5&Layer=facility_build&Level={z}&IDX={x}&IDY={y}&DataFile={f}", "facility_build", 0, 15, 90, -90, -180, 180, "dat", textureOption); // cmworld.addReal3DLayer("facility_build_at", "http://xdworld.vworld.kr:8080/XDServer/requestLayerNode?Layer=facility_build&Level={z}&IDX={x}&IDY={y}&APIKey=350E1668-0D3F-348A-A950-7F80174028D5", // "http://xdworld.vworld.kr:8080/XDServer/requestLayerObject?APIKey=350E1668-0D3F-348A-A950-7F80174028D5&Layer=facility_build_at&Level={z}&IDX={x}&IDY={y}&DataFile={f}", "facility_build", 0, 15, 90, -90, -180, 180, "dat", textureOption); } layer = cmworld.getLayer("facility_build"); if (layer) layer.visible = v; } }); folder.add(params, 'opacity', 0, 1).name("Terrain Opacity").onChange ( function () { if (cmworld) { cmworld.setTerrainTransparancy(params.opacity); } }); gui.open(); animate() }; function animate() { requestAnimationFrame(animate); compass.style.transform = `rotate(${360.0 - cmworld.getCamera().head}deg)`; } var m_jijuk_ptlist; function openShp() { var layer = cmworld.getLayer(m_AcceptableLayerName); if (layer) { //alert('이미 레이이가 존재합니다.'); layer.visible = !layer.visible; return; } var url2 = "./demofiles_01/jijuk.zip"; shp(url2).then(function (data2) { var geoDataLen2 = data2.features.length; // 실행한 shp 파일의 객체 수를 저장합니다 if (geoDataLen2 == 0) return; var pnus = {}; for (var i = 0; i < geoDataLen2; i++) { pnus[data2.features[i].properties.A1] = data2.features[i].geometry.coordinates[0]; //PNU에 포인트 할당 } var url = "./demofiles_01/shp_acceptable.zip"; // shp 파일을 실행하여 데이터를 조회합니다 shp(url).then(function (data) { var geoDataLen = data.features.length; // 실행한 shp 파일의 객체 수를 저장합니다 if (geoDataLen == 0) return; var light = new THREE.DirectionalLight(0x606060); light.position.set(0.75, 0.75, 1.0).normalize(); cmworld.getWorldScene().add(light); /* 2021.04.11 추가(위치이동) */ var minx = Number.MAX_VALUE, miny = Number.MAX_VALUE, maxx = Number.MIN_VALUE, maxy = Number.MIN_VALUE; var color = 0x505050; var jijuk_ptlist, code, areaLand, areaBuild, isLight; var areaY; //용적율 면적 var ptlist, dHeight, h, model, dFloor, iFloor; for (var i = 0; i < geoDataLen; i++) { try { ptlist = data.features[i].geometry.coordinates[0]; ptlist.length = ptlist.length - 1; for (var j = 0; j < ptlist.length; j++) { ptlist[j].x = ptlist[j][0]; ptlist[j].y = ptlist[j][1]; } jijuk_ptlist = pnus[data.features[i].properties.A1]; //PNU if (!jijuk_ptlist) continue; for (var j = 0; j < jijuk_ptlist.length; j++) { jijuk_ptlist[j].x = jijuk_ptlist[j][0]; jijuk_ptlist[j].y = jijuk_ptlist[j][1]; /* 2021.04.11 추가(위치이동) */ minx = Math.min(minx, jijuk_ptlist[j][0]); miny = Math.min(miny, jijuk_ptlist[j][1]); maxx = Math.max(maxx, jijuk_ptlist[j][0]); maxy = Math.max(maxy, jijuk_ptlist[j][1]); } code = data.features[i].properties.CODE.trim(); isLight = data.features[i].properties.ISLIGHT; if (!m_BuildingRates[code]) continue; h = cmworld.getGroundHeight(ptlist[0].x, ptlist[0].y); //지형 높이 areaLand = data.features[i].properties.LAND_AREA; areaBuild = data.features[i].properties.BUILD_AREA; areaY = areaLand * m_BuildingRates[code]; //토지면적 X 용적율 = 가능한 면적 //가능 층수 dFloor = areaY / areaBuild; iFloor = parseInt(dFloor); data.features[i].properties.BUILD_LEVEL = iFloor + 1; var bBoxBuild = true; if (code.indexOf('UQA1') == 0 && isLight == true) //주거지역은 사선처리 { if (iFloor > 2) //3층 이하이면 박스로 그림 { bBoxBuild = false; //토지면적, 건물면적, 용적율, 토지ptlist, 건물 ptlist //areaLand, areaBuild, m_BuildingRates[code], jijuk_ptlist, ptlist //사선으로 건물 그리자. model = makeBuildingMesh2(iFloor, areaLand, areaBuild, m_BuildingRates[code], jijuk_ptlist, ptlist); //console.log(iFloor); //dHeight = iFloor * 3; //model = makeBuildingMesh(ptlist, dHeight, 0); if (model) { var obj = new CMWORLD.UserObject(name, model, new THREE.Vector3(ptlist[0].x, ptlist[0].y, h)); obj.rotate4GlobeEarth(); var userLayer = getUserLayer(m_AcceptableLayerName); userLayer.add(obj); data.features[i].properties.BUILD_LEVEL = model.BUILD_LEVEL; } } } if (bBoxBuild == true) //박스형 건물 { dHeight = iFloor * 3; //ptlist를 dHeight만큼 그리고, 나머지 옥상 그림 remareaBuild = areaBuild * (dFloor - iFloor); //옥상 면적... ptlist 다시 계산해서 옥상 그리기 if (dHeight < 3) dHeight = 3; var color = 0x505050; //건물 그리자. ptlist = sortSouthFirst(ptlist); model = makeBuildingMesh(ptlist, dHeight, areaBuild, remareaBuild, color); //console.log(data.features[i]); if (model) { var obj = new CMWORLD.UserObject(name, model, new THREE.Vector3(ptlist[0].x, ptlist[0].y, h)); obj.rotate4GlobeEarth(); var userLayer = getUserLayer(m_AcceptableLayerName); userLayer.add(obj); } } } catch (e) { //console.log("Error Message: " + i.toString() + " " + e.message); } } var userLayer = getUserLayer(m_AcceptableLayerName); if (userLayer) { $('#divVisible').show(); $('#divBuildable').show(); } ///* 2021.04.11 추가(위치이동) */ var cptx = (minx + maxx) / 2.0; var cpty = (miny + maxy) / 2.0; if (120 < cptx && cptx < 140 && 20 < cpty && cpty < 40) { cmworld.gotoGeo(cptx, cpty); } }); }); } function openBuildableShp() { var layer = cmworld.getLayer(m_BuildableLayerName); if (layer) { //alert('이미 레이이가 존재합니다.'); layer.visible = !layer.visible; return; } var url = "./demofiles_01/shp_buildable.zip"; // shp 파일을 실행하여 데이터를 조회합니다 shp(url).then(function (data) { var geoDataLen = data.features.length; // 실행한 shp 파일의 객체 수를 저장합니다 if (geoDataLen == 0) return; var color = 0x505050; var code, areaLand, areaBuild, isLight; var areaY; //용적율 면적 var ptlist, dHeight, h, model, dFloor, iFloor; for (var i = 0; i < geoDataLen; i++) { try { ptlist = data.features[i].geometry.coordinates[0]; ptlist.length = ptlist.length - 1; for (var j = 0; j < ptlist.length; j++) { ptlist[j].x = ptlist[j][0]; ptlist[j].y = ptlist[j][1]; } code = data.features[i].properties.CODE.trim(); isLight = data.features[i].properties.ISLIGHT; if (!m_BuildingRates[code]) continue; h = cmworld.getGroundHeight(ptlist[0].x, ptlist[0].y); //지형 높이 areaLand = data.features[i].properties.LAND_AREA; areaBuild = data.features[i].properties.BUILD_AREA; areaY = areaLand * m_BuildingRates[code]; //토지면적 X 용적율 = 가능한 면적 //가능 층수 dFloor = areaY / areaBuild; iFloor = parseInt(dFloor); data.features[i].properties.BUILD_LEVEL = iFloor + 1; var bBoxBuild = true; if (code.indexOf('UQA1') == 0 && isLight == true) //주거지역은 사선처리 { if (iFloor > 2) //3층 이하이면 박스로 그림 { bBoxBuild = false; //토지면적, 건물면적, 용적율, 건물 ptlist //areaLand, areaBuild, m_BuildingRates[code], ptlist //사선으로 건물 그리자. model = makeBuildingMesh3(iFloor, areaLand, areaBuild, m_BuildingRates[code], jijuk_ptlist, ptlist); //console.log(iFloor); //dHeight = iFloor * 3; //model = makeBuildingMesh(ptlist, dHeight, 0); if (model) { var obj = new CMWORLD.UserObject(name, model, new THREE.Vector3(ptlist[0].x, ptlist[0].y, h)); obj.rotate4GlobeEarth(); var userLayer = getUserLayer(m_BuildableLayerName); userLayer.add(obj); data.features[i].properties.BUILD_LEVEL = model.BUILD_LEVEL; } } } if (bBoxBuild == true) //박스형 건물 { data.features[i].properties.BUILD_LEVEL = 34; dHeight = 100; var color = 0x505000; //건물 그리자. ptlist = sortSouthFirst(ptlist); model = makeBuildingMesh(ptlist, dHeight, areaBuild, 0, color, 0.5); //console.log(data.features[i]); if (model) { var obj = new CMWORLD.UserObject(name, model, new THREE.Vector3(ptlist[0].x, ptlist[0].y, h)); obj.rotate4GlobeEarth(); var userLayer = getUserLayer(m_BuildableLayerName); userLayer.add(obj); } } } catch (e) { //console.log("Error Message: " + i.toString() + " " + e.message); } } var userLayer = getUserLayer(m_BuildableLayerName); if (userLayer) $('#divBuildVisible').show(); }); } function getUserLayer(layerName) { var layer = cmworld.getLayer(layerName); if (layer) { return layer; } // 없으면 만들어서 추가한다. var userLayer = new CMWORLD.UserObjectLayer(layerName); cmworld.addLayer(userLayer); return userLayer; } function setVisible(div, lname) { var userLayer = getUserLayer(lname); if (!userLayer) return; if (userLayer.visible == true) { $(div).text("레이어보이기"); userLayer.visible = false; } else { $(div).text("레이어숨기기"); userLayer.visible = true; } } ///////////////////////////////////////////////////////// /* 2021.04.11 추가(폴더 shp 열기) */ var m_BaseDir = './demofiles_01/'; //var m_BaseDir = './fsm3d/zip/'; ///////////////////////////////////////////////////////// /* 2021.04.11 추가(폴더 shp 열기) */ var m_BaseDir = './fsm3d/zip/'; function openFolderShp(bType) { //기본 zip 폴더: fsm3d / zip //1. 지적도: land //2. 건축가능평면: build //3. 허용가능평면: accept //4. 포디움: podium //5. 포디움 외: nPodium var layername = '포디움 외'; var url; var color = 0x505050; //색상 설정 if (bType == 1) { url = 'land'; layername = "지적도"; color = 0x505050; } else if (bType == 2) { url = 'build'; layername = "건축가능평면"; color = 0x505050; } else if (bType == 3) { url = 'accept'; layername = "허용가능평면"; color = 0x505050; } else if (bType == 4) { url = 'podium'; layername = "포디움"; color = 0x505050; } else if (bType == 5) url = 'nPodium'; var layer = cmworld.getLayer(layername); if (layer) { //alert('이미 레이이가 존재합니다.'); layer.visible = !layer.visible; return; } var t = "openshp.jsp?btype=" + url; var content = request(t, true); content = content.trim(); var tmps = content.split('|'); if (tmps.length < 1) return; url = m_BaseDir + url + '/'; for (var i = 0; i < tmps.length; i++) { console.log(tmps[i]); tmps[i] = tmps[i].trim(); if (!tmps[i]) continue; openFolderShp_sub(bType, url + tmps[i], layername, color); } } function openFolderShp_sub(bType, url, layername, color) { var heightPerFloor = 3; //1층에 3m로 계산 var floorField = 'FLOOR'; //층수 필드명 // shp 파일을 실행하여 데이터를 조회합니다 shp(url).then(function (data) { var geoDataLen = data.features.length; // 실행한 shp 파일의 객체 수를 저장합니다 if (geoDataLen == 0) return; var ptlist, dHeight, h, iFloor; var minx = Number.MAX_VALUE, miny = Number.MAX_VALUE, maxx = Number.MIN_VALUE, maxy = Number.MIN_VALUE; for (var i = 0; i < geoDataLen; i++) { try { ptlist = data.features[i].geometry.coordinates[0]; ptlist.length = ptlist.length - 1; for (var j = 0; j < ptlist.length; j++) { ptlist[j].x = ptlist[j][0]; ptlist[j].y = ptlist[j][1]; minx = Math.min(minx, ptlist[j][0]); miny = Math.min(miny, ptlist[j][1]); maxx = Math.max(maxx, ptlist[j][0]); maxy = Math.max(maxy, ptlist[j][1]); } h = cmworld.getGroundHeight(ptlist[0].x, ptlist[0].y); //지형 높이 //가능 층수 iFloor = data.features[i].properties[floorField]; if (!iFloor) iFloor = 3; //필드가 없으면 3층으로 고정 dHeight = iFloor * heightPerFloor; //건물 그리자. ptlist = sortSouthFirst(ptlist); if (bType == 4) { dHeight = 2 * heightPerFloor; model = makeBuildingMeshExtrude(ptlist, dHeight, 0x505000, 1); if (model) { var obj = new CMWORLD.UserObject('podbase_' + i, model, new THREE.Vector3(ptlist[0].x, ptlist[0].y, h)); obj.rotate4GlobeEarth(); var userLayer = getUserLayer(layername); userLayer.add(obj); h += dHeight; dHeight = iFloor * heightPerFloor; } } model = makeBuildingMeshExtrude(ptlist, dHeight, color, 1); if (model) { var obj = new CMWORLD.UserObject('gmt_' + i, model, new THREE.Vector3(ptlist[0].x, ptlist[0].y, h)); obj.rotate4GlobeEarth(); var userLayer = getUserLayer(layername); userLayer.add(obj); } } catch (e) { console.log("Error Message: " + i.toString() + " " + e.message); } } ///* 2021.04.11 추가(위치이동) */ var cptx = (minx + maxx) / 2.0; var cpty = (miny + maxy) / 2.0; if (120 < cptx && cptx < 140 && 20 < cpty && cpty < 40) { cmworld.gotoGeo(cptx, cpty); } }); } //서버 request function request(url, bNoParse) { var xhr = new XMLHttpRequest(); xhr.open("GET", url, false); xhr.send(null); if (!xhr.response) return null; if (bNoParse == true) return xhr.response; else return JSON.parse(xhr.response); } </script> </head> <body> <!-- 3D GIS --> <canvas id="cmworldCanvas"></canvas> <button type="button" class="btn_search_open viewlevel0" title="검색"></button> <div class="search"> <div class="search_area"> <ul class="tabs"> <li class="active" rel="tab2">주소/명칭</li> <li rel="tab1" class=""></li> <li rel="tab3" class=""></li> </ul> <!-- Tab2: 주소검색 --> <div id="tab2" class="form" style=""> <form name="formPopUpAPIDiv" id="formPopUpAPIDiv" method="post"> <label>현재 페이지<input type="hidden" id="currentPage" name="currentPage" value="1" style="width: 100px"> </label> <label>페이지 숫자<input type="hidden" id="countPerPage" name="countPerPage" value="5" style="width: 100px"> </label> <label>총 페이지<input type="hidden" name="countPageTot" value=""></label> <!-- 총 건수 --> <label>키값<input type="hidden" name="confmKey" value=""> </label> <label>URL<input type="hidden" name="returnUrl" value=""> </label> <label>타입<input type="hidden" name="resultType" value=""> </label> <label>주소<input type="hidden" name="rtAddrPart1" id="rtAddrPart1"> </label> <label>주소<input type="hidden" name="rtAddrPart2" id="rtAddrPart2"> </label> <label>우편번호<input type="hidden" name="rtAddrZip" id="rtAddrZip"> </label> <label>키워드<input type="hidden" name="keyword" id="keyword"></label> </form> <!-- 팝업 예시 --> <div class="form_line"> <input type="text" class="inp_search" title="검색어 입력" name="keyword1" id="keyword1" style="ime-mode: active;" placeholder="도로명/지번/건물명" value=""> <a href="#map" class="btn_search" alt="검색" onclick="getSearchUrlJuso();">검색</a> </div> <div class="result" id="resultList" style="margin-top: 7px;"></div> <!-- Search Result --> <div class="search_result"> <ul class="sch_result_list"></ul> <div class="paginate" id="paggingDiv"></div> </div> <!-- //Search Result --> </div> </div> <button type="button" class="btn_search_close" title="닫기"></button> </div> <div id="compassContainer" style="position: fixed; right:0; top: 0;"> <svg version="1.1" id="compass" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="150" height="150" viewBox="0 0 200 200" xml:space="preserve"> <g transform="translate(19 -19)"> <path fill-rule="evenodd" clip-rule="evenodd" fill="#fdfdfd" d="M162.312,118.21l-24.773,4.063 c-0.41,7.021-2.08,13.585-4.961,19.679c-2.871,6.094-6.787,11.466-11.581,16.075c-4.717,4.609-10.233,8.359-16.542,11.173 c-6.239,2.891-12.87,4.443-19.988,4.922l-2.881,23.341l-3.906-23.341c-7.509-0.479-14.471-2.031-20.779-4.922 c-6.318-2.813-11.757-6.642-16.386-11.251c-4.638-4.678-8.388-10.147-11.269-16.31c-2.792-6.172-4.472-12.735-4.873-19.835 L0,118.21l24.373-3.115c0.4-7.032,2.08-13.595,4.873-19.679c2.881-6.085,6.63-11.476,11.347-16.085 c4.717-4.61,10.234-8.282,16.542-11.085c6.318-2.725,13.192-4.375,20.545-4.766l3.906-23.966l3.125,23.741 c7.108,0.469,13.749,2.109,19.979,4.912c6.23,2.813,11.747,6.631,16.464,11.241c4.716,4.688,8.554,10.078,11.425,16.163 c2.881,6.162,4.551,12.646,4.961,19.522L162.312,118.21L162.312,118.21z M62.007,73.627c-6.22,3.126-11.581,6.798-15.976,11.017 c-4.482,4.219-8.065,9.141-10.868,14.825L58.901,109l0.879-1.406L46.832,84.409L71.84,96.666l0.566-0.234L62.007,73.627 L62.007,73.627z M58.901,129.372l-0.4-1.016l-23.495,9.142c5.351,12.021,13.974,20.763,25.809,25.997l10.556-22.56l-1.045-0.391 l-23.495,12.169L58.901,129.372L58.901,129.372z M126.992,100.104c-5.204-11.554-13.427-19.991-24.783-25.461l-11.024,22.18 l1.191,0.859l23.338-13.272l-12.47,24.044c0.254,0.234,0.488,0.469,0.645,0.781c0.078,0.234,0.322,0.625,0.566,1.016 L126.992,100.104L126.992,100.104z M90.94,140.779c-0.156,0.078-0.557,0.156-1.191,0.156l11.415,22.56 c11.123-5.156,19.511-13.429,25.184-24.747l-22.693-9.767l-0.645,0.781l12.704,22.951L90.94,140.779L90.94,140.779z M91.34,118.366 c0-2.725-0.879-4.913-2.793-6.71c-1.835-1.719-4.159-2.656-6.962-2.656c-2.871,0-5.341,0.938-7.343,2.656 c-2.08,1.797-3.037,3.985-3.037,6.71c0,2.891,0.957,5.313,3.037,7.412c2.002,2.109,4.472,3.203,7.343,3.203 c2.803,0,5.127-1.094,6.962-3.203C90.461,123.679,91.34,121.257,91.34,118.366L91.34,118.366z M101.574,74.018 c-2.479-0.928-5.038-1.719-7.675-2.412c-2.637-0.625-5.352-1.172-8.153-1.416l3.759,26.008c0,0.313,0.244,0.469,0.801,0.469 L101.574,74.018L101.574,74.018z M57.701,126.716l-26.854-4.053c0.557,5.303,1.914,10.147,4.16,14.601l23.25-9.298L57.701,126.716 L57.701,126.716z M76.791,167.792l-4.15-26.466l-0.645-0.391l-10.624,22.95c1.68,1.094,4.003,1.953,6.875,2.578 C71.206,167.089,73.998,167.479,76.791,167.792L76.791,167.792z M35.007,100.104c-2.402,5.693-3.759,10.381-4.16,14.21l27.41-3.673 l0.244-0.625L35.007,100.104L35.007,100.104z M88.87,141.795l-3.524,25.997c2.479-0.313,5.038-0.703,7.597-1.328 s5.029-1.484,7.353-2.578l-10.79-22.56C89.504,141.639,89.26,141.795,88.87,141.795L88.87,141.795z M130.498,123.444l-26.043,3.896 l-0.166,0.781l22.059,9.767c1.113-2.422,1.992-4.844,2.559-7.188C129.541,128.278,130.107,125.856,130.498,123.444L130.498,123.444 z M76.791,70.189c-2.793,0.244-5.195,0.635-7.343,1.104c-2.158,0.469-4.395,1.162-6.796,1.943l10.233,22.961L76.791,70.189 L76.791,70.189z M130.498,114.313c-0.322-2.579-0.635-4.923-1.123-7.032c-0.469-2.109-1.191-4.297-1.992-6.563l-22.459,9.922 L130.498,114.313L130.498,114.313z M131.298,98.229c-2.471-6.095-6.151-11.554-11.024-16.319 c-4.795-4.844-10.155-8.751-15.985-11.72l-1.279,2.666c11.825,6.241,20.458,15.069,26.053,26.613L131.298,98.229L131.298,98.229z M61.216,71.439l-1.279-1.865c-6.64,2.412-12.392,6.084-17.264,10.851C37.8,85.269,34.05,90.972,31.248,97.682l2.714,1.006 C39.079,86.206,48.189,77.144,61.216,71.439L61.216,71.439z M128.183,139.529c-6.474,12.179-15.35,20.685-26.609,25.372l1.27,2.5 c12.704-6.016,22.06-14.834,28.055-26.622L128.183,139.529L128.183,139.529z M58.745,167.167l1.426-2.422 c-5.986-2.422-11.259-5.859-15.897-10.303c-4.717-4.376-8.154-9.679-10.556-15.929l-2.714,0.781 C36.677,152.177,45.953,161.464,58.745,167.167L58.745,167.167z M81.996,107.203c1.279,0.234,2.549,0.703,3.838,1.25 c1.348,0.469,2.313,1.094,3.036,1.797l5.029-4.922c-1.992-1.719-3.828-2.891-5.674-3.516c-1.757-0.625-3.837-1.016-6.229-1.094 V107.203L81.996,107.203z M80.794,100.719c-4.472,0.234-8.388,2.031-11.913,5.469l4.794,4.063c1.279-1.094,2.402-1.797,3.369-2.109 c0.957-0.391,2.148-0.703,3.75-0.938V100.719L80.794,100.719z M99.739,117.985c-0.322-2.344-0.811-4.376-1.523-6.173 c-0.635-1.875-1.836-3.75-3.516-5.625l-4.951,4.453c2.158,2.188,3.271,4.61,3.271,7.345H99.739L99.739,117.985z M99.739,119.382 H93.02c-0.234,1.641-0.479,2.891-0.723,3.896c-0.156,0.947-0.879,1.963-1.992,3.047l4.15,4.453 C97.415,127.966,99.172,124.147,99.739,119.382L99.739,119.382z M63.296,119.382c0.156,2.188,0.635,4.297,1.435,6.318 c0.879,2.031,2.07,3.828,3.76,5.469l4.15-4.453c-1.123-1.084-1.835-2.266-2.314-3.584c-0.4-1.25-0.566-2.5-0.566-3.75H63.296 L63.296,119.382z M81.996,136.248c2.393,0,4.385-0.391,6.151-1.172c1.758-0.859,3.594-2.031,5.518-3.516l-4.16-4.454 c-1.123,0.703-2.079,1.328-2.792,1.875c-0.801,0.469-2.324,1.016-4.717,1.406V136.248L81.996,136.248z M80.794,130.388 c-3.115,0-5.429-1.016-7.119-3.047l-4.384,4.454c1.67,1.328,3.427,2.422,5.195,3.281c1.836,0.781,3.906,1.172,6.308,1.172V130.388 L80.794,130.388z M69.76,117.985c0-2.734,0.957-5.157,2.88-7.345l-4.56-3.828c-1.436,1.719-2.471,3.438-3.35,5.156 c-0.8,1.719-1.279,3.673-1.435,6.017H69.76L69.76,117.985z M135.458,122.663l-3.125,0.615c-0.078,2.666-0.557,5.313-1.191,7.813 c-0.723,2.501-1.602,5.079-2.725,7.813l2.48,1.25C133.701,134.451,135.214,128.591,135.458,122.663L135.458,122.663z M84.955,66.137l0.391,2.422c2.88,0.156,5.751,0.625,8.632,1.406c2.871,0.859,5.674,1.709,8.397,2.646l1.279-2.646 c-3.037-0.938-6.151-1.797-9.276-2.5C91.262,66.693,88.147,66.293,84.955,66.137L84.955,66.137z M76.791,169.043 c-5.273-0.548-10.625-1.954-15.976-4.142l-1.035,2.5c4.717,2.579,10.546,4.063,17.421,4.454L76.791,169.043L76.791,169.043z M85.345,169.043l-0.635,2.813c3.202-0.156,6.151-0.547,8.876-1.328c2.705-0.781,5.43-1.72,8.222-2.97l-0.645-2.422 C96.135,167.479,90.862,168.729,85.345,169.043L85.345,169.043z M135.458,114.704c-0.088-2.657-0.557-5.313-1.201-7.892 c-0.723-2.578-1.592-5.234-2.715-7.959l-2.08,1.25c0.713,2.256,1.279,4.678,1.836,7.178c0.566,2.5,0.957,4.922,1.035,7.267 L135.458,114.704L135.458,114.704z M33.483,137.498c-1.601-3.281-2.636-5.859-2.949-7.735c-0.41-1.875-0.732-4.287-0.967-7.1 l-3.115-0.625c0.244,2.969,0.8,5.771,1.513,8.428c0.801,2.657,1.758,5.392,2.881,8.282L33.483,137.498L33.483,137.498z M26.453,114.704l3.115-0.156c0.234-3.126,0.723-5.86,1.357-8.282c0.635-2.344,1.514-4.609,2.558-6.797l-2.48-1.24 C28.767,103.531,27.253,109,26.453,114.704L26.453,114.704z M77.201,66.137c-2.715,0.156-5.518,0.391-8.232,0.781 c-2.637,0.469-5.439,1.172-8.154,2.266l0.801,2.031c2.393-0.703,4.794-1.25,7.353-1.797c2.626-0.547,5.273-0.938,8.076-1.016 L77.201,66.137z" /> <text transform="matrix(1 0 0 1 77 37)" fill="#fdfdfd" font-family="Arial" font-size="12">N</text> </g> </svg> </div> <ul class="mnu"> <li><a href="#" onclick="openShp();">shp열기(용적율계산으로 허용가능건물모양))</a></li> <!--<li><a href="#" onclick="setVisible(this, 'acceptableLayer');" id="divVisible" style="display:none;">레이어숨기기</a></li>--> <li><a href="#" onclick="openBuildableShp();" id="divBuildable" style="display:none;">건축가능필지공간</a></li> <!--<li><a href="#" onclick="setVisible(this, 'buildableLayer');" id="divBuildVisible" style="display:none;">레이어숨기기</a></li>--> <li><a href="#" onclick="openFolderShp(4, 'shp_buildable.zip')">포디움</a></li> <li><a href="#" onclick="openFolderShp(5, 'shp_buildable.zip')">판상형 등</a></li> </ul> </body> </html>