본문 바로가기

카카오 지도 JS API 길찾기·로드뷰 한 번에: URL 스킴·지오코딩·클러스터

728x90

  • 무엇: 웹페이지에 지도를 넣고(표시/이동/확대), 마커·오버레이, 장소 검색, 주소↔좌표 변환, 마커 클러스터링, 도형 그리기 등을 제공하는 JS API.
  • 어떻게: Kakao 개발자 콘솔에서 앱 생성→Web 플랫폼 도메인 등록→JavaScript 키 발급 후, SDK 스크립트를 로드하여 사용.
  • 추가 도구: 지도 URL(링크)로 지도/길찾기/로드뷰/검색결과를 직접 여는 패턴 제공.

키 발급 & 도메인 등록 (필수)

  1. 카카오 개발자 사이트 접속 → 로그인.
  2. 내 애플리케이션에서 앱 생성.
  3. 앱 설정 → 플랫폼 → Web 플랫폼 등록에서 사이트 도메인 등록
  4. 앱 키 → JavaScript 키를 복사하여 SDK appkey로 사용.

주의: 등록된 도메인에서만 JS 키가 동작합니다. 운영/개발(로컬) 도메인을 각각 등록하세요.

로컬 테스트(정적 서버)

  • Python 3: cd /path/to/your/folder python3 -m http.server 8080
  • Node(http-server): npx http-server -p 8080

브라우저에서 http://localhost:8080 접속. (로컬 도메인을 Web 플랫폼에 등록해야 동작)

최소 예제로 지도 띄우기

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8"/>
  <title>Kakao 지도 시작하기</title>
  <style>
    /* 지도가 보이려면 width/height가 필수 */
    #map { width: 500px; height: 400px; }
  </style>
</head>
<body>
  <div id="map"></div>

  <!-- 필수: 발급받은 JavaScript 키 사용 -->
  <script src="//dapi.kakao.com/v2/maps/sdk.js?appkey=YOUR_JS_KEY"></script>
  <script>
    // 1) 컨테이너와 옵션
    const container = document.getElementById('map');
    const options = {
      center: new kakao.maps.LatLng(33.450701, 126.570667), // 위도,경도
      level: 3
    };
    // 2) 지도 생성
    const map = new kakao.maps.Map(container, options);
  </script>
</body>
</html>

center는 반드시 설정해야 합니다(위도→경도 순).

확장 라이브러리 로드(services/clusterer/drawing)

  • 한 번에 필요한 라이브러리만 선택해서 로드합니다.
    <script src="//dapi.kakao.com/v2/maps/sdk.js?appkey=YOUR_JS_KEY&libraries=services,clusterer,drawing"></script>
  • services: 장소 검색, 주소↔좌표 변환
  • clusterer: 마커 클러스터링
  • drawing: 마커/도형 그리기 UI

지도 URL로 “지도/길찾기/로드뷰/검색결과” 바로 열기

  • 지도 보기
    • /link/map/위도,경도
    • /link/map/이름,위도,경도
    • /link/map/장소ID
  • 길찾기(이동수단: car/traffic/walk/bicycle)
    • /link/to/이름,위도,경도
    • /link/from/…/to/…
    • /link/by/{car|traffic|walk|bicycle}/…
  • 로드뷰: /link/roadview/위도,경도 또는 장소ID
  • 검색결과: /link/search/검색어
    → 사용 환경에 따라 PC/모바일웹 카카오맵으로 자동 연결.
<!-- 예: 목적지로 길찾기 -->
<a target="_blank"
   href="https://map.kakao.com/link/to/카카오판교아지트,37.3952969470752,127.110449292622">
  카카오맵 길찾기 열기
</a>

비동기 로딩(autoload=false) & Lazy Load 패턴

  • autoload=false로 SDK를 “불러만 두고”, 필요 시 kakao.maps.load(() => {...})에서 초기화 코드를 실행할 수 있습니다.
  • 단, SDK 스크립트 요청 시점에 이미 쿼터가 소모됩니다(로드 후 콜백과 무관). 정말 필요할 때 스크립트를 동적으로 주입하는 방식으로 최적화하세요.
<script>
  function injectKakaoSdk(cb) {
    if (window.kakao && window.kakao.maps) return cb();
    const s = document.createElement('script');
    s.src = "//dapi.kakao.com/v2/maps/sdk.js?appkey=YOUR_JS_KEY&autoload=false&libraries=services,clusterer,drawing";
    s.onload = () => kakao.maps.load(cb);
    document.head.appendChild(s);
  }

// 필요 시점에 호출
  injectKakaoSdk(() => {
    const map = new kakao.maps.Map(document.getElementById('map'), {
      center: new kakao.maps.LatLng(37.5665, 126.9780), level: 5
    });
    // … 추가 초기화
  });
</script>
300x250

자주 쓰는 실전 코드 스니펫

1) 마커 + 인포윈도우

const pos = new kakao.maps.LatLng(37.5665, 126.9780);
const marker = new kakao.maps.Marker({ position: pos, map });
const iw = new kakao.maps.InfoWindow({ content: '<div style="padding:8px">서울시청</div>' });
kakao.maps.event.addListener(marker, 'click', () => iw.open(map, marker));

2) 지도 이벤트(클릭 시 좌표 표시)

kakao.maps.event.addListener(map, 'click', (mouseEvent) => {
  const latlng = mouseEvent.latLng;
  console.log('위도:', latlng.getLat(), '경도:', latlng.getLng());
});

3) 주소 → 좌표(Geocoder) + 마커

// libraries=services 필요
const geocoder = new kakao.maps.services.Geocoder();
geocoder.addressSearch('서울특별시 중구 세종대로 110', (result, status) => {
  if (status === kakao.maps.services.Status.OK) {
    const coords = new kakao.maps.LatLng(result[0].y, result[0].x);
    new kakao.maps.Marker({ map, position: coords });
    map.setCenter(coords);
  }
});

services 라이브러리의 Geocoder 사용.

4) 키워드(장소) 검색 + 리스트/마커

// libraries=services 필요
const ps = new kakao.maps.services.Places();
ps.keywordSearch('카페', (data, status) => {
  if (status !== kakao.maps.services.Status.OK) return;
  data.forEach(place => {
    const coords = new kakao.maps.LatLng(place.y, place.x);
    new kakao.maps.Marker({ map, position: coords });
  });
});

5) 마커 클러스터링

// libraries=clusterer 필요
const clusterer = new kakao.maps.MarkerClusterer({
  map, averageCenter: true, minLevel: 7
});
const markers = coordsArray.map(c => new kakao.maps.Marker({ position: new kakao.maps.LatLng(c.lat, c.lng) }));
clusterer.addMarkers(markers);

6) 그리기 모드(도형/거리 측정 UI)

// libraries=drawing 필요
const options = {
  map, drawingMode: [kakao.maps.drawing.OverlayType.POLYLINE, kakao.maps.drawing.OverlayType.POLYGON],
  guideTooltip: ['draw', 'drag', 'edit']
};
const manager = new kakao.maps.drawing.DrawingManager(options);
// 예: 그리기 시작/종료는 manager API로 제어

7) 길찾기/로드뷰/검색 URL 열기

// 목적지로 길찾기(자동차)
window.open('https://map.kakao.com/link/by/car/출발지명,37.5665,126.9780/도착지명,37.3952969470752,127.110449292622', '_blank');
// 로드뷰
window.open('https://map.kakao.com/link/roadview/37.5665,126.9780', '_blank');

URL 패턴은 공식 가이드를 참고하세요.

React/SPA에서의 로딩 팁

  1. 초기 1회만 SDK 주입: 상단의 injectKakaoSdk() 유틸로 중복 로딩 방지.
  2. 컴포넌트 마운트 시점에 지도 생성: useEffect에서 kakao.maps.load 콜백 안에서 생성.
  3. 라우팅 전환 시 메모리 관리: 지도/오버레이/리스너 참조를 모아 언마운트 때 해제.

window.kakao 존재 확인 후 초기화하는 패턴을 권장(전역 SDK).

보안 점검 체크리스트

A. 키 & 도메인 통제

  • 환경 분리: 운영/개발/테스트 각각 별도 앱/키 권장.
  • 도메인 화이트리스트 정확성: https 포함, 서브도메인 범위, 로컬(http://localhost:8080) 등록 확인.
  • 키 노출 방지: 공개 저장소/정적 HTML에 직접 하드코딩 금지. 배포 파이프라인에서 템플릿 치환(예: .env→CI/CD 주입).

B. 스크립트/콘텐츠 보안

  • HTTPS 강제 + CSP(script-src, connect-src 최소화).
  • 라이브러리 최소 로드: services,clusterer,drawing 중 필요한 것만.
  • Lazy Load: 정말 필요할 때만 SDK를 동적 주입(쿼터/로드 최적화).

C. 입력값 검증 & 개인정보

  • URL/좌표 파라미터 검증: 사용자 입력으로 지도 URL을 조립할 때 인젝션/오픈 리다이렉트 점검.
  • 위치정보 최소화/동의 절차: 정밀 좌표 공개 전 사전 고지, 마스킹/일반화 고려.

D. 사용량/장애 대비

  • 호출·오류·지연 모니터링: 클러스터링/검색 결과 캐싱, 초기 지도 생성 최소화(탭 전환 시 로드).
  • 쿼터 초과 대응: 에러 핸들링·폴백 화면·재시도 정책.

E. 내부 점검 체크리스트

  1. 키 보관(비밀관리), 노출 스캔, 권한 최소화
  2. Web 플랫폼 도메인 정확성(프로토콜/서브도메인/로컬 포함)
  3. HTTPS, CSP, 중복 스크립트 로딩 방지
  4. 라이브러리 최소·지연 로딩 설계
  5. 지도 URL/입력값 검증, 위치정보 보호
  6. 모니터링/알림, 장애 대응·요금 관리

트러블슈팅(실무에서 자주 겪는 문제)

  • kakao가 undefined: SDK가 아직 로드 전입니다. → autoload=false + kakao.maps.load() 콜백에서 초기화하거나, onload 이후 실행.
  • 지도가 안 보임: 컨테이너에 width/height 누락.
  • 도메인 오류: Web 플랫폼에 등록되지 않은 도메인에서 호출.
  • 과도한 네트워크 로드: 페이지 전환마다 SDK 재로딩 → 중복 로딩 방지 유틸 사용.

확장 예시 모음(복붙용)

1) 반경 N m 내 카페 검색 + 마커

// services 필요
const ps = new kakao.maps.services.Places();
const center = new kakao.maps.LatLng(37.5665, 126.9780);
ps.keywordSearch('카페', (data, status) => {
  if (status !== kakao.maps.services.Status.OK) return;
  data.filter(p => kakao.maps.geometry ? true : true) // (geometry 제공 X, 반경 필터는 앱 로직으로)
      .forEach(p => new kakao.maps.Marker({ map, position: new kakao.maps.LatLng(p.y, p.x) }));
}, { location: center, radius: 1000 }); // m 단위

2) 대량 마커 클러스터링

// clusterer 필요
const clusterer = new kakao.maps.MarkerClusterer({ map, averageCenter:true, minLevel:6 });
const markers = bigList.map(p => new kakao.maps.Marker({ position:new kakao.maps.LatLng(p.lat, p.lng) }));
clusterer.addMarkers(markers);

3) 다각형(폴리곤)으로 서비스 구역 표시

const path = [
  new kakao.maps.LatLng(37.57, 126.98),
  new kakao.maps.LatLng(37.58, 126.99),
  new kakao.maps.LatLng(37.56, 127.01)
];
const polygon = new kakao.maps.Polygon({
  map, path, strokeWeight:2, strokeColor:'#333', fillColor:'#00AEEF', fillOpacity:0.3
});

4) 지하철 노선도 길찾기(서울)

<a target="_blank" href="https://map.kakao.com/link/by/subway/seoul/판교역/강남역">
  카카오맵 지하철 길찾기
</a>

활용 시나리오(아이디어)

  • 매장/지점 찾기(Store Locator): 주소→좌표 변환 + 마커 + 클러스터링
  • 배달 가능 구역: 폴리곤으로 범위 시각화, 범위 밖 주문 안내
  • 부동산/숙박 지도: 수천 개 매물 클러스터링 + 상세 오버레이
  • 내부 운영 지도: 설비/사고 위치 실시간 마킹, URL로 길찾기 안내

성능·운영 팁(대량 데이터 기준)

  • 마커/오버레이 재사용(show/hide)로 GC/재생성 비용 감소
  • 지연 로딩 & 가시 범위만 그리기(bounds 내 데이터만)
  • 결과 캐싱(장소/지오코딩)과 요청 합치기로 API 호출 절감
  • 쿼터 초과 대비: 사용자 메시지/폴백 제공, 서버 캐시로 완화

보안 점검표(배포 직전 10분 체크)

  1. JavaScript 키 노출 스캔(Git/정적 파일) & 비밀관리 반영
  2. Web 플랫폼 도메인 정확성(https/서브도메인/localhost)
  3. SDK 중복 로딩 금지, autoload=false + 동적 주입 설계
  4. CSP 적용(script-src/connect-src 최소)
  5. 입력값 검증(지도 URL, 위/경 범위) & 위치정보 최소화
  6. 모니터링: 오류율/지연/호출량 알림

공식 문서(필독)

  • Kakao 지도 Web API 가이드(라이브러리·지도 URL 패턴·예시)
  • Kakao Developers — JavaScript SDK 시작하기(앱/플랫폼 등록 흐름)
  • DevTalkautoload=false와 로딩/쿼터 이슈 설명
728x90
그리드형(광고전용)

댓글