카카오맵에 전기차 충전소 위치 표시하기

리액트 기반으로 공공데이터와 지도 API 연동하기
글로벌사이버대학교 AI융합학과 김일국 교수님 사례 –

글로벌사이버대학교 AI융합학과
김일국 교수입니다

안녕하세요. 앱과 자바스프링을 강의하고 있는 김일국입니다. 컴퓨터 학원과 직업 학교를 거쳐 지금은 글로벌사이버대학교 AI융합학과에서 학생들을 만나고 있어요. 요즘은 인터넷 강의를 준비하고 촬영하면서 바쁘게 지내고 있습니다.

카카오맵에 전기차 충전소 위치를
표시하는 기능을 만들었어요

함수형
https://server-basic-fekuw.run.goorm.io/

구름IDE로 🔗카카오맵에 전기차 충전소 위치를 표시하는 기능을 개발했습니다. 공공데이터포털의 데이터를 끌어오는 API Node.js 서버를 만들고, 받아온 데이터를 React.js에서 파싱하는 플로우예요. 자세한 개발 과정은 제 블로그에 8편 분량으로 소개해두었습니다. 순서대로 따라 하시면 구름IDE React 스택을 이용해 Node.js 서버와 React.js 앱을 만들어보실 수 있어요.

개발 순서는 다음과 같아요.

  1. 구름IDE에서 리액트 컨테이너 생성 → npm install로 기본 패키지 설치 → 리액트 홈 실행
  2. 공공데이터포털에서 API 활용 신청 → Kakao Developers에서 지도 API 애플리케이션 생성
  3. 공공데이터포털의 API 데이터를 Node.js API의 서버 기능으로 구름IDE에 가져오기
  4. 리액트에서 카카오맵 API 샘플 코드를 사용해 클래스형 컴포넌트 생성 → 라우터 기능으로 메뉴에 추가
  5. 이전에 생성한 Node.js API 데이터를 리액트 카카오맵 클래스형 컴포넌트에 바인딩해서 지도에 표시
  6. 클래스형 카카오맵 컴포넌트를 참조해 함수형 컴포넌트 생성 → Node.js API 데이터를 바인딩해서 지도에 표시
  7. npm 빌드 대신 yarn 빌드를 사용하기 위한 yarn 설치 → 빌드로 build 폴더에 index.html 생성
  8. 컨테이너를 나간 후에도 Node.js 서버 실행을 유지하기 위한 forever 설치(Node.js 버전 업그레이드 필수) → forever로 앱 실행

다양한 분야의 데이터를 가공해 화면에 출력하는 RestAPI 프로세스는 반드시 알아야 하는 내용이라고 생각합니다. Node.js 기반의 React.js 프로젝트로 RestAPI를 익혀보세요.

오픈 API는 카카오맵 API를 추천합니다. 특히 학생들에게요. 카카오 계정만 있으면 사용 가능한 유일한 오픈 API거든요. 타사의 지도 API는 오픈 API지만 신용카드 정보가 필요해요. 오픈 소스로 사용할 만한 지도 API를 찾는다면 추천하고 싶습니다.

클래스형 카카오맵과 함수형 카카오맵을
모두 구현했어요

클래스형

성능 차이는 없습니다. 구분해서 만든 이유는 리액트 컴포넌트 제작 방식에 클래스형과 함수형 두 가지가 있고, 두 개 소스는 호환 가능하다는 걸 확인하기 위해서인데요.

구름에서 리액트 프로젝트를 만들 때 소프트웨어 스택을 리액트로 선택하면 클래스형 컴포넌트가 기본 구조로 생성됩니다. 소프트웨어 스택을 Express로 선택해서 create-react-app 명령으로 리액트 프로젝트를 만들면 함수형 컴포넌트가 기본 구조로 생성되고요. 클래스형과 함수형 컴포넌트의 차이를 알고 있어야 하죠.

클래스형과 함수형 중 하나를 골라야 한다면 함수형 컴포넌트를 추천합니다. 최근에는 파이썬이나 클래스 기반의 자바에서 함수 기반의 코틀린으로 많이 넘어가고 있죠. 함수형 개발 패턴을 사용하는 경우가 더 많은 것 같습니다.

Express로 서버까지 만든 이유는

서버 없이 자바스크립트만으로 구현하는 방법도 있긴 합니다. 다만 공공데이터포털은 https(보안 접속)로 시작하는 API 접근 방식을 지원하지 않는 곳이 많아요.

제가 사용한 공공데이터포털의 전기 자동차 데이터는 http(비 보안 접속)만 지원하는 API 서비스였어서 자바스크립트단에서 http(비 보안 접속) 접근을 허용하지 않는 문제가 나타나게 되죠.

그래서 Express 서버에서 공공데이터포털의 전기 자동차 API 데이터를 http(비 보안 접속)로 가져와서 파싱하는 과정이 필요합니다.

클래스형 컴포넌트에
Node.js API 데이터를 바인딩해
지도에 표시하기까지

this.setState({totalCount:  contents['response']['body']['totalCount']['_text']});//화면처리
            var positions = [];//배열 선언
            var jsonData;
            jsonData=contents['response']['body']['items'];
            console.log(jsonData);
            jsonData['item'].forEach((element) => {//람다식 사용 function(element) {}
                positions.push(
                  {
                    content: "<div>"+element["csNm"]['_text']+"</div>",//충전소 이름
                    latlng: new kakao.maps.LatLng(element["lat"]['_text'], element["longi"]['_text']) // 위도(latitude), 경도longitude)
                  }
                );
            });
            var index = parseInt(positions.length/2);//배열은 인덱스순서 값을 필수로 가지고, 여기서는 반환 값의 개수로 구한다.
            console.log(jsonData["item"][index]["lat"]['_text']);
            //console.log(jsonData);
            var mapContainer = document.getElementById('map'), // 지도를 표시할 div  
                mapOption = { 
                    center: new kakao.maps.LatLng(jsonData["item"][index]["lat"]['_text'], jsonData["item"][index]["longi"]['_text']),
                    //center: new kakao.maps.LatLng(33.450701, 126.570667), // 지도의 중심좌표
                    level: 10 // 지도의 확대 레벨
                };

            var map = new kakao.maps.Map(mapContainer, mapOption); // 지도를 생성합니다
            for (var i = 0; i < positions.length; i ++) {
                // 마커를 생성합니다
                var marker = new kakao.maps.Marker({
                    map: map, // 마커를 표시할 지도
                    position: positions[i].latlng // 마커의 위치
                });

                // 마커에 표시할 인포윈도우를 생성합니다 
                var infowindow = new kakao.maps.InfoWindow({
                    content: positions[i].content // 인포윈도우에 표시할 내용
                });

                // 마커에 mouseover 이벤트와 mouseout 이벤트를 등록합니다
                // 이벤트 리스너로는 클로저를 만들어 등록합니다 
                // for문에서 클로저를 만들어 주지 않으면 마지막 마커에만 이벤트가 등록됩니다
                kakao.maps.event.addListener(marker, 'mouseover', makeOverListener(map, marker, infowindow));
                kakao.maps.event.addListener(marker, 'mouseout', makeOutListener(infowindow));
            }
            // 인포윈도우를 표시하는 클로저를 만드는 함수입니다 
            function makeOverListener(map, marker, infowindow) {
                return function() {
                    infowindow.open(map, marker);
                };
            }

            // 인포윈도우를 닫는 클로저를 만드는 함수입니다 
            function makeOutListener(infowindow) {
                return function() {
                    infowindow.close();
                };
            }

제가 작성한 코드입니다. 3가지 핵심을 짚어드리면 도움이 되실 것 같은데요.

① React 클래스형 컴포넌트의 생명 주기에 대한 기초 지식

영어로 라이프 사이클(Life cycle)이라고도 하죠. 컴포넌트가 실행, 업데이트, 제거될 때 특정한 이벤트들이 자동으로 발생합니다.

  • 클래스 마운트(렌더링) 전: componentWillMount()
  • 클래스 마운트(렌더링-여기에 핵심코드) 후: componentDidMount()
  • 클래스 업데이트(리렌더링) 후: componentDidUpdate()
  • 클래스 언마운트(컴포넌트 화면전환) 전: componentWillUnmount()

② 아래 React 클래스형 컴포넌트 서식에 해당하는 구현 코드 확인

import React, {Component} from 'react';
class KakaoMap extends Component {
constructor (props) {
super(props); //부모의 props속성을 사용하겠다고 선언, 필수
//검색어 상태 값 초기화는 코드 추가
}
componentDidMount () {// 생명주기 중 초기 화면 렌더링 후 실행함수
//Express서버에 접근해서 전기자동차데이터를 가져오는 코드 추가
//위 데이터를 카카오 맵  js에 바인딩하는 코드 추가
this.getData();//지도 데이터 처리 + 출력
}
render() {
//아래 div에 위 카카오 맵 js가 출력된다. 실습에서는 검색태그를 추가함.
return (
<div>
<div id="map" style={{width:"100%",height:"350px"}}></div>
</div>
);//return 함수 끝
}//reder 함수 끝
}//클래스 끝
export default KakaoMap;

③ 위 getData() 함수 내에서 카카오맵에 전기 자동차 데이터를 바인딩하는 코드 확인

학생들을 위한 최적의 실습 환경을
찾으신다면

오픈api

학원에서 C와 Java 기초 강의를 할 때 학습을 시작하려면 가장 먼저 C와 Java 컴파일러를 설치해야 했습니다. 학생들이 학원을 마친 후에 실습을 이어가려면 본인 PC에 새로 컴파일러를 설치해야 했죠. 번거롭지 않게 실습할 수 있는 개발 환경을 고민하다가 구름IDE를 이용하게 됐습니다. 웹 브라우저 기반이라 어디서든 작성한 코드를 확인하고 수정할 수 있으니까요.

보통 취업을 준비하는 학생들과 진행하는 IT 개발자 과정은 3개월에서 6개월 동안 면접에서 사용할 프로젝트를 준비합니다. 이력서와 자기소개서에 포트폴리오로 넣을 수 있는 수준의 프로젝트를 진행하고, 최종 결과를 배포하는 과정에서 클라우드를 사용하죠. 클라우드에 배포하는 이유는 면접관이 어디서든 결과물을 확인하기 편해서인데요. 구름IDE는 클라우드 기반의 개발 환경을 제공하기도 하고, 항상 켜두기 기능을 포트폴리오 관리에 활용할 수 있어서 교수님이나 학생들에게 추천하고 싶습니다.

Edit Sunny Design Lily


공공데이터와 지도 API를 연동해볼까요?

Posted by
goorm

ANYONE CAN DEVELOP