지창언

Merge branch 'to_mod_wea_api' into 'master'

weather page is updated for dropdown button

weather page is updated for dropdown button&menu...

See merge request !3
1 +<!--
2 + 휴게소 표준정보의 service area code 의 우측끝 3자리 == 휴게소 날씨 표준정보의 unitCode
3 +-->
1 <!DOCTYPE html> 4 <!DOCTYPE html>
2 <html lang="en"> 5 <html lang="en">
3 <head> 6 <head>
...@@ -11,7 +14,7 @@ ...@@ -11,7 +14,7 @@
11 <!-- Bootstrap icons--> 14 <!-- Bootstrap icons-->
12 <link href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.5.0/font/bootstrap-icons.css" rel="stylesheet" /> 15 <link href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.5.0/font/bootstrap-icons.css" rel="stylesheet" />
13 <!-- Core theme CSS (includes Bootstrap)--> 16 <!-- Core theme CSS (includes Bootstrap)-->
14 - <link href="css/styles.css" rel="stylesheet" /> 17 + <link href="css/styles.css" rel="stylesheet" />
15 </head> 18 </head>
16 19
17 20
...@@ -56,11 +59,26 @@ ...@@ -56,11 +59,26 @@
56 <div class="text-center my-5"> 59 <div class="text-center my-5">
57 <h1 class="fw-bolder mb-3">휴게소 날씨</h1> 60 <h1 class="fw-bolder mb-3">휴게소 날씨</h1>
58 <p class="lead fw-normal text-muted mb-4">Just search the name of the rest stop,<br>You'll find out the weather of the rest area.</p> 61 <p class="lead fw-normal text-muted mb-4">Just search the name of the rest stop,<br>You'll find out the weather of the rest area.</p>
59 - 62 + <div class="dropdown">
60 - <!--검색 버튼으로 검색할 휴게소 이름 입력 받기--> 63 +
61 - <p><input type="text" placeholder="휴게소 이름" id="name"><input type="button" onclick="Showweather()" value="확인"></p> 64 + <button class ="btn btn-primary dropdown-toggle " id="highway" data-bs-toggle="dropdown">
62 - 65 + 고속도로 선택
66 + </button>
67 + <div class ="dropdown-menu">
68 + <a class="dropdown-item" onclick="addReststop('0010')">경부선</a>
69 + <a class="dropdown-item" onclick="addReststop('0550')">중앙선</a>
70 + <a class="dropdown-item" onclick="addReststop('0500')">영동선</a>
71 + </div>
72 + <button class ="btn btn-primary dropdown-toggle " id = "rest_stop" data-bs-toggle="dropdown">
73 + 휴게소 선택
74 + </button>
75 + <div class ="dropdown-menu" id = "select_restStop">
76 + </div>
77 + </div>
63 </div> 78 </div>
79 +
80 +
81 +
64 </div> 82 </div>
65 </div> 83 </div>
66 </div> 84 </div>
...@@ -124,8 +142,9 @@ ...@@ -124,8 +142,9 @@
124 </div> 142 </div>
125 </section> 143 </section>
126 144
127 - 145 + <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
128 <script> 146 <script>
147 +
129 //날씨 오픈 api는 조회 방식이나 끌어오는 데이터가 복잡해서 주석을 자세히 작성함 148 //날씨 오픈 api는 조회 방식이나 끌어오는 데이터가 복잡해서 주석을 자세히 작성함
130 149
131 //* 휴게소 날씨 오픈 api 주의 사항 () 150 //* 휴게소 날씨 오픈 api 주의 사항 ()
...@@ -141,7 +160,7 @@ ...@@ -141,7 +160,7 @@
141 let present_date = present.getDate(); 160 let present_date = present.getDate();
142 let present_time = ('0'+(present.getHours())).slice(-2); 161 let present_time = ('0'+(present.getHours())).slice(-2);
143 162
144 - //현재 년도, 월, 날짜를 YYYYMMDD형태로 변형 163 + //현재 년도, 월, 날짜를 YYYYMMDD형태로 변형
145 //날씨 오픈 api의 연일월 입력타입이 YYYYMMDD 164 //날씨 오픈 api의 연일월 입력타입이 YYYYMMDD
146 let YYYYMMDD = String(present_year)+String(present_month)+String(present_date); 165 let YYYYMMDD = String(present_year)+String(present_month)+String(present_date);
147 166
...@@ -155,11 +174,152 @@ ...@@ -155,11 +174,152 @@
155 174
156 console.log(yesterday_YYYYMMDD) 175 console.log(yesterday_YYYYMMDD)
157 console.log(YYYYMMDD) 176 console.log(YYYYMMDD)
177 +
178 +
158 179
180 + // 모든 자식요소들을 삭제하는 함수
181 + function removeAllchild(div) {
182 + while (div.hasChildNodes()) {
183 + div.removeChild(div.firstChild);
184 + }
185 + }
186 +
187 + var serviceAreaCode= "";
188 +
159 189
160 - //검색창에 휴게소 이름을 입력하면 실행되는 함수 Showweather() 190 + // 각 고속도로에 존재하는 휴게소 리스트를 작성하여 드랍다운 메뉴에 추가합니다.
161 - function Showweather() { 191 + function addReststop(lineNumber){
162 192
193 + // 아래 조건문은 각 고속도로 선택시 해당 고속도로 이름이 버튼(html)에 기록되도록 하기 위함입니다.
194 + let highway_Area = document.getElementById('highway');
195 + if(lineNumber==='0010'){
196 + highway_Area.innerHTML = '경부선';
197 + }
198 + else if(lineNumber==='0550'){
199 + highway_Area.innerHTML = '중앙선';
200 + }
201 + else if(lineNumber==='0500'){
202 + highway_Area.innerHTML = '영동선';
203 + }
204 + let tagArea = document.getElementById('select_restStop'); // 드랍다운 메뉴 추가할 태그 아이디 저장
205 + removeAllchild(tagArea); // 고속도로 선택시마다 새로운 휴게소를 불러와야 하므로 현재 드랍다운 메뉴에 존재하는 자식요소 싹다 삭제합니다.
206 +
207 +
208 +
209 +
210 + // 아래의 ajax 문을 통해서 휴게소표준 api를 불러옵니다. 각 고속도로에 대한 모든 휴게소이름과 휴게소 코드를 가져오기 위함입니다.
211 + // 여기서 가져오게되는 휴게소 코드(serviceAreaCode)는 추후에 휴게소별 날씨정보 api에 있는 unitCode와 상응하는 데이터입니다.
212 + var routeCodes = [];
213 + var svarAddrs = [];
214 + var rest_names = [];
215 + var serviceAreaCodes = [];
216 + // 페이지 1
217 + $.ajax({
218 + url: "http://data.ex.co.kr/openapi/business/conveniServiceArea?key=1817997939&type=json&numOfRows=99&pageNo=1",
219 + async:false,
220 + success: function(data){
221 + //변수 설정
222 + userData = data;
223 + },
224 + }).done(function() {
225 + var routeCode = "";
226 + var svarAddr = "";
227 + var rest_name = "";
228 + var data_count = userData["list"].length // 데이터 개수 얻기
229 +
230 + for (var i =0; i<data_count; i++){
231 + routeCode = JSON.stringify(userData["list"][i]["routeCode"]); // 고속도로 번호를 가져옵니다.
232 + rest_name = JSON.stringify(userData["list"][i]["serviceAreaName"]); // 휴게소 이름을 가져옵니다.
233 + serviceCode = JSON.stringify(userData["list"][i]["serviceAreaCode"]); // 휴게소코드를 가져옵니다.
234 +
235 + if(routeCode.substring(1,5) === lineNumber){ // 고속도로 코드가 같다면
236 + rest_names.push(rest_name); //휴게소 이름을 저장해둡니다...
237 + serviceAreaCodes.push(serviceCode); // 휴게소 코드를 저장해둡니다.
238 + }
239 + }
240 + // 아래 forEach문은 저장한 모든 휴게소에 대해, 드랍다운 버튼을 생성하기 위함입니다.
241 + rest_names.forEach(function(addr,index){
242 + let new_A_Button = document.createElement('a'); // a 속성 생성
243 + new_A_Button.setAttribute('class','dropdown-item');
244 + new_A_Button.setAttribute('onclick',"Showweather("+serviceAreaCodes[index]+","+rest_names[index]+")");
245 + new_A_Button.innerHTML = rest_names[index].substring(1,rest_names[index].length-1);
246 + tagArea.appendChild(new_A_Button);
247 + })
248 + })
249 +
250 + // 페이지 2, 페이지 1과 모든 과정이 동일하며, 오픈 api 데이터 가져오는 특성상 페이지를 나누었습니다.
251 + $.ajax({
252 + url: "http://data.ex.co.kr/openapi/business/conveniServiceArea?key=1817997939&type=json&numOfRows=99&pageNo=2",
253 + async:false,
254 + success: function(data){
255 + //변수 설정
256 + userData = data;
257 + },
258 + }).done(function() {
259 + var routeCode = "";
260 + var svarAddr = "";
261 + var rest_name = "";
262 + var data_count = userData["list"].length // 데이터 개수 얻기
263 +
264 + for (var i =0; i<data_count; i++){
265 + routeCode = JSON.stringify(userData["list"][i]["routeCode"]);
266 + rest_name = JSON.stringify(userData["list"][i]["serviceAreaName"]); // 휴게소 이름...
267 + serviceCode = JSON.stringify(userData["list"][i]["serviceAreaCode"]);
268 +
269 + if(routeCode.substring(1,5) === lineNumber){ // 고속도로 코드가 같다면
270 + rest_names.push(rest_name); //휴게소 이름...
271 + serviceAreaCodes.push(serviceCode);
272 + }
273 + }
274 + rest_names.forEach(function(addr,index){
275 + let new_A_Button = document.createElement('a'); // a 속성 생성
276 + new_A_Button.setAttribute('class','dropdown-item');
277 + new_A_Button.setAttribute('onclick',"Showweather("+serviceAreaCodes[index]+","+rest_names[index]+")");
278 + new_A_Button.innerHTML = rest_names[index].substring(1,rest_names[index].length-1);
279 + tagArea.appendChild(new_A_Button);
280 + })
281 + })
282 + // 페이지 3
283 + $.ajax({
284 + url: "http://data.ex.co.kr/openapi/business/conveniServiceArea?key=1817997939&type=json&numOfRows=99&pageNo=3",
285 + async:false,
286 + success: function(data){
287 + //변수 설정
288 + userData = data;
289 + },
290 + }).done(function() {
291 + var routeCode = "";
292 + var svarAddr = "";
293 + var rest_name = "";
294 + var data_count = userData["list"].length // 데이터 개수 얻기
295 +
296 + for (var i =0; i<data_count; i++){
297 + routeCode = JSON.stringify(userData["list"][i]["routeCode"]);
298 + rest_name = JSON.stringify(userData["list"][i]["serviceAreaName"]); // 휴게소 이름...
299 + serviceCode = JSON.stringify(userData["list"][i]["serviceAreaCode"]);
300 +
301 + if(routeCode.substring(1,5) === lineNumber){ // 고속도로 코드가 같다면
302 + rest_names.push(rest_name); //휴게소 이름...
303 + serviceAreaCodes.push(serviceCode);
304 + }
305 + }
306 + rest_names.forEach(function(addr,index){
307 + let new_A_Button = document.createElement('a'); // a 속성 생성
308 + new_A_Button.setAttribute('class','dropdown-item');
309 + new_A_Button.setAttribute('onclick',"Showweather("+serviceAreaCodes[index]+","+rest_names[index]+")");
310 + new_A_Button.innerHTML = rest_names[index].substring(1,rest_names[index].length-1);
311 + tagArea.appendChild(new_A_Button);
312 + })
313 + })
314 +
315 + }
316 +
317 + //검색창에 휴게소 이름을 입력하면 실행되는 함수 Showweather() serviceCode = 휴게소 코드, rest_name = 휴게소 이름
318 + function Showweather(serviceCode,rest_name) {
319 +
320 + serviceCode = serviceCode.substring(3,serviceCode.length); //가져온 휴게소코드를 여기서 사용하는 휴게소코드인 unitCode와 동일한포맷으로 바꿉니다.
321 + let rest_stop = document.getElementById('rest_stop'); // 해당 줄과 바로 아랫줄은 드랍다운 버튼선택시 해당 휴게소이름을 html에 적용하기 위함입니다.
322 + rest_stop.innerHTML =rest_name;
163 //휴게소 이름을 검색하기 전까지는 기타 html 구성 요소들은 숨기기 위하여 innerHTML사용 323 //휴게소 이름을 검색하기 전까지는 기타 html 구성 요소들은 숨기기 위하여 innerHTML사용
164 //휴게소 이름 검색시 화면에 표시 324 //휴게소 이름 검색시 화면에 표시
165 //bar 325 //bar
...@@ -177,9 +337,9 @@ ...@@ -177,9 +337,9 @@
177 document.querySelector('exp6').innerHTML = '지금으로부터 9시간 전부터 3시간 전까지의 풍속을 조회합니다. '; 337 document.querySelector('exp6').innerHTML = '지금으로부터 9시간 전부터 3시간 전까지의 풍속을 조회합니다. ';
178 338
179 //사용자가 입력한 휴게소 이름의 값을 name 변수에 할당 339 //사용자가 입력한 휴게소 이름의 값을 name 변수에 할당
180 - name = document.getElementById('name').value 340 + name = rest_name
181 //bar부분에 휴게소 이름 출력 341 //bar부분에 휴게소 이름 출력
182 - document.querySelector('reststop_name').innerHTML = name; 342 + document.querySelector('reststop_name').innerHTML = rest_name;
183 343
184 344
185 345
...@@ -192,7 +352,7 @@ ...@@ -192,7 +352,7 @@
192 var ttempdata = new Array(10); 352 var ttempdata = new Array(10);
193 var hhumidata = new Array(10); 353 var hhumidata = new Array(10);
194 var wwinddata = new Array(10); 354 var wwinddata = new Array(10);
195 - 355 +
196 for(let k=5; k>1; k--){ 356 for(let k=5; k>1; k--){
197 //present_time-k가 음수인 경우 방지 357 //present_time-k가 음수인 경우 방지
198 if(present_time-k <0){ 358 if(present_time-k <0){
...@@ -218,17 +378,25 @@ ...@@ -218,17 +378,25 @@
218 index2=text.indexOf(']') 378 index2=text.indexOf(']')
219 ndata=text.substr(index1+1, index2-index1+1) 379 ndata=text.substr(index1+1, index2-index1+1)
220 nndata=ndata.split('},'); 380 nndata=ndata.split('},');
221 - 381 +
222 382
223 //ReststopName (휴게소 이름) 데이터 추출 383 //ReststopName (휴게소 이름) 데이터 추출
224 for(let i=0; i<nndata.length; i++){ 384 for(let i=0; i<nndata.length; i++){
385 + // 아래 두줄의 코드를 통해서 휴게소코드를 가져옵니다.
386 + let index1forUnitCode = nndata[i].indexOf('"unitCode":"');
387 + unitCode = nndata[i].substr(index1forUnitCode+12,3);
388 +
225 index3=nndata[i].indexOf('"unitName":"') 389 index3=nndata[i].indexOf('"unitName":"')
226 index4=nndata[i].indexOf('"unitCode":"') 390 index4=nndata[i].indexOf('"unitCode":"')
227 ReststopName=nndata[i].substr(index3+12, index4-index3-14) 391 ReststopName=nndata[i].substr(index3+12, index4-index3-14)
228 392
229 //데이터에서 추출한 휴게소 이름 ReststopName이 검색창을 통해서 사용자에게 입력받은 이름 name과 일치하는 경우 393 //데이터에서 추출한 휴게소 이름 ReststopName이 검색창을 통해서 사용자에게 입력받은 이름 name과 일치하는 경우
230 //그 데이터 셋에서 weather, temperature, humidity, wind를 추출하도록 함. 394 //그 데이터 셋에서 weather, temperature, humidity, wind를 추출하도록 함.
231 - if(ReststopName == name){ 395 +
396 + // 해당 함수의 매개변수로 가져온 휴게소 코드와, 함수 안에서 fetch를 통해 가져온 오픈 api의 휴게소코드가 동일한지 비교합니다.
397 + if(serviceCode == unitCode){
398 + console.log("unitCode access");
399 +
232 //Weather 400 //Weather
233 index5=nndata[i].indexOf('"weatherContents":"') 401 index5=nndata[i].indexOf('"weatherContents":"')
234 index6=nndata[i].indexOf('"statusNo":"') 402 index6=nndata[i].indexOf('"statusNo":"')
...@@ -253,8 +421,9 @@ ...@@ -253,8 +421,9 @@
253 ttempdata[k]=bar_temperature; 421 ttempdata[k]=bar_temperature;
254 hhumidata[k]=bar_humidity; 422 hhumidata[k]=bar_humidity;
255 wwinddata[k]=bar_wind; 423 wwinddata[k]=bar_wind;
256 - } 424 + }
257 - } 425 + }
426 +
258 //innerhtml을 이용해서 html화면에 데이터 표기 427 //innerhtml을 이용해서 html화면에 데이터 표기
259 //5시간 전, 4시간 전, 3시간 전, 2시간 전의 데이터 중 가장 최근의 데이터를 출력하도록 함 428 //5시간 전, 4시간 전, 3시간 전, 2시간 전의 데이터 중 가장 최근의 데이터를 출력하도록 함
260 for(let o=5; o>1; o-- ){ 429 for(let o=5; o>1; o-- ){
...@@ -299,7 +468,7 @@ ...@@ -299,7 +468,7 @@
299 }) 468 })
300 }) 469 })
301 } 470 }
302 - 471 +
303 472
304 //그래프 그리기 473 //그래프 그리기
305 //온도, 습도, 풍속 데이터를 array에 저장하여 그래프에 넘겨줌 474 //온도, 습도, 풍속 데이터를 array에 저장하여 그래프에 넘겨줌
...@@ -307,7 +476,7 @@ ...@@ -307,7 +476,7 @@
307 var humidata = new Array(10); 476 var humidata = new Array(10);
308 var winddata = new Array(10); 477 var winddata = new Array(10);
309 478
310 - name = document.getElementById('name').value 479 + name = rest_name
311 480
312 for(let j=0; j<7; j++){ 481 for(let j=0; j<7; j++){
313 //present_time-3-j가 음수인 경우 방지 482 //present_time-3-j가 음수인 경우 방지
...@@ -321,7 +490,7 @@ ...@@ -321,7 +490,7 @@
321 date2 = YYYYMMDD 490 date2 = YYYYMMDD
322 } 491 }
323 492
324 - name = document.getElementById('name').value 493 + name = rest_name
325 fetch('http://data.ex.co.kr/openapi/restinfo/restWeatherList?key=6806352377&type=json&sdate='+ date2 +'&stdHour=' + ('0'+String(time2)).slice(-2)).then(function(response){ 494 fetch('http://data.ex.co.kr/openapi/restinfo/restWeatherList?key=6806352377&type=json&sdate='+ date2 +'&stdHour=' + ('0'+String(time2)).slice(-2)).then(function(response){
326 //testing 495 //testing
327 // fetch('http://data.ex.co.kr/openapi/restinfo/restWeatherList?key=test&type=json&sdate='+ "20220524" +'&stdHour='+ ('0'+ String(22-j)).slice(-2)).then(function(response){ 496 // fetch('http://data.ex.co.kr/openapi/restinfo/restWeatherList?key=test&type=json&sdate='+ "20220524" +'&stdHour='+ ('0'+ String(22-j)).slice(-2)).then(function(response){
...@@ -337,12 +506,15 @@ ...@@ -337,12 +506,15 @@
337 506
338 //ReststopName (휴게소 이름) 507 //ReststopName (휴게소 이름)
339 for(let i=0; i<nndata.length; i++){ 508 for(let i=0; i<nndata.length; i++){
509 + let index1forUnitCode = nndata[i].indexOf('"unitCode":"');
510 + unitCode = nndata[i].substr(index1forUnitCode+12,3);
511 +
340 index3=nndata[i].indexOf('"unitName":"') 512 index3=nndata[i].indexOf('"unitName":"')
341 index4=nndata[i].indexOf('"unitCode":"') 513 index4=nndata[i].indexOf('"unitCode":"')
342 ReststopName=nndata[i].substr(index3+12, index4-index3-14) 514 ReststopName=nndata[i].substr(index3+12, index4-index3-14)
343 515
344 516
345 - if(ReststopName == name){ 517 + if(serviceCode == unitCode){
346 //Weather 518 //Weather
347 index5=nndata[i].indexOf('"weatherContents":"') 519 index5=nndata[i].indexOf('"weatherContents":"')
348 index6=nndata[i].indexOf('"statusNo":"') 520 index6=nndata[i].indexOf('"statusNo":"')
......