Day 29

김정동·2021년 12월 9일
0

우리는 물론 카카오지도를 써보겠으나

구글, 네이버, 카카오 지도 세가지가 있다.

국내에서는 지금 카카오맵을 쓰는게 좀 더 부드럽다(구글의 경우는 조금 더 비쌈)

각각 사이트들은 개발자 사이트가 따로 있다.

Meta의 개발자 사이트(페이스북)

네이버 개발자 사이트

https://developers.kakao.com/

카카오개발자 사이트

문서로 가면 지도에 관한 부분이 있다.

1일 300,000회까지는 무료라고 써있고
왼쪽에는 guide(세팅) sample(예제), docs(추가내용)이 있다.

그럼 가이드로 들어가서 연결해보자
(!주의사항은 next까지쓸때의 변경점)

개발자 등록 및 앱 생성 부분을 하기 위해서
카카오 개발자사이트에 로그인을 먼저 해야한다. 내 애플리케이션 - 애플리케이션 추가하기


프로젝트명, 로고, 사업자명 등을 설정할 수 있다.

여기서 중요한 것은 앱 키다. 각각 용도에 맞는 기능을 사용할 때 이 기능을 써야한다.
또한 이 키가 돈과 관련되어있기 때문에 이 키는 유출하지 않는게 좋다.

플랫폼 - web - 등록하기

http://localhost:3000 (로컬호스트일때는 이렇게 입력한다 3000은 포트)

이럼 기본적인 세팅은 끝이다.

시작하기부분으로 가보자

자바스크립트 API를 불러오는 부분을 Head에 담고(기능가져오기)

담을 영역을 만들기 부분을 Return 부분에 담고(지도를 담을 박스 만들기)


코드 작성 부분이 이제 실제로 지도를 띄우는 부분이다.

실제 코드를 작성해보자

근데 지도를 담을 영역을 만들기를 붙이려고 보니 예제는 HTML이고,
내가 작성하는건 JSX(javaScript XML)이다. 자바스크립트로 작성하는 html로 생각하면 편하다. 즉 이뜻은 HTML과 완전히 같지 않다는 뜻

그래서 그대로 쓰면 에러만 날 뿐이다

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

이렇게 바꿔야한다. style안에{}{width와 height}를 담는 느낌이라 2개의 중괄호를 써야한다.

스크립트를 불러오기 위해서는 Head를 써야한다.

import Head from "next/head";

그리고 return 부분 Head 안에 스크립트를 작성하면된다.

import Head from "next/head";
export default function KakaoMapPage() {
  return (
    <>
      <Head>
        <script
          type="text/javascript"
          src="//dapi.kakao.com/v2/maps/sdk.js?appkey=발급받은 APP KEY를 넣으시면 됩니다."
        ></script>
      </Head>
      <div id="map" style={{ width: "500px", height: "400px" }}></div>
    </>
  );
}

이제 APP key를 넣으라고 나온다.

아까 봤던 앱 키들 중 javaScript키를 복사해서 붙여넣는다.

그리고 이제 코드 작성 부분을 붙여넣으면 되는데
이제보면 div map을 그리고 나서 지도를 띄우는 코드를 실행시켜야되는데 이대로라면 코드가 먼저 실행되서 지도가 뜰 수 없다.

-> 배웠던 UseEffect를 사용해서 나중에 실행되게한다.

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

  const map = new window.kakao.maps.Map(container, options); // 지도 생성 및 객체 리턴
}, []);

위치를 바꾸고 싶다면 지도상의 좌표를 가져와서 수정하면된다.

구글 지도에서 원하는 위치를 찍으면 좌표가 나오고 그 좌표로 수정하면 된다.

그리고 타입부분이 정해지지 않았다.
window 를 넣어서 전역변수 안에 넣는다, 그리고 타입을 지정해주면 된다. (하는김에 오래된 var도 const로 바꾸자)

declare const window: typeof globalThis & {
kakao: any;
};

const map = new window.kakao.maps.Map(container, options); // 지도 생성 및 객체 리턴

근데 아무리 키를 숨겨봤자 개발자 도구- head에 가면 누구든지 내 앱키를 볼 수 있다.

웹 도메인을 지정한 이유가 있다. 도메인 인증을 거친다음, localhost:3000이 아니면 실행되지 않게끔 지정했다.

만약 진짜 찐짜 노출하고 싶지 않다면???
-> 백엔드에 저장하는게 좋다.

완성 예시

import Head from "next/head";
import { useEffect } from "react";

declare const window: typeof globalThis & {
  kakao: any;
};

export default function KakaoMapPage() {
  useEffect(() => {
    const container = document.getElementById("map"); // 지도를 담을 영역의 DOM 레퍼런스
    const options = {
      // 지도를 생성할 때 필요한 기본 옵션
      center: new kakao.maps.LatLng(37.513742, 126.979394), // 지도의 중심좌표.
      level: 3, // 지도의 레벨(확대, 축소 정도)
    };

    const map = new window.kakao.maps.Map(container, options); // 지도 생성 및 객체 리턴
  }, []);

  return (
    <>
      <Head>
        <script
          type="text/javascript"
          src="//dapi.kakao.com/v2/maps/sdk.js?appkey=나의앱키"
        ></script>
      </Head>
      <div id="map" style={{ width: "500px", height: "400px" }}></div>
    </>
  );
}

이렇게 기본 지도 표시는 됐지만 다양한 기능을 추가할 수 있다.

마커표시나 다각형 이벤트 등록하기 등등, sample에 다있음

Next를 쓰면서 생기는 문제

import { useRouter } from "next/router";

export default function KakaoMapRoutingPage() {
const router = useRouter();
function onClickMoveToMap() {
  router.push("/29-03-kakao-map-routed");
}

return <button onClick={onClickMoveToMap}> 맵으로 이동하기!</button>;
}

이렇게 간단한 코드를 작성해서 아까 만든 카카오맵(routed로 이름을 바꿨을뿐)으로 router를 통해서 이동하게 했는데 에러가 뜬다.

브라우저에서 Frontend에서 HTML, CSS, JS를 가져온다

router의 이동방식은 전체를 다 가져와서 보여줄 페이지를 보여주고 안쓰는 페이지는 감추는 방식이다
이를 SPA(Single Page Application)

사실상 한 페이지를 통채로 가져온 건데 보여주는 것이 다를 뿐이다.
이런 SPA 는 이전의 html 과 다른방식으로 이런 방식을 사용하면 페이지 한번 바꿀때마다 새로고침을 하는게 아니고 이미 한번에 다 그려왔기 때문에 훨씬 좋다.
즉 이전 자바스크립트보다 더 성능이 좋은 개념이라고 본다.

근데 이 과정이랑 router를 썼는데 뭐가 문젠가?
head에 있던 카카오 map이 없는데 useeffect로 카카오맵을 불러왔으니 작동하지 않은 것이다.

그래서 어떻게 고치나요?
두가지방법이 있다.

첫번째 다운로드를 미리한다.
app.js를 수정한다(맨 처음 실행되는 페이지)

return (
    <>
      <Head>
        <script
          type="text/javascript"
          src="//dapi.kakao.com/v2/maps/sdk.js?appkey=b69e916819dbc040afacc37720eebc50"
        ></script>
      </Head>
      <GlobalContext.Provider value={myvalue}>
        <ApolloProvider client={client}>
          <Global styles={globalStyles} />
          <Layout>
            <Component {...pageProps} />
          </Layout>
        </ApolloProvider>
      </GlobalContext.Provider>
    </>
  );
  // 물론 헤드도 import해온다

근데 맵을 쓰지 않는 페이지 또한 다운받아와야함으로 비효율적이다.

useEffect안에서 스크립트가 실행될 수 있도록 한다.

    const script = document.createElement("script"); // <script></script>
    script.src =
      "//dapi.kakao.com/v2/maps/sdk.js?appkey=나의키";

이후 만든 스크립트를 return의 head에 넣는다고하고

document.head.appendChild(script);

그때 실행시킨다고 명령을 내려야한다.

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

      const map = new window.kakao.maps.Map(container, options); // 지도 생성 및 객체 리턴
    };

쿼리스트링

그리고 autoload를 false를 써야되는데 앞에 appkey도 있으니 &으로 연결해야한다.이렇게 키와 밸류로 연결된 것을 쿼리스트링이라고한다.
(autoload에 관한 부분은 docs를 참고한다)

이렇게 하면 맵이 실제로 필요한 페이지에서만 쓸 수 있게된다.

마커 생성하기

sample에가보면 이렇게 마커를 추가하는 예시가 있다.

이미 앞에 지도를 띄우는 예제는 했으니 마커를 표시하는 부분만 넣으면 된다.

짜잔 - 대신 오래된 var와 위도, 경도는 내가 아까 설정한 곳이나, 구글지도를 참고한다.

클릭한 위치에 마커 표시하기

이번에도 지도를 표시할 부분까지는 다 작성했으니 marker.setMap(map) 아래부분만 붙이면된다.

다각형에 이벤트 등록하기

다각형에 이벤트 등록하기도 같은원리다
지도를 표시하는 부분
var map = new kakao.maps.Map(mapContainer, mapOption); // 지도를 생성합니다

밑에 붙이면 작동한다.
근데 위치가 제주도로 설정되어있어서

제주도의 정해진 위치에만 초록색 구역이 설정된다.
(공통적으로 var를 let으로 고치고 window.을 붙임)

좌표를 바꾸면 이렇게 원하는 위치로 바꿀 수 있다.
(공통적으로 var를 let으로 고치고 window.을 붙임)

profile
개발자 새싹🌱 The only constant is change.

0개의 댓글