cluster.getMarkers()에대한 질문입니다~

클러스터를 클릭하면 그 안에있는 마커들의 정보를 가져오고 싶은데요! cluster.getMarkers()이거는.,… 오브젝트로 해서 어떻게하는건지모르겟어요ㅜㅜㅜㅜ 그리구 클러스터에 32라고뜨면 32개 전부, 가져올수 있나요?? 방법알려주세요!

http://apis.map.daum.net/web/sample/addClustererClickEvent/
이 예제를 조금 변형해서 marker들을 가져오는 코드를 작성했습니다.
주석을 추가한 줄을 중점적으로 보시면 됩니다.

var map = new daum.maps.Map(document.getElementById('map'), {
    center : new daum.maps.LatLng(36.2683, 127.6358),
    level : 14
});

var clusterer = new daum.maps.MarkerClusterer({
    map: map,
    averageCenter: true,
    minLevel: 10,
    disableClickZoom: true // 이 옵션을 필수로 적용시켜야 하며
});

$.get("/download/web/data/chicken.json", function(data) {
    var markers = $(data.positions).map(function(i, position) {
        return new daum.maps.Marker({
            position : new daum.maps.LatLng(position.lat, position.lng)
        });
    });

    clusterer.addMarkers(markers);
});

daum.maps.event.addListener(clusterer, 'clusterclick', function(cluster) {
     console.log(cluster.getMarkers()); // 이런식으로 이벤트 핸들러 내부에서 가져옵니다.
});
var data = {"positions":[{"lat":33.450701,"lng":126.570667},
                         {"lat":33.450701,"lng":126.570667},
                         {"lat":33.450701,"lng":126.570667},
                         {"lat":33.450701,"lng":126.570667},
                         {"lat":33.450701,"lng":126.570667},
                         {"lat":33.450701,"lng":126.570667},
                         {"lat":33.450701,"lng":126.570667},
                         {"lat":33.450701,"lng":126.570667},
                         {"lat":33.450701,"lng":126.570667},
                         {"lat":33.450701,"lng":126.570667},
                         {"lat":33.450701,"lng":126.570667},
                         {"lat":33.450701,"lng":126.570667},
                         ]};
for (i = 0; i < rdnb.length; i++) {
    geocoder.addressSearch(rdnb[i], function(index) {
        return function(result, status) {
            if (status === daum.maps.services.Status.OK) {
                var coords = new daum.maps.LatLng(result[0].y, result[0].x);
                // var marker = new daum.maps.Marker({map:map, position:coords, image:markerImage});
                //var marker = new daum.maps.Marker({map:map, position:coords});
                // var infowindow = new daum.maps.InfoWindow({
                //     content: '<div style="width:150px;text-align:center;padding:6px 0;">더바른</div>'
                // });
                //daum.maps.event.addListener(marker, 'click', function() {
                //    clickOffice();
                //});
                var gps3 = new Array();
                points[index] = new daum.maps.LatLng(result[0].y, result[0].x);
                var gps1 = points[index].toString();
                var length = gps1.length;
                length = length - 1;
                var gps2 = gps1.slice(1, length);
                var gps3 = gps2.split(',');
                // var ggg=hey.substring(1,18).toString();
                // var sss=hey.substring(19,37).trim().toString();
                // var dot =
                // var yay="\"lng\""+sss;
                // var dfasdf="{"+dot+","+yay+"}"
                var lat = gps3[0];
                var lng = gps3[1];
                data.positions[index].lat = lat;
                data.positions[index].lng = lng;
                if(index==(rdnb.length-1)){
                    var clusterer = new daum.maps.MarkerClusterer({
                        map           : map,     // 마커들을 클러스터로 관리하고 표시할 지도 객체
                        averageCenter : true,    // 클러스터에 포함된 마커들의 평균 위치를 클러스터 마커 위치로 설정
                        minLevel      : 1,        // 클러스터 할 최소 지도 레벨
                        disableClickZoom: true,
                    });

                    var markers = data.positions.map(function(position,i) {
                        return new daum.maps.Marker({
                            position : new daum.maps.LatLng(position.lat, position.lng)
                        });
                    });

                    clusterer.addMarkers(markers);
                    clusterer.setMinClusterSize(1);
                    daum.maps.event.addListener(clusterer, 'clusterclick', function(cluster) {
                        //console.log(cluster.getMarkers());
                        //console.log(cluster.getSize());
                        var dfaf = cluster.getMarkers();
                        var csize = cluster.getSize();
                        var resultSpan = document.getElementById("loginForm");            
                        for(k = 0;k < csize; k++){
                            var input1 = document.createElement("input");
                            input1.type= "hidden";
                            input1.id="rdnmAddr"+k;
                            input1.name="rdnmAddr";
                            resultSpan.appendChild(input1);   
                        }
                        for (i = 0; i < csize; i++) {
                            cluster[i]= dfaf[i].getPosition();
                        }

                        for (j = 0; j < csize; j++) {
                            var coord = cluster[j];
                            var callback = function(idx) {
                                return function(result, status) {
                                    if (status === daum.maps.services.Status.OK) {
                                        rdnmAddr[idx] = result[0].road_address.address_name;
                                        $('#rdnmAddr'+idx).val(rdnmAddr[idx]);
                                    }
                                    if (idx == (csize-1)) {
                                       clickOffice();
                                    }
                                }
                            }(j);
                            //var callback = function(result1, status1) {
                            //        if (status1 === daum.maps.services.Status.OK) {
                            //            rdnmAddr[j] = result1[0].road_address.address_name;
                            //            $('#rdnmAddr'+j).val(rdnmAddr[j]);
                            //        }
                            //};
                            geocoder.coord2Address(coord.getLng(), coord.getLat(), callback);
                        }
                    });
                }

            }
        }
    }(i));
}

이 코드가 잘못된건가요…? 계속 클러스터가 처음들어갔을때는 하나가안나오다가 f5키를 누르다보면,…다시되네요… addListener 가 notfound된다느것도나오고,
GET http://dapi.kakao.com/v2/local/search/keyword.json?query=&page=1&size=15 409 (Conflict) 이런에러두 뜨네용…ㅜㅡㅜ 어떻게해결하나요

제가 비지니스 로직 모두를 알 수는 없기 때문에
코드를 보고 그 의도를 알아내기 어렵네요.
첨부 코드에서 짚어낼 수 있는 오류는
for문을 위해 사용한 i, j, k 들이 var 로 선언이 되지 않아서 clusterclick 콜백 함수 내부 반복문이 꼬일 것 같다는 것 뿐이네요.

for 문을 돌려서 좌표로 주소를 찾아 모으는 단계 따로
그 모은 주소를 나중에 클러스터링 하는 단계 따로
두 단계를 분리하셔서 생각하셔야 할 듯 합니다.

현재 하나의 함수 내부에서 너무 많은 일을 하고 있습니다.
이는 작성자라고 해도 코딩중에 흐름을 놓치기 쉽습니다.
일단 로직을 나눠서 한 단계씩 진행하다보면 답이 나올 것 같아요.

감사합니다~~ 하다가 모르는거있으면 또 질문할게융!

아., 클로져의 특성인지는 모르겟지만 클러져가 코드의 순서대로 움직이지않고 제일 나중에 실행되는것두 있던데…그건왜그런건가요??? 예를들면
var points=[];
for (i = 0; i < rdnb.length; i++) {
geocoder.addressSearch(rdnb[i], function(index) {
return function(result, status) {
points[i]= aaa;
alert( points[0]);
}(i));
}
alert( points[0]);
이런식으로했을때 for문 안에서의 aaa는 값이 찍히지만 for문 바깥에서의 points는 값이 들어있지않아서…ㅜㅜ

저건 클로져의 특성 때문이라기 보다는 다른 문제입니다.

addressSearch의 두 번째 파라메터로 넘겨준 비동기 통신의 콜백이 맨 아랫줄의 alert 보다 나중에 실행되기 때문입니다.

반복문에서 넘겨주는 인덱스 값의 순서를 맞추기 위해 클로저를 사용하신 것은 옳습니다.
하지만 코드의 흐름상으로 나중에 실행되기에
주소 검색 데이터를 수집이 끝났는지 여부는 콜백 내부에서만 확인 가능합니다.

보통 주소 검색을 하기 위한 쿼리의 갯수는 알고 있으므로 (rdnb.length 가 되겠죠?)
콜백 함수의 마지막 부분에서 모든 결과를 받았는지 체크를 해주면 되죠.

아래의 구조가 될겁니다.

var counter = 0;
var resultObj = {};

for (i = 0; i < rdnb.length; i++) {
    geocoder.addressSearch(rdnb[i], function(index) {
        return function(result, status) {
            // 
            // ...
            // ...
            resultObj[index] = result;
            counter++;

            if (counter === rdnb.length) {
                // 콜백의 호출 횟수가 전체 입력 쿼리 수와 일치하게 된다면
                // 다음 단계로 넘어가는 함수를 호출하면 됩니다.
                doNext();
            }
        }
    }
}

function doNext() {
    // 여기서 resultObj을 다루면 됩니다.
}

비동기 프로그래밍에서 싱크를 맞추는 가장 단순하고 확실한 방식입니다.
다만 결과가 없거나 통신이 문제가 생길 경우의 예외처리는 따로 해 주셔야 합니다.

질문하나만 더 할게요! 그 클러스터할때
var data = {“positions”:[{“lat”:33.450701,“lng”:126.570667},
{“lat”:33.450701,“lng”:126.570667},
{“lat”:33.450701,“lng”:126.570667},
{“lat”:33.450701,“lng”:126.570667},
{“lat”:33.450701,“lng”:126.570667},
{“lat”:33.450701,“lng”:126.570667},
{“lat”:33.450701,“lng”:126.570667},
{“lat”:33.450701,“lng”:126.570667},
{“lat”:33.450701,“lng”:126.570667},
{“lat”:33.450701,“lng”:126.570667},
{“lat”:33.450701,“lng”:126.570667},
{“lat”:33.450701,“lng”:126.570667},
]};
이렇게하자나유~ 그럼 data를 object로 해도되나요???

일단,
질문을 제가 이해하지 못했습니다 ^^;
조금만 더 자세히 설명 부탁드립니다.

var data = {“positions”:[{“lat”:33.450701,“lng”:126.570667},
{“lat”:33.450701,“lng”:126.570667},
{“lat”:33.450701,“lng”:126.570667},
{“lat”:33.450701,“lng”:126.570667},
{“lat”:33.450701,“lng”:126.570667},
{“lat”:33.450701,“lng”:126.570667},
{“lat”:33.450701,“lng”:126.570667},
{“lat”:33.450701,“lng”:126.570667},
{“lat”:33.450701,“lng”:126.570667},
{“lat”:33.450701,“lng”:126.570667},
{“lat”:33.450701,“lng”:126.570667},
{“lat”:33.450701,“lng”:126.570667},
]};
var clusterer = new daum.maps.MarkerClusterer({
map : map, // 마커들을 클러스터로 관리하고 표시할 지도 객체
averageCenter : true, // 클러스터에 포함된 마커들의 평균 위치를 클러스터 마커 위치로 설정
minLevel : 1, // 클러스터 할 최소 지도 레벨
disableClickZoom: true,
});

                    var markers = data.positions.map(function(position,i) {
                        return new daum.maps.Marker({
                            position : new daum.maps.LatLng(position.lat, position.lng)
                        });
                    });

                    clusterer.addMarkers(markers);

이렇게 클러스터를 만들때 var data를 만들어서 직접 만드는데
이 var data= new Object();만들어서 해도되나요??

객체에 담아서 넣을 수는 없습니다.
http://apis.map.daum.net/web/documentation/#MarkerClusterer_addMarkers
문서를 보시면 요소가 마커인 배열만 넘겨줄 수 있도록 되어 있습니다.

감사합니다~~~

1개의 좋아요

daum.maps.event.addListener(clusterer, ‘clusterclick’, function(cluster) {
console.log(cluster.getMarkers()); // 이런식으로 이벤트 핸들러 내부에서 가져옵니다.
});

이부분의 console.log 가 undefined 납니다. 저도 클러스터 클릭 이벤트 리스너로 띠웠구요 클러스터 12개 표시 되어있는데 리턴값이 array 이던데 doc 의 예제 말고 cluster.getMarkers() 를 배열에 담을 수 있는 다른방법좀 알려주시면 감사하겠습니다.

var clusterer = new daum.maps.MarkerClusterer({
    map: map,
    averageCenter: true,
    minLevel: 10,
    disableClickZoom: true // 이 옵션을 필수로 적용시켜야 합니다.
});

disableClickZoom: true 옵션을 적용시키지 않았을 경우 undefined 가 뜨기는 합니다.

위 옵션이 false 일 경우 undefined 를 반환하는 이유는
Cluster를 클릭하면 자동으로 줌인이 되는데 그 순간 마커 데이터 전체를 다시 클러스터링 하게 되기 때문에 반환 값 자체가 의미가 없어지기 때문입니다.

true 로 옵션을 주면 Cluster 를 클릭 했을 때, 줌인이 되지 않습니다.
이 경우에 클릭한 Cluster가 보존되기 때문에
cluster.getMarkers() 가 정상적으로 동작합니다.