기존 예시 코드의 지도 범위 설정 기준
https://apis.map.kakao.com/web/sample/keywordList/
내가 사용한 샘플 코드인 '키워드로 장소검색하고 목록으로 표출하기' 코드는 displayPlaces() 메서드 내에서 지도 범위를 설정한다.
현재 코드는 아래 흐름으로 동작한다.
1. 키워드로 검색 -> 검색 결과 목록이 나옴
2. for문을 돌면서 검색 결과 목록에 있는 장소의 좌표들이 다 포함된 영역(.extend())으로 지도 범위가 설정됨(.setBounds())
3. 즉, 검색 결과 목록 2페이지로 넘어가게되면 2페이지에 있는 장소들이 모두 보이는 범위로 재설정됨
원래 샘플 코드는 검색 결과 목록에 있는 모든 장소들이 지도에 마커로 표시되는 것이지만, 나는 수정해서 내가 원하는 장소만 지도에 마커로 표시되게 했음.
4. 그럼 1페이지에 있는 장소에 마커를 찍어놨어도 2페이지로 넘어가게되면 기준 좌표가 바뀌어서 마커가 범위 밖에 표시될 수 있음
-> 내가 원하는 동작은 지도에 마커가 찍힐 때마다 마커들이 한 번에 다 보이도록 재설정하고 싶음
사진으로 동작 방식을 살펴보자.
왼쪽 사진이 1페이지의 지도 범위, 오른쪽 사진이 2페이지의 지도 범위이다.
만약 더 넓게 보이는 2페이지에 마커를 찍고, 1페이지로 넘어간다면? 2페이지에서 찍은 마커는 숨겨졌다가 지도를 축소해야 보일 것이다.
장소 추가 시 범위 재설정하도록 바꿔보자
지도 범위에 포함할 좌표를 설정하고, 범위를 재설정하는 과정을 살펴보자.
1. kakao.maps.LatLngBounds 객체의 .extend()의 인자로 kakao.maps.LatLng 객체(좌표 정보)를 넣어서 지도 범위를 확장한다.
API 문서에 포함된 그림을 보면 좀 더 이해하기 쉽다!
2. new kakao.maps.Map 객체의 .setBounds()의 인자로 kakao.maps.LatLngBounds 객체를 넣어 지도 범위를 재설정한다.
그럼 내 코드에는 어떻게 적용할까?
내 코드에서는 bounds가 kakao.maps.LatLngBounds 객체이고, placePosition이 좌표 정보인 kakao.maps.LatLng 객체가 된다.
-> 그럼 장소 선택 버튼을 클릭할 때마다 bounds에 placePosition을 넣어서 지도 범위를 확장하자!
1. 현재 코드는 검색 결과로 나온 15개 항목에 대해 for문 15번 돌면서 placePosition이 15개나오기 때문에 bounds에도 15개가 들어가게 된다. 이러면 검색 결과로 나온 15개 항목에 대해 지도 범위가 재설정 되기 때문에 내가 원하는 동작이 아니다.
2. 내가 원하는 동작인 선택한 장소에 대해서만 지도 범위를 재설정하게 하려면 선택 버튼 클릭 이벤트에 재설정을 넣어줘야한다.
- handleSelectBtnClick()에서도 쓸 수 있도록 bound를 전역 변수로 바꿔주자.
// 지도를 재설정할 범위정보를 가지고 있을 LatLngBounds 객체를 생성
const bounds = new kakao.maps.LatLngBounds();
3. displayPlaces()에서 검색 결과로 지도 재설정을 더 이상 할 필요가 없으니 관련 코드는 지워준다.
- 아래 두 라인은 displayPlaces()에서 지우자.
bounds.extend(placePosition);
map.setBounds(bounds);
4. 선택 버튼 클릭 이벤트 핸들러인 handleSelectBtnClick()에서 쓸 setBounds()를 작성하자.
- 선택한 장소의 placePosition을 bounds에 넣어줘야 기준을 만들 수 있으니 파라미터로 placePosition을 넘겨준다.
/**
* 지도 범위 재설정 함수
*/
function setBounds(placePosition) {
// LatLngBounds 객체에 좌표를 추가
bounds.extend(placePosition);
// LatLngBounds 객체에 추가된 좌표들을 기준으로 지도의 범위를 재설정합니다
// 이때 지도의 중심좌표와 레벨이 변경될 수 있습니다
map.setBounds(bounds);
}
- 이미 핸들러에 placePosition이 파라미터로 넘어오기 때문에 setBounds()에도 바로 placePosition을 넘겨줄 수 있다.
5. 마지막으로 handleSelectBtnClick()에서 지도에 마커 추가 후 범위를 재설정하는 setBounds()를 호출 해주면 끝!
// 장소를 추가할 때마다 모든 마커가 보이도록 지도 범위 재설정
setBounds(placePosition);
🔽 handleSelectBtnClick() 전체 코드
/**
* 선택 버튼 클릭 이벤트 핸들러
*/
function handleSelectBtnClick(event, place, placePosition) {
event.stopPropagation(); // 이벤트 버블링 방지
const isAlreadySelected = selectedPlaces.some(p => p.id === place.id);
// 이미 선택된 장소인지 확인
if (isAlreadySelected) {
alert('이미 선택된 장소입니다.');
return;
}
// 최대 15개까지만 선택되도록 제한
if (selectedPlaces.length >= 15) {
alert('최대 15개의 장소만 추가할 수 있습니다.');
return;
}
// 같은 id를 가진 장소가 없고, 15개 초과가 아니라면 선택 장소 목록 배열에 추가
selectedPlaces.push(place);
// 배열 인덱스로 마커에 번호 부여
const index = selectedPlaces.length;
addSelectedMarker(placePosition, index);
setBounds(placePosition);
}
동작 예시
장소 한 개 선택했을 때랑 두 개 선택했을 때의 지도 범위가 다르게 보인다!
그럼 장소 제거 시 지도 범위 재설정은 어떻게?
예를 들어 아래 사진에서 10번 장소를 제거하면 1~9 장소를 기준으로 확대되어 보였으면 했다.
근데 아래 문서 그림을 보면 3개 장소의 좌표를 bounds에 넣는다해서 bounds에 3개 좌표가 저장되는게 아니라, 기존 sw, ne 세트에서 확장되는 개념이라 일치하는 좌표를 찾아서 제거하는게 불가능하다.
콘솔창에 bounds를 찍어보면 아래처럼 확장된 값인 sw, ne만 나온다.
또한 따로 축소하는 함수도 API 문서에 없었다.
그럼 구현하려면 내가 추가한 좌표값(placePosition)을 계속 기억해두었다가, 장소를 제거하면 기억해둔 저장된 좌표값들에서 제거하려는 해당 좌표를 지우고, 남은 좌표값들로 배열을 만들어 setBounds() 해주어야 할 것 같다.
그래서 너무 번거로워져서 제거 시에는 따로 구현하지 않았다..🫢
'🛠️ Project > 🗺️ Kakao Maps API' 카테고리의 다른 글
[카카오 지도 API] 장소 사이를 선(polyline)으로 이어서 나타내기 (0) | 2024.09.26 |
---|---|
[카카오 지도 API] 마커 이미지 색상 여러 가지로 변경해서 적용하기 (0) | 2024.09.24 |
[카카오 지도 API] 선택한 장소의 마커를 지도에서 제거하기 및 마커 번호 재정렬하기 (0) | 2024.09.20 |
[카카오 지도 API] 장소를 선택한 순서대로 마커 숫자 지정하기 (0) | 2024.09.18 |
[카카오 지도 API] AJAX를 이용해 선택된 장소 데이터를 백단으로 전송하기 (0) | 2024.09.12 |