Logo

웹 페이지에 구글 지도 띄우기 (구글 Maps API)

구글 지도(Google Maps)는 구글에서 제공하는 글로벌 지도 서비스입니다. 네이버나 카카오에서 제공하는 지도 서비스와 달리 국내 지도 뿐만 아니라 해외 지도까지 제공하기 때문에 전 세계 사용자를 대상으로 하는 애플리케이션을 개발할 때 특히 유용하게 사용할 수 있는데요.

이번 포스팅에서는 구글 지도를 웹페이지 상에서 띄우고 제어할 때 사용하는 구글 Maps API에 대해서 알아보려고 합니다. 차근차근 따라오시다보면 위와 같은 구글 지도를 웹페이지에 나오게 수 있으실 것입니다. 😁

API 키 발급 받기

구글 Maps API를 사용하려면 우선 구글에서 발급해주는 API 키가 필요한데요. 아래 구글 클라우드 콘솔(Google Cloud Console) 링크로 들어가면 API 키를 발급받을 수 있습니다.

(이전에 구글에서 제공하는 다른 API를 사용해보신 분이라면 크게 어렵지 않겠지만, 이번에 처음으로 API 키를 발급받으시는 거라면 약간 해매실 수도 있으실 것 같아요. 하지만 API 키 발급이라는 산만 넘으면 그 다음부터는 훨씬 수월하니 부디 인내심을 갖고 꼭 성공하시기 바랍니다. 💪)

구글 Maps API는 사용한 만큼 과금이 되는 유료 API이기 때문에 반드시 결제 정보를 구글에 제공해야 AIP 키가 발급되게 되어 있습니다. 한 달에 28,500번 정도는 무료로 호출이 가능하니 개인 학습용으로는 차고 넘치실 거에요.

단, 누군가가 악의적인 의도로를 갖고 내 API 키를 사용해서 구글 Maps API를 엄청나게 호출해버리면 곤란하겠죠? 그러므로 API 키를 공유하거나 도난 당하는 일이 없도록 주의하셔야 합니다. 가장 안전한 방법은 API 키를 사용한 후 API 키를 삭제해버리시는 것일 겁니다. 🚮

실제 상용 서비스에서는 일반적으로 API 키가 특정 도메인에서만 작동하도록 제한을 두어 API 키를 보호합니다.

지도를 보여줄 구역 지정

우선 웹페이지 상에서 구글 지도를 어디에 보여줄 지를 결정하고 이 구역에 표시를 해줘야합니다. HTML 문서 상에서 지도를 보여줄 <div> 요소의 id 속성으로 map으로 설정해줍니다.

저는 구글 지도 외에는 딱히 실습 페이지에 보여줄 게 없어서 아래와 같이 HTML 코드를 작성하였습니다.

index.html
<body>
  <div id="map" style="height: 600px;"></div>
</body>

여기서 많은 분들이 간과하는 부분이 있는데요. 바로 반드시 <div> 요소의 높이를 CSS로 지정해주어야 한다는 것입니다. 비어있는 <div> 요소는 높이의 기본값은 0이 되기 때문에 구글 지도가 절대 화면 상에 나타나지 않을 것이기 때문입니다.

구글 Maps API 스크립트 불러오기

이제 HTML 문서에 2개의 자바스크립트 파일을 불러올 건데요. 첫번째 <script> 요소는 Google Maps API를 사용하기 위해 로컬에서 작성할 코드를 불러오기 위함이고, 두번째 <script> 요소는 원격에 있는 구글 서버로 부터 Google Maps API의 코드를 내려받기 위함입니다.

index.html
<head>
  <script defer src="./index.js"></script>
  <script
    defer
    src="https://maps.googleapis.com/maps/api/js?key=<API 키>&callback=initMap"
  ></script>
</head>

구글 Google Maps API의 주소에는 2개의 파라미터를 명시해줘야하는데요. key 파라미터에는 발급받은 API 키를 넣어주고, callback 파라미터에는 Google Maps API 코드의 다운로드가 완료되면 호출되야하는 함수의 이름을 넣어야하는데요. 저는 관행적으로 많이 사용하는 initMap으로 설정해주었지만 원하는 함수명을 아무거나 사용해도 무방합니다.

여기서 자바스크립트 파일을 불러올 때 defer 옵션을 사용한 이유가 궁금하신 분들은 관련 포스팅에서 자세히 다루고 있으니 참고바라겠습니다.

구글 지도 보여주기

이제 index.js 파일을 만들고 콜백 함수의 코드를 작성해볼까요? 저는 위에서 initMap을 함수명으로 사용했기 때문에, window 객체의 initMap 속성에 콜백 함수를 할당하고 있습니다.

window.initMap = function () {
  const map = new google.maps.Map(document.getElementById("map"), {
    center: { lat: 37.5400456, lng: 126.9921017 },
    zoom: 10,
  });
};

document.getElementById("map")은 HTML 문서 상에서 id 속성이 map<div> 요소를 찾아서 반환합니다. 이것을 google.maps.Map() 생성자의 인자로 넘겨서 호출하면 구글 지도 객체를 얻을 수 있습니다.

이 생성자 함수의 두 번째 인자로 구글 지도를 어떻게 보여줄건지 옵션을 넘길 수 있는데요. center 옵션에 지도의 중앙 위치의 위도 경도를 설정해주고, zoom 옵션에 지도를 얼마나 가깝게 볼 건지를 설정해줄 수 있습니다.

짜잔! 🎉 여기까지 해주면 웹페이지에 구글 지도가 나타나고 그 안에 서울시에 보일 것입니다.

마커로 위치 표시하기

구글 지도에서 특징 위치를 표시할 때는 마커(Marker)라는 것을 사용할 수 있는데요. google.maps.Marker() 생성자 함수에 마커를 놓고 싶은 위치의 위경도와 라벨(label) 그리고 위에서 생성한 지도 객체를 넘기면 됩니다.

예를 들어, 서울에 있는 7곳의 쇼핑몰을 구글 지도에 마커로 표시해볼까요?

window.initMap = function () {
  const map = new google.maps.Map(document.getElementById("map"), {
    center: { lat: 37.5400456, lng: 126.9921017 },
    zoom: 10,
  });

  const malls = [    { label: "C", name: "코엑스몰", lat: 37.5115557, lng: 127.0595261 },    { label: "G", name: "고투몰", lat: 37.5062379, lng: 127.0050378 },    { label: "D", name: "동대문시장", lat: 37.566596, lng: 127.007702 },    { label: "I", name: "IFC몰", lat: 37.5251644, lng: 126.9255491 },    { label: "L", name: "롯데월드타워몰", lat: 37.5125585, lng: 127.1025353 },    { label: "M", name: "명동지하상가", lat: 37.563692, lng: 126.9822107 },    { label: "T", name: "타임스퀘어", lat: 37.5173108, lng: 126.9033793 },  ];  malls.forEach(({ label, name, lat, lng }) => {    const marker = new google.maps.Marker({      position: { lat, lng },      label,      map,    });  });};

이제 구글 지도에 서로 다른 알파벳으로 시작하는 7개의 마커📍가 나타날 것입니다.

지도 경계 조정하기

그런데 구글 지도에 여러 장소의 위치를 표시하니 가장자리에 불필요한 영역이 좀 좀 거슬리는 것 같습니다. 마커들이 지도의 가장자리에 딱 맞도록 좀 더 타이트하게 배치되면 좋겠죠?

google.maps.LatLngBounds() 생성자로 경계 객체를 생성한 후 extend() 메서드를 호출하여 각 마커의 위치 정보를 넘겨줍니다. 그 다음에 지도 객체의 fitBounds() 메서드에 지도 경계 객체를 넘겨주세요.

window.initMap = function () {
  const map = new google.maps.Map(document.getElementById("map"), {
    center: { lat: 37.5400456, lng: 126.9921017 },
    zoom: 10,
  });

  const malls = [
    { label: "C", name: "코엑스몰", lat: 37.5115557, lng: 127.0595261 },
    { label: "G", name: "고투몰", lat: 37.5062379, lng: 127.0050378 },
    { label: "D", name: "동대문시장", lat: 37.566596, lng: 127.007702 },
    { label: "I", name: "IFC몰", lat: 37.5251644, lng: 126.9255491 },
    { label: "L", name: "롯데월드타워몰", lat: 37.5125585, lng: 127.1025353 },
    { label: "M", name: "명동지하상가", lat: 37.563692, lng: 126.9822107 },
    { label: "T", name: "타임스퀘어", lat: 37.5173108, lng: 126.9033793 },
  ];

  const bounds = new google.maps.LatLngBounds();
  malls.forEach(({ label, name, lat, lng }) => {
    const marker = new google.maps.Marker({
      position: { lat, lng },
      label,
      map,
    });
    bounds.extend(marker.position);  });

  map.fitBounds(bounds);};

이렇게 마커들이 지도에 골고루 배치가 되고 줌(zoom)도 그에 맞게 적당히 조정이 될 것입니다.

클릭 시 정보 보여주기

각 마커를 클릭했을 때 그 위치에 대한 부가적인 정보를 제공하면 매우 유용할 것 같은데요. 이럴 때는 구글 지도에서 정보창(Info Window)이라 것을 사용할 수 있습니다.

우선 google.maps.InfoWindow() 생성자로 정보창을 하나 생성합니다. 그 다음, 각 마커의 클릭(click) 이벤트가 발생하면 정보창이 뜨도록 설정해주세요.

window.initMap = function () {
  const map = new google.maps.Map(document.getElementById("map"), {
    center: { lat: 37.5400456, lng: 126.9921017 },
    zoom: 10,
  });

  const malls = [
    { label: "C", name: "코엑스몰", lat: 37.5115557, lng: 127.0595261 },
    { label: "G", name: "고투몰", lat: 37.5062379, lng: 127.0050378 },
    { label: "D", name: "동대문시장", lat: 37.566596, lng: 127.007702 },
    { label: "I", name: "IFC몰", lat: 37.5251644, lng: 126.9255491 },
    { label: "L", name: "롯데월드타워몰", lat: 37.5125585, lng: 127.1025353 },
    { label: "M", name: "명동지하상가", lat: 37.563692, lng: 126.9822107 },
    { label: "T", name: "타임스퀘어", lat: 37.5173108, lng: 126.9033793 },
  ];

  const bounds = new google.maps.LatLngBounds();
  const infowindow = new google.maps.InfoWindow();
  malls.forEach(({ label, name, lat, lng }) => {
    const marker = new google.maps.Marker({
      position: { lat, lng },
      label,
      map,
    });
    bounds.extend(marker.position);

    marker.addListener("click", () => {      infowindow.setContent(name);      infowindow.open({        anchor: marker,        map,      });    });  });

  map.fitBounds(bounds);
};

지도 중심 이동하기

마커를 클릭했을 때 마커가 있는 위치로 지도의 중심이 이동한다면 사용자에게 좀 더 동적인 경험을 제공할 수 있겠죠?

이 때는 지도 객체의 panTo() 메서드에 마커의 위치 정보를 넘기면 되겠습니다.

window.initMap = function () {
  const map = new google.maps.Map(document.getElementById("map"), {
    center: { lat: 37.5400456, lng: 126.9921017 },
    zoom: 10,
  });

  const malls = [
    { label: "C", name: "코엑스몰", lat: 37.5115557, lng: 127.0595261 },
    { label: "G", name: "고투몰", lat: 37.5062379, lng: 127.0050378 },
    { label: "D", name: "동대문시장", lat: 37.566596, lng: 127.007702 },
    { label: "I", name: "IFC몰", lat: 37.5251644, lng: 126.9255491 },
    { label: "L", name: "롯데월드타워몰", lat: 37.5125585, lng: 127.1025353 },
    { label: "M", name: "명동지하상가", lat: 37.563692, lng: 126.9822107 },
    { label: "T", name: "타임스퀘어", lat: 37.5173108, lng: 126.9033793 },
  ];

  const bounds = new google.maps.LatLngBounds();
  const infoWindow = new google.maps.InfoWindow();

  malls.forEach(({ label, name, lat, lng }) => {
    const marker = new google.maps.Marker({
      position: { lat, lng },
      label,
      map,
    });
    bounds.extend(marker.position);

    marker.addListener("click", () => {
      map.panTo(marker.position);      infoWindow.setContent(name);
      infoWindow.open({
        anchor: marker,
        map,
      });
    });
  });

  map.fitBounds(bounds);
};

전체 코드

본 포스팅에서 작성한 코드는 아래에서 확인하시고 직접 실행해보실 수 있습니다.

마치면서

지금까지 간단한 예제 코드를 작성하면서 구글 Maps API를 어떻게 사용하는지 대략적으로 살펴보았습니다. 구글 Maps API를 활용할 수 있는 방법은 무궁무진하기 때문에 이 포스팅을 통해 어느 정도 감을 잡으셨다면 이제 공식 레퍼런스를 보시면서 다른 기능들에 대해서도 배워보시면 좋을 것 같습니다.