...
Geolocation API
Geolocation API는 자바스크립트 프로그램이 사용자의 실제 위치를 브라우저에게 요청할 수 있도록 해준다.
물론 이런 정보들은 주요한 개인 정보와 관련되어 있으므로, 브라우저에서는 Geolocation API가 물리적인 위치 정보에 접근하기 전에 자바스크립트 프로그램이 항상 사용자의 허락을 받도록 하고 있다.
Geolocation API는 환경에 따라 GPS를 비롯한 Wi-Fi, 휴대전화의 기지국, IP 주소 등에서 위치 정보를 알아낸다.
브라우저가 지원하는 Geolocation API는navigator.gelocation으로 정의되어 있다.
Geolocation API 사용법
이 객체에는 다음 세가지 메서드가 존재한다.
navigator.geolocation.getCurrentPosition()
- 사용자의 현재 위치를 요청한다.
Geolocation API는 비동기적으로 동작한다.
위치를 요청하는 가장 간단한 형태는 다음과 같다.
navigator.geolocation.getCurrentPosition(function(pos) {
console.log(pos);
var latitude = pos.coords.latitude;
var longitude = pos.coords.longitude;
alert("현재 위치는 : " + latitude + ", "+ longitude);
});
성공적인 geolocation 요청은 위도와 경도 외에도 미터 단위의 정확도 값을 반환한다. 이 정확도 값은 해당 좌표와 얼마나 가까운지를 나타낸다.
Position 객체의 주요 속성
속성 | 개요 |
coords.latitude | 고도 |
coords.latitude | 위도 |
coords.longitude | 경도 |
coords.accuracy | 위도/경도의 오차(m) |
coords.altitudeAccuracy | 고도의 오차(m) |
coords.heading | 방위(도) |
coords.speed | 속도(m/초) |
timestamp | 취득 날짜 (1970년부터 경과 밀리초) |
+ 위치 구할 때 에러 처리나 옵션 설정하기
getCurrentPosition()은 첫 번째 콜백 인자뿐만 아니라, geolocation 요청이 실패했을 때 호출될 두 번째 콜백 인자를 선택적으로 사용할 수 있다.
에러처리(실패콜백)는 인수로 PositionError객체를 받는다. 콜백함수의 내부에서는 이 정보를 바탕으로 오류 메시지 표시 등을 처리한다.
navigator.geolocation.getCurrentPosition(showYourLocation, showErrorMsg);
function showYourLocation(position) { // 성공했을때 실행
var userLat = position.coords.latitude;
var userLng = position.coords.longitude;
}
function showErrorMsg(error) { // 실패했을때 실행
switch(error.code) {
case error.PERMISSION_DENIED:
loc.innerHTML = "이 문장은 사용자가 Geolocation API의 사용 요청을 거부했을 때 나타납니다!"
break;
case error.POSITION_UNAVAILABLE:
loc.innerHTML = "이 문장은 가져온 위치 정보를 사용할 수 없을 때 나타납니다!"
break;
case error.TIMEOUT:
loc.innerHTML = "이 문장은 위치 정보를 가져오기 위한 요청이 허용 시간을 초과했을 때 나타납니다!"
break;
case error.UNKNOWN_ERROR:
loc.innerHTML = "이 문장은 알 수 없는 오류가 발생했을 때 나타납니다!"
break;
}
}
PositionError 객체의 주요 속성
속성 | 개요 |
code | 에러 코드 |
message | 상세 에러 메시지 |
이 두 메서드는 성공 콜백과 오류 콜백뿐만 아니라 세번재 선택적 인자로 옵션 객체도 사용할 수 있다.
옵션에는 높은 수준의 위치 정확도가 요구되는지, 어떤 위치 '상태'를 허용할지, 시스템이 얼마나 오랜 시간동안 위치 추적을 허용할지를 지정할 수 있다.
옵션은 '옵션명: 값' 형식의 해시로 지정할 수 있다. 지정할 수 있는 옵션은 아래 표와 같다.
옵션 | 개요 |
timeout | 위치 정보 읽기 타임아웃(밀리초) |
maximumAge | 위치 정보의 캐시 기한 (밀리초). 0이면 캐시 안함(=항상 최신 정보를 얻음) |
enableHighAccuracy | 높은 정확도의 위치 정보를 구할지(true | false) enableHighAccuracy 옵션을 true로 한 경우 스마트폰 환경에서는 GPS에서 위치정보를 사용하려고 한다. 이것으로 위치 정보의 정확도는 향상되지만 그만큼 배터리소비도 빠르다. |
navigator.geolocation.watchPosition()
- 현재 위치를 요청하는 것은 동일하지만, 지속적으로 확인하여 사용자의 위치가 변경될 때마다 지정된 콜백 함수를 호출한다.
navigator.geolocation.clearWatch()
- 사용자의 위치 정보를 수집하는 작업을 중단하다. 이 메서드의 전달인자는 watchPosition()을 호출한 다음 반환받은 숫자 값(감시를 식별하기 위한 ID값)이어야 한다.
Geolocation 예제
나의 현재 위치정보 출력하기
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<div id="myLocationInfo"></div>
</body>
</html>
/* 비동기적으로 현재 위치를 알아내어 지정된 요소에 출력한다. */
function whereami(elt) {
// 이 객체를 getCurrentPosition() 메서드의 세번째 인자로 전달한다.
var options = {
// 가능한 경우, 높은 정확도의 위치(예를 들어, GPS 등) 를 읽어오려면 true로 설정
// 그러나 이 기능은 배터리 지속 시간에 영향을 미친다.
enableHighAccuracy: false, // 대략적인 값이라도 상관 없음: 기본값
// 위치 정보가 충분히 캐시되었으면, 이 프로퍼티를 설정하자,
// 위치 정보를 강제로 재확인하기 위해 사용하기도 하는 이 값의 기본 값은 0이다.
maximumAge: 30000, // 5분이 지나기 전까지는 수정되지 않아도 됨
// 위치 정보를 받기 위해 얼마나 오랫동안 대기할 것인가?
// 기본값은 Infinity이므로 getCurrentPosition()은 무한정 대기한다.
timeout: 15000 // 15초 이상 기다리지 않는다.
}
if(navigator.geolocation) // geolocation 을 지원한다면 위치를 요청한다.
navigator.geolocation.getCurrentPosition(success, error, options);
else
elt.innerHTML = "이 브라우저에서는 Geolocation이 지원되지 않습니다.";
// geolocation 요청이 실패하면 이 함수를 호출한다.
function error(e) {
// 오류 객체에는 수치 코드와 텍스트 메시지가 존재한다.
// 코드 값은 다음과 같다.
// 1: 사용자가 위치 정보를 공유 권한을 제공하지 않음.
// 2: 브라우저가 위치를 가져올 수 없음.
// 3: 타임아웃이 발생됨.
elt.innerHTML = "Geolocation 오류 "+e.code +": " + e.message;
}
// geolocation 요청이 성공하면 이 함수가 호출된다.
function success(pos) {
console.log(pos); // [디버깅] Position 객체 내용 확인
// 항상 가져올 수 있는 필드들이다. timestamp는 coords 객체 내부에 있지 않고,
// 외부에서 가져오는 필드라는 점에 주의하다.
var msg = "당신은 " +
new Date(pos.timestamp).toLocaleString() + "에 " +
" 위도 " + pos.coords.latitude +
" 경도 " + pos.coords.longitude + "에서 "+
" 약 " + pos.coords.accuracy + " 미터 떨어진 곳에 있습니다.";
// 해당 기기가 고도 (altitude)를 반환하면, 해당 정보를 추가한다.
if(pos.coords.altitude) {
msg += " 당신은 해발 " + pos.coords.altitude + " ± " +
pos.coords.altitudeAccuracy + " 미터에 있습니다.";
}
// 해당 기기가 속도와 북쪽 기준 각 (heading)을 반환한다면 역시 추가해준다.
if(pos.coords.speed) {
msg += " 당신은 " + pos.coords.heading + " 방향으로 " +
"초속 " + pos.coords.speed + "(m/s)의 속도로 움직이고 있습니다.";
}
elt.innerHTML = msg; // 모든 위치 정보를 출력한다.
}
}
// 나의 위치정보를 출력할 객체 구하기
var elt = document.getElementById("myLocationInfo");
// 나의 위치정보 출력하기
whereami(elt);
정기적으로 위치 정보 얻기
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script src="http://code.jquery.com/jquery-1.11.0.js"></script>
<script>
$(function() {
// Geolocation API에 액세스할 수 있는지를 확인
if (navigator.geolocation) {
//위치 정보를 정기적으로 얻기
var id = navigator.geolocation.watchPosition(
function(pos) {
$('#latitude').html(pos.coords.latitude); // 위도
$('#longitude').html(pos.coords.longitude); // 경도
});
// 버튼 클릭으로 감시를 중지
$('#btnStop').click(function() {
navigator.geolocation.clearWatch(id);
});
} else {
alert("이 브라우저에서는 Geolocation이 지원되지 않습니다.")
}
});
</script>
</head>
<body>
<ul>
<li>위도:<span id="latitude"></span></li>
<li>경도:<span id="longitude"></span></li>
</ul>
<input id="btnStop" type="button" value="감시를 끝낸다" />
</body>
</html>
내 위치의 날씨, 온도 가져오기
api를 쓰기위해 해당 웹사이트에 들어가서 회원가입 해주자. 그리고 api key를 얻자.
우리가 사용할 api는 Current Weather Data라는 api이다.
다양한 rest api요청 들이 있고, 우리가 사용할것은, 경도와 위도를 통해 해당 날씨 정보를 얻는 것이다.
해당 uri로 들어가면 json형태의 데이터를 얻을수 있다. 우리는 fetch를 통해 ajax통신으로 해당 json데이터 값을 가져와 사용할 것이다.
[최종 코드]
const API_KEY = '당신의 API 키를 여기에 기재하세요';
function onGeoOk(position) {
const latitude = position.coords.latitude;
const longitude = position.coords.longitude;
// console.log(`You live in ${latitude} and ${longitude}`);
fetch(
`https://api.openweathermap.org/data/2.5/weather?lat=${latitude}&lon=${longitude}&appid=${API_KEY}&units=metric`,
)
.then(response => response.json())
.then(data => console.log(`온도 : ${data.main.temp}, 날씨 : ${data.weather[0].main}`));
}
function onGeoError() {
alert("Can't find you. No weather for you.");
}
navigator.geolocation.getCurrentPosition(onGeoOk, onGeoError);
이 글이 좋으셨다면 구독 & 좋아요
여러분의 구독과 좋아요는
저자에게 큰 힘이 됩니다.