본문 바로가기
개발일기/리액트,Next.js

React에서 다음 KaKao 지도 API 사용 하는법 - 클릭이벤트, 좌표를 주소로 변환 geocoder, 커스텀 인포윈도우 등 요점 정리

by 프로그래머콩 2020. 3. 3.

리액트로 인포 윈도우 넣는 방법,

geocoder 좌표-주소 변환하는 방법 등은

kakao api에 나와있지 않아 좀 애를 먹었죠 

 

그래서 시험치기전 보는 필승 공략집 처럼

요점 정리 노트 하나 만들어 놓으면 좋을듯 해서

작성해봅니다.


다음 지도 시작하기

단순하게 지도를 띄우는건 간단한 코드 몇줄만으로도 가능합니다

 

우선 kakao map api 키를 발급 받고

index.html head라인에 다음과 같은 코드를 추가합니다.

 

<index.html>

<script type="text/javascript" src="//dapi.kakao.com/v2/maps/sdk.js?appkey=발급받은 APIKEY넣기"></script>

 

그런다음 맵을 구현할 컴포넌트인 

<PopUp.js>를 만들고

다음과 같이 작성해주었습니다.

/*global kakao*/
import React from 'react';


class PopUp extends React.Component {
   constructor(props) {
        super(props);	
    }
    map;
    markers = []
    infowindows = []
    componentDidMount(){
        var container = document.getElementById('myMap'); //지도를 담을 영역의 DOM 레퍼런스
        var options = { //지도를 생성할 때 필요한 기본 옵션
            center: new kakao.maps.LatLng(35.157588, 129.058822), //지도의 중심좌표.
            level: 4 //지도의 레벨(확대, 축소 정도)
        };
	    this.map = new kakao.maps.Map(container, options); //지도 생성 및 객체 리턴
        }
    render() {
        return (
            <div className='popup'>
               <div id='myMap'/>
            </div>
        )
    }
}
export default PopUp;

( /*global kakao*/ = kakao를 글로벌로 선언해서 사용함 )

 

 

그리고 만든 컴포넌트를 띄워봅시다

import React from 'react';
import PopUp from './PopUp'
class Form extends React.Component{
.
.
.
<PopUp />

.
.
.

( *지도에 width, height 를 주어야 나타납니다.)

 


클릭 이벤트

지도에 클릭 이벤트를 추가 하는것도 간단해요

kakao map api에 addListener이라는 함수가 있는데 

이 함수를 통해 다양한 이벤트를 추가할 수 있습니다.

 

<PopUp.js>

    constructor(props) {
        super(props);
	    this.kakao = kakao.maps;
	
    }
    map;
    markers = []
    componentDidMount(){
        var container = document.getElementById('myMap'); //지도를 담을 영역의 DOM 레퍼런스
        var options = { //지도를 생성할 때 필요한 기본 옵션
            center: new kakao.maps.LatLng(35.157588, 129.058822), //지도의 중심좌표.
            level: 4 //지도의 레벨(확대, 축소 정도)
        };
	    this.map = new kakao.maps.Map(container, options); //지도 생성 및 객체 리턴
	    kakao.event.addListener(this.map, 'click', (mouseEvent) => {
        	// 원하는 액션 넣어주기
		    this.removeMarker();
		    this.addMarker(mouseEvent.latLng)
	    })
}

 

addListener(this.map, 'click', () => {...});

this.map에 'click'이벤트가 일어날 때마다 

{} (함수) 에 적어 놓은 액션을 실행하겠다는 뜻입니다.

 

예를들어 제 소스의 경우엔 맵을 클릭할때마다

이벤트 리스너에 안에 있는 

this.removeMarket(); 함수와 this.addMarket(); 함수가 실행이 됩니다

 

addListener()에 등록해놓은 클릭 이벤트가 발생할때

매개변수 mouseEvent 를 받도록 설정해두었는데요,

 

 

이때의 매개변수는 클릭 이벤트가 발생할때 넘어오는 값으로,

클릭한 지점의 좌표값이 들어있습니다.

 

 


좌표-주소 변환, geocoder

제가 하고 싶었던 작업은

좌표를 이용해서 주소를 가져오는 작업이었고

그러기 위해서는 geocoder객체 사용 방법을 알아야 했어요 

 

 

<PopUp.js> - 확장

componentDidMount(){
      var container = document.getElementById('myMap'); //지도를 담을 영역의 DOM 레퍼런스
      var options = { //지도를 생성할 때 필요한 기본 옵션
          center: new kakao.maps.LatLng(35.157588, 129.058822), //지도의 중심좌표.
          level: 4 //지도의 레벨(확대, 축소 정도)
      };
      
      this.map = new kakao.maps.Map(container, options); //지도 생성 및 객체 리턴
	
	  // 좌표-주소로 변환 도와줄
	  // geocoder 라이브러리
	  const geocoder = new kakao.maps.services.Geocoder();
	
	  // mousedown 이벤트 맵에 등록
      this.kakao.event.addListener(this.map, 'mousedown', (mouseEvent) => {
          this.removeMarker();
	        //geocoder 라이브러리 addressSearch 메서드 사용
	        console.log(mouseEvent)
	        geocoder.coord2Address(mouseEvent.latLng.getLng(), mouseEvent.latLng.getLat(), async (result, status) => {
		        let address =''
		        if(result.length>=1) {
			        if (result[0].road_address != null && result[0].road_address != undefined) {
				        address = result[0].road_address.address_name
			        }
			        else {
				        if (result[0].address != null && result[0].address != undefined) {
					        address = result[0].address.address_name
				        }
				        else {
					        address = "주소 정보 없음"
				        }
			        }
		        }
		        else {
			        if (result.length >= 1) {
				        if (result.road_address != null && result.road_address != undefined) {
					        address = result.road_address.address_name
				        }
				        else {
					        if (result.address != null && result.address != undefined) {
						        address = result.address.address_name
					        }
					        else {
						        address = "주소 정보 없음"
					        }
				        }
			        }
		        }
		        console.log(address)
		        if (status === kakao.maps.services.Status.OK) {
			        const coords = new kakao.maps.LatLng(result[0].y, result[0].x);
			        console.log(coords);
			        this.setState({
				        customAddressTitle:'',
				        customAddress:result[0].road_address.address_name,
			        })
			        this.addMarker(mouseEvent.latLng)
		        }
	        });
      });
    }

좌표-주소 변환 도와줄 geocoder 변수 선언 후 

(const geocoder = new kakao.maps.services.Geocoder();)

addListener()안에 좌표를 주소로 바꿔주는 Coord2Address()함수를 작성해줬습니다.

 

Coord2Address()함수에 인자값은 세가지가 들어가는데 

인자값은 앞에서부터 순서대로

Latitude, Longitude, 이벤트 액션 처리 함수(콜백함수) 입니다.

 

좌표값인 Latitude, Longitude를 가져오는 방법은 다양합니다.

이전 설명과 같이 클릭한 지점의 위치를 가져오는 방법도 있고,

현재 지도가 나타내는 center 위치를 가져올 수도 있으며

geocoder내 함수를 이용해 주소(address)를 좌표로 변환해 가져올 수도 있습니다.

 

바로위 예시에서는 addListener() 마우스 이벤트 내에 작성 해서

마우스가 클릭한 좌표를 받아 주소로 바꾸도록 하였습니다.

 

 


커스텀 오버레이 (인포윈도우) 참고

위에서 addListener() 이벤트 등록 함수 안에 사용 되었던

this.addMarker()함수 내용

 

addMarker(mouseLatLng) {
        const content = document.createElement('div');
        content.className = 'overlay_info';

        const w2 = document.createElement('div');
        w2.innerHTML = `<button class="goto_" onmouseup=${() => this.onMouseUp()}>확인</button>`;


        content.innerHTML = `<div class='post-marker'>
        <div class="kind"></div>
        <div class='average-price'>
        <span>${this.state.customAddress}</span>
        </div>
        <div>
        <div class='counting'}>`+ w2.innerHTML +`

        </div>
        </div>
        </div>`;
		
		
        // 커스텀 오버레이가 표시될 위치입니다
        let latlng= mouseLatLng
        const po = new this.kakao.LatLng(latlng.getLat(), latlng.getLng());
        console.log(po)
        // 커스텀 오버레이를 생성합니다
        const mapCustomOverlay = new this.kakao.CustomOverlay({
            position: po,
            content: content,
            // xAnchor: 0.5, // 커스텀 오버레이의 x축 위치입니다. 1에 가까울수록 왼쪽에 위치합니다. 기본값은 0.5 입니다
            // yAnchor: 1.1 // 커스텀 오버레이의 y축 위치입니다. 1에 가까울수록 위쪽에 위치합니다. 기본값은 0.5 입니다
        });
        // 커스텀 오버레이를 지도에 표시합니다
        mapCustomOverlay.setMap(this.map);
        this.markers.push(mapCustomOverlay);

        content.addEventListener('onkeypress',this.handleChangeAddressTitle)
        content.addEventListener('mouseup',this.onMouseUp)
	}

 

 

좌표 참고

	getLatLng() {
		const bounds = this.map.getBounds();
		// 영역의 남서쪽 좌표를 얻어옵니다
		const swLatLng = bounds.getSouthWest();
		// 영역의 북동쪽 좌표를 얻어옵니다
		const neLatLng = bounds.getNorthEast();
		const message = `지도의 남서쪽 좌표는 ${swLatLng.getLat()}, ${swLatLng.getLng()} 이고 <br>
		북동쪽 좌표는 ${neLatLng.getLat()}, ${neLatLng.getLng()} 입니다`;
		const args = {
			sw_lat: swLatLng.getLat(),
			sw_lng: swLatLng.getLng(),
			ne_lat: neLatLng.getLat(),
			ne_lng: neLatLng.getLng(),
			message: message,
		};
		return args;
	}

 

 

 

 

 

미래의 나에게 도움이 되길 바라며

이만 글 마침.