카카오 지도 api 활용 - 카테고리에 따른 마커 생성
전기차 충전소 데이터베이스에 분류되어있는 카테고리 중 지역구 , 운영기관 , 충전기 타입 , 시설 이 있어 이에 따라 분류하여 checkbox를 선택하면 해당 마커만 생성되게 하는 기능을 구현했다.
생각보다 여러가지 기능이 들어가야해서 어려웠던 작업이었다.
우선 지역구별로 분류한 city를 예로 들겠다.
나머지는 동일한 방법으로 진행했다.
1. 데이터베이스에서 해당 카테고리에 해당하는 충전소만 마커 생성되게 하는 코드
function getData1(city) {
fetch('/tetest/data')
.then(response => response.json())
.then(data => {
data.forEach(v => {
const lat = v.latitude;
const lng = v.longitude;
const cityData = v.city;
if (cityData === city) {
var address = `${v.address}`;
var kakaoMapLink = "https://map.kakao.com/link/map/" + encodeURIComponent(address);
var content =
`<div class="ininfo"> 충전소 위치: ${v.name} <br> 주소: ${v.address} <br> 운영기관: ${v.company} <br> 이용가능시간: ${v.tim} <br>
<a href="${kakaoMapLink}" target="_blank">카카오맵에서 보기</a> </div>`;
cityaddress = city;
console.log(city);
createMarker1(lat, lng, content);
}
});
})
.catch(error => console.log(error));
}
데이터를 json형태로 가져와야 script안에서 사용하기가 용이해진다.
json형태로 가져오는것은 controller에서 아래와 같이 작성하면 된다.
@GetMapping("/tetest/data")
@ResponseBody
public List<Station> tetestData(){
List<Station> excels = stationRepository.findAll();
return excels;
}
데이터베이스에서 지역구를 cityData 로 가져오고 이를 checkbox 의 city 값과 같은지를 비교한다.
checkbox 관련 코드는 아래와 같이 html에 checkbox가 나오고 onclick 함수로 handleCheckboxChange 함수를 지정하여 city 값을 넣어주었다.
<li class="list-group-item">
<label style="color: black;"><input type="checkbox" id="areacheck1"
onchange="handleCheckboxChange('북구', this.checked)">북구</label>
<label style="color: black;"><input type="checkbox" id="areacheck2"
onchange="handleCheckboxChange('광산구', this.checked)">광산구</label>
<label style="color: black;"><input type="checkbox" id="areacheck3"
onchange="handleCheckboxChange('서구', this.checked)">서구</label>
<label style="color: black;"><input type="checkbox" id="areacheck4"
onchange="handleCheckboxChange('동구', this.checked)">동구</label>
<label style="color: black;"><input type="checkbox" id="areacheck5"
onchange="handleCheckboxChange('남구', this.checked)">남구</label>
<label style="color: black;"><input type="checkbox" id="areacheck6"
onchange="handleCheckboxChange2('전체', this.checked)">전체</label><br>
</li>
handleCheckboxChange 함수이다.
function handleCheckboxChange(city, checked) {
if (checked) {
getData1(city);
} else {
removeInfo1();
removeMarkers1(city);
}
}
2. 한 checkbox를 선택한 후에 해제하면 마커가 사라지는 기능 구현
marker를 mark 라는 큰 틀로 묶으며 add 에 해당 city 값이 저장되도록 하고 mark.add 값과 동일한 city값인 경우의 데이터의 마커만 사라지게 만들었다.
function removeMarkers1(city) {
markers.forEach(mark => {
const marker = mark.marker;
if (mark.add === city) {
marker.setMap(null); // 지도에서 제거
}
});
}
3. 각 데이터의 infowindow 생성
특정 마커를 클릭했을때 해당 마커의 충전소에 관한 데이터가 나오는 infowindow가 생성되도록 구현하는것이 제일 오래 걸렸던 문제였다. 코드의 위치와 순서에 따라 infowindow가 생성되지 않기도, 한 데이터 값만 나오는 infowindow가 생성되기도 하였다.
이를 해결하기 위해 getData 에서 content를 지정하여 원하는 데이터를 출력하고 createMarker에서 infowindow를 생성하기 위해 createMarker에 해당 데이터의 위도 경도에 더하여 content값까지 보냈더니 생성 되었다.
function createMarker1(lat, lng, content, city) {
const markerPosition = new kakao.maps.LatLng(lat, lng);
var imageSrc = 'https://cdn-icons-png.flaticon.com/512/7512/7512521.png', // 마커이미지의 주소입니다
imageSize = new kakao.maps.Size(50, 52), // 마커이미지의 크기입니다
imageOption = { offset: new kakao.maps.Point(27, 69) }; // 마커이미지의 옵션입니다. 마커의 좌표와 일치시킬 이미지 안에서의 좌표를 설정합니다.
// 마커의 이미지정보를 가지고 있는 마커이미지를 생성합니다
var markerImage = new kakao.maps.MarkerImage(imageSrc, imageSize, imageOption);
const marker = new kakao.maps.Marker({
position: markerPosition,
image: markerImage
});
infowindow = new kakao.maps.InfoWindow({
content: content,
removable: true
});
kakao.maps.event.addListener(marker, 'click', function () {
infowindow.setContent(content);
infowindow.open(map, marker);
map.panTo(markerPosition);
});
const mark = {
marker: marker,
add: cityaddress
}
markers.push(mark);
marker.setMap(map);
}
4. 다른 카테고리를 선택했을때 infowindow 제거
marker는 removeMarkers로 지워지지만 infowindow는 남는 현상이 발생하였다.
아래 코드를 checkbox 해제 되었을때 removeMarkers와 같이 넣어주니 infowindow도 사라졌다.
function removeInfo1() {
infowindow.close();
}
5. 전체 카테고리 생성 + 제거
전체 충전소 마커를 생성하고 제거하는 기능을 구현하였다.
전체의 경우 checkbox에서 city를 "전체"로 주도록 하고
전체라는 지역구가 없기 때문에 별도의 handleCheckboxChange2라는 함수를 부여하고 선택되면 모든 지역구의 값을 getData()에 넣어 모든 마커가 생성되도록 하였다.
삭제도 동일한 방식으로 수행하였다.
function handleCheckboxChange2(city, checked) {
if (checked) {
getData1('북구');
getData1('광산구');
getData1('동구');
getData1('남구');
getData1('서구');
} else {
removeMarkers1('북구');
removeMarkers1('광산구');
removeMarkers1('동구');
removeMarkers1('남구');
removeMarkers1('서구');
}
}
기나긴 여정을 함께해준 이 님께 thanks를..❤️