[REACT] KAKAO MAPS API 사용해서 지도 그리기, 현재 위치 받기 with TypeScript

THOVY·2022년 12월 31일
3

PROJECT

목록 보기
19/20

kakao map api 를 이용해 페이지에 지도를 출력할거다.

CRA 로 프로젝트를 만들었고 TS 를 사용합니다.

준비물: kakao 개발센터 map api APP KEY

참고: Kakao Maps API 를 보고 따라해보자.
매우 간단하고 직관적으로 적혀있어서 한번이라도 보면 대강 이해가 된다. 물론 vanilajs
참고로 KAKAO MAPS 는 TS 에 대한 타입설정을 해놓은 공식 패키지가 없단다. 네이버는 있다.
언젠가 같은 사고를 당한 두 기업의 달랐던 결과가 떠오르죠?

재밌는 api 사용

시작 👊

사랑합니다 카카오.

  1. APP KEY 를 사용할 건데 이 소중한 걸 그냥 html 에 박아놓을 순 없으니 <.env 파일 에 app key 넣기> 를 보고 옵니다.
  1. env 에 넣었다면, index.html
<!-- index.html -->
<script type="text/javascript" strategy="beforeInteractive" src="//dapi.kakao.com/v2/maps/sdk.js?appkey=<%= process.env.REACT_APP_KAKAOMAP_API_KEY%>"></script>

지도 그리는 api script 를 이렇게 넣어 사용할 수 있을 거예요.

strategy="beforeInteractive" : 어떤 코드보다도 먼저 script 를 로드하게 해준답니다.
카카오의 설명서에도 이렇게 적혀있기 때문에 적어줍시다.
사실 지금 당장은 문제가 되지 않을 수 있지만, 나중에 이것 저것 살을 붙이다보면 컴퓨터일이 어떻게 될지 모르잖아요?

  1. 그리고 그 지도가 그려질 틀을 만들어야하는데,
    나는 html 파일에 div 를 이용해 지도틀을 만들어주지 않고, 컴포넌트로 만들어줄거다.
    그래서 컴포넌트의 return 에다가 div 를 만들어서 id='map' 이라고 해줬다.
// Map.tsx
return (
        <div id="map" style={{ width:"500px", height:"400px"}}></div>
  )
  1. 지도를 띄우는 코드 작성을 해볼 건데, 일단 그대로 넣어줘도 된다. 그다음 ts 에 맞게 타입을 지정해줘야하는데.
    요기 ( kakao.maps.d.ts - JaeSeo Kim ) 를 참고해서 타입 정의 패키지를 설치해주자.

❗ 타입 굳이 정의 하기 싫다? html 에 그냥 다 갖다 써주면된다.

<!-- index.html -->
<script>
  var container = document.getElementById('map'); //지도를 담을 영역의 DOM 레퍼런스
  var options = { //지도를 생성할 때 필요한 기본 옵션
      center: new kakao.maps.LatLng(33.450701, 126.570667), //지도의 중심좌표.
      level: 3 //지도의 레벨(확대, 축소 정도)
  };

  var map = new kakao.maps.Map(container, options); //지도 생성 및 객체 리턴
</script>
  1. 하지만 그냥 갖다쓰기 싫기 때문에 컴포넌트 Map.tsx 에 script 를 넣어줘야지
// Map.tsx

const mapRef = useRef<HTMLElement | null>(null);

const initMap = () =>{
  const container = document.getElementById('map');
  const options = {
    center: new kakao.maps.LatLng(37.483034, 126,902435),
    level: 2
  };

  var map = new kakao.maps.Map(container as HTMLElement, options);
  (mapRef as MutableRefObject<any>).current = map;
}

useEffect(()=>{
  kakao.maps.load(()=>initMap());
},[mapRef])

return (
  <div id="map" style={{ width:"500px", height:"400px"}}></div>
)

이렇게 하면 map 을 바로 로드해준다.

지도 그리기 끝

추가

현재 위치로 시작하기.

나의 현재 위치를 시작으로 지도를 살피고 싶기 때문에, 내 현재 위치에서 지도가 그려지면 좋겠다.

  1. React 의 navigator.geolocation 을 이용해 현재 값을 받아올 Locations.tsx 를 만들었다.
// Locations.tsx

const [location, setLocation] = useState<{latitude: number; longitude: number} | string>('');

useMemo(()=>{
  if (navigator.geolocation){
    navigator.geolocation.getCurrentPosition(success, error);
  }

  function success(position: any){
    setLocation({
      latitude: position.coords.latitude,
      longitude: position.coords.longitude
    });
  }

  function error(){
    setLocation({
      latitude: 37.483034,
      longitude: 126.902435
    })
    console.log("위치 받기 실패");
  }
},[navigator.geolocation.getCurrentPosition])

return ( location )
  1. 받아온 위치를 Map.tsx 에서 사용하도록 코드를 수정한다.
// Map.tsx

const location:any = Locations();

...


const initMap = () =>{
  if (typeof location != 'string' ){
    const container = document.getElementById('map');
    const options = {
      center: new kakao.maps.LatLng(location.latitude, location.longitude),
      level: 2
    };

    var map = new kakao.maps.Map(container as HTMLElement, options);
    (mapRef as MutableRefObject<any>).current = map;
  }
}

useEffect(()=>{
  kakao.maps.load(()=>initMap());
},[mapRef, location])

처음부터 나의 현재 위치로 지도를 잘 그려준다.

버튼 클릭으로 위치 조정하기

지도를 이리저리 옮겨다니며 보다가. 다시 내 위치로 돌아오고 싶어.
되돌아가기 버튼을 만들어야겠죠?

나는 지금 일단 매우 단순하게 기능을 중점적으로 만들고 있기 때문에 그냥 return 에 때려박았는데 나중에 component 로 빼는 게 좋을 거다.

아무튼 시작

  1. button 만들기
// Map.tsx

...

return(
  <>
  	<div id="map" style={{ width:"500px", height:"400px"}}></div>
	<button>위치 조정</button>
  </>
  1. 이따구로 만들어지죠?
  1. 하지만 중요한 건 기능이지. 버튼을 클릭했을 때 위치조정될 이벤트를 만들어주자.
// Map.tsx

...

return(
  <>
  	<div id="map" style={{ width:"500px", height:"400px"}}></div>
	<button
		onClick={()=>initMap}
	>위치 조정</button>
  </>
  1. 그럼 일단 위치를 잘 찾아간다. 왜냐면 지도를 이리저리 이동한다고 해도
    locations 변수에는 내 현재 위치가 잘 들어가 있기 때문이다. 그래서 그냥 지도를 다시 그려주면됨.
  1. 하지만 버튼을 저렇게 절반만 보여준다면 가슴이 너무 아프니까 CSS postionz-index 을 사용해서 올려준다.
// Map.tsx

...

return(
  <>
  	<div id="map" style={{ width:"500px", height:"400px"}}></div>
	<button
		style={{ position:"relative", zIndex:"2"}}
		onClick={()=>initMap}
	>위치 조정</button>
  </>

❗ 만약에 지도틀인 mapz-index:"-1" 로 내려버리면, 지도를 이리저리 움직일 수 없게 된다.
pointer-events:none 으로도 조작이 안되니 position 을 이용하도록 하자.

  1. 대충 만든 거지만 올라왔죠?

    더 세밀한 조정은 나중에 CSS 를 전반적으로 만질 때 만들기로 하고, 일단 지도 잘 그리고 위치조정 잘 되잖아요?

진짜 끝

별거 아닌 거 같았던 지도그리기가 끝났다.
별거 아니긴 한데 뭔게 얼렁뚱땅 만들어낸 거 같은 기분이 든다. Kakao Maps DocsKakao Maps Sample 을 보면서 그리는 것부터 제대로 만들어볼까 하는데, 그리는 건 이게 다인 거 같다.

그 뒤에 내가 더 원하는 기능은 지도에 Kakao Maps 커스텀 오버레이 생성하기 2 정도인데

적당히 응용하면 될 거같다

매우 많은 도움이 된 참고
kakao maps 전환기
naver map 생성하기
JaeSeo Kim - kakao.maps.d.ts
react 에서 geolocation 사용하기

profile
BEAT A SHOTGUN

0개의 댓글