이미 선택한 장소의 제거 버튼을 클릭하면 지도에 있는 마커가 삭제되도록 만들어보자.
1. 선택한 장소들의 배열인 selectedPlaces에서 제거할 장소를 찾아서 지우기
2. 선택한 장소들의 마커 배열인 markers에서 제거할 장소를 찾아서 지우기
3. 장소를 제거했으니 순서에 맞게 마커 숫자를 재정렬하기
장소 선택 버튼 클릭 이벤트 핸들러 메서드와 동일하게 제거 버튼 클릭 이벤트 핸들러 메서드도 event, place, placePosition을 파라미터로 넘겨주도록 작성했다.
function handleRemoveBtnClick(event, place, placePosition) {
선택한 장소들의 배열인 selectedPlaces에서 제거하기
같은 장소인지 구별하는 방법은 파라미터로 넘어온 선택한 장소의 정보인 place와 selectedPlaces에 있는 요소의 id 값을 비교하면 된다.
애초에 selectedPlaces.push(place)를 통해 넣어줬기 때문에 같은 값이 들어가있다.
.fitler()를 통해 selectedPlaces 배열의 각 요소의 id와 파라미터로 넘어온 place의 id를 비교해서 다른 요소들만 selectedPlaces에 남긴다. 즉, id가 같은 장소는 selectedPlaces에서 삭제된다.
// 배열의 각 요소 p의 id가 파라미터로 전달된 place의 id와 다른 요소만 filter해서 selectedPlaces에 남김
selectedPlaces = selectedPlaces.filter(p => p.id !== place.id);
선택한 장소의 마커 배열인 markers에서 제거하기
markers 배열의 요소인 marker.getPosition()과 파라미터로 넘어온 placePosition의 경도, 위도 값을 비교해 장소를 구별하면 된다.
주의할 점은 부동소수점 문제 때문에 오차범위 설정을 꼭 해줘야한다! -> 아래 관련 게시글에 자세히 작성해두었다.
const tolerance = 0.00000001; // 허용 오차 범위 설정
// findIndex는 배열에 각 요소에 대해 조건을 만족하는 첫 번째 요소의 인덱스 반환
// markers 배열에서 해당 장소 위치에 해당하는 marker 요소 제거
const markerIndex = markers.findIndex(marker => {
const markerPos = marker.getPosition();
return Math.abs(markerPos.La - placePosition.La) < tolerance &&
Math.abs(markerPos.Ma - placePosition.Ma) < tolerance;
});
if (markerIndex !== -1) { // 해당 장소 위치의 마커가 존재한다면
markers[markerIndex].setMap(null); // 지도에서 마커 제거
markers.splice(markerIndex, 1); // 배열에서 마커 제거. 인덱스부터 1개의 요소 삭제
}
아래 글에 markers 배열 제거와 관련된 트러블슈팅 과정을 작성해두었다.
2024.09.18 - [🔫 트러블슈팅] - [카카오 지도 API] 같은 장소인데 다른 좌표로 판단하는 부동소수점 오차 문제
그리고 markers 배열에서 마커를 제거했기 때문에 지도에 나타나는 마커의 숫자도 순서대로 재정렬해야 한다.
지도에 표시되는 마커 숫자 재정렬하기
예를 들어, 3개의 장소를 선택했다면 지도에 마커가 순서대로 1, 2, 3이 생성된다.
만약 2번째로 추가한 장소를 지우게되면 순서대로 마커 숫자를 지정해주기 때문에 1, 2, 3에서 1, 3이 아닌 1, 2가 남아야한다.
지도에 나타나는 마커의 숫자는 아닌 마커 스프라이트 이미지와 연관되어있다.
1~15까지의 숫자가 한 이미지에 묶인 마커 스프라이트 이미지에서 사용할 영역의 좌표 값을 설정해 1, 2, 3, .. 숫자를 분리해 사용하는 것이다.
즉, 마커 숫자를 재정렬하기 위해서는 markers 배열의 요소인 marker의 마커 이미지 좌표값만 재설정해주면 된다.
카카오에서 제공하는 addMarker() 메서드와 setImage()를 조합해 코드를 작성해보자.
markers 배열을 돌면서 요소마다 마커 이미지만 재설정해주면 되니 markers를 파라미터로 넘긴다.
reorederMarkers()는 제거 버튼 클릭 이벤트 핸들러의 가장 마지막에 넣을 것이기 때문에 markers 배열에는 이미 해당 장소는 제거된 후의 값이 넘어온다.
그러므로 for문을 돌면서 남은 장소들의 마커 이미지만 .setImage()를 통해 재설정하면 된다.
(저번 게시글에 작성한 장소 선택 시 마커 이미지 좌표 설정과 달리 이번엔 i가 0부터 시작하므로 (i*46)을 그대로 사용했다.)
/**
* 제거 버튼 클릭 이벤트 발생 시 기존에 있던 마커 번호(마커 이미지)를 재정렬하는 함수
*/
function reorderMarkers(markers) {
for (let i = 0; i < markers.length; i++) {
const marker = markers[i];
const imageSrc = 'https://t1.daumcdn.net/localimg/localimages/07/mapapidoc/marker_number_blue.png', // 마커 이미지 url, 스프라이트 이미지를 씁니다
imageSize = new kakao.maps.Size(36, 37), // 마커 이미지의 크기
imgOptions = {
spriteSize: new kakao.maps.Size(36, 691), // 스프라이트 이미지의 크기
spriteOrigin: new kakao.maps.Point(0, (i*46) + 10), // 스프라이트 이미지 중 사용할 영역의 좌상단 좌표
offset: new kakao.maps.Point(13, 37) // 마커 좌표에 일치시킬 이미지 내에서의 좌표
},
markerImage = new kakao.maps.MarkerImage(imageSrc, imageSize, imgOptions);
marker.setImage(markerImage);
}
}
이렇게 작성한 뒤, handleRemoveBtnClick()의 가장 마지막에 호출하면 끝!
(그리고 나는 선택한 장소를 리스트로 넘기는 선택 완료 버튼도 만들었고, 선택 완료 버튼을 누른 뒤에도 추가로 더 장소를 선택 -> 선택 완료로 장소를 추가할 수 있게 했기 때문에 handleSelectBtnClick()에도 마지막에 호출해줬다!)
테스트해보면 아래처럼 1, 2, 3, 4에서 2번째로 추가한 장소를 제거할 시, 1, 2, 3으로 마커 번호가 잘 재정렬된다😆
전체 코드
/**
* 제거 버튼 클릭 이벤트 핸들러
*/
function handleRemoveBtnClick(event, place, placePosition) {
event.stopPropagation();
selectedPlaces = selectedPlaces.filter(p => p.id !== place.id);
const tolerance = 0.00000001; // 허용 오차 범위 설정
const markerIndex = markers.findIndex(marker => {
const markerPos = marker.getPosition();
return Math.abs(markerPos.La - placePosition.La) < tolerance &&
Math.abs(markerPos.Ma - placePosition.Ma) < tolerance;
});
if (markerIndex !== -1) { // 해당 장소 위치의 마커가 존재한다면
markers[markerIndex].setMap(null); // 지도에서 마커 제거
markers.splice(markerIndex, 1); // 배열에서 마커 제거. 인덱스부터 1개의 요소 삭제
reorderMarkers(markers); // 마커 번호 재정렬
}
}
'🛠️ Project > 🗺️ Kakao Maps API' 카테고리의 다른 글
[카카오 지도 API] 마커 이미지 색상 여러 가지로 변경해서 적용하기 (0) | 2024.09.24 |
---|---|
[카카오 지도 API] 장소 추가 시 지도에 보이는 범위 재설정하기 (0) | 2024.09.23 |
[카카오 지도 API] 장소를 선택한 순서대로 마커 숫자 지정하기 (0) | 2024.09.18 |
[카카오 지도 API] AJAX를 이용해 선택된 장소 데이터를 백단으로 전송하기 (0) | 2024.09.12 |
[카카오 지도 API] 장소 검색 목록에서 선택한 장소만 지도에 마커 표시하기 (0) | 2024.09.12 |