본문 바로가기
컴퓨터/웹 : JS

[Node.js](개인 프로젝트) 카카오 지도 연동하기

by 도도새 도 2023. 3. 4.

지도 연동

 

오늘은 드디어 지도를 넣을 예정이다. 문제는 네이버 지도는 이제 지원하지 않고, 구글 지도는 유료라는 것이다. 구글 지도를 넣고 싶은데 문제는 접근이 0이라도 약간의 돈이 든다. 나는 지금 만드는 사이트를 실제로 호스팅하고 광고까지 넣을 예정이지만(물론 수익이 크게 발생할 거라는 생각은 하지 않는다. 우선적으로 내가 타겟으로 하는 지역이 내 대학 주변 뿐이기도 하기 때문이다.) 광고 수익이 지도 발생 수익을 상회할 거라는 계산이 안 든다.

 

게다가 만약 운이 좋아서 사용자가 있다? 애매하게 사용자가 붙으면 DB를 띄워주는 값과 호스팅하는데 쓰이는 값, 사진업로드 API를 이용하는 값까지 내야한다. 현재 블로그에 애드센스를 이용하기에 광고료에 대한 잣대가 대충 있긴 하다. 600뷰에 2달러 정도라고 본다. 그런데 내 웹사이트가 하루에 600명 이상의 사람이 올까? 결단코 아니다. 서비스가 다른 대기업 사이트에 비해 월등히 좋은 점 역시 없다. 단지 상권 중심으로 보여주자!라는 차별화 지점만 존재하는 느낌이다.

 

사실 이번 사이트 같은 경우는 기술적으로 내가 이런 것들을 할 수 있다!라는 포트폴리오용으로는 적합하지만 실제 수익과 연동시키기에는 한계가 있다. 거기다 수익을 키우려 할수록 유지 운용 난이도가 올라가는 시스템이라고 생각한다.

 

따라서 지도는 우선 무료로 지원해주는 지도 사이트를 이용하기로 한다. 이전 프로젝트에서는 해외 사이트를 이용했는데, 이번에는 카카오지도를 이용해보고자 한다. 130만회 접근이 가능하다고 하니까, 사실상 절대로 돈이 들 일은 없고, 만약 실사용자가 많아져서 30만회 접근이 이루어진다면, 횡재지 뭐.

 

아무튼 결론적으로 오늘은 지도 API를 연동하고, 실제 주소와 카페를 매칭시키고자 한다. 하는 김에 카루셀 크기도 줄이고.

 

여유가 있다면 사진api까지 연동시키겠다만, CNN 이용한 플러터 앱 개발이라는 졸업과제의 압박이 다가오기 때문에, 오늘은 이것까지만 하고 플러터 공부를 해야한다....

 

카카오지도 연동

 

카카오 지도 API 가이드가 있다. 따라서 시키는 대로 하자. 개발을 하다보면 맨날 따라서 시키는대로 하는 것 같다.

https://apis.map.kakao.com/web/guide/

우선 키 발급이 되니 지도는 잘 띄어진다. 이제 현재 주소를 저장해야하므로, 현재 장소 검색을 해 줄 수 있는 라이브러리를 사용한다. 카카오에서 제공해준다. 고맙다. 이전에 지도를 올릴 때 geocode니 뭐니 해서 살짝 복잡했던 기억이 있어 들어가기에 앞서 벌써 괴롭다.

 

 

   <script >

     var container = document .getElementById ('map');

     var options = {

       center :new kakao .maps .LatLng (33.450701 , 126.570667 ),

       level :3

     };

     var map = new kakao .maps .Map (container , options );

     var places = new kakao .maps .services .Places ();

     places .setMap (map );

     

     var callback = function (result , status ) {

   if (status === kakao .maps .services .Status .OK ) {

     console .log (result );

   }

};

places .keywordSearch ('OOO카페', callback );

   

   </script >

우선 이렇게 하면 places.keywordSearchOOO카페의 결과를 객체 배열로 반환해준다. 객체에는 굉장히 많은 정보가 담겨 있다.(콜백 함수 내에서)

카카오지도 객체

 

그러니까 내가 할 것은, 사용자가 검색하면 저 배열 중 하나를 사용자에게 고르도록 하고, 고른 결과를 저장하면 될 것이다. 그리고 사용자가 해당 카페에 접근 할 경우 해당 카페 모델 내부의 위도 경도와 카카오맵을 연동시켜서 현재 위치를 마커로 찍어주면 되리라 생각한다. 되겠찌...? 해보자. 우선 위도 경도가 결과로서 표시가 된다!!

 

일단 버튼을 누르면 모달 팝업을 뛰우고 거기서 검색을 하면 검색 결과를 받아와서 배열로 보여주고, 해당 아이템 중 하나를 클릭하면 현재 input태그에 해당 값이 들어가도록 하면 되지 않을까? 내가 저장할 것은 위, 경도니까 invisible한 인풋 태그도 만들면 되겠다....

 

라고 생각했으나 검색을 하면 axios로 검색 결과를 받아와서 배열로 보여주고, 이부분은 보여지는 html 파일 내에서 진행하면 되겠다.

 

아무튼 Docs가 시키는 대로 한다.(결론적으로 내가 axios를 이용할 일은 없었다. 카카오가 지원해주는 api를 이용하기에 해당 부분과 통신만 되면 된다. 즉 와이파이 연결이 필요!)

카카오지도 DOCs

 

키워드로 장소를 검색하면 아래 xy를 얻을 수 있는데, x가 경도 y가 위도이다. 그런데 다른 함수에 위도 경도를 넣을 때는, y x순서로, 즉 위도 경도 순서로 넣어야한다.

아무튼 지도와 연동되도록 하였다.

카카오지도 연동

 

카페이름이나 카페 위치 인풋을 누르면 모달이 뜬다. 거기서 선택을 하면 지도에 그 위치가 즉각 반영되고 인풋에 이름과 위치가 들어간다.

카카오지도 연동

 

JS

 

이 작업들을 위해 JSCSS를 다소 만지게 되었다. 우선 모달 팝업에 스크롤바를 띄우는 것은 css로 처리해야하고, 카페 목록에 마우스가 포커스 되면 백그라운드 컬러 지정, 떨어지면 해당 백그라운드 컬러를 주는 클라스를 삭제하는 걸로 구현되었다.

 

           e .addEventListener ('mouseenter', ()=>{

             e .classList .add ('hover_changeBg');

           })

           e .addEventListener ('mouseleave', ()=>{

             e .classList .remove ('hover_changeBg');

           })

이런식으로 hover이벤트를 js로 구현하였다. 현재는 배열을 돌며 모든 요소에 해당 이벤트를 추가하였지만, :hover를 적용한 css id나 클래스를 전체에 적용하는 것도 한 가지 방법이 되리라 생각한다.(지금 생각해보면 이게 더 직관적일지도?)

 

또한 쉽게 정보를 서버로 넘기기 위해 보이지 않는 input을 사용해 해당 input에 위도 경도를 넣어 서버로 넘겼다.

 

             <input id ="inputLatitude"style ="display: none;"name ="cafe[latitude]"readonly ><!--위도 저장-->

             <input id ="inputlongitude"style ="display: none;"name ="cafe[longitude]"readonly ><!--경도 저장-->

 

map객체 cluster객체 marker객체 등 지도와 관련 된 부분은 그냥 공식 문서를 보고 하라는 대로 했다. 이게 웃긴게 이전에 영어 문서를 읽으면서 했을 때는 아주 어렵게 느껴졌는데 한글로 된 문서를 읽으니 세상 쉽게 느껴진다.

 

기회가 되면 날 잡고 아무 기술이나 공식 문서 통 번역하는 연습을 해야겠다. 그러다보면 오히려 개발실력이 늘 것 같다. 사실 나에게 필요했던 건 영어실력일지도?

 

 

 locationSearchBtn .addEventListener ('click', async e =>{

     e .preventDefault ();

     locationSearchContainer .innerHTML = '';

     var places = new kakao .maps .services .Places ();

     var callback = await function (result , status ) {

       locationObjectArr = [];

       locationTags = [];

       if (status === kakao .maps .services .Status .OK ) {

         for (element of result ){

           let temp = document .createElement ("div");

           let tempObj = {

             name :element .place_name ,

             location :element .road_address_name ,

             x :element .x ,

             y :element .y

           };

           locationObjectArr .push (tempObj );

           temp .innerText = `${element .place_name } (${element .road_address_name })`;//태그 설정

           temp .setAttribute ('class', 'mb-1')

           locationTags .push (temp );

           locationSearchContainer .appendChild (temp );

         };

         locationTags .forEach (e =>{

           e .addEventListener ('click', evt =>{

             result_locationObject =  locationObjectArr [childIndex (e )];

             locationSearch .value = result_locationObject ?result_locationObject .name :"";

             clusterer .clear ();

             let marker = new kakao .maps .Marker ({

               position :new kakao .maps .LatLng (result_locationObject .y , result_locationObject .x )

             });

             map .setCenter (new kakao .maps .LatLng (result_locationObject .y , result_locationObject .x ));

             clusterer .addMarker (marker );

           })

           e .addEventListener ('mouseenter', ()=>{

             e .classList .add ('hover_changeBg');

           })

           e .addEventListener ('mouseleave', ()=>{

             e .classList .remove ('hover_changeBg');

           })

         })

       }

     };

     places .keywordSearch (locationSearch .value , callback );

   })

 

실제 서치하고 데이터를 처리하여 태그를 만드는 부분이다. 콜백 함수 내의 result에는 배열로 서치 정보들이 담긴다. 나는 해당 요소들을 돌며 태그를 생성하고, 임시 객체를 생성하였다. 그리고 전역으로 만들어 둔 array에 해당 객체와 태그를 넣었다. 어레이에 태그도 들어간다는 사실이 재밌었다.

 

CC++에서 이런식으로 처리하면, 함수 내의 요소들을 밖에서 접근이 가능했던 기억으로 비슷하게 코딩해보았다. 어쨌든 해당 객체가 존재하는 위치값만 배열에 바르게 쓰이면 읽을 수 있을 테니까, 라는 접근이었다.

 

그리고 뭐 마커 생성하고, 맵 이동하고 등등의 작업도 여기서 진행되었다. 어쩌다 보니 맵과 관련된 js코드만 100줄이 되어서 살짝 심란하지만, 어쩃든 맵과 관련된 작업을 일부 완성했다. 사실 카페를 생성하는 사람에게 맵을 보여주는 건 선택사항이었지만, 내가 딱 주소를 보고 위치 가늠이 한 번에 안 되길래 넣었다. 사용자 경험이 중요하다고 하니까.

 

이제 이걸 리액트 페이지에서도 뛰우고, 사용자가 카카오톡으로 공유할 수 있는 기능을 만들면 참 좋겠다.

댓글