지난 포스팅까지 하여 주소검색을 통해 마커를 이동하는 방법에 대해 알아보았다. 이번 편은 클릭한 곳의 좌표를 가져오는 방법과 드래그한 마커의 위치또한 좌표로 가져올 수 있는 방법에 대해 알아보도록 하자 .
우선 예제 소스 전체를 보기전 마커 드래그 이벤트중 하나인 `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에서 제공해주는 이벤트를 통해 좌표를 출력하는 방법에 대해 알아 보았다. 다음편은 언제 포스팅할지 아직 예정은 없으나 다음 편의 경우 다수 위치기반 데이터를 이용하여 마커로 표시하고 해당 마커를 클릭 시 이벤트를 발생시키는 방법에 대해 알아보도록 하자.