[React/Typescript] 네이버 지도 API (3편) - 보이는 지도의 영역에만 마커 표시하기

bible_k_·2023년 10월 31일
3

네이버 Map API

목록 보기
3/5

api 연동, 지도 생성, 여러개의 마커 생성에 대한 내용은 1~2편을 참고해주시길 바랍니다.

지도 마커를 여러개 찍는 경우라면 이미 한두개는 아닐 것입니다.
지도를 움직일 때마다 마커가 노출되어야하니 마커를 만들어서 배열에 담아둬야하지요.
하지만 보이는 영역의 외의 마커를 적절히 처리하지 않으면 화면에서는 보이지 않아도 성능 이슈가 발생합니다.

https://developers.naver.com/forum/posts/26171

저도 300개 이상의 데이터를 지도에서 마커로 관리해야했고, 혹시나 하는 마음에 찾아보니 위와 같은 네이버 개발자센터 답변을 확인할 수 있었습니다.
"200~250개 정도를 찍으면 성능이슈로 인해 서비스가 어려운 상태가 된다"

이번 편에서는 보이는 영역의 마커만 노출시키고 그 외의 마커는 숨기는 방법을 알아보겠습니다.

1. 이벤트 핸들러 등록

useEffect를 사용해 지도가 새로 그려질 때 이벤트 리스너를 등록하고, 컴포넌트가 언마운트 될 때 이벤트리스너를 해제해줍니다.
idle: 지도 움직임이 멈추었을 때 이벤트 발생
idle 이벤트가 발생하면, 즉 지도의 움직이고 멈추면 indleHandler 함수를 실행시킵니다.

  useEffect(() => {
    if (newMap) {
      const MoveEventListner = naver.maps.Event.addListener(
        newMap,
        'idle',
        idleHandler
      );
      return () => {
        naver.maps.Event.removeListener(MoveEventListner);
      };
    }
  }, [newMap]);

  const idleHandler = () => {
    updateMarkers(newMap, createMarkerList);
  };

2. idleHandler

지도가 움직이면 idleHandler를 통해 updateMarkers 함수를 호출합니다.
이 때 파라미터는 지도 인스턴스와 마커 객체 배열을 넣어줍니다.

  const idleHandler = () => {
    updateMarkers(newMap, createMarkerList);
  };

3. updateMarkers

updateMarkers에서는 마커가 현재 보이는 영역에 있는지 확인하고 보이는 영역에 있다면 showMarker 함수 호출, 숨겨진 영역에 있다면 hideMarker 함수를 호출합니다.

Map 클래스의 getBounds 메서드:

  • 지도 화면의 좌표 경계를 반환합니다.
  • 반환된 좌표 객체는 hasPoint 메서드를 가지며 이 메서드를 통해 객체의 좌표 경계 내에 지정한 좌표가 있는지 여부를 확인할 수 있습니다.

Marker 클래스의 getPosition 메서드
: 마커의 위치를 반환합니다.

  const updateMarkers = (
    map: naver.maps.Map | null,
    markers: naver.maps.Marker[]
  ) => {
    if (!map) return;
    // 현재 지도의 화면 영역을 mapBounds 변수에 저장
    let mapBounds = map.getBounds();
    let marker: naver.maps.Marker, position;
    
    // 마커 객체 배열을 순회하며 각 마커의 위치를 position 변수에 저장   
    for (var i = 0; i < markers.length; i++) {
      marker = markers[i];
      position = marker.getPosition();
      
      // mapBounds와 비교하며 마커가 현재 화면에 보이는 영역에 있는지 확인
      if (mapBounds.hasPoint(position)) {
        // 보이는 영역에 있다면 마커 표시
        showMarker(map, marker);
      } else {
        // 숨겨진 영역에 있다면 마커 숨김 
        hideMarker(marker);
      }
    }
  };

4. showMarker, hideMarker

Marker 클래스의 getMap 메서드:

  • 현재 오버레이가 추가된 Map 객체를 반환합니다.

Marker 클래스의 setMap(map) 메서드:

  • 오버레이를 지도에 추가합니다. 인수로 null을 전달하면 오버레이를 지도에서 제거합니다.
  const showMarker = (map: naver.maps.Map, marker: naver.maps.Marker) => {
    // 지도에 표시되어있는지 확인
    if (marker.getMap()) return;
    // 표시되어있지 않다면 오버레이를 지도에 추가
    marker.setMap(map);
  };

  const hideMarker = (marker: naver.maps.Marker) => {
    // 지도에 표시되어있는지 확인
    if (!marker.getMap()) return;
    // 표시되어있다면 오버레이를 지도에서 삭제
    marker.setMap(null);
  };

⬇️ 싸커퀵 ⬇️
https://soccerquick.kr/

profile
후론트엔드 개발자

0개의 댓글