[항해 57일 . TIL] kakao map & geolocation

박예슬·2022년 5월 3일
1
post-custom-banner

나는 오늘

✔ 마이페이지 전체적인 뷰 완성
마이페이지에서 kakao map 띄우기
geolocation 으로 사용자 위치정보 가져오기
✔ 하단 메뉴바 추가


기억해보자

kakao map API

우리팀의 프로젝트는 다양한 등산정보와, 사용자의 위치정보를 기반으로한 트래킹 서비스를 제공한다.
그에따라 어플리케이션에 지도를 띄워야하는 것이 필수적이었다.
지도 api를 가져와야하는데, naver, google, kakao 등 다양한 플랫폼 중 kakao를 선택하게 됐는데,
kakao가 산의 등산코스를 다른 것들에 비해 잘 보여주고있기 때문이다.

👉 kakaoMaps API

우리 프로젝트는 웹어플리케이션이기때문에 web을 선택!

web을 선택하면 나오는 화면인데 옆 사이드의 메뉴를 선택해서 docs를 읽을 수 있다.
Guide 메뉴를 통해 kakao 지도 api를 사용하기 위해 준비해야할것부터, 지도를 띄우는 코드를 작성하는 것 등등 쉽게 따라갈 수 있다.
Sample 메뉴엔 다양한 상황, 지도를 이용한 다양한 이벤트들에대한 샘플 코드가 있어 참고해서 코드를 작성하면 지도를 가지고 다양한 효과를 쉽게 보여줄 수 있다.



react-kakao-maps-sdk

기본적으로 kakao map API는 javascript 와 html을 다루기때문에,
샘플 코드 등이 getElementById 등 DOM 요소를 직접 건드리는 코드로 되어있다.
이걸 React에서 적용할때,
적절해보이진 않지만 getElementById와 같은 코드를 똑같이 사용하거나, useRef를 사용하여 요소에 접근하는 식으로 코드를 작성해야한다.
우리팀은 지도를 사용해서 여러 이벤트도 적용하고, 마커나 인포윈도우 등의 스타일 부여 등..
코드를 작성하며, 여러가지 건드려야할게 많을 것 같아 라이브러리를 이용하기로 했다.

그래서 선택한 라이브러리는 react-kakao-maps-sdk !!
Kakao Maps API를 react에 맞게 포팅한 라이브러리다.

👉 react-kakao-maps-sdk github repo
👉 react-kakao-maps-sdk Docs

이 라이브러리를 사용하면, kakao map api를 리액트에 적용하기 위해 따로 이것저것 고려할 필요없고
컴포넌트를 이용해 간단하게 구현이 가능하기때문에 기능구현에만 집중 할 수 있다.
문서를 읽어보면 Tutorial 과 sample 코드도 잘 나와있어, 신경써야하는게 1/10 수준으로 줄어든다!!

준비단계
필수 준비물은 Kakao 지도 Javscript API 를 사용하기 위한 key 이다.
kakao maps api Guide준비하기 절차에 과정이 상세히 잘 나와있기 때문에,
잘 따라하기만하면 key 발급을 할 수있다.

Key 발급이 완료됐다면, 실제 지도를 그리는 javascript API를 불러와야 한다.

// index.html

<script
  type="text/javascript"
  src="//dapi.kakao.com/v2/maps/sdk.js?appkey=발급받은 APP KEY&libraries=services,clusterer"
></script>

kakao 문서를 보면, 'API를 로딩하는 스크립트 태그는 HTML파일안의 head, body 등 어떠한 위치에 넣어도 상관없지만, 반드시 실행 코드보다 먼저 선언되어야 한다'고한다.

index.html 파일에 해당 코드를 작성해준다.

이제 라이브러리만 설치해주면, 카카오 지도 api를 사용하기위한 준비 끝!

# 라이브러리 설치
yarn add react-kakao-maps-sdk

지도띄우기
이제 코드를 작성해서 지도를 띄워주면 된다


import { Map } from "react-kakao-maps-sdk";

const KakaoMap = () => {
  return (
    <Map // 지도를 표시할 Container
      center={{
        // 지도의 중심좌표
        lat: 33.450701,
        lng: 126.570667,
      }}
      style={{
        // 지도의 크기
        width: "100%",
        height: "450px",
      }}
      level={3} // 지도의 확대 레벨
    />
  );
}


geolocation API

사용자의 현재 위치를 지도에 표시하거나, 현재 위치 정보를 기반으로 데이터를 제공하는것이 필요했다.
HTML5의 Geolocation을 이용하면 사용자의 접속위치를 얻어올 수 있다.
Geolocation API는 사용자가 원할 경우 웹 애플리케이션에 위치 정보를 제공할 수 있는 API로, 개인정보 보호를 위해, 브라우저는 위치 정보를 제공하기 전에 사용자에게 위치 정보 권한에 대한 확인을 받는다.


geolocation API 접근하기
Geolocation API는 navigator.geolocation 객체를 통해 사용할 수 있다.
geolocation 객체가 존재하는 경우 위치 정보 서비스를 지원하는 것이므로, 존재여부를 물으며 코드를 시작하면 된다.

if(navigator.geolocation) {
  // 위치정보 사용 가능
  // 위치정보 가져오기
} else {
  // 위치정보 사용 불가능
}

현재 위치 가져오기
geolocation의 메서드 중 우리가 사용할 메서드는 getCurrentPosition()
getCurrentPosition() 메서드를 호출해서 사용자의 현재 위치를 얻을 수 있다.

navigator.geolocation.getCurrentPosition(success, error, [options])

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

즉, getCurrentPosition() 메서드는 사용자의 위치를 탐지하여 알아낸 후 지정한 콜백 함수를 호출한다.
우리는 그 콜백 함수에서 현재위치 값을 가져오면 된다

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

GeolocationPosition 은 GeolocationCoordinates 인스턴스를 가진 coords 속성을 갖는데, coords.latitude, coords.longitude 으로 각 위도, 경도값을 가져올 수 있다.
보통 지도에서 위치 값, 좌표를 이용할 때 위도, 경도를 객체에 담아 이용하는 경우가 많기 때문에 여기서 값을 받아와 객체에 담아놓으면 편하다.


사용자의 현재 위치 기반 지도 띄우기
위치정보를 가져오는 것은 크게 어렵지않기때문에, MDN 문서를 한번 읽고 그대로 코드를 작성하면된다.
참고로 ReactKakaoMapSDK 문서에도 geolocation을 이용하는 코드가 나와있긴하니 참고해도 된다.
# 별다른건 없다😁

const Tracker = (props) => {

  const [myLoca, setMyLoca] = useState({ lat: 36.5, lng: 127.8 }); // 현재위치 객체 값 설정
  
  React.useEffect(() => {
    if (navigator.geolocation) {
      // GeoLocation을 이용해서 접속 위치를 얻어온다
      navigator.geolocation.getCurrentPosition(
        (position) => {
          setMyLoca({
            lat: position.coords.latitude,	// 위도
            lng: position.coords.longitude,	// 경도
          });
        },
        (err) => {
          alert("현재 위치를 표시할 수 없어요");
        },
        { enableHighAccuracy: true } // 위치정보의 정확도를 높이는 옵션
      );
    } else {
      // HTML5의 GeoLocation을 사용할 수 없을때
      alert("현재 위치를 표시할 수 없어요");
    }
  }, []);
  
  return (
    <Map
    	center={myLoca}
        level={3}
        style={{
          width: "100%",
          height: "100%",
        }}
    />
  );
} 


참고 링크

profile
공부중인 개발자
post-custom-banner

0개의 댓글