Js 클러스터 content값 문제

스크린샷 2024-03-21 오전 8.47.04

이렇게 값을 뽑는데 clusterMarkers에 찍힌것은 클러스터 전제 값을 뽑은거고 cluster.getMarkers()이 값은 클리한 클러스터 값인데 안에 내용보면 content값이 없어서 클릭한 클러스터 안에 텍스트들을 못불러 옵니다. 그래서 비교해서 하려고 했느데 2개나 4개 짜리 값은 잘오는데 많은 데이터들이 있으면 중복값으로 엄청 나오는데 어떻게 해야 클릭한 클러스터 마커 내용들을 가져올수 있을까요? for문이 문제인거 같은데 어찌 수정해야할지…막막합니다.

var markers = [];
        var clusterMarkers = [];
        for (var i = 0; i < positions.length; i++) {
            // 마커를 생성합니다
            var marker = new kakao.maps.Marker({
                // map: map, // 마커를 표시할 지도
                position: positions[i].latlng,  // 마커의 위치
            });
            // 마커에 표시할 인포윈도우를 생성합니다
            var infowindow = new kakao.maps.InfoWindow({
                content: positions[i].content // 인포윈도우에 표시할 내용
            });

            var clusterMarker = new kakao.maps.Marker({
                // map: map, // 마커를 표시할 지도
                position: clusterPositions[i].latlng,  // 마커의 위치
            });
            // 마커에 표시할 인포윈도우를 생성합니다
            var clusterInfowindow = new kakao.maps.InfoWindow({
                position: positions[i].latlng,
                content: positions[i].content // 인포윈도우에 표시할 내용
            });

            kakao.maps.event.addListener(marker, 'mouseover', makeOverListener(map, marker, infowindow));
            kakao.maps.event.addListener(marker, 'mouseout', makeOutListener(infowindow));
            markers.push(marker);
            clusterMarkers.push(clusterInfowindow);
        }
        clusterer.addMarkers(markers);

kakao.maps.event.addListener(clusterer, 'clusterclick', function (cluster) {
            console.log("clusterMarkers : ", clusterMarkers);
            console.log("cluster.getMarkers() : ", cluster.getMarkers());
            document.getElementById("htmlList").innerHTML = '';
            let schHtml = '';
            clusterMarkers.forEach(infowindow => {
                cluster.getMarkers().forEach(function (v, k) {

                    var lng = v.getPosition().getLng();
                    var lat = v.getPosition().getLat();

                    if (infowindow.getPosition().getLat() == lat && infowindow.getPosition().getLng() == lng) {
                        schHtml += infowindow.getContent();
                    }
                })
            });
            document.getElementById("htmlList").innerHTML = schHtml;
        });

생성된 모든 infowindow 개수에서 클릭한 클러스터의 마커 개수로 반복문을 돌면 마커에 맞는 infowindow으로 목록이 표시되지 않을뿐더러 값이 중복 또는 누락됩니다.
별도로 클릭한 클러스터에 포함된 마커와 일치하는 infowindow를 가져오는 기능을 구현해주셔야 합니다.

예를 들면 특정 키로 marker와 infowindow를 맵핑해서 키에 매칭되는 데이터를 가져오는 방법이 있습니다.
아래 코드는 인덱스 값을 활용해서 맵핑한 코드로 참고로만 봐주세요.

let markers = []; //클러스터러에 추가할 마커를 담는 배열
let mapping = {}; //{key: {marker: maker, infowindow: infowindow} 값을 저장하는 맵핑 테이블

list.forEach(function(i, position) {
    let marker = new kakao.maps.Marker({
        title: i, //i값으로 마커의 title을 설정하며 이를 활용해서 mapping object에 접근합니다.
        position : new kakao.maps.LatLng(position.lat, position.lng)
    });

    let infowindow = new kakao.maps.InfoWindow({
        map: map,
        content: '<div>'+position.lat+', '+position.lng+'</div>',
        position : new kakao.maps.LatLng(position.lat, position.lng)
    });

    //i값으로 생성한 마커와 인포윈도우를 object에 저장합니다.
    mapping[i] = {
        marker: marker,
        infowindow: infowindow
    };

    markers.push(marker);
});

// 클러스터러에 마커들을 추가합니다
clusterer.addMarkers(markers);

// 마커 클러스터러에 클릭이벤트를 등록합니다
kakao.maps.event.addListener(clusterer, 'clusterclick', function(cluster) {
    let clusterMarkers = cluster.getMarkers(); //클릭한 클러스터의 마커 정보를 가져옵니다.
    clusterMarkers.forEach((marker) => {
        var i = +marker.getTitle();//마커의 title에 저장한 키(인덱스) 값을 가져옵니다.
        console.log(mapping[i].infowindow.getContent()); //키값으로 맵핑 object에 접근하여 인포윈도우의 컨텐츠를 가져옵니다.
    });
});

스크린샷 2024-03-21 오후 12.34.07

infowindow.안에 map 넣으니까 초기 위치를 이상한 곳으로 잡고 인포윈도우가 띄어져있는 상태인데…

저는 일단 중복없이 콘솔에 text값을 가져오고싶어요 ㅠ

             var markers = [];
        var mapping = {};
        var clusterMarkers = [];
        for (var i = 0; i < positions.length; i++) {
            // 마커를 생성합니다
            var marker = new kakao.maps.Marker({
                // map: map, // 마커를 표시할 지도
                position: positions[i].latlng,  // 마커의 위치
            });
            // 마커에 표시할 인포윈도우를 생성합니다
            var infowindow = new kakao.maps.InfoWindow({
                content: positions[i].content // 인포윈도우에 표시할 내용
            });

            var clusterMarker = new kakao.maps.Marker({
                title: i,
                // map: map, // 마커를 표시할 지도
                position: clusterPositions[i].latlng,  // 마커의 위치
            });
            // 마커에 표시할 인포윈도우를 생성합니다
            var clusterInfowindow = new kakao.maps.InfoWindow({
                map : map,
                position: positions[i].latlng,
                content: positions[i].content // 인포윈도우에 표시할 내용
            });

            kakao.maps.event.addListener(marker, 'mouseover', makeOverListener(map, marker, infowindow));
            kakao.maps.event.addListener(marker, 'mouseout', makeOutListener(infowindow));
            mapping[i] = {
                marker: clusterMarker,
                infowindow: clusterInfowindow
            };
            markers.push(marker);
            clusterMarkers.push(clusterMarker);
        }
        clusterer.addMarkers(markers);
        kakao.maps.event.addListener(clusterer, 'clusterclick', function (cluster) {
            // let clusterMarkers = clusterMarkers; //클릭한 클러스터의 마커 정보를 가져옵니다.
            clusterMarkers.forEach((marker) => {
                console.log("marker : ", marker);
                var i = +marker.getTitle();//마커의 title에 저장한 키(인덱스) 값을 가져옵니다.
                console.log(mapping[i].infowindow.getContent()); //키값으로 맵핑 object에 접근하여 인포윈도우의 컨텐츠를 가져옵니다.
            });
            });

let clusterMarkers = cluster.getMarkers();
이렇게 해서도 돌려봤는데 클러스터를 클릭한 데이터가 아니라 전체 데이터만 가져옵니다…

우선 코드에서 마커와 인포윈도우를 중복 생성하고 있고
클러스터러에 추가한 마커는 title값이 적용된 마커가 아닌 다른 마커(clusterMarker가 담긴 배열)로 추가하고 있어요.
클릭한 클러스터러의 마커 title 정보로 맵핑테이블값을 찾아야 하는데 이를 활용할 수 없는 구조입니다.

그리고 cluster.getMarkers()를 호출하면 전체 마커가 들어온다고 하셨는데
clusterclick 이벤트에서 cluster.getMarkers() 호출하면 클러스터에 포함된 마커 정보만 가져옵니다.
클러스터에 마커를 중복해서 넣었는지 확인해 주세요.

앞서 말씀드린 대로 제가 작성한 코드는 참고로 봐주시고 코드 스타일에 맞게 변경해서 사용하시면 됩니다.
저는 Infowindow에 map 속성을 넣어 지도에 표시했지만 표시하는 걸 원치 않으시면 map 옵션을 막아서 사용해 주시면 되세요.

요점은 동일한 값으로 생성한 마커와 인포윈도우 정보를 가져오는 것으로
서로 맵핑된 구조를 가져야 하고 저는 인덱스 값을 활용한 맵핑 테이블을 이용하는 방법으로 코드를 작성드렸습니다.

아래 코드는 전문으로 기본 html에서 실행해 보면
클릭한 클러스터에 포함된 마커의 title값으로 맵핑 테이블의 infowindow를 가져와서
마커와 content(위치값이 적힌 div) 값을 출력하는데 중복없이 marker와 동일한값을 가진 infowindow가 출력되는 걸 확인할 수 있습니다.

코드는 구현 방법에 따라 다르게 작성될 수 있어서 맵핑 테이블 사용으로 값을 가져오는 방법을 참고해 주시고
포인트는 클릭한 클러스터에 포함된 마커와 동일한 값으로 생성한 인포윈도우를 찾아야 하는 부분으로
또 다른 방법이 있으면 그에 맞게 작성해 주시면 됩니다.

let mapContainer = document.getElementById('map');
let mapOption = {
    center: new kakao.maps.LatLng(36.66656766668533, 127.43347203619975),
    level: 14
};

//지도를 생성합니다.
let map = new kakao.maps.Map(mapContainer, mapOption);

//클러스터를 생성합니다.
let clusterer = new kakao.maps.MarkerClusterer({
    map: map,
    averageCenter: false,
    minLevel: 14,
    calculator : 1,
    disableClickZoom: true
});

const list = [
    {
        "lat": 37.27943075229118,
        "lng": 127.01763998406159
    },
    {
        "lat": 37.55915668706214,
        "lng": 126.92536526611102
    },
    {
        "lat": 35.13854258261161,
        "lng": 129.1014781294671
    },
    {
        "lat": 37.55518388656961,
        "lng": 126.92926237742505
    },
    {
        "lat": 35.20618517638034,
        "lng": 129.07944301057026
    },
    {
        "lat": 37.561110808242056,
        "lng": 126.9831268386891
    },
    {
        "lat": 37.86187129655063,
        "lng": 127.7410250820423
    },
    {
        "lat": 37.47160156778542,
        "lng": 126.62818064142286
    },
    {
        "lat": 35.10233410927457,
        "lng": 129.02611815856181
    },
    {
        "lat": 35.10215562270429,
        "lng": 129.02579793018205
    },
    {
        "lat": 35.475423012251106,
        "lng": 128.76666923366042
    },
    {
        "lat": 35.93282824693927,
        "lng": 126.95307628834287
    },
    {
        "lat": 36.33884892276137,
        "lng": 127.393666019664
    },
    {
        "lat": 37.520412849636,
        "lng": 126.9742764161581
    },
    {
        "lat": 35.155139675209675,
        "lng": 129.06154773758374
    },
    {
        "lat": 35.816041994696576,
        "lng": 127.11046706211324
    },
    {
        "lat": 38.20441110638504,
        "lng": 128.59038671285234
    },
    {
        "lat": 37.586112739308916,
        "lng": 127.02949148517999
    },
    {
        "lat": 37.50380641844987,
        "lng": 127.02130716617751
    },
    {
        "lat": 37.55155704387368,
        "lng": 126.92161115892036
    },
    {
        "lat": 37.55413060051369,
        "lng": 126.92207472929526
    },
    {
        "lat": 36.362321615174835,
        "lng": 127.35000483225389
    },
    {
        "lat": 37.55227862908755,
        "lng": 126.92280546294998
    },
    {
        "lat": 37.490413948014606,
        "lng": 127.02079678472444
    },
    {
        "lat": 35.172358507549596,
        "lng": 126.90545394866643
    },
    {
        "lat": 35.15474103200252,
        "lng": 129.11827889154455
    },
    {
        "lat": 37.516081250973485,
        "lng": 127.02369057166361
    },
    {
        "lat": 36.80711722863776,
        "lng": 127.14020346037576
    },
    {
        "lat": 37.28957415752673,
        "lng": 127.00103752005424
    },
    {
        "lat": 35.83953896766896,
        "lng": 128.7566880321854
    },
    {
        "lat": 37.51027412948879,
        "lng": 127.08227718124704
    },
    {
        "lat": 37.493581783270294,
        "lng": 126.72541955660554
    },
    {
        "lat": 35.135291862962795,
        "lng": 129.10060911448775
    },
    {
        "lat": 35.174574933144065,
        "lng": 126.91389980787773
    },
    {
        "lat": 37.795887691878654,
        "lng": 127.10660416587146
    },
    {
        "lat": 37.59288687521181,
        "lng": 126.96560524627377
    },
    {
        "lat": 37.45076411130452,
        "lng": 127.14593003749792
    }
]

let markers = [];
let mapping = {};
for (let i = 0; i < list.length; i++) {
    const position = list[i];
    let marker = new kakao.maps.Marker({
        title: i,
        map: map,
        position: new kakao.maps.LatLng(position.lat, position.lng),
    });


    let infowindow = new kakao.maps.InfoWindow({
        position: new kakao.maps.LatLng(position.lat, position.lng),
        content: '<div>'+position.lng+', '+position.lat+'</div>'
    });

    mapping[i] = {
        marker: marker,
        infowindow: infowindow
    };

    markers.push(marker);
}

clusterer.addMarkers(markers);

kakao.maps.event.addListener(clusterer, 'clusterclick', function (cluster) {
    cluster.getMarkers().forEach((marker) => {
        console.log("marker : ", marker.getPosition());
        let i = +marker.getTitle();
        console.log(mapping[i].infowindow.getContent());
    });
});