MarkerClusterer 관련 문의 및 Docs 오타 공유

[FAQ] 지도/로컬 API 문의 전 꼭 읽어 주세요.

안녕하세요. 카카오 지도 관련해서 개발하고 있는데, 질문이 많이 생기네요.

다른게 아니라 marker.setVisible(false); 을 진행하게 되면 마커의 정보는 남아있으나 화면에 표출만 되지 않는데, 이와 같은 기능이 markercluster에는 없는 걸까요?

clear한다음 다시 추가하는거에 대한 부담이 있어서 여쭤봅니다…

추가로
https://apis.map.kakao.com/web/documentation/#MarkerClusterer_addMarkers
해당 부분에 예시 코드 부분
addMarkers 가 아닌 addMarker 으로 기재되어있습니다~

추가 질문 입니다.

직접 만든 메소드(hideStation, showStation)에서 이렇게 오류가 발생 하게 되는데 어떤 점을 봐야할까요?


var imageSize = new kakao.maps.Size(30, 40);

// 마커 이미지를 생성합니다
var markerImage = new kakao.maps.MarkerImage(
/assets/icons/icon_busStop_white.svg,
imageSize,
);
data.forEach(item => {
var marker = new kakao.maps.Marker({
map: map,
position: item.POSITION,
zIndex: 7,
image: markerImage,
});
marker.setVisible(showBusStation.value);
routeVertexStore.Markers.push(marker);

showStation() {
this.Markers.forEach(item => {
try {
item.setVisible(true);
} catch (err) {
console.error(item);
console.error(err);
}
});
},
hideStation() {
this.Markers.forEach(item => {
try {
item.setVisible(false);
} catch (err) {
console.error(item);
console.error(err);
}
});
},

네~ 안녕하세요~

일단, 다큐멘테이션 사이트에서, getMarkers 부분의 철자는 수정되어 배포나가도록 하겠습니다. 확인해 주셔서 감사드립니다!

그리고 말씀하신 메인 질문에 대해서 답변을 드리겠습니다.
현재 MarkerClusterer에는 말씀하신 것처럼 visible을 제어하는 함수는 없습니다. 이 부분은 마냥 쉽게 추가를 하긴 어려워서 시간이 좀 필요합니다;;;

해당 모듈은 초기에 마커들을 쉽게 클러스터링 하는 것에 초점이 맞춰져서 개발되고 이후에 기능추가가 된 모듈로써, 간단히 화면에 표출되어 진 클러스터와 마커들을 visible on/off 를 하는 기능은 만들어져 있지 않습니다.

일단 그래서 말씀하신 내용의 clusterer의 serVisible 관련된 함수는 내부 논의를 해보겠습니다만, 단순하게 marker를 순환하면서 setVisible을 처리할 수는 없습니다.

추가질문하신 부분이 바로 그 부분인데요.
this.markers가, 아마 clusterer의 getMarkers를 통해서 가져온 마커 배열로 생각이 됩니다.
marker.setVisible의 경우엔 marker가 setMap(map)이라는 함수가 호출되어 지도와 연관된 DOM으로 DOM tree안에 들어가 있을때 해당 함수가 정상 동작이 됩니다.

MarkerClusterer를 통해 addMarker를 진행시, 모든 각각의 마커들은 DomTree안에 존재하지 않습니다. MarkerClusterer의 로직에 따라 표시할 마커는 표시하고, 모아야되는 마커는 삭제하고 그 위에 클러스터 마커를 별도로 올리는 동작을 수행합니다.
그렇기 때문에 두번째 질문에 있는 this.marker.forEach를 통해서 marker들을 순환하게 되면, 클러스터링된 마커들은 dom-tree 에 없기 때문에 오류가 발생하게 됩니다.

이부분 저희의 예외처리가 확실하지 않는 것도 문제가 있기 때문에, 해당 부분은 수정 보완을 하도록 하겠습니다.

그리고 MarkerClusterer를 clear() - add()를 하지 않고, 잠시 안보이게 했다가 보이게 하는 방법은, 정식 방법은 아니지만, 노출된 API들을 이용하여 간접적으로 구현이 가능합니다.

marker의 setOpacity 함수와
MarkerClusterer의 setStyles의 Opacity 속성을 사용하면 가능합니다.

const styles = clusterer.getStyles() //클러스터러의 스타일들을 가져옵니다.
const onStyles = styles.map(style => ({ opacity: 1, ...style })); //클러스터 마커를 보이게할 스타일
const offStyles = styles.map(style => ({ opacity: 0, ...style })); //클러스터 마커를 안보이게 할 스타일

//클러스터와, 클러스터에 속해있지 않은 개별 마커를 안보이게 함
clusterer.getMarkers().forEach(item => { item.setOpacity(0) })
clusterer.setStyles(offStyles);
clusterer.redraw(); //스타일은 변경해도 바로 반영이 안되므로 다시 그려야 합니다.

//클러스터와 클러스터에 속해있지 않은 개별 마커를 보이게 함
clusterer.getMarkers().forEach(item => { item.setOpacity(1) })
clusterer.setStyles(onStyles);
clusterer.redraw();

위처럼 스타일의 opacity를 이용해서 숨기는 방법이 있습니다.

다만 이처럼 할 경우에 화면에서는 보이지 않지만, DOM-tree에 여전히 남아있기 때문에 클러스터러의 내부 로직과, 이벤트 로직은 계속 동작합니다.

임시적으로 화면에서 사라지게 하고, 이때는 지도인터렉션이 없을 것 같은 곳에서는 사용해도 괜찮으나, 사라지게 한 상태에서도 지도 인터렉션을 계속 해야한다면, 차라리 clear()를 하는게 성능상 더 좋다고 생각됩니다.

1개의 좋아요

좋은 답변 감사합니다…!!

marker Cluster인데 marker를 안보이게 하였음에도 보여서 클러스터는 보여서 당황스럽기에 질문 드렸습니다.
말씀해주신 방법이랑 clear를 잘 섞어가며 해보겠습니다. 감사합니다 ~