Geolocation API 사용하기

Secure context
This feature is available only in secure contexts (HTTPS), in some or all supporting browsers.


Geolocation API는 사용자의 현재 위치를 가져오는 API로, 지도에 사용자 위치를 표시하는 등 다양한 용도로 사용할 수 있습니다. 이 안내서는 Geolocation API의 기초적 사용법을 설명합니다.

geolocation 객체

Geolocation APInavigator.geolocation 객체를 통해 사용할 수 있습니다.

geolocation 객체가 존재하는 경우 위치 정보 서비스를 지원하는 것입니다. 존재 여부는 다음과 같이 알아낼 수 있습니다.

if('geolocation' in navigator) {
  /* 위치정보 사용 가능 */
} else {
  /* 위치정보 사용 불가능 */
}

현재 위치 가져오기

getCurrentPosition() 메서드를 호출해서 사용자의 현재 위치를 얻을 수 있습니다. getCurrentPosition()은 사용자의 위치를 탐지하는 비동기 요청을 초기화하고, 위치 관련 하드웨어에 최신 정보를 요청합니다. 위치를 알아낸 후에는 지정한 콜백 함수를 호출합니다. 선택적으로, 이 과정 중 오류가 발생하면 호출할 오류 콜백을 두 번째 매개변수로 지정할 수도 있습니다. 세 번째 매개변수 역시 선택 항목이며, 위치 정보의 최대 수명, 요청의 최대 대기시간, 고정밀 위치정보 여부 등의 옵션을 담은 객체입니다.

참고: getCurrentPosition()의 기본값에서는 최대한 빠르게 낮은 정밀도의 응답을 반환합니다. 정확하지 않더라도 빠른 정보가 필요한 상황에서 유용합니다. 예를 들어, GPS 기능을 가진 장비는 보정 과정에 수 분이 걸릴 수도 있으므로 IP 위치와 WiFi 등 정확하지 않은 출처에 기반한 위치 정보를 반환할 수 있습니다.

navigator.geolocation.getCurrentPosition((position) => {
  doSomething(position.coords.latitude, position.coords.longitude);
});

위의 예제는 사용자 위치가 확인되면 doSomething() 함수를 실행합니다.

현재 위치 추적하기

장치가 이동했거나 더 정확한 정보를 사용할 수 있어서 위치 정보가 바뀐 경우 호출할 콜백 함수를 watchPosition() 메서드로 설정할 수 있으며, getCurrentPosition()과 같은 매개변수를 받습니다. 콜백은 계속해서 호출될 수 있으므로, 브라우저가 사용자의 이동 시, 또는 고정밀 위치 기술을 사용할 수 있는 시점에 새로운 위치 정보를 제공할 수 있습니다. getCurrentPosition()과 마찬가지로 선택 사항인 오류 콜백 역시 여러 번 호출할 수 있습니다.

참고: getCurrentPosition()을 먼저 호출하지 않고도 watchPosition()을 사용할 수 있습니다.

const watchID = navigator.geolocation.watchPosition((position) => {
  doSomething(position.coords.latitude, position.coords.longitude);
});

watchPosition() 메서드는 위치 추적 요청의 고유 식별자를 나타내는 숫자값을 반환합니다. 해당 식별자를 clearWatch() 메서드에 전달해서 추적을 종료할 수 있습니다.

navigator.geolocation.clearWatch(watchID);

응답 미세 조정

getCurrentPosition()watchPosition() 둘 다 성공 콜백, 실패 콜백 외에도 PositionOptions 객체를 받을 수 있습니다.

PositionsOptions 객체를 사용하면 고정밀도 활성화 여부, 위치 정보의 캐시 수명(수명이 끝나기 전까지는 이전에 반환한 위치 정보를 저장해뒀다가, 같은 요청을 또 받을 경우 그대로 반환합니다), 그리고 위치 정보 요청의 응답을 대기할 최대 대기시간을 지정할 수 있습니다.

옵션 객체를 사용한 watchPosition의 호출 예시는 다음과 같습니다.

function success(position) {
  doSomething(position.coords.latitude, position.coords.longitude);
}

function error() {
  alert('Sorry, no position available.');
}

const options = {
  enableHighAccuracy: true, 
  maximumAge: 30000, 
  timeout: 27000
};

const watchID = navigator.geolocation.watchPosition(success, error, options);

위치 표현

사용자의 위치는 GeolocationPosition 객체를 담은 GeolocationCoordinates 객체를 사용하여 표현합니다.

GeolocationPosition은 단 두 가지만 가집니다. 하나는 GeolocationCoordinates 인스턴스를 가진 coords 속성이고, 다른 하나는 위치 정보의 기록 시점을 나타내는 DOMTimeStamp 인스턴스입니다.

GeolocationCoordinates 인스턴스는 다수의 속성을 갖지만, 그 중 가장 많이 쓰게 될 항목은 지도의 지점을 가리킬 때 사용할 latitudelongitude입니다. 따라서 대부분의 Geolocation 성공 콜백은 아래와 같이 꽤 간단한 형태입니다.

function success(position) {
  const latitude  = position.coords.latitude;
  const longitude = position.coords.longitude;

  // Do something with your latitude and longitude
}

그러나 GeolocationCoordinates 객체에서 고도, 속도, 장치의 방향, 위경도와 고도의 정확도 등 다른 다양한 정보도 가져올 수 있습니다.

오류 처리

getCurrentPosition() 또는 watchPosition()에 오류 콜백을 제공한 경우, 콜백은 첫 번째 매개변수로 GeolocationPositionError 객체를 받습니다. 해당 객체는 오류의 유형을 나타내는 code 속성과, 사람이 읽을 수 있는 형태로 오류 코드의 뜻을 설명한 message 속성을 갖습니다.

다음 형태로 사용할 수 있습니다.

function errorCallback(error) {
  alert(`ERROR(${error.code}): ${error.message}`);
};

예제

다음 예제는 Geolocation API를 사용해 사용자의 위경도를 가져옵니다. 성공한 경우, 사용자의 위치를 가리키는 openstreetmap.org 링크를 생성해 하이퍼링크에 할당합니다.

HTML

<button id = "find-me">Show my location</button><br/>
<p id = "status"></p>
<a id = "map-link" target="_blank"></a>

JavaScript

function geoFindMe() {

  const status = document.querySelector('#status');
  const mapLink = document.querySelector('#map-link');

  mapLink.href = '';
  mapLink.textContent = '';

  function success(position) {
    const latitude  = position.coords.latitude;
    const longitude = position.coords.longitude;

    status.textContent = '';
    mapLink.href = `https://www.openstreetmap.org/#map=18/${latitude}/${longitude}`;
    mapLink.textContent = `Latitude: ${latitude} °, Longitude: ${longitude} °`;
  }

  function error() {
    status.textContent = 'Unable to retrieve your location';
  }

  if(!navigator.geolocation) {
    status.textContent = 'Geolocation is not supported by your browser';
  } else {
    status.textContent = 'Locating…';
    navigator.geolocation.getCurrentPosition(success, error);
  }

}

document.querySelector('#find-me').addEventListener('click', geoFindMe);

결과