본문 바로가기
Dev/JavaScript

다음 우편번호 api와 카카오 맵 api 사용기

by vellahw 2023. 3. 7.

 

 

프로젝트를 마무리 하고 쫌쫌따리 추가구현 중인 것들이 있는데 그중 하나인 카카오 map api

'모임'이 주제인 프로젝트인만큼 모임 장소를 지도로 표시해주는게 좋을  것 같아 시작하게 되었다.

모임을 개설하는 방장이 다음 우편번호 api를 통해 주소를 검색하면 카카오 맵으로 해당 장소를 띄워줄 계획이다.

 

💭 시작하기 전..

  • 지도에 대한 정보를 담는 테이블을 따로 생성해서 위도, 경도, 검색한 주소, 상세주소, 모임 번호, 주소 번호 시퀀스를 받는 6개의 컬럼을 만들어뒀다.
  • 디테일 페이지에서 주소에 해당하는 위도, 경도를 가지고 있기 위해 쿼리를 추가로 작성하여 DAO 클래스의 디테일 처리 메소드에 추가해두었다.
  • 지도 테이블에 insert 해주는 쿼리문을 따로 작성해 모임 개설(=게시글 등록) 시 쿼리가 돌아가도록  DAO 클래스에서 처리해주었다.

 


 

카카오 맵 api를 사용하기 위해선 카카오 개발자사이트(https://developers.kakao.com/)에서 회원가입-로그인-어플리케이션 등록(App key 발급)-플랫폼 등록의 절차가 필요하다. (검색하면 많이 나오기도 하고 대충 봐도 쉬운 절차이니 설명은 생략ㅎ)

 

1. 지도 띄우기

사용할  jsp 파일 안에 자바스크립트 api를 불러와준다.

1
2
3
<!-- KAKAO POSTCODE & MAP -->
<script src="//t1.daumcdn.net/mapjsapi/bundle/postcode/prod/postcode.v2.js"></script>
<script type="text/javascript" src="//dapi.kakao.com/v2/maps/sdk.js?appkey=발급받은앱키&libraries=services"></script>
cs

 

위는 우편번호 자바스크립트 api, 아래는 카카오맵 자바스크립트 api이다.

카카오 개발자사이트에 올라온 설명에 의하면 이 스크립트 태그는 head, body 어디에 선언 되어도 상관은 없지만 반드시 실행 코드보다 먼저 선언되어야 한다고 한다.

나는 전페이지 공용으로 쓰고 있는 header 파일에 선언해주었다.

  • 카카오맵 스크립트 태그의 src 끝에 붙은 libraries=services는 주소의 위도, 경도를 불러와 마커로 표시하기 위해 필요한 라이브러리이다. 
  • 위도, 경도 값 추출해서 지도에 표시 해주고자 한다면 똑같이 필수로 선언해둘 것!!
  • (처음에 급하게 찾아보느라 선언 되지 않은 채 스크립트 돌렸어서 Geocorder가 적용이 안 돼 헤맸었다.. ㅎ)

 

1
<div id="map" style="width:500px;height:400px;"></div>
cs

다음으로 지도를 띄워줄 위치에 위 코드를 붙여넣고

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
var latitude = document.getElementById('latitude').value; //위도
var longitude = document.getElementById('longitude').value; //경도
var address = document.getElementById('address').value;
var detail_address = document.getElementById('detail-address').value;
 
var container = document.getElementById('map'); //지도를 담을 영역의 DOM 레퍼런스
var options = { //지도를 생성할 때 필요한 기본 옵션
   center: new kakao.maps.LatLng(latitude, longitude), //지도의 중심좌표.
   level: 3 //지도의 레벨(확대, 축소 정도)
};
 
var map = new kakao.maps.Map(container, options); //지도 생성 및 객체 리턴
 
//지도를 클릭한 위치에 표출할 마커
var marker = new kakao.maps.Marker({ 
   // 지도 중심좌표에 마커를 생성
   position: map.getCenter() 
}); 
//지도에 마커를 표시
marker.setMap(map);
 
// 인포윈도우로 장소에 대한 설명을 표시
var infowindow = new kakao.maps.InfoWindow({
    content'<div style="width:150px;text-align:center;padding:6px 0;">'+address+'<br>'+detail_address+'</div>'
});
 
infowindow.open(map, marker); 
cs

스크립트도 붙여준다.

변수로 선언한 wii와 kyung은 디테일 페이지에서 hidden으로 가지고 있는 위도와 경도 값을 저장해준 것이다.

이 값을 이용해서 지도에 마커를 찍어주도록 중심좌표를 바꿔주었다.

여기서 위도, 경도는 직접 주소를 검색해서 insert한 것이 아닌 테스트용으로 넣어둔 데이터를 사용했다.

 

지도 띄우기 성공!

 

 

2. 다음 우편번호 api로 검색한 주소를 카카오 맵에 띄우기

모임 개설 시(=게시글 작성) 주소를 검색하면 바로 지도에 마커를 찍어주도록 구현하고자 했다.

아래는 jsp의 일부이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
<tr>
    <th class="header"><label for="MO_MAP" >모임 장소</label></th>
    <td class="contents">
        <input type="text" class="form-control" id="MO_MAP" readonly="readonly" name="ADDRESS">
        <button type="button" class="searchMap"
                   onclick="kaMap()">주소 검색</button>
        <br/>           
        <input type="text" id="detailAddress" placeholder="상세주소 입력" name="DEADDRESS">
        <div id="map" style="width:500px;height:400px; margin-top: 10px;"></div>
        <input type="hidden" name="WII">
        <input type="hidden" name="KYUNG">
    </td>
</tr>
cs

주소 검색 버튼을 누르면 onclick 이벤로 kaMap() 함수가 작동한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
/* 지도 띄우기 */
var container = document.getElementById('map');
var options = { //지도를 생성할 때 필요한 기본 옵션
     center: new kakao.maps.LatLng(33.450701126.570667), //지도의 기본 중심좌표
    level: 3 //지도의 레벨(확대, 축소 정도)
};
 
var map = new kakao.maps.Map(container, options); //지도 생성 및 객체 리턴     
 
/* 다음 주소검색 및 마커 표시 */
var geocoder = new kakao.maps.services.Geocoder();
 
/* 주소 검색 onclick */
function kaMap() {
   var width = 500//팝업의 너비
   var height = 600//팝업의 높이
   new daum.Postcode({
       width: width, 
       height: height,
   
       oncomplete: function(data) {
           var addr = ''// 주소 변수
           var extraAddr = ''// 참고항목 변수
           //사용자가 선택한 주소 타입에 따라 해당 주소 값을 가져온다.
           if (data.userSelectedType === 'R') { // 사용자가 도로명 주소를 선택했을 경우
               addr = data.roadAddress;
           } else { // 사용자가 지번 주소를 선택했을 경우(J)
               addr = data.jibunAddress;
           }
           // 사용자가 선택한 주소가 도로명 타입일때 참고항목을 조합한다.
           if(data.userSelectedType === 'R'){
               // 법정동명이 있을 경우 추가한다. (법정리는 제외)
               // 법정동의 경우 마지막 문자가 "동/로/가"로 끝난다.
               if(data.bname !== '' && /[동||가]$/g.test(data.bname)){
                   extraAddr += data.bname;
               }
               // 건물명이 있고, 공동주택일 경우 추가한다.
               if(data.buildingName !== '' && data.apartment === 'Y'){
                   extraAddr += (extraAddr !== '' ? ', ' + data.buildingName : data.buildingName);
               }
               // 표시할 참고항목이 있을 경우, 괄호까지 추가한 최종 문자열을 만든다.
               if(extraAddr !== ''){
                   extraAddr = ' (' + extraAddr + ')';
               }
               // 조합된 참고항목을 해당 필드에 넣음
           
           } else { }
           
           // 우편번호와 주소 정보를 해당 필드에 넣음
           document.getElementById("MO_MAP").value = addr;
           //상세주소 입력 폼으로 포커스 이동
           document.getElementById("detailAddress").focus();
 
           // 주소 검색 후 지도에 마커 표시하기
           geocoder.addressSearch(addr, function(result, status) {
           
             // 정상적으로 검색이 완료됐으면 
             if (status === kakao.maps.services.Status.OK) {
             
              //위도, 경도 저장
              var letlng = new kakao.maps.LatLng(result[0].y, result[0].x);
              var wii = result[0].y; //위도
              var kyung = result[0].x; //경도
              
              document.getElementById('detailAddress').style.display = 'block';
              document.getElementById('map').style.display = 'block';
                
              //hidden input value 바꿔주기
              var hidden_latitude = document.querySelector('input[name="WII"]'); 
              hidden_latitude.value = wii;
    
              var hidden_longitude = document.querySelector('input[name="KYUNG"]');
              hidden_longitude.value = kyung;
                
              // 결과값으로 받은 위치를 마커로 표시
              var marker = new kakao.maps.Marker({
                  map: map,
                  position: letlng
              });
         
              // 인포윈도우로 장소에 대한 설명을 표시
              var infowindow = new kakao.maps.InfoWindow({
                  content'<div style="width:150px;text-align:center;padding:6px 0;">'+addr+'</div>'
              });
              infowindow.open(map, marker);
         
              // 지도의 중심을 결과값으로 받은 위치로 이동
              map.setCenter(letlng);
            } 
         }); 
       }
   }).open({
    //팝업 가운데 정렬
    left: (window.screen.width / 2- (width / 2),
    top: (window.screen.height / 2- (height / 2),
    //팝업창 타이틀 지정
    popupTitle: '모임 장소 검색하기'
   });
}
cs

지도를 띄워주는 건 1번과 똑같고 기본으로 설정한 위치를 주소 검색 후 geocoder.addressSearch()를 이용해 위도, 경도를 구해서 마커를 이동시켜준다.

 

1
2
3
4
5
new daum.Postcode({
        oncomplete: function(data) {
            ...           
        }
}).open();
cs

우편번호는 위 코드 블럭 안에 있는 코드들로 동작한다.

카카오에서 올려준 코드를 참고하면 된다! ( https://postcode.map.daum.net/guide )

 

적용 완료된 폼

검색한 주소와 상세주소를 input 태그로 넘기고 hidden input 태그로 위도, 경도 각각을 담아 넘기도록 처리 했기 때문에 이대로 모임을 개설하면 DB에 잘 들어가게 된다.

 

 

디테일 페이지에서 세부지역 옆의 버튼을 클릭하면 지도가 나오게끔 수정해주었다.

카카오맵 연동하기 완료!

 

 


참고

댓글