123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170 |
- <%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
- <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
- <%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
- <%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
- <%@ page import="java.text.NumberFormat" %>
- <section class="main-container">
- <!-- 좌측목록 지도 영역 -->
- <article class="left-Area">
- <ul class="sub-Tab">
- <li class="on"><a href="#">소통통계</a></li>
- <%-- <li><a href="#">교차로교통량</a></li>--%>
- </ul>
- <div class="left-list">
- <div class="condition-box">
- <div class="search-box">
- <input type="text" autocomplete="off" placeholder="검색어를 입력해주세요" id="searchText" alt="교차로 검색" onkeyup="searchEvent(event)">
- <div id="searchBtn" onclick="searchEvent()">조회</div>
- </div>
- <div class="condition">
- <div class="list-box">
- <c:if test="${atrdNmList.size() > 0}">
- <c:forEach var="item" items="${atrdNmList}" varStatus="status">
- <input type="checkbox" value="${item.atrd_id}" id="atrd_${item.atrd_id}" style="display: none;" title="${item.atrd_nm}">
- <label for="atrd_${item.atrd_id}" ondblclick="moveEvent('selected-atrd', 'list-box')" onclick="atrdTrfInfo('${item.atrd_id}')" title="${item.atrd_nm}">${item.atrd_nm}</label>
- </c:forEach>
- </c:if>
- </div>
- <div class="list-select">
- <select name="infoList" id="infoList" onchange="optionChange(this)">
- <option>도로목록</option>
- <c:if test="${atrdNmList.size() > 0}">
- <c:forEach var="item" items="${atrdNmList}" varStatus="status">
- <option value="${item.atrd_id}">${item.atrd_nm}</option>
- </c:forEach>
- </c:if>
- </select>
- <label for="infoList" style="display: none;"></label>
- </div>
- </div>
- <div class="button-box">
- <div>
- <div onclick="moveEvent('selected-atrd', 'list-box')">▼</div>
- <div onclick="moveEvent('list-box', 'selected-atrd')">▲</div>
- </div>
- <div>
- <div onclick="totMoveEvent('selected-atrd', 'list-box')">전체선택</div>
- <div onclick="totMoveEvent('list-box', 'selected-atrd')">전체해제</div>
- </div>
- </div>
- <div class="condition selected-atrd">
- <div>
- <c:if test="${atrdNmList.size() > 0}">
- <c:forEach var="item" items="${atrdNmList}" varStatus="status">
- <input type="checkbox" value="${item.atrd_id}" id="atrd_${item.atrd_id}_selected" style="display: none;" title="${item.atrd_nm}">
- <label for="atrd_${item.atrd_id}_selected" style="display: none;" ondblclick="moveEvent('list-box', 'selected-atrd')" onclick="atrdTrfInfo('${item.atrd_id}')" title="${item.atrd_nm}">${item.atrd_nm}</label>
- </c:forEach>
- </c:if>
- </div>
- </div>
- <div class="condition statisticList">
- <select name="sTimeType" id="sTimeType">
- <option value="sTime">시통계</option>
- <option value="sDay">일통계</option>
- <option value="sMonth">월통계</option>
- <option value="sYear">년통계</option>
- </select>
- <label for="sTimeType"></label>
- </div>
- <div class="condition2 statisticList">
- <label>검색선택</label>
- <span>
- <select id="infoYear" name="year" class="statis-search-select" onchange="selectDateChanger(true, false)" style="width: 70px;">
- <c:forEach begin="2022" end="${thisYear}" varStatus="status">
- <option value="${status.current}" <c:if test="${status.current == thisYear}">selected</c:if>>${status.current}</option>
- </c:forEach>
- </select>
- <label for="infoYear">년</label>
- <select id="infoMonth" name="month" class="statis-search-select" style="width: 50px;" onchange="selectDateChanger(false, false)">
- <c:forEach begin="1" end="${thisMonth}" varStatus="status">
- <option value="<fmt:formatNumber pattern="00" value="${status.current}"/>" <c:if test="${status.current == thisMonth}">selected</c:if>><fmt:formatNumber pattern="00" value="${status.current}"/></option>
- </c:forEach>
- </select>
- <label for="infoMonth" class="infoMonth">월</label>
- <select id="infoDate" name="date" class="statis-search-select" style="width: 50px;">
- <c:forEach begin="1" end="${thisDate}" varStatus="status">
- <option value="<fmt:formatNumber pattern="00" value="${status.current}"/>" <c:if test="${status.current == (thisDate - 1)}">selected</c:if>><fmt:formatNumber pattern="00" value="${status.current}"/></option>
- </c:forEach>
- </select>
- <label for="infoDate" class="infoDate">일</label>
- <select id="infoHour" name="hour" class="statis-search-select" style="width: 50px;">
- <c:forEach begin="0" end="23" varStatus="status">
- <option value="<fmt:formatNumber pattern="00" value="${status.current}"/>" <c:if test="${status.current == 0}">selected</c:if>><fmt:formatNumber pattern="00" value="${status.current}"/></option>
- </c:forEach>
- </select>
- <label for="infoHour" class="infoHour">시</label>
- </span>
- <span>~</span>
- <span>
- <select id="infoYear2" name='year2' class="statis-search-select" style="width: 70px;" onchange="selectDateChanger(true, true)">
- <c:forEach begin="2022" end="${thisYear}" varStatus="status">
- <option value="${status.current}" <c:if test="${status.current == thisYear}">selected</c:if>>${status.current}</option>
- </c:forEach>
- </select>
- <label for="infoYear2">년</label>
- <select id="infoMonth2" name='month2' class="statis-search-select" style="width: 50px;" onchange="selectDateChanger(false, true)">
- <c:forEach begin="1" end="${thisMonth}" varStatus="status">
- <option value="<fmt:formatNumber pattern="00" value="${status.current}"/>" <c:if test="${status.current == thisMonth}">selected</c:if>><fmt:formatNumber pattern="00" value="${status.current}"/></option>
- </c:forEach>
- </select>
- <label for="infoMonth2" class="infoMonth2">월</label>
- <select id="infoDate2" name='date2' class="statis-search-select" style="width: 50px;">
- <c:forEach begin="1" end="${thisDate}" varStatus="status">
- <option value="<fmt:formatNumber pattern="00" value="${status.current}"/>" <c:if test="${status.current == (thisDate - 1)}">selected</c:if>><fmt:formatNumber pattern="00" value="${status.current}"/></option>
- </c:forEach>
- </select>
- <label for="infoDate2" class="infoDate2">일</label>
- <select id="infoHour2" name='hour2' class="statis-search-select" style="width: 50px;">
- <c:forEach begin="0" end="23" varStatus="status">
- <option value="<fmt:formatNumber pattern="00" value="${status.current}"/>" <c:if test="${status.current == 23 }">selected</c:if>><fmt:formatNumber pattern="00" value="${status.current}"/></option>
- </c:forEach>
- </select>
- <label for="infoHour2" class="infoHour2">시</label>
- </span>
- </div>
- <div class="btn-box statisticList">
- <button type="button" value="통계조회" class="btn-main search-btn" onclick="selectData()">통계 조회</button>
- </div>
- <div class="btn-box statisticList">
- <button type="button" value="엑셀" class="btn-sub excel-btn" onclick="excelDown()">엑셀 저장</button>
- <button type="button" value="엑셀" class="btn-sub csv-btn" onclick="csvDown()">텍스트 저장</button>
- <a class='csv-a' style="display:none;"></a>
- </div>
- <div style="display: flex; gap: 10px; align-items: center; justify-content: flex-end; margin-top: 5px; padding: 2px; margin-left: auto;">
- <label for="limit" style="font-size: 16px;">조회된 라인 수</label><input style="width: 150px; box-sizing: border-box; padding-right: 10px; text-align: right;" id="limit" disabled type="text" name="limit" value="0" title="조회된 라인 수">
- </div>
- </div>
- </div>
- </article>
- <!-- // 좌측목록 지도 영역 -->
- <!-- 서브 지도 영역 -->
- <article class="mapArea statistics">
- <div id="statistics_map">
- </div>
- <div class="move-up" onclick="move(this)"></div>
- <div class="mapContent statistics">
- <div class="check-text">※ 속도와 통행시간 확인 후 이용하시기 바랍니다.</div>
- <div class="road_info-box sub-road_info">
- <img alt="loading" src="/images/ajax_loading.gif" id="loading" style="display:none;position:absolute;left:calc(50% - 25px);top:calc(50%);z-index:10; width: 50px; height: 50px;"/>
- <table id ="info-road-list" class="info-road-list">
- <colgroup>
- <col width="20%">
- <col width="30%">
- <col width="20%">
- <col width="15%">
- <col width="15%">
- </colgroup>
- <thead>
- <tr>
- <th scope="col">도로명</th>
- <th scope="col">구간</th>
- <th scope="col">통계시각</th>
- <th scope="col">속도(km/h)</th>
- <th scope="col">통행시간(sec)</th>
- </tr>
- </thead>
- <tbody class="content">
- <tr>
- <td colspan="5" class="nodata" style="height:155px; text-align: center;">표출할 정보가 없습니다.</td>
- </tr>
- </tbody>
- </table>
- <div class="pagination"></div>
- </div>
- </div>
- </article>
- <!-- // 서브 지도 영역 -->
- </section>
- <script type="text/javascript" src="//dapi.kakao.com/v2/maps/sdk.js?appkey=${key}"></script>
- <script src="/js/xlsx-0.18.12.min.js"></script>
- <script src="/js/fileSaver-1.3.8.min.js"></script>
- <script type="text/javascript">
- let _statLimit = ${statLimit};
- let atrdList = '${atrdNmList}';
- let _AtrdSideMarkerArr = [];
- let _FwdLineArr = [];
- let _BwdLineArr = [];
- let _prevLevel = 0;
- let _atrdMap = new Map();
- let _atrdMarkerArr = [];
- let _RoadPolyArr = [];
- let _RoadPolyBackArr = [];
- let _beforeLevel;
- let _seletData = [];
- let _type = null;
- const regex = /atrd_id=([\w,]+).*?road_count=(\w+)/g;
- const idToRoadCountMap = new Map();
- for (const match of atrdList.matchAll(regex)) {
- let ids = match[1].slice(0, -1);
- let roadCount = Number(match[2]);
- if (ids.split(",").length > 2) {
- roadCount = (Number(match[2])/ids.split(",").length) * 2;
- }
- idToRoadCountMap.set(ids, roadCount);
- }
- const mapContainer = document.getElementById('statistics_map'), // 지도를 표시할 div
- mapOption = {
- center: new kakao.maps.LatLng('37.01423130393533', '126.93995173968553'), // 평택지도의 중심좌표
- maxLevel: 9,
- minLevel: 6,
- level: 10, // 지도의 확대 레벨
- disableDoubleClickZoom: true
- };
- function move(el) {
- $('.mapContent.statistics').toggleClass('on');
- $('#statistics_map').toggleClass('on');
- $(el).toggleClass('on');
- }
- function optionChange(el) {
- const value = $(el).val();
- totMoveEvent('list-box', 'selected-ixr');
- if (value) {
- $('label[for="ixr_'+value+'"]').click();
- $('label[for="ixr_'+value+'"]').dblclick();
- }
- }
- /**
- * 좌측 상단 도로명 위, 아래 이동 이벤트
- * @param show 보여주는 박스
- * @param hide 가리는 박스
- */
- function moveEvent(show, hide) {
- const hideEl = $("." + hide + ' input[type="checkbox"]:checked');
- const hideLabel = hideEl.next();
- const showEl = $('.' + show + ' input[value="'+hideEl.val()+'"]');
- const showLabel = showEl.next();
- hideLabel.css('display', 'none');
- showLabel.css('display', 'inline-block');
- showEl.prop('checked', true);
- }
- /**
- * 좌측 상단 도로명 전체 선택, 해제 이벤트
- * @param show 보여주는 박스
- * @param hide 가리는 박스
- */
- function totMoveEvent(show, hide) {
- const showEl = $("." + show + ' input[type="checkbox"]');
- const showLabel = showEl.next();
- const hideEl = $("." + hide + ' input[type="checkbox"]');
- const hideLabel = hideEl.next();
- hideLabel.css('display', 'none');
- showLabel.css('display', 'inline-block');
- const checked = $('.' + hide + ' input[type="checkbox"]:checked');
- if (checked.length) {
- $('.' + show + ' input[value="'+checked.val()+'"]').prop('checked', true);
- }
- }
- _Map = new kakao.maps.Map(mapContainer, mapOption);
- const mapTypeControl = new kakao.maps.MapTypeControl();
- const zoomControl = new kakao.maps.ZoomControl();
- _Map.addControl(mapTypeControl, kakao.maps.ControlPosition.RIGHT);
- _Map.addControl(zoomControl, kakao.maps.ControlPosition.RIGHT);
- kakao.maps.event.addListener(_Map, 'zoom_changed', function () {
- // 지도의 현재 레벨을 얻어옵니다
- _Level = _Map.getLevel();
- drawRoadMap();
- });
- kakao.maps.event.addListener(_Map, 'dragend', function () {
- drawRoadMap();
- });
- getAtrdInfo();
- /**
- * 도로 정보
- */
- function getAtrdInfo() {
- $.ajax({
- type: "POST",
- contentType:"application/x-www-form-urlencoded;charset=utf-8",
- url: '/common/getRoadVertexArr.do',
- success: function (data) {
- if (data && data.length) {
- data.forEach((obj)=>{
- if (!_atrdMap.get(obj.levl)) {
- _atrdMap.set(obj.levl, new Map());
- _atrdMap.get(obj.levl).set("markerObj", []);
- }
- const polyObj = new PolyObj(obj);
- _atrdMap.get(obj.levl).get("markerObj").push(polyObj);
- if (obj.atrd_id) {
- if (!_atrdMap.get(obj.levl).get(obj.atrd_id)) {
- _atrdMap.get(obj.levl).set(obj.atrd_id, []);
- }
- _atrdMap.get(obj.levl).get(obj.atrd_id).push(polyObj);
- }
- });
- }
- },
- complete: function () {
- drawRoadMap()
- },
- error: function (request, status, error) {
- },
- });
- }
- function getAtrdLevel() {
- let level = _Level;
- if (level <= 7) {
- level = 5;
- }
- else {
- level = 6;
- }
- return level;
- }
- /**
- * 도로 표출 Object
- */
- class PolyObj {
- constructor(obj) {
- this.atrd_id = obj.atrd_id;
- this.road_nm = obj.road_nm;
- this.strt_nm_node = obj.strt_nm_node;
- this.end_nm_node = obj.end_nm_node;
- this.sect_lngt = obj.sect_lngt;
- this.levl = obj.levl;
- this.x_crdn = obj.x_crdn;
- this.y_crdn = obj.y_crdn;
- this.y_crdn_min = obj.y_crdn_min;
- this.y_crdn_max = obj.y_crdn_max;
- this.x_crdn_min = obj.x_crdn_min;
- this.x_crdn_max = obj.x_crdn_max;
- this.road_ord = obj.road_ord;
- this.obj = obj;
- this.polyline = null;
- this.polylineBack = null;
- this.content = null;
- this.marker = null;
- this.makeMarkers();
- this.isClick = false;
- }
- makeMarkers() {
- let xCrdnArr = this.x_crdn.split(',');
- let yCrdnArr = this.y_crdn.split(',');
- let linePath = [];
- for (let ii = 0; ii < xCrdnArr.length; ii++) {
- linePath.push(new daum.maps.LatLng(yCrdnArr[ii], xCrdnArr[ii]));
- }
- const cmtrGradColor = '#00981e';
- let strokeWeight = 3;
- let strokeWeightBack = 5;
- let size = 48;
- let imageName = this.obj.drct_cd === '상행' ? 'S' : 'E';
- if (this.levl > 6) {
- strokeWeight = 2;
- strokeWeightBack = 4;
- size = 24;
- }
- this.polyline = new daum.maps.Polyline({
- path: linePath,
- strokeWeight: strokeWeight,
- strokeColor: cmtrGradColor,
- strokeOpacity: 1,
- strokeStyle: 'solid',
- zIndex: 2,
- });
- this.polylineBack = new daum.maps.Polyline({
- path: linePath,
- strokeWeight: strokeWeightBack,
- strokeColor: '#FFFFFF',
- strokeOpacity: 1,
- strokeStyle: 'solid',
- zIndex: 1,
- });
- if (this.road_ord === 1) {
- const imageSrc = '/images/traffic/map-marker' + imageName + '.png';
- const imageSize = new daum.maps.Size(size, size);
- const imageOption = {
- offset: new daum.maps.Point(size/2, size)
- };
- const markerImage = new daum.maps.MarkerImage(imageSrc, imageSize, imageOption);
- const markerPosition = new daum.maps.LatLng(yCrdnArr[0], xCrdnArr[0]); // 마커가 표시될 위치입니다
- this.marker = new daum.maps.Marker({position: markerPosition, image: markerImage, zIndex: 5});
- }
- const obj = this;
- let sectLngt = obj.sect_lngt;
- if (sectLngt && !isNaN(Number(sectLngt))) {
- sectLngt = sectLngt.toString().replace(/\B(?<!\.\d*)(?=(\d{3})+(?!\d))/g, ",");
- }
- this.content = '<div class="mapPop traffic_LTC0">'
- + '<div class="head"><span class="title">' + obj.road_nm + '</span></div>'
- + '<div class="cont"><dl>'
- + '<dt>[ ' + obj.strt_nm_node + ' ] 부터<br/>[ ' + obj.end_nm_node + ' ] 까지</dt>'
- + '<dd>구간거리 : ' + sectLngt + ' m</dd>'
- + '</dl></div>';
- daum.maps.event.addListener(this.polyline, 'mouseover', function (mouseEvent) {
- const beforeOver = $('.mapPop.traffic_LTC0')
- if (beforeOver.length) beforeOver.remove();
- this.setOptions({strokeColor: 'blue'});
- const overlay = $(obj.content);
- $('.main-container').append(overlay);
- daum.maps.event.addListener(obj.polyline, 'mouseout', function (mouseEvent) {
- if (overlay) {
- overlay.remove();
- }
- this.setOptions({strokeColor: cmtrGradColor});
- });
- });
- }
- /**
- * 지도 표출 선 색상 변경(선택)
- */
- setSelectStyle() {
- if (this.polylineBack) {
- this.polylineBack.setOptions({
- zIndex : 3,
- strokeColor : '#000000',
- })
- }
- if (this.polyline) {
- this.polyline.setOptions({zIndex : 4})
- }
- if (this.marker) {
- this.marker.setMap(_Map);
- this.isClick = true;
- }
- }
- /**
- * 지도 표출 선 색상 변경(기본)
- */
- setDefaultStyle() {
- if (this.polylineBack) {
- this.polylineBack.setOptions({
- zIndex : 1,
- strokeColor : '#FFFFFF',
- })
- }
- if (this.polyline) {
- this.polyline.setOptions({zIndex : 2})
- }
- if (this.marker) {
- this.marker.setMap(null);
- this.isClick = false;
- }
- }
- /**
- * 보이기/숨기기
- * @param isShow : _Map or null
- */
- showHide(isShow) {
- if (this.polylineBack) {
- this.polylineBack.setMap(isShow);
- }
- if (this.polyline) {
- this.polyline.setMap(isShow);
- }
- if (this.marker && this.isClick) {
- this.marker.setMap(isShow);
- }
- }
- }
- /**
- * 지도에 도로 표출
- */
- function drawRoadMap() {
- let level = getAtrdLevel();
- if (level === _beforeLevel) return; //이전 레벨과 레벨이 같다면 안그림
- if (_beforeLevel) { // 기존께 있다면 지움
- const markerArr = _atrdMap.get(_beforeLevel).get("markerObj");
- markerArr.forEach((marker)=>{
- marker.showHide(null);
- });
- }
- _beforeLevel = level;
- const currentMarkerArr = _atrdMap.get(level).get("markerObj");
- currentMarkerArr.forEach((marker)=>{
- marker.showHide(_Map);
- });
- }
- /**
- * 선택 해제(기본 스타일로 변경)
- * @param atrdId 선택 해제 간선도로 ID
- */
- function removeLines(atrdId) {
- if (_AtrdId && _AtrdId.length) {
- const atrdArr = atrdId.split(",");
- if (atrdArr[0] !== _AtrdId[0]) {
- _AtrdId.forEach((atrd)=>{
- setStyle(_atrdMap.get(5).get(atrd), "setDefaultStyle");
- setStyle(_atrdMap.get(6).get(atrd), "setDefaultStyle");
- });
- }
- }
- }
- function setStyle(arr, method) {
- if (arr && arr.length) {
- arr.forEach((line)=>{
- line[method]();
- })
- }
- }
- function atrdTrfInfo(atrdId) {
- if (!atrdId && !atrdId.includes(",")) return;
- if ($(document.getElementById(atrdId)).is(':checked') || $(document.getElementById(atrdId + '_selected')).is(':checked')) return;
- $('.condition input[type="checkbox"]').prop("checked", false);
- removeLines(atrdId);
- _AtrdId = atrdId.split(',');
- if (_AtrdId.length < 2) return;
- const bounds = new daum.maps.LatLngBounds();
- for (let ii = 0; ii < 2; ii++) {
- const atrd = _AtrdId[ii];
- const atrd5 = _atrdMap.get(5).get(atrd);
- const atrd6 = _atrdMap.get(6).get(atrd);
- for (let jj = 0; jj < atrd5.length; jj++) {
- const polyObj = atrd5[jj];
- bounds.extend(new daum.maps.LatLng(polyObj.y_crdn_min, polyObj.x_crdn_min));
- bounds.extend(new daum.maps.LatLng(polyObj.y_crdn_max, polyObj.x_crdn_max));
- }
- setStyle(atrd5, "setSelectStyle");
- setStyle(atrd6, "setSelectStyle");
- }
- _Map.setBounds(bounds);
- }
- function excelDown(){
- if (!_seletData || !_seletData.list || !_seletData.list.length) {
- return alert('조회된 교차로 교통량 정보가 없습니다.');
- }
- exportExcel();
- }
- function exportExcel() {
- const fileName = '소통통계 - '+ $('option[value="'+_type+'"]').text() + '_' + nowTime() + '.xlsx';
- const link = document.createElement('a');
- const blob = base64ToBlob(_seletData.excel, 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
- const url = URL.createObjectURL(blob);
- link.href = url;
- link.download = fileName; // 다운로드할 파일 이름 설정
- link.click();
- URL.revokeObjectURL(url); // URL 객체 해제
- }
- function base64ToBlob(base64, mimeType) {
- const byteCharacters = atob(base64); // Base64를 디코딩
- const byteArrays = [];
- for (let offset = 0; offset < byteCharacters.length; offset += 1024) {
- const slice = byteCharacters.slice(offset, offset + 1024);
- const byteNumbers = new Array(slice.length);
- for (let i = 0; i < slice.length; i++) {
- byteNumbers[i] = slice.charCodeAt(i);
- }
- const byteArray = new Uint8Array(byteNumbers);
- byteArrays.push(byteArray);
- }
- return new Blob(byteArrays, { type: mimeType });
- }
-
- function csvDown(){
- if (!_seletData || !_seletData.list || !_seletData.list.length) {
- return alert('조회된 교차로 교통량 정보가 없습니다.');
- }
- const csv = [];
- const row = [];
-
- //1열에는 컬럼명
- row.push(
- "도로명",
- "구간",
- "통계시각",
- "속도(km/h)",
- "통행시간(sec)"
- );
-
- csv.push(row.join(","));
- for (let obj of _seletData.list) {
- const statDt = obj.stat_dt;
- let prcnDt = '-';
- if (statDt) {
- const yyyy = statDt.substring(0,4);
- const mm = statDt.substring(4,6);
- const dd = statDt.substring(6,8);
- const hh = statDt.substring(8,10);
- const mi = statDt.substring(10,12);
- const ss = statDt.substring(12,14);
- if (_type === 'sYear') {
- prcnDt = yyyy + '년';
- }
- else if (_type === 'sMonth') {
- prcnDt = yyyy + '년 ' + mm + '월';
- }
- else if (_type === 'sDay') {
- prcnDt = yyyy + '/' + mm + '/' + dd;
- }
- else {
- prcnDt = yyyy + '/' + mm + '/' + dd + ' ' + hh + ':' + mi + ':' + ss;
- }
- }
- const row = [
- obj.road_nm + "," +
- obj.strt_nm + " - " + obj.end_nm + "," +
- prcnDt + "," +
- obj.sped + "," +
- obj.trvl_hh
- ]
- csv.push(row);
- }
- csv = csv.join("\n");
- const filename = '소통통계 - ' + $('option[value="'+_type+'"]').text() + '_' + nowTime() + '.csv';
-
- //한글 처리를 해주기 위해 BOM 추가하기
- const BOM = "\uFEFF";
- csv = BOM + csv;
-
- const csvFile = new Blob([csv], { type: "text/csv" });
- const downloadLink = document.querySelector(".csv-a");
- downloadLink.download = filename;
- downloadLink.href = window.URL.createObjectURL(csvFile);
- downloadLink.style.display = "none";
- document.body.appendChild(downloadLink);
- downloadLink.click();
- downloadLink.remove();
- }
- function nowTime() {
- let now = new Date();
- let year = now.getFullYear().toString();
- let month = timeFormmater(now.getMonth() + 1).toString();
- let date = timeFormmater(now.getDate()).toString();
- let hour = timeFormmater(now.getHours()).toString();
- let minutes = timeFormmater(now.getMinutes()).toString();
- let seconds = timeFormmater(now.getSeconds()).toString();
- return year + month + date + hour + minutes + seconds;
- }
-
- //시간 한자리 경우 2자리로 세팅
- function timeFormmater(time) {
- let result = time < 10 ? "0" + time.toString() : time.toString();
- return result;
- }
- /**
- * 통계 타입에 따른 보이기 감추기
- * @param visible 보이는 목록
- * @param hide 가리는 목록
- */
- function inputVisible(visible, hide) {
- if (visible && visible.length) {
- visible.forEach((el)=>{
- $('#' + el).show();
- $('.' + el).show();
- });
- }
- if (hide && hide.length) {
- hide.forEach((el)=>{
- $('#' + el).hide();
- $('.' + el).hide();
- });
- }
- }
- $('#sTimeType').change(function(){
- let sTimeTypeVal = $('#sTimeType option:selected').val();
- if (sTimeTypeVal === 'sDay') {
- inputVisible(['infoMonth', 'infoDate', 'infoMonth2', 'infoDate2'], ['infoHour', 'infoHour2']);
- }
- else if (sTimeTypeVal === 'sMonth') {
- inputVisible(['infoMonth', 'infoMonth2'], ['infoDate', 'infoDate2', 'infoHour', 'infoHour2']);
- }
- else if (sTimeTypeVal === 'sYear') {
- inputVisible([], ['infoMonth', 'infoMonth2', 'infoDate', 'infoDate2', 'infoHour', 'infoHour2']);
- }
- else {
- inputVisible(['infoMonth', 'infoMonth2', 'infoDate', 'infoDate2', 'infoHour', 'infoHour2'], []);
- }
- });
- // let sTimeTypeVal = 'sTime';
- let _AtrdNm= ''
- function btnActiveState(stts){
- const searchBtn = $('.btn-main.search-btn');
- const excelBtn = $('.btn-sub.excel-btn');
- const csvBtn = $('.btn-sub.csv-btn');
- searchBtn.prop('disabled', stts);
- excelBtn.prop('disabled', stts);
- csvBtn.prop('disabled', stts);
- }
-
- function selectData(){
- const type = $('#sTimeType').val();
- const selectList = $('.list-select');
- // let ids = "";
- let ids = [];
- let checkIds = [];
- if (selectList.css('display') === 'none') {
- const checkArr = $('.selected-atrd input[type="checkbox"]');
- for (let ii = 0; ii < checkArr.length; ii++) {
- const check = checkArr.eq(ii);
- if (check.next().css('display') !== 'none') {
- // console.log(check.val());
- const atrdIds = check.val();
- checkIds.push(atrdIds);
- if (atrdIds.includes(',')) {
- const arr = atrdIds.split(',');
- ids.push(arr[0], arr[1]);
- }
- }
- }
- }
- else {
- const infoList = $('#infoList');
- if (infoList.val().includes(',')) {
- const atrdIds = infoList.val().split(',');
- checkIds.push(infoList.val());
- ids.push(atrdIds[0], atrdIds[1]);
- }
- }
- const selectSize = ids.length;
- if (selectSize === 0) return alert('도로목록을 선택해주세요.');// 선택 도로목록 확인
- const year2El = $("#infoYear2");
- const month2El = $("#infoMonth2");
- const date2El = $("#infoDate2");
- const hour2El = $("#infoHour2");
- let year = $("#infoYear").val();
- let month = $("#infoMonth").val();
- let date = $("#infoDate").val();
- let hour = $("#infoHour").val();
- let year2 = year2El.val();
- let month2 = month2El.val();
- let date2 = date2El.val();
- let hour2 = hour2El.val();
- let from, to, fromDate, toDate, fromDateWord;
- if (type === 'sTime') {
- from = year+month+date+hour + '0000';
- to = year2+month2+date2+hour2 + '5959';
- toDate = new Date(year2 + "-" +month2 + "-" + date2 + " " + hour2 + ":59:59");
- fromDateWord = year + "-" +month + "-" + date + " " + hour + ":00:00";
- fromDate = new Date(fromDateWord);
- fromDate.setDate(new Date(fromDate).getDate() - 1);
- fromDate.setSeconds(new Date(fromDate).getSeconds() - 1);
- }
- else if (type === 'sDay') {
- from = year+month+date + '000000';
- to = year2+month2+date2 + '235959';
- toDate = new Date(year2 + "-" +month2 + "-" + date2 + " 23:59:59");
- fromDateWord = year + "-" +month + "-" + date + " 00:00:00";
- fromDate = new Date(fromDateWord);
- fromDate.setDate(new Date(fromDate).getDate() - 1);
- fromDate.setSeconds(new Date(fromDate).getSeconds() - 1);
- }
- else if (type === 'sMonth') {
- const lastDate = new Date(year2, month2, 0);
- const last = lastDate.getDate();
- from = year+month + '01000000';
- to = year2+month2 + last + '235959';
- toDate = new Date(year2 + "-" +month2 + "-" + last + " 23:59:59");
- fromDateWord = year + "-" +month + "-01 00:00:00";
- fromDate = new Date(fromDateWord);
- fromDate.setDate(new Date(fromDate).getDate() - 1);
- fromDate.setSeconds(new Date(fromDate).getSeconds() - 1);
- }
- else if (type === 'sYear') {
- from = year + '0101000000';
- to = year2 + '1231235959';
- }
-
- if (from > to) {
- return alert("검색 시작 일이 종료 일보다 큽니다.");
- }
- const limitDate = getLimitDate(selectSize, type, fromDate, checkIds);
- if (type !== 'sYear' && toDate > limitDate) {
- const yyyy = limitDate.getFullYear();
- const MM = String(limitDate.getMonth() + 1).padStart(2, '0');
- const dd = String(limitDate.getDate()).padStart(2, '0');
- const HH = String(limitDate.getHours()).padStart(2, '0');
- const mm = String(limitDate.getMinutes()).padStart(2, '0');
- const ss = String(limitDate.getSeconds()).padStart(2, '0');
- const formattedDate = `\${yyyy}-\${MM}-\${dd} \${HH}:\${mm}:\${ss}`;
- if (confirm("현재 조회 기간이 데이터 조회 최대 기간을 초과하였습니다. \n조회 기간을 변경하여 데이터를 조회" +
- "하시겠습니까?\n검색 기간 : " + fromDateWord + " ~ " + formattedDate)) {
- to = yyyy + MM + dd + HH + mm + ss;
- year2El.val(yyyy).change();
- month2El.val(MM).change();
- date2El.val(dd);
- hour2El.val(HH);
- }
- else {
- return;
- }
- }
- const params = {
- atrdIds : ids,
- from : from,
- to : to,
- type : type,
- }
- const tbody = $('.content');
- const pagination = $('.pagination');
- pagination.empty();
- tbody.empty();
- $('#limit').val(0);
- _seletData = null;
- $.ajax({
- type:'POST',
- url: "/statistics/getAtrdStat.do",
- traditional : true,
- data: params,
- success: function(data){
- _seletData = data;
- _type = type;
- const cnt = _seletData.list.length.toString().replace(/\B(?<!\.\d*)(?=(\d{3})+(?!\d))/g, ",");
- alert("데이터 " + cnt + "건이 조회되었습니다.");
- $('#limit').val(cnt);
- // let vertexData = data;
- },
- error : (error)=> {
- console.log(error);
- alert("데이터 조회중 오류가 발생했습니다.\n" + error.responseJSON.message);
- },
- beforeSend : function(){
- $('#loading').show();
- btnActiveState(true);
- },
- complete : function(){
- $('#loading').hide();
- btnActiveState(false);
- drawTable(1);
- // loadPage(1);
- }
- });
- }
- function appendDataToTable(startIndex, endIndex) {
- let str = '';
- const tbody = $('.content');
- const table = $('.info-road-list');
- if (_seletData.list.length === 0) {
- table.css('height', '100%');
- tbody.append($('<tr><td colspan="5" class="nodata" style="height:155px">표출할 정보가 없습니다.</td></tr>'));
- }
- else {
- table.css('height', 'auto');
- const paginatedData = _seletData.list.slice(startIndex, endIndex);
- paginatedData.forEach(item => {
- const row = document.createElement('tr');
- const statDt = item.stat_dt;
- const yyyy = statDt.substring(0,4);
- const mm = statDt.substring(4,6);
- const dd = statDt.substring(6,8);
- const hh = statDt.substring(8,10);
- const mi = statDt.substring(10,12);
- const ss = statDt.substring(12,14);
- let prcnDt;
- if (_type === 'sYear') {
- prcnDt = yyyy + '년';
- }
- else if (_type === 'sMonth') {
- prcnDt = yyyy + '년 ' + mm + '월';
- }
- else if (_type === 'sDay') {
- prcnDt = yyyy + '/' + mm + '/' + dd;
- }
- else {
- prcnDt = yyyy + '/' + mm + '/' + dd + ' ' + hh + ':' + mi + ':' + ss;
- }
- row.innerHTML = `<td>\${item.road_nm}</td>
- <td>\${item.strt_nm} - \${item.end_nm}</td>
- <td>\${prcnDt}</td>
- <td>\${item.sped} km/h</td>
- <td>\${item.trvl_hh}</td>`;
- tbody.append(row);
- });
- }
- }
- function loadPage(page) {
- const rowsPerPage = 10;
- const startIndex = (page - 1) * rowsPerPage;
- const endIndex = page * rowsPerPage;
- appendDataToTable(startIndex, endIndex);
- }
- //
- // let currentPage = 1;
- // const tableContainer = $('.road_info-box.sub-road_info');
- // tableContainer.on('scroll', ()=>{
- // if ($(this).scrollTop() + $(this).innerHeight() >= this.scrollHeight - 5) {
- // currentPage++;
- // loadPage(currentPage);
- // }
- // })
- function getLimitDate(selectSize, type, startDate, ids) {
- let tot = 0;
- for(let id of ids) {
- tot += idToRoadCountMap.get(id) || 0;
- }
- const limitRate = Math.floor(_statLimit / tot);
- const date = new Date(startDate);
- let setMethod = "Hours";
- if (type === 'sDay') {
- setMethod = "Date";
- }
- else if (type === 'sMonth') {
- setMethod = "Month";
- }
- return new Date(date["set" + setMethod](date["get" + setMethod]() + limitRate));
- }
- function drawTable(idx) {
- let str = '';
- const tbody = $('.content');
- const table = $('.info-road-list');
- const pagination = $('.pagination');
- pagination.hide();
- const rowsPerPage = 14;
- const pagesPerGroup = 10;
- if (!_seletData || !_seletData.list || _seletData.list.length === 0) {
- table.css('height', '100%');
- str = $('<tr><td colspan="5" class="nodata" style="height:155px">표출할 정보가 없습니다.</td></tr>');
- }
- else {
- table.css('height', 'auto');
- let start = (idx - 1) * rowsPerPage;
- let end = start + rowsPerPage;
- let max = _seletData.list.length;
- if (max < end) end = max;
- let pageStr = "";
- if (max > rowsPerPage) {
- const totalPage = Math.ceil(max / rowsPerPage);
- const currentGroup = Math.ceil(idx / pagesPerGroup);
- const startPage = (currentGroup - 1) * pagesPerGroup + 1;
- const endPage = Math.min(startPage + pagesPerGroup - 1, totalPage);
- pagination.css('display', 'flex');
- if (startPage > 10) {
- pageStr += "<div onclick='drawTable("+(startPage - 1)+")'>[PREV]</div>";
- }
- for (let ii = startPage; ii <= endPage; ii++) {
- let className = "";
- if (ii === idx) {
- className = "on";
- }
- pageStr += "<div class='"+className+"' onclick='drawTable("+ ii +")'>["+ii+"]</div>";
- }
- if (totalPage > endPage) {
- pageStr += "<div onclick='drawTable("+(endPage + 1)+")'>[NEXT]</div>";
- }
- pagination.html(pageStr);
- }
- for (let ii = start; ii < end; ii++) {
- const obj = _seletData.list[ii];
- const statDt = obj.stat_dt;
- let prcnDt = '-';
- if (statDt) {
- const yyyy = statDt.substring(0,4);
- const mm = statDt.substring(4,6);
- const dd = statDt.substring(6,8);
- const hh = statDt.substring(8,10);
- const mi = statDt.substring(10,12);
- const ss = statDt.substring(12,14);
- if (_type === 'sYear') {
- prcnDt = yyyy + '년';
- }
- else if (_type === 'sMonth') {
- prcnDt = yyyy + '년 ' + mm + '월';
- }
- else if (_type === 'sDay') {
- prcnDt = yyyy + '/' + mm + '/' + dd;
- }
- else {
- prcnDt = yyyy + '/' + mm + '/' + dd + ' ' + hh + ':' + mi + ':' + ss;
- }
- }
- str += '<tr>';
- str += '<td>'+obj.road_nm+'</td>';
- str += '<td>'+obj.strt_nm+' - '+obj.end_nm+'</td>';
- str += '<td>'+prcnDt+'</td>';
- str += '<td>'+obj.sped+'</td>';
- str += '<td>'+obj.trvl_hh+'</td>';
- str += '</tr>';
- }
- }
- tbody.html(str);
- }
- /**
- * 년도 날짜에 따른 월, 일 범위값 설정
- * @param(boolean) isSetMonth 일만 변경할건지
- */
- function selectDateChanger(isSetMonth, isTo) {
- const year = $("#infoYear");
- const month = $("#infoMonth");
- const day = $("#infoDate");
- const toYear = $("#infoYear2");
- const toMonth = $("#infoMonth2");
- const toDay = $("#infoDate2");
- let now = new Date();
- let nowDay = now.getDate();
- let nowYear = now.getFullYear();
- let nowMonth = now.getMonth() + 1;
- let dayVal = day.val();
- let monthVal = month.val();
- let yearVal = year.val();
- let monthEl = month;
- let dayEl = day;
- if (isTo) {
- dayVal = toDay.val();
- monthVal = toMonth.val();
- yearVal = toYear.val();
- monthEl = toMonth;
- dayEl = toDay;
- }
- let lastDate = new Date(yearVal, monthVal, 0);
- let minDay = lastDate.getDate();
- let minMonth = 12;
- if (nowYear.toString() === yearVal) {
- minMonth = nowMonth;
- if (nowMonth === Number(monthVal)) minDay = nowDay;
- }
- if (isSetMonth) {
- setSelectOption(minMonth, monthVal, monthEl);
- }
- setSelectOption(minDay, dayVal, dayEl);
- }
- /**
- * 날짜 Select Box option Setting
- * @param min 마지막 값
- * @param value 현재 값
- * @param target 요소
- * @param word 날짜 글자
- */
- function setSelectOption(min, value, target) {
- let option = getOption(min);
- target.html(option);
- if (min < Number(value)) {
- target.val('01');
- }
- else {
- target.val(value);
- }
- }
- /**
- * 날짜 Select option for문
- * @param rate 종료 값
- * @param word 날짜 글짜
- * @returns {string}
- */
- function getOption(rate) {
- let option = ''
- for ( let ii = 1; ii <= rate; ii++) {
- let value = ii;
- if (ii < 10) {
- value = ('0'+ii);
- }
- option += '<option value="'+value+'">'+value + '</option>';
- }
- return option;
- }
- /**
- * 교차로 검색 이벤트
- * @param el
- */
- function searchEvent(ev) {
- if (!ev || ev.key === 'Enter') {
- const searchText = $('#searchText').val();
- if (searchText === "") {
- return alert('검색어를 입력해주세요');
- }
- const labelArr = $('.list-box label');
- // totMoveEvent('list-box', 'selected-atrd');
- for (let ii = 0; ii < labelArr.length; ii++) {
- const label = labelArr.eq(ii);
- if (label.text().includes(searchText)) {
- label.click();
- label.dblclick();
- }
- }
- }
- }
- </script>
|