[Spring] 카카오 API로 지도 구현하기

jinsung·2026년 4월 2일

BootCamp

목록 보기
6/10
post-thumbnail

✅ 개요

2차 팀 프로젝트에서 스크럼을 통해 지도를 추가하자고 했다.
네이버는 유료여서 카카오 지도 API를 선택했고 그 과정을 적어보려 한다.

✅ 카카오 지도를 선택한 이유

국내 사용자 기준 접근성과 구현 효율이 가장 좋다고 판단했다.
또한 공연장 위치를 직관적으로 제공하기에 적합했고 프론트엔드와 연동이 매우 간단했다.

✅ 카카오 지도 사전 설정

1. API 키 발급받기

카카오 지도 API 발급 받기

2. 앱 만들기


학습용이라 프로젝트이름을 입력하면 된다.

3. API 키 받고 도메인 입력하기


플렛폼 키 들어가면 자바스크립트 API 키를 제공해주는데 프론트에 카카오 지도를 제공해주는데 사용하면 된다.
SDK url은 도메인까지만 입력하면 된다.

4. 카카오맵 사용 설정 ON


마지막으로 카카오맵 사용 설정 여부만 ON으로 바꿔주면 된다.
이게 있는지 모르고 좀 지도가 왜 안 나오지 하면서 좀 헤맸다..
여기까지 하면 코드짜기 전 사전 작업 끝이다.

✅ 카카오 지도 플로우 코드로 이해하기

1. 백단에서 프론트단으로 API 내려주기

@Value("${kakao.map.app-key}")
    private String kakaoMapAppKey;
    
@GetMapping("/config/map")
    public Map<String, String> getMapConfig() {
        return Map.of("kakaoMapAppKey", kakaoMapAppKey);
    }

아까 받은 API를 환경변수화 해서 키에 넣은 후 프론트단에 내려준다.

2. Json 응답보기

{
  "id": 1,
  "imageUrl": "https://operation-grape.s3.ap-northeast-2.amazonaws.com/p1.jpeg",
  "performanceName": "뮤지컬 데스노트",
  "venue": "디큐브 링크아트센터",
  "startDate": "2026-04-20",
  "endDate": "2026-06-30",
  "performanceTime": 165,
  "startedAt": "2026-03-26T19:00:49.359692",
  "price": 95000,
  "remainingSeatLimit": null,
  "address": "서울특별시 구로구 경인로 662 (신도림동, 디큐브시티)",
  "latitude": 37.5089149,
  "longitude": 126.888417
}

카카오 지도 위치를 찍기 위해 위경도를 같이 내려줬다.

3. 카카오 지도 API 불러와서 연동하기

	let kakaoMap = null;
    let kakaoMarker = null;

    async function loadKakaoSdk() {
        if (window.kakao && window.kakao.maps) {
            return;
        }

        const res = await fetch('/api/performances/config/map');
        if (!res.ok) {
            throw new Error('카카오 지도 설정을 불러오지 못했습니다.');
        }

        const config = await res.json();
        const appKey = config.kakaoMapAppKey;

        if (!appKey) {
            throw new Error('카카오 지도 키가 없습니다.');
        }

        await new Promise((resolve, reject) => {
            const existing = document.querySelector('script[data-kakao-map="true"]');
            if (existing) {
                existing.addEventListener('load', resolve, { once: true });
                return;
            }

            const script = document.createElement('script');
            script.src = `https://dapi.kakao.com/v2/maps/sdk.js?appkey=${appKey}&libraries=services&autoload=false`;
            script.dataset.kakaoMap = 'true';
            script.onload = () => kakao.maps.load(resolve);
            script.onerror = () => reject(new Error('카카오 SDK 로드 실패'));
            document.head.appendChild(script);
        });
    }

4. 카카오 지도에 특정 위치를 직접 표시

async function openMapModal() {
        try {
            if (!data) return;

            const venueName = data.venue || '공연장';
            const address = data.address;
            const latitude = data.latitude;
            const longitude = data.longitude;

            if ((latitude == null || longitude == null) && !address) {
                alert('공연장 위치 정보가 없습니다.');
                return;
            }

            await loadKakaoSdk();

            document.getElementById('mapTitle').textContent = `${venueName} 위치`;
            document.getElementById('mapModal').classList.add('active');

            const mapContainer = document.getElementById('kakaoMap');
            const defaultCenter = new kakao.maps.LatLng(37.5665, 126.9780);

            if (!kakaoMap) {
                kakaoMap = new kakao.maps.Map(mapContainer, {
                    center: defaultCenter,
                    level: 3
                });
            }

            kakaoMap.relayout();

            if (kakaoMarker) {
                kakaoMarker.setMap(null);
            }

            // 위도/경도 있으면 바로 지도 표시
            if (latitude != null && longitude != null) {
                const coords = new kakao.maps.LatLng(latitude, longitude);

                kakaoMap.setCenter(coords);
                kakaoMap.setLevel(3);

                kakaoMarker = new kakao.maps.Marker({
                    map: kakaoMap,
                    position: coords
                });

                const infowindow = new kakao.maps.InfoWindow({
                    content: `
                            <div style="
                                padding:8px 12px;
                                font-size:13px;
                                font-weight:600;
                                color:#191919;
                                background:#ffffff;
                                border:1px solid #ddd;
                                border-radius:8px;
                                white-space:nowrap;
                            ">
                                ${venueName}
                            </div>
    `
                });
                infowindow.open(kakaoMap, kakaoMarker);
                return;
            }

            // 주소 fallback
            const geocoder = new kakao.maps.services.Geocoder();

            geocoder.addressSearch(address, function(result, status) {
                if (status === kakao.maps.services.Status.OK) {
                    const coords = new kakao.maps.LatLng(result[0].y, result[0].x);

                    kakaoMap.setCenter(coords);
                    kakaoMap.setLevel(3);

                    kakaoMarker = new kakao.maps.Marker({
                        map: kakaoMap,
                        position: coords
                    });

                    const infowindow = new kakao.maps.InfoWindow({
                        content: `<div style="padding:6px 10px;font-size:13px;">${venueName}</div>`
                    });
                    infowindow.open(kakaoMap, kakaoMarker);
                } else {
                    alert('공연장 위치를 찾을 수 없습니다.');
                }
            });
        } catch (error) {
            console.error('지도 열기 실패:', error);
            alert(error.message || '지도를 불러오지 못했습니다.');
        }
    }

JSON 응답 → 위도/경도 꺼냄 → 카카오 좌표 생성 → 지도 중심 이동 → 마커 표시


실제 JSON 값의 위치가 나오는 모습이다.

profile
Data Engineer

0개의 댓글