Vue.js에서 카카오맵API 사용하기

sdsdsrd·2020년 11월 15일
3

졸업프로젝트

목록 보기
14/15
post-thumbnail

1. 카카오맵 api 사용하기

package.json

"eslintConfig": {
  "globals": {
    "kakao": false
  }
}

추가한다.

mounted() {
  if (window.kakao && window.kakao.maps) {
    this.initMap();
  } else {
    const script = document.createElement('script');
    /* global kakao */
    script.onload = () => kakao.maps.load(this.initMap);
    script.src =
      'http://dapi.kakao.com/v2/maps/sdk.js?autoload=false&appkey=카카오API_KEY';
    document.head.appendChild(script);
  }
},

2. 지도 나타내기 (methods 부분)

methods: {
  initMap() {
    var mapContainer = document.getElementById('map'), // 지도를 표시할 div
        mapOption = {
          center: new kakao.maps.LatLng(37.564343, 126.947613), // 지도의 중심좌표
          level: 3, // 지도의 확대 레벨
        };

    var map = new kakao.maps.Map(mapContainer, mapOption);

3. 마커 이미지를 사용하여 여러개의 마커 띄우기

var positions = [
  {
    id: 1,
    store: '학생문화관점',
    location: '학생문화관 지하1층 로비',
    time: '학기 중: 월~금 08:30~19:00 | 토 09:00~14:00',
    vacation: '방학 중: 월~금 08:30~18:00 | 토 09:00~14:00',
    tel: '02-3277-3707',
    latlng: new kakao.maps.LatLng(37.562632898194835, 126.9454282268269),
  },
  {
    ...
    latlng: new kakao.maps.LatLng(37.56195884514403, 126.94922601468826),
  },
  ...

  var imageSrc = require('@/assets/marker.png'), // 마커이미지의 주소입니다
    imageSize = new kakao.maps.Size(24, 35), // 마커이미지의 크기입니다
    imageOption = { offset: new kakao.maps.Point(20, 35) }; // 마커이미지의 옵션입니다. 마커의 좌표와 일치시킬 이미지 안에서의 좌표를 설정합니다.

// 마커의 이미지정보를 가지고 있는 마커이미지를 생성합니다
var markerImage = new kakao.maps.MarkerImage(imageSrc, imageSize, imageOption);

// 마커를 생성합니다
  positions.forEach(function(pos) {
    var marker = new kakao.maps.Marker({
      map: map, // 마커를 표시할 지도
      position: pos.latlng, // 마커의 위치
      image: markerImage,
    });
  

4. 커스텀 오버레이 띄우기

먼저 html로 작성하면

<div class="overlaybox">
  <div class="map-popup-title">
    <h3 class="popup-name">공학관점</h3>
    <div class="congestion">
      <span class="congestion-text">바쁨</span>
    </div>
  </div>
  <span class="store-location">아산공학관 1층(110호)</span>
  <div>
    <span class="when">학기 중:</span>
    <span class="time-text">평일 08:30~19:00</span>
    <span class="bar">|</span>
    <span class="time-text">주말 08:30~19:00</span>
  </div>
  <div>
    <span class="when">방학 중:</span>
    <span class="time-text">평일 08:30~19:00</span>
    <span class="bar">|</span>
    <span class="time-text">주말 08:30~19:00</span>
  </div>
  <span class="telephone">02-3277-4873</span>
  <div class="popup-buttons">
    <div>
      <button class="popup-button" type="button">취소</button>
    </div>
    <div>
      <button class="popup-button" type="button">선택</button>
    </div>
  </div>
</div>

이 모양을 DOM Manipulation을 이용해서 만들어준다.

//for문이 아닌 forEach를 이용하여 dom에 직접 접근해야한다.
positions.forEach(function(pos) {
  // 마커를 생성합니다
  var marker = new kakao.maps.Marker({
    map: map, // 마커를 표시할 지도
    position: pos.latlng, // 마커의 위치
    image: markerImage,
  });

  var customOverlay = new kakao.maps.CustomOverlay({
    position: pos.latlng,
    xAnchor: 0.5,
    yAnchor: 1.05,
  });

  var content = document.createElement('div');
  content.className = 'overlaybox';

  var title = document.createElement('div');
  title.className = 'map-popup-title';

  var store = document.createElement('h3');
  store.className = 'popup-name';
  store.appendChild(document.createTextNode(pos.store));
  title.appendChild(store);
  content.appendChild(title);

  var location = document.createElement('span');
  location.className = 'store-location';
  location.appendChild(document.createTextNode(pos.location));
  content.appendChild(location);

  var timeContainer = document.createElement('div');

  var time = document.createElement('p');
  time.className = 'time-text';
  time.appendChild(document.createTextNode(pos.time));
  timeContainer.appendChild(time);
  var vacation = document.createElement('p');
  vacation.className = 'time-text';
  vacation.appendChild(document.createTextNode(pos.vacation));
  timeContainer.appendChild(vacation);
  content.appendChild(timeContainer);

  var tel = document.createElement('span');
  tel.className = 'telephone';
  tel.appendChild(document.createTextNode(pos.tel));
  content.appendChild(tel);

  var buttonContainer = document.createElement('div');
  buttonContainer.className = 'popup-buttons';

  var closeBtn = document.createElement('button');
  closeBtn.className = 'popup-button';
  closeBtn.appendChild(document.createTextNode('취소'));
  closeBtn.onclick = function() {
    customOverlay.setMap(null);
  };

  var selectBtn = document.createElement('button');
  selectBtn.className = 'popup-button';
  selectBtn.appendChild(document.createTextNode('선택'));
  selectBtn.onclick = function() {
    if (localStorage.getItem('store-id') != pos.id) { //store가 바뀌면 현재 장바구니를 비운다
      if (localStorage.length > 0) {
        for (let i = 0; i < localStorage.length; i++) {
          if (
            localStorage.key(i) !== 'loglevel:webpack-dev-server' &&
            localStorage.key(i) !== 'store-id' &&
            localStorage.key(i) !== 'store' &&
            localStorage.key(i) !== 'nearest-store-id' &&
            localStorage.key(i) !== 'nearest-store'
          ) {
            localStorage.removeItem(localStorage.key(i));
          }
        }
      }
    }
    localStorage.setItem('store-id', pos.id);
    localStorage.setItem('store', pos.store);
    customOverlay.setMap(null);
    window.location.reload();
  };

  buttonContainer.appendChild(closeBtn);
  buttonContainer.appendChild(selectBtn);

  content.appendChild(buttonContainer);

  kakao.maps.event.addListener(marker, 'click', function() {
    customOverlay.setMap(map);
  });

  customOverlay.setContent(content);
});

5. 현재 위치에서 가장 가까운 store 찾기

if (navigator.geolocation) {
  // GeoLocation을 이용해서 접속 위치를 얻어옵니다

  navigator.geolocation.getCurrentPosition(function(position) {
    var lat = position.coords.latitude, // 위도
        lon = position.coords.longitude; // 경도

    var polyline = new kakao.maps.Polyline({
      path: [new kakao.maps.LatLng(lat, lon), positions[0].latlng],
    });
    var minDistance = polyline.getLength();
    var minIndex = 0;
    for (let i = 1; i < positions.length; i++) {
      polyline = new kakao.maps.Polyline({
        path: [new kakao.maps.LatLng(lat, lon), positions[i].latlng],
      });
      var distance = polyline.getLength();
      if (minDistance > distance) {
        minDistance = distance;
        minIndex = i;
      }
    }

    localStorage.setItem('nearest-store-id', positions[minIndex].id);

    localStorage.setItem('nearest-store', positions[minIndex].store);
  });
} else {
  // HTML5의 GeoLocation을 사용할 수 없을때 마커 표시 위치와 인포윈도우 내용을 설정합니다
  // eslint-disable-next-line no-unused-vars
  var locPosition = new kakao.maps.LatLng(37.564343, 126.947613);
}

6. 결과화면

2개의 댓글

comment-user-thumbnail
2021년 4월 16일

안녕하세요.
기프티스타라는 앱이 있는데 이와 유사한 서비스를 기획했는데 혹시 알바로 구현해 주실 수 있으신지요?
연락 주시면 감사하겠습니다. 010 7168 1777

답글 달기
comment-user-thumbnail
2021년 9월 30일

안녕하세요 : ) 지나가던 주니어 개발자입니다. 소연님 포스팅 덕분에 카카오맵 위에서 마커까지 올바르게 구현할 수 있었습니다. 큰 도움 주셔서 너무 감사합니다!!

답글 달기