아르꼬의 코딩일기

[카카오맵] DB에 위도,경도 값을 다중 마커 / 커스텀 오버레이 / 클러스터 본문

API

[카카오맵] DB에 위도,경도 값을 다중 마커 / 커스텀 오버레이 / 클러스터

아르꼬 2022. 10. 25. 14:07

 코트 엔티티에 모든 정보를 프론트로 모델에 담아서 보낸다.

	// 코트 예약 페이지
	@GetMapping(value = "/reservation")
	public String courtReservation(Model model) {
		List<Court> courtAll = courtService.getCourtAll();
		System.out.println(courtAll);
		model.addAttribute("courtList", courtAll);
		return "court/reservation";
	}

 

reservation.html 에서 아래와 같이 자바스크립트를 설정하는데  자바스크립트 안에서 타임리프문을 사용하려면

첫문장에 /*<![CDATA[*/

 끝문장에 /*]]>*/ 를 붙인다.. ( 타임리프 버전이 올라가면서 안써도 된다고하는데 일단은 적용시킨 상태로 한다)

백에서 받아온 court를 th:each문을 사용해서 아래와 같이 데이터를 꺼낸다.

/*[# th:each="court : ${courtList}"]*/
			// 마커 이미지의 이미지 크기 입니다
			var imageSize = new kakao.maps.Size(24, 35);

			// 마커 이미지를 생성합니다    
			var markerImage = new kakao.maps.MarkerImage(imageSrc, imageSize);


			var markers = [];
			var data = /*[[${court}]]*/;
			//console.log(data);
			//console.log(data.lat);

			displayMarker(data);
			clusterer.addMarkers(markers);

			/*[/]*/

 

 

다중 마커 같은경우 카카오 맵 개발자 페이지에 자세한 설명이 나와있기 때문에 그것을 참고해서 작업을 했고,

어려웠던점은 커스텀 오버레이에서 닫기 버튼을 클릭했을때 맨 마지막에 생긴 커스텀 오버레이만 이벤트가 적용이 됐다.. 이것을 해결하려고 관련 자료를 찾았고, displayMarker라는 함수를 만들어서 DOM형식으로 처리했다.

아래 코드는 클러스터도 같이 적용되어있다. 

 

			// 지도에 마커를 표시하는 함수입니다    
			function displayMarker(data) {

				var l = new kakao.maps.LatLng(data.lat, data.lng);
				var marker = new kakao.maps.Marker({
					map: map,
					position: l,
					image: markerImage // 마커 이미지 
				});
				var overlay = new kakao.maps.CustomOverlay({
					yAnchor: 3,
					map: map,
					position: marker.getPosition()
				});

				var wrap = document.createElement('div');
				//wrap.innerHTML = data.name;
				wrap.className = "wrap";

				var info = document.createElement('div');
				info.className = "info";

				wrap.appendChild(info);

				var title = document.createElement('div');
				title.className = "title";
				sometext = document.createTextNode(data.name);

				title.appendChild(sometext);
				info.append(title);

				var close = document.createElement('div');
				close.className = "close";
				close.title = '닫기';
				close.onclick = function () {
					overlay.setMap(null);
				};
				title.appendChild(close);

				var body = document.createElement('div');
				body.className = "body";
				info.appendChild(body);

				var imgDiv = document.createElement('div');
				imgDiv.className = "img";
				body.appendChild(imgDiv);

				var img = document.createElement('img');
				img.className = "image";
				img.src = "/img/kiwi.png";
				// img.width="40";
				// img.height="40";
				imgDiv.appendChild(img);

				var desc = document.createElement('div');
				desc.className = "desc";
				body.appendChild(desc);

				var ellipsis = document.createElement('div');
				ellipsis.className = "ellipsis";

				var text = document.createTextNode(data.address1);

				ellipsis.appendChild(text);

				desc.appendChild(ellipsis);

				var jibun = document.createElement('div');
				jibun.className = "jibun ellipsis";

				var text2 = document.createTextNode(data.call_number);

				jibun.appendChild(text2);

				desc.appendChild(jibun);

				var footerDev = document.createElement('div');

				desc.appendChild(footerDev);

				var link = document.createElement('a');
				link.className = "link";

				var text3 = document.createTextNode("구장 정보 보기");

				link.appendChild(text3);
				link.target = "_blank";
				link.href = "http://www.kakaocorp.com/main";

				footerDev.appendChild(link);




				overlay.setContent(wrap);
				markers.push(marker);
				kakao.maps.event.addListener(marker, 'click', function () {
					overlay.setMap(map);
					console.log("하이용");
				});
			}

 

전체 자바스크립트 코드

<div id="map" style="width: 1213px; height: 600px; margin-right: 80px; margin-left: 55px;"></div>
		<script th:inline="javascript">
			/*<![CDATA[*/
			var mapContainer = document.getElementById('map'), // 지도를 표시할 div 
				mapOption = {
					center: new kakao.maps.LatLng(37.40785375, 126.6325097), // 지도의 중심좌표
					level: 5 // 지도의 확대 레벨
				};

			var map = new kakao.maps.Map(mapContainer, mapOption); // 지도를 생성합니다
			var imageSrc = "https://t1.daumcdn.net/localimg/localimages/07/mapapidoc/markerStar.png";

			// 일반 지도와 스카이뷰로 지도 타입을 전환할 수 있는 지도타입 컨트롤을 생성합니다
			var mapTypeControl = new kakao.maps.MapTypeControl();

			// 지도에 컨트롤을 추가해야 지도위에 표시됩니다
			// kakao.maps.ControlPosition은 컨트롤이 표시될 위치를 정의하는데 TOPRIGHT는 오른쪽 위를 의미합니다
			map.addControl(mapTypeControl, kakao.maps.ControlPosition.TOPRIGHT);

			// 지도 확대 축소를 제어할 수 있는  줌 컨트롤을 생성합니다
			var zoomControl = new kakao.maps.ZoomControl();
			map.addControl(zoomControl, kakao.maps.ControlPosition.RIGHT);


			// 마커 클러스터러를 생성합니다 
			var clusterer = new kakao.maps.MarkerClusterer({
				map: map, // 마커들을 클러스터로 관리하고 표시할 지도 객체 
				averageCenter: true, // 클러스터에 포함된 마커들의 평균 위치를 클러스터 마커 위치로 설정 
				minLevel: 10 // 클러스터 할 최소 지도 레벨 
			});


			/*[# th:each="court : ${courtList}"]*/
			// 마커 이미지의 이미지 크기 입니다
			var imageSize = new kakao.maps.Size(24, 35);

			// 마커 이미지를 생성합니다    
			var markerImage = new kakao.maps.MarkerImage(imageSrc, imageSize);


			var markers = [];
			var data = /*[[${court}]]*/;
			//console.log(data);
			//console.log(data.lat);

			displayMarker(data);
			clusterer.addMarkers(markers);

			/*[/]*/

			// 지도에 마커를 표시하는 함수입니다    
			function displayMarker(data) {

				var l = new kakao.maps.LatLng(data.lat, data.lng);
				var marker = new kakao.maps.Marker({
					map: map,
					position: l,
					image: markerImage // 마커 이미지 
				});
				var overlay = new kakao.maps.CustomOverlay({
					yAnchor: 3,
					map: map,
					position: marker.getPosition()
				});

				var wrap = document.createElement('div');
				//wrap.innerHTML = data.name;
				wrap.className = "wrap";

				var info = document.createElement('div');
				info.className = "info";

				wrap.appendChild(info);

				var title = document.createElement('div');
				title.className = "title";
				sometext = document.createTextNode(data.name);

				title.appendChild(sometext);
				info.append(title);

				var close = document.createElement('div');
				close.className = "close";
				close.title = '닫기';
				close.onclick = function () {
					overlay.setMap(null);
				};
				title.appendChild(close);

				var body = document.createElement('div');
				body.className = "body";
				info.appendChild(body);

				var imgDiv = document.createElement('div');
				imgDiv.className = "img";
				body.appendChild(imgDiv);

				var img = document.createElement('img');
				img.className = "image";
				img.src = "/img/kiwi.png";
				// img.width="40";
				// img.height="40";
				imgDiv.appendChild(img);

				var desc = document.createElement('div');
				desc.className = "desc";
				body.appendChild(desc);

				var ellipsis = document.createElement('div');
				ellipsis.className = "ellipsis";

				var text = document.createTextNode(data.address1);

				ellipsis.appendChild(text);

				desc.appendChild(ellipsis);

				var jibun = document.createElement('div');
				jibun.className = "jibun ellipsis";

				var text2 = document.createTextNode(data.call_number);

				jibun.appendChild(text2);

				desc.appendChild(jibun);

				var footerDev = document.createElement('div');

				desc.appendChild(footerDev);

				var link = document.createElement('a');
				link.className = "link";

				var text3 = document.createTextNode("구장 정보 보기");

				link.appendChild(text3);
				link.target = "_blank";
				link.href = "http://www.kakaocorp.com/main";

				footerDev.appendChild(link);




				overlay.setContent(wrap);
				markers.push(marker);
				kakao.maps.event.addListener(marker, 'click', function () {
					overlay.setMap(map);
					console.log("하이용");
				});
			}





			/*]]>*/

		</script>

 

결과

 

 

출처 : https://devtalk.kakao.com/t/topic/64848/9