gocamp - naver map api(3) / 마커

ryan·2022년 8월 15일
0

개요

전국 야영장 데이터를 네이버 map에 오버레이하기 위해선 marker를 사용해야 한다.

마커 생성 / 마커 이벤트 등록

  • map을 생성하는 것과 동일하게 Marker 객체를 새롭게 생성하면 간편하게 마커를 생성할 수 있다.

mapApis.js

  • addMarkerHandler라는 함수로 분리하여 마커를 추가했다.
  • 매개변수로는 naver 객체와 map을 관리하고 있는 mapRef를 받고 mapRef 객체의 내부 값인 marker에 Marker 객체를 넣어 관리한다.
  • MarkerOption으로는 position(마커가 생성되는 위치), map(참조할 대상), icon(marker)
    • icon option에는 url/content/size/anchor 등 다양한 옵션으로 마커의 세부적인 위치, css등을 설정해줄 수 있다.
  • 마커 이벤트는 지도에 이벤트를 등록하는 것과 동일하게 해줄 수 있다.
export const addMarkerHandler = (naver, ref) => {
  // 마커 생성 
      ref.marker = new naver.maps.Marker({
        position: new naver.maps.LatLng(number, number),
        map: ref.map,
        icon: {
          url: "/img/logo32.png",
          size: new naver.maps.Size(32, 32),
          anchor: new naver.maps.Point(0, 0),
        },
      });
      // 마커 클릭 이벤트 등록
      naver.maps.Event.addListener(ref.marker, "click", () => {
			console.log('marker clicked')
      });
    });
  }
};

다중 마커 생성

  • 고캠프의 경우, 지도 위치를 기반으로 야영장 배열이 반환되는 형태를 취하고 있다. 배열을 통해 다중 마커를 생성할 수 있다.
  • 다중 마커를 생성할 때 유의할 점은 등록한 마커 객체를 배열로 관리해야 나중에 삭제할 수 있다.
    • naver map api에서는 오버레이를 따로 관리하는 api는 없기 때문이다.

mapAPis.js

  • list라는 야영장 배열 데이터를 매개변수로 받아 list에 map을 사용하여 마커 객체를 생성했고, mapRef.current.markerList에 넣어준 뒤 마커 배열을 관리했다.
export const addMarkerHandler = (naver, ref, list) => {
    list.map((e) => {
      ref.marker = new naver.maps.Marker({
        position: new naver.maps.LatLng(Number(e.mapY), Number(e.mapX)),
        map: ref.map,
        icon: {
          url: "/img/logo32.png",
          size: new naver.maps.Size(32, 32),
          anchor: new naver.maps.Point(0, 0),
        },
      });
      // ref에 마커 객체 넣어주기
      ref.markerList.push(ref.marker);

      // 마커 클릭 이벤트 설정
      naver.maps.Event.addListener(ref.marker, "click", () => {
		console.log(e)
      });
    });
  }
};

마커 삭제하기

  • 마커를 삭제해야 하는 상황은 다양하지만, 나의 경우 성능 관리를 위해 마커를 삭제해야 됐다.
    • naver api의 공식 답변으로는 보통 200개 이상의 마커가 지도에 찍혀있으면 과부하가 걸려 버벅일 수 있다고 한다.
  • mapRef.current.markerList로 관리하고 있는 마커 배열에 반복문으로 마커를 삭제할 수 있다.

mapApis.js

  • addMarkerHandler 함수에 첫 부분에 기존 마커를 삭제하는 부분을 추가해줬다.
  • 첫 렌더링이나, 데이터가 없는 지역도 있기 때문에 야영장 데이터가 생성되지 않은 경우 return하는 if문을 추가했다.
  • markerList에 값이 있으면 반복문으로 마커 배열을 돌면서 setMap(null)을 통해 오버레이(마커)를 제거해준다. 그리고 마커 배열을 빈 배열로 초기화해준다.

    순서
    myLocation state 변경 > 야영장 데이터 받아오기 > 마커 삭제 > 마커 추가 반복

export const addMarkerHandler = (naver, ref, list, pick) => {
  if (!Array.isArray(list)) return;
  // 기존 마커 있는 경우, 초기화
  if (ref.markerList[0]) {
    ref.markerList.forEach((e) => {
      e.setMap(null);
    });
    // markerList 배열 초기화
    ref.markerList.splice(0);
  }

기타 (api로 지도 조작하기)

  • 사용자가 직접 지도를 조작해서 움직이는 것이 아니라, 어떤 텍스트를 클릭하거나 마커를 클릭했을 때 지도 위치가 자동적으로 움직이게 하고 싶다면 Map 객체 메서드를 사용할 수 있다. 참고자료의 naver map api 2에서 확인할 수 있다.

mapApis.js

  • 클러스터링된 마커에 등록한 클릭 이벤트 리스너이다.
  • morph메서드의 경우 매개변수로 위치 정보, zoom level을 받는다.
  • 이외에 panTo, getBounds 등 유용한 메서드가 매우 많다.
 naver.maps.Event.addListener(ref.marker, "click", (e) => {
        ref.map.morph(e.coord, 12);
      });

결과물

  • 마커 클러스터링의 경우, naver map api를 사용하지 않고 javascript로 직접 구현했기 때문에, 이후 문제 해결 포스팅에서 다룰 예정이다.

마커 클러스터링

마커

마커 이벤트

  • 클러스터링된 마커를 클릭할 경우 중심 지역으로 확대

마커 이벤트(2)

  • 일반 마커를 클릭할 경우, 상세 정보 표시

참고자료

profile
프론트엔드 개발자

0개의 댓글