맹주환

Merge branch 'feature/Location' into feature/react.js

# Conflicts:
#	package-lock.json
#	package.json
1 +<!DOCTYPE html>
2 +<html>
3 + <head>
4 + <title>Take an Umbrella</title>
5 + <meta charset="UTF-8">
6 + <link rel="stylesheet" type="text/css" href="style.css" />
7 + </head>
8 + <body>
9 + <h1 style="font-family:Nanum Gothic;"> Take an Umbrella </h1>
10 + <h3 style="font-family:Nanum Gothic;"> 철학과 2017101598 맹주환 </h3>
11 + <pre align="center" style="font-family:Nanum Gothic;" font size="20">
12 + 반가워요!
13 + Take an umbrella는 스마트 조명 제품 Philips hue API와 기상청 공공데이터 날씨 API로 구성되어 있어요.
14 + Hue가 연결된 WI-FI로 접속하셔서 아래의 지도로 현재 위치를 조회하시면, 해당 지역 기상 예보를 받아와 조명을 통해 우산을 챙겨야 하는지 알려줘요!
15 + </pre>
16 + <div id="map"></div>
17 + <!-- Async script executes immediately and must be after any DOM elements used in callback. -->
18 +
19 + <h1 style="font-family:Nanum Gothic;"> 당신의 현재 위치 </h1>
20 + <div align="center">현재 위도: <span id="lat"></span></div>
21 + <div align="center">현재 경도: <span id="lng"></span></div>
22 + </body>
23 + <script src="map.js"></script>
24 + <script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script>
25 + <script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyAguo3zH8vWZJbzXEqyp8D8UvnBh3zX8rQ&callback=initMap&v=weekly" async> </script>
26 +</html>
...\ No newline at end of file ...\ No newline at end of file
1 +// Note: This example requires that you consent to location sharing when
2 +// prompted by your browser. If you see the error "The Geolocation service
3 +// failed.", it means you probably did not give permission for the browser to
4 +// locate you.
5 +
6 +let map, infoWindow;
7 +
8 +function initMap() {
9 + map = new google.maps.Map(document.getElementById("map"), {
10 + center: { lat: 37.5642135, lng: 127.0016985 },
11 + zoom: 10,
12 + });
13 + infoWindow = new google.maps.InfoWindow();
14 +
15 + const locationButton = document.createElement("button");
16 +
17 + locationButton.textContent = "위치 조회 하기";
18 + locationButton.classList.add("custom-map-control-button");
19 + map.controls[google.maps.ControlPosition.TOP_CENTER].push(locationButton);
20 + locationButton.addEventListener("click", () => {
21 + // Try HTML5 geolocation.
22 + if (navigator.geolocation) {
23 + navigator.geolocation.getCurrentPosition(
24 + (position) => {
25 + const pos = {
26 + lat: position.coords.latitude,
27 + lng: position.coords.longitude,
28 + };
29 + infoWindow.setPosition(pos);
30 + infoWindow.setContent("위치를 찾았습니다.");
31 + infoWindow.open(map);
32 + map.setCenter(pos);
33 + document.getElementById("lat").innerHTML = pos.lat;
34 + document.getElementById("lng").innerHTML = pos.lng;
35 + // console.log(dfs_xy_conv("toXY",pos.lat,pos.lng));
36 +
37 + },
38 + () => {
39 + handleLocationError(true, infoWindow, map.getCenter());
40 + }
41 + );
42 + } else {
43 + // Browser doesn't support Geolocation
44 + handleLocationError(false, infoWindow, map.getCenter());
45 + }
46 + });
47 +}
48 +
49 +function handleLocationError(browserHasGeolocation, infoWindow, pos) {
50 + infoWindow.setPosition(pos);
51 + infoWindow.setContent(
52 + browserHasGeolocation
53 + ? "Error: 위치 조회 서비스가 실패하였습니다."
54 + : "Error: 브라우저가 위치 조회 기능을 지원하지 않습니다."
55 + );
56 + infoWindow.open(map);
57 +}
...\ No newline at end of file ...\ No newline at end of file
1 +/* Always set the map height explicitly to define the size of the div
2 + * element that contains the map. */
3 +
4 + @import url(http://fonts.googleapis.com/earlyaccess/nanumgothic.css);
5 + h1 { text-align: center; }
6 + h2 { text-align: center; }
7 + h3 { text-align: center; }
8 +
9 + #map {
10 + width:600px;
11 + height:400px;
12 + margin: 0 auto;
13 +
14 +
15 + }
16 + .custom-map-control-button {
17 + background-color: #fff;
18 + border: 0;
19 + border-radius: 2px;
20 + box-shadow: 0 1px 4px -1px rgba(0, 0, 0, 0.3);
21 + margin: 10px;
22 + padding: 0 0.5em;
23 + font: 400 18px Roboto, Arial, sans-serif;
24 + overflow: hidden;
25 + height: 40px;
26 + cursor: pointer;
27 + }
28 + .custom-map-control-button:hover {
29 + background: #ebebeb;
30 + }
31 +
...\ No newline at end of file ...\ No newline at end of file
1 +const request = require('request');
2 +const moment = require('moment');
3 +require('moment-timezone');
4 +moment.tz.setDefault("Asia/seoul");
5 +let date = new String(get_base_date());
6 +let time = new String(get_base_time());
7 +var url = 'http://apis.data.go.kr/1360000/VilageFcstInfoService_2.0/getVilageFcst';
8 +var queryParams = '?' + encodeURIComponent('serviceKey') + '=5e8RQfsCMcXO61FvD7j5tgt5fHf0NYadkSaW6%2FhYQHdoxSgQFXbN7VSb4CI%2BW9scLv2usb3riB7UAGNF7Wb6nA%3D%3D'; /* Service Key*/
9 +queryParams += '&' + encodeURIComponent('pageNo') + '=' + encodeURIComponent('1'); /* */
10 +queryParams += '&' + encodeURIComponent('numOfRows') + '=' + encodeURIComponent('10'); /* */
11 +queryParams += '&' + encodeURIComponent('dataType') + '=' + encodeURIComponent('JSON'); /* */
12 +queryParams += '&' + encodeURIComponent('base_date') + '=' + encodeURIComponent(date); /* */
13 +queryParams += '&' + encodeURIComponent('base_time') + '=' + encodeURIComponent(time); /* */
14 +queryParams += '&' + encodeURIComponent('nx') + '=' + encodeURIComponent('55'); /* */
15 +queryParams += '&' + encodeURIComponent('ny') + '=' + encodeURIComponent('127'); /* */
16 +
17 +
18 +function get_base_date() // 날짜 추출 함수
19 +{
20 + // 0000~0210 사이 시간대에 조회시 전일(date -1)로 변경
21 + let date =moment().format('YYYYMMDD');
22 + let time = new String(moment().format('HHmm'));
23 + if ('0000'<=time && time<'0210'){date -= 1}
24 + return date
25 +}
26 +
27 +function get_base_time() // 시간 추출 함수
28 +{
29 + //단기예보
30 + //- Base_time : 0200, 0500, 0800, 1100, 1400, 1700, 2000, 2300 (1일 8회)
31 + //- API 제공 시간(~이후) : 02:10, 05:10, 08:10, 11:10, 14:10, 17:10, 20:10, 23:10
32 + //- 시간대 맞추기
33 + let time = new String(moment().format('HHmm'));
34 + if ('0000'<=time && time<'0210'){time = '2300'}
35 + else if ('0210'<=time && time<'0510'){time = '0200'}
36 + else if ('0510'<=time && time<'0810'){time = '0500'}
37 + else if ('0810'<=time && time<'1110'){time = '0800'}
38 + else if ('1110'<=time && time<'1410'){time = '1100'}
39 + else if ('1410'<=time && time<'1710'){time = '1400'}
40 + else if ('1710'<=time && time<'2010'){time = '1700'}
41 + else if ('2010'<=time && time<'2310'){time = '2010'}
42 + else if ('2310'<=time && time<'2359'){time = '2300'}
43 + return time
44 + }
45 +
46 +request({
47 + url: url + queryParams,
48 + method: 'GET'
49 +}, function (error, response, body) {
50 + console.log('Status', response.statusCode);
51 + console.log('Headers', JSON.stringify(response.headers));
52 + console.log('Reponse received', body);
53 +});
54 +
55 +//
56 +// (사용 예)
57 +// var rs = dfs_xy_conv("toLL","60","127");
58 +// console.log(rs.lat, rs.lng);
59 +
60 +dfs_xy_conv = function (code, v1, v2) {
61 +// 소스출처 : http://www.kma.go.kr/weather/forecast/digital_forecast.jsp
62 +// LCC DFS 좌표변환 ( code : "toXY"(위경도->좌표, v1:위도, v2:경도), "toLL"(좌표->위경도,v1:x, v2:y) )
63 +
64 + var RE = 6371.00877; // 지구 반경(km)
65 + var GRID = 5.0; // 격자 간격(km)
66 + var SLAT1 = 30.0; // 투영 위도1(degree)
67 + var SLAT2 = 60.0; // 투영 위도2(degree)
68 + var OLON = 126.0; // 기준점 경도(degree)
69 + var OLAT = 38.0; // 기준점 위도(degree)
70 + var XO = 43; // 기준점 X좌표(GRID)
71 + var YO = 136; // 기1준점 Y좌표(GRID)
72 +
73 + var DEGRAD = Math.PI / 180.0;
74 + var RADDEG = 180.0 / Math.PI;
75 +
76 + var re = RE / GRID;
77 + var slat1 = SLAT1 * DEGRAD;
78 + var slat2 = SLAT2 * DEGRAD;
79 + var olon = OLON * DEGRAD;
80 + var olat = OLAT * DEGRAD;
81 +
82 + var sn = Math.tan(Math.PI * 0.25 + slat2 * 0.5) / Math.tan(Math.PI * 0.25 + slat1 * 0.5);
83 + sn = Math.log(Math.cos(slat1) / Math.cos(slat2)) / Math.log(sn);
84 + var sf = Math.tan(Math.PI * 0.25 + slat1 * 0.5);
85 + sf = Math.pow(sf, sn) * Math.cos(slat1) / sn;
86 + var ro = Math.tan(Math.PI * 0.25 + olat * 0.5);
87 + ro = re * sf / Math.pow(ro, sn);
88 + var rs = {};
89 + if (code == "toXY") {
90 + rs['lat'] = v1;
91 + rs['lng'] = v2;
92 + var ra = Math.tan(Math.PI * 0.25 + (v1) * DEGRAD * 0.5);
93 + ra = re * sf / Math.pow(ra, sn);
94 + var theta = v2 * DEGRAD - olon;
95 + if (theta > Math.PI) theta -= 2.0 * Math.PI;
96 + if (theta < -Math.PI) theta += 2.0 * Math.PI;
97 + theta *= sn;
98 + rs['x'] = Math.floor(ra * Math.sin(theta) + XO + 0.5);
99 + rs['y'] = Math.floor(ro - ra * Math.cos(theta) + YO + 0.5);
100 + }
101 + else {
102 + rs['x'] = v1;
103 + rs['y'] = v2;
104 + var xn = v1 - XO;
105 + var yn = ro - v2 + YO;
106 + ra = Math.sqrt(xn * xn + yn * yn);
107 + if (sn < 0.0) - ra;
108 + var alat = Math.pow((re * sf / ra), (1.0 / sn));
109 + alat = 2.0 * Math.atan(alat) - Math.PI * 0.5;
110 +
111 + if (Math.abs(xn) <= 0.0) {
112 + theta = 0.0;
113 + }
114 + else {
115 + if (Math.abs(yn) <= 0.0) {
116 + theta = Math.PI * 0.5;
117 + if (xn < 0.0) - theta;
118 + }
119 + else theta = Math.atan2(xn, yn);
120 + }
121 + var alon = theta / sn + olon;
122 + rs['lat'] = alat * RADDEG;
123 + rs['lng'] = alon * RADDEG;
124 + }
125 + return rs;
126 + }
...\ No newline at end of file ...\ No newline at end of file
1 +<<<<<<< HEAD
2 +경위도 : https://developers.google.com/maps/documentation/javascript/examples/map-geolocation?hl=ko#maps_map_geolocation-javascript
3 +=======
4 +https://www.data.go.kr/tcs/dss/selectApiDataDetailView.do?publicDataPk=15084084 기상청
5 +>>>>>>> feature/add_Weather_API
......
1 +// 서비스 제공을 위한 html 홈페이지를 express로 구현하기 (기본적인 뼈대)
2 +var express = require('express')
3 +var app = express(); // express 선언
4 +const port = 10000 //임의의 포트 10000
5 +
6 +// request 와 response 라는 인자를 줘서 콜백 함수를 만든다.
7 +// localhost:port 브라우저에 res.sendFile() 내부의 파일이 띄워진다.
8 +app.use(express.static(__dirname + "/html"));
9 +
10 +app.get('/', function(req,res) {
11 + res.sendFile(__dirname + "/html/index.html")
12 +})
13 +
14 +//임의의 포트 10000, 접속 주소 localhost:10000/
15 +app.listen(port, function(){
16 + console.log('서버 구동중 port : %d', port);
17 +});
...\ No newline at end of file ...\ No newline at end of file