지난 포스팅까지 하여 주소검색을 통해 마커를 이동하는 방법에 대해 알아보았다. 이번 편은 클릭한 곳의 좌표를 가져오는 방법과 드래그한 마커의 위치또한 좌표로 가져올 수 있는 방법에 대해 알아보도록 하자 .

 

우선 예제 소스 전체를 보기전 마커 드래그 이벤트중 하나인 `dragend` 와 지도 클릭 이벤트 `click` 대해 알아보도록 하자. 아래의 이벤트는 마커 드래그가 끝나는 시점에 발생되는 이벤트 이다. 

// 마커 드래그 이벤트
kakao.maps.event.addListener(thisObj.item[id].markers[i], 'dragend', function(e) {
	var getPosition = thisObj.item[id].markers[i].getPosition();
	thisObj.item[id].lat = getPosition.getLat();
	thisObj.item[id].lng = getPosition.getLng();
	thisObj.viewPosition('map');			    
});

 

해당 이벤트를 보면 지도객체, 이벤트 타입, callback 함수 등으로 구성되어있다. 해당 이벤트가 발생 시 `getPosition` 변수에 이동된 마커의 위치 객체를 담고 해당 객체를 이용하여 위도, 경도를 저장 한 후 최종적으로 위도, 경도 출력에 적용해 주고 있다. 

 

그다음 이벤트 소스는 `click` 이벤트로 마우스로 지도를 클릭 할 시 발생되는 이벤트이다. 

// 클릭 이벤트
kakao.maps.event.addListener(thisObj.item[id].map, 'click', function(mouseEvent) {        
   // 클릭한 위도, 경도 정보를 가져옵니다 
   var getPosition = mouseEvent.latLng; 
    
   // 마커 위치를 클릭한 위치로 옮깁니다
   thisObj.item[id].markers[i].setPosition(getPosition);

	thisObj.item[id].lat = getPosition.getLat();
	thisObj.item[id].lng = getPosition.getLng();
   thisObj.viewPosition('map');		
});				

 

이벤트를 보면 위의 `dragend` 이벤트와 동일하게 지도 객체, 이벤트타입, callback 함수등으로 구성되어있으며 callback 함수에서는 마우스 이벤트 변수를 메소드로 받을 수 있다.  해당 이벤트가 발생되면 마우스 이벤트 변수를 받아서 현재의 위치를 객체에 담고 해당 객체를 이용하여 위도, 경도를 추출 후 최종 위도, 경도를 출력해 준다. 

 

그럼 아래와 같이 전체 소스를 이용하여 예제 소스를 확인해보도록 하자.

 

마커 드래그 이벤트 + 클릭한 곳 이벤트 적용 예제

 

[샘플보기]

<!-- jquery -->
<script src="//code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script><?php // http://craftpip.github.io/jquery-confirm/ ?> 

<!-- kakao 지도 api (+ services와 clusterer, drawing 라이브러리 불러오기) -->
<!-- 
@libraries 설명 for kakao 
	clusterer: 마커를 클러스터링 할 수 있는 클러스터러 라이브러리 입니다.
	services: 장소 검색 과 주소-좌표 변환 을 할 수 있는 services 라이브러리 입니다.
	drawing: 지도 위에 마커와 그래픽스 객체를 쉽게 그릴 수 있게 그리기 모드를 지원하는 drawing 라이브러리 입니다.
-->
<script type="text/javascript" src="//dapi.kakao.com/v2/maps/sdk.js?appkey=543d067cfc41f7325d2f408e2f32264d&libraries=services,clusterer,drawing"></script>

<!-- style -->
<style>
	.container{  overflow: hidden; }
	.container { overflow: hidden; width:100%; max-width: 500px; margin:40px auto;  }
	.container .evt-map{ width:100%; height:300px; border:solid 1px #eee; }
	.container .form{ margin:10px 0; border-bottom: solid 3px #eee; padding:5px 0;}
	.container .form input{ width:280px; padding:5px 3px; font-size:12px; }
	.container .form a{ display: inline-block; width:80px; text-align:center; border:solid 1px #eee; text-decoration: none; color:#333; font-size:12px; padding:5px 0; }

	.container .position{ margin:10px 0; border-top: solid 3px #eee; }
	.container .position dl{ border-bottom: dotted 1px #333;}
	.container .position dt{ font-weight: 900; padding: 5px 0;}

</style>

<!-- 지도를 띄울 Container -->
<div class="container">
	<div class="group">
		<h1>지도</h1>
		<div class="form">
			<input type="text" class="evt-address" name="address" value="" placeholder="주소입력">
			<a href="#none" onclick="return false;" class="evt-search">검색</a>
		</div>
		<div class="evt-map" id="map"></div>

		<div class="position">
			<dl>
				<dt>위도</dt>
				<dd class="evt-view-lat">00.00</dd>
			</dl>
			<dl>
				<dt>경도</dt>
				<dd class="evt-view-lng">00.00</dd>
			</dl>			
		</div>
	</div>
</div>

<!-- script -->
<script>
	var map = {
		item : {},

		// 맵 로드
		load : function(id, options){
			var thisObj = this;
			if (typeof id == 'undefined'){ return false; }

			// 옵션이 없을 경우 기본값 정의
			if(typeof options == 'undefined'){ options = {};}

			// 지도객체 아이템을 조금더 세분화 
			thisObj.item[id] = {};

			// 지도의 옵션 초기화
			if(typeof options.lat =='undefined'){ options.lat = 33.450701;}
			if(typeof options.lng =='undefined'){ options.lng = 126.570667;}
			if(typeof options.level =='undefined'){ options.level = 3;}

			var coords = new kakao.maps.LatLng(options.lat, options.lng); // 지도의 중심좌표

			thisObj.item[id].lat = options.lat;
			thisObj.item[id].lng = options.lng;

			// 맵 옵션
			var mapOptions = {
				center: coords,
				level: options.level // 지도의 확대 레벨				
			}

			// 지도 생성
			thisObj.item[id].map = new kakao.maps.Map(document.getElementById(id),mapOptions);

			// 마커 생성
			thisObj.item[id].markers =[];
			thisObj.item[id].markers[thisObj.item[id].markers.length] = new kakao.maps.Marker({
			    position: coords,
			});		

			$.each(thisObj.item[id].markers,function(i,v){
				// 마커 이벤트적용
				thisObj.item[id].markers[i].setMap(thisObj.item[id].map);
				thisObj.item[id].markers[i].setDraggable(true);

				// 마커 드래그 이벤트
				kakao.maps.event.addListener(thisObj.item[id].markers[i], 'dragend', function(e) {
					var getPosition = thisObj.item[id].markers[i].getPosition();
					thisObj.item[id].lat = getPosition.getLat();
					thisObj.item[id].lng = getPosition.getLng();
					thisObj.viewPosition('map');			    
				});

				// 클릭 이벤트
				kakao.maps.event.addListener(thisObj.item[id].map, 'click', function(mouseEvent) {        
				   // 클릭한 위도, 경도 정보를 가져옵니다 
				   var getPosition = mouseEvent.latLng; 
				    
				   // 마커 위치를 클릭한 위치로 옮깁니다
				   thisObj.item[id].markers[i].setPosition(getPosition);

					thisObj.item[id].lat = getPosition.getLat();
					thisObj.item[id].lng = getPosition.getLng();
				   thisObj.viewPosition('map');		
				});				

			});

			thisObj.viewPosition('map');

		},
		search : function(id,address){
			var thisObj = this;
			if( typeof id == 'undefined') return false;
			if( typeof address == 'undefined') return false;
			if( typeof thisObj.item[id] == 'undefined') return false;


			// 주소-좌표 변환 객체를 생성합니다
			var geocoder = new kakao.maps.services.Geocoder();


			// 주소로 좌표를 검색합니다
			geocoder.addressSearch(address, function(result, status) {


			    // 정상적으로 검색이 완료됐으면 
			     if (status === kakao.maps.services.Status.OK) {

			     		var coords = new kakao.maps.LatLng(result[0].y, result[0].x);

						thisObj.item[id].lat = result[0].y;
						thisObj.item[id].lng = result[0].x;


			     		// 현재 마커들을 삭제
						$.each(thisObj.item[id].markers,function(i,v){
							// 마커를 적용
							thisObj.item[id].markers[i].setMap(null);
							thisObj.item[id].markers = [];

						});			     		

						// 마커 생성
						thisObj.item[id].markers[thisObj.item[id].markers.length] = new kakao.maps.Marker({
						    position: coords
						});		

			     		// 마커 다시 적용
						$.each(thisObj.item[id].markers,function(i,v){
							// 마커를 적용
							thisObj.item[id].markers[i].setMap(thisObj.item[id].map);
							thisObj.item[id].markers[i].setDraggable(true);

							kakao.maps.event.addListener(thisObj.item[id].markers[i], 'dragend', function(e) {
								var getPosition = thisObj.item[id].markers[i].getPosition();
								thisObj.item[id].lat = getPosition.getLat();
								thisObj.item[id].lng = getPosition.getLng();
								thisObj.viewPosition('map');			    
							});

							// 클릭 이벤트
							kakao.maps.event.addListener(thisObj.item[id].map, 'click', function(mouseEvent) {        
							   // 클릭한 위도, 경도 정보를 가져옵니다 
							   var getPosition = mouseEvent.latLng; 
							    
							   // 마커 위치를 클릭한 위치로 옮깁니다
							   thisObj.item[id].markers[i].setPosition(getPosition);

								thisObj.item[id].lat = getPosition.getLat();
								thisObj.item[id].lng = getPosition.getLng();
							   thisObj.viewPosition('map');		
							});		

						});			     		

						thisObj.item[id].map.panTo(coords);    
						thisObj.viewPosition('map');


			    } 
			    else{
			    	alert('주소 검색에 실패하였습니다.');
			    }
			});    

		},

		viewPosition:function(id,lat,lng){
			var thisObj = this;
			if( typeof id == 'undefined') return false;
			if( typeof thisObj.item[id] == 'undefined') return false;

			if( typeof lat == 'undefined'){ lat = thisObj.item[id].lat; }
			if( typeof lng == 'undefined'){ lng = thisObj.item[id].lng; }

			$('.evt-view-lat').text(lat);
			$('.evt-view-lng').text(lng);
		}
	};
	$(document).ready(function(e){
		map.load('map',{});
	});

	// 주소검색 이벤트 -- 검색 버튼 클릭 시
	$(document).on('click','.evt-search',function(e){
		var address = $('.evt-address').val();
		if( $.trim(address) == ''){ alert("주소를 입력해주세요."); return false; }
		map.search('map',address);
	});

	// 주소검색 이벤트 -- 검색어 엔터 시
	$(document).on('keydown','.evt-address',function(e){
		if( e.keyCode == 13){
			var address = $(this).val();
			if( $.trim(address) == ''){ alert("주소를 입력해주세요."); return false; }
			map.search('map',address);
		}
	});

</script>

 

결과) 

 

이처럼 지도 API에서 제공해주는 이벤트를 통해 좌표를 출력하는 방법에 대해 알아 보았다. 다음편은 언제 포스팅할지 아직 예정은 없으나 다음 편의 경우 다수 위치기반 데이터를 이용하여 마커로 표시하고 해당 마커를 클릭 시 이벤트를 발생시키는 방법에 대해 알아보도록 하자.