티스토리 뷰

반응형

2026.05.12 - [API] - Google Maps API 구글 지도 API 연동 - 3. 장소

Step 3에서 장소를 검색하는 법을 배웠다면, 이제는 내 데이터베이스에 있는 수많은 장소(예: 전국의 맛집 5,000곳)를 지도 위에 어떻게 효율적으로 뿌릴 것인가를 고민해야 합니다. 마커가 너무 많으면 지도는 느려지고, 사용자는 화면을 뒤덮은 핀들 때문에 아무것도 볼 수 없게 됩니다.

본 포스팅에서는 마커 클러스터링(Marker Clustering)을 통해 복잡한 데이터를 깔끔하게 그룹화하고, 기본 핀 대신 서비스의 개성을 담은 커스텀 마커를 제작하는 방법을 상세히 다룹니다.

 

1. 마커 클러스터링: 수천 개의 핀을 하나로 묶는 기술

마커 클러스터링은 인접한 여러 개의 마커를 하나의 숫자 아이콘으로 합쳐서 보여주는 기법입니다. 사용자가 지도를 확대(Zoom-in)하면 클러스터가 깨지면서 개별 마커가 나타나고, 축소(Zoom-out)하면 다시 뭉쳐집니다.

1.1 왜 클러스터링이 필요한가?

  1. 시각적 명확성: 화면이 수백 개의 마커로 덮이는 '마커 스팸' 현상을 방지합니다.
  2. 렌더링 성능: 브라우저가 수천 개의 DOM 요소를 개별적으로 계산할 필요가 없어지므로 지도가 훨씬 부드럽게 움직입니다.
  3. 데이터 요약: 특정 지역에 얼마나 많은 데이터가 밀집되어 있는지 한눈에 파악할 수 있게 해줍니다.

 

2. 사전 준비: 클러스터러 라이브러리 추가

마커 클러스터러는 구글 지도 핵심 SDK에 포함되어 있지 않은 별도의 오픈소스 라이브러리입니다. 구글에서 공식적으로 관리하는 라이브러리를 CDN을 통해 불러와야 합니다.

<!-- 클러스터러 라이브러리 추가 -->
<script src="https://unpkg.com/@googlemaps/markerclusterer/dist/index.min.js"></script>

 

3. 실전 구현: 마커 클러스터링과 커스텀 마커 적용하기

이번 예제에서는 가상의 위치 데이터를 생성하여 클러스터링을 적용하고, 기본 마커 대신 귀여운 아이콘이나 SVG를 사용하는 방법을 알아봅니다.

3.1 전체 예제 코드 (HTML/JS)

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <title>Google Maps 클러스터링 실전 가이드</title>
    <style>
        body { margin: 0; font-family: 'Pretendard', sans-serif; }
        #map { width: 100%; height: 100vh; }
        .custom-label { background: white; padding: 5px 10px; border-radius: 20px; border: 2px solid #4285F4; font-weight: bold; font-size: 12px; }
    </style>
</head>
<body>

    <div id="map"></div>

    <!-- 1. Google Maps SDK 로드 -->
    <script async src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap"></script>
    <!-- 2. Marker Clusterer 라이브러리 로드 -->
    <script src="https://unpkg.com/@googlemaps/markerclusterer/dist/index.min.js"></script>

    <script>
        function initMap() {
            const map = new google.maps.Map(document.getElementById("map"), {
                zoom: 10,
                center: { lat: 37.5665, lng: 126.9780 }, // 서울 기준
                mapId: "DEMO_MAP_ID", // 최신 마커 기능을 사용하기 위해 필요할 수 있음
            });

            // 가상의 데이터 생성 (서울 인근 100개의 좌표)
            const locations = Array.from({ length: 100 }, (_, i) => ({
                lat: 37.5665 + (Math.random() - 0.5) * 0.2,
                lng: 126.9780 + (Math.random() - 0.5) * 0.2,
                name: `장소 ${i + 1}`
            }));

            // 마커 배열 생성
            const markers = locations.map((location, i) => {
                // 커스텀 아이콘 설정
                const icon = {
                    url: "https://maps.google.com/mapfiles/kml/pal2/icon10.png", // 외부 이미지 URL
                    scaledSize: new google.maps.Size(40, 40), // 아이콘 크기 조절
                    origin: new google.maps.Point(0, 0),
                    anchor: new google.maps.Point(20, 40) // 마커의 발끝이 좌표에 오도록 설정
                };

                const marker = new google.maps.Marker({
                    position: { lat: location.lat, lng: location.lng },
                    label: {
                        text: (i + 1).toString(),
                        color: "#fff",
                        fontSize: "12px",
                        fontWeight: "bold"
                    },
                    icon: icon, // 커스텀 아이콘 적용
                    map: map
                });

                // 마커 클릭 시 정보 표시
                const infowindow = new google.maps.InfoWindow({
                    content: `<div><strong>${location.name}</strong><br>상세 정보가 표시됩니다.</div>`
                });

                marker.addListener("click", () => {
                    infowindow.open(map, marker);
                });

                return marker;
            });

            // 3. 마커 클러스터러 초기화
            new markerClusterer.MarkerClusterer({
                map: map,
                markers: markers,
                // 클러스터 아이콘이나 스타일을 커스텀하고 싶을 때 알고리즘 설정 가능
            });
        }
    </script>
</body>
</html>
반응형

4. 심화 학습: 마커를 더 예쁘게 만드는 'Advanced Markers'

2023년 구글은 기존 google.maps.Marker를 대체하는 Advanced Marker Content 기능을 발표했습니다. 이제 이미지가 아니라 순수 HTML과 CSS로 마커를 만들 수 있습니다.

4.1 HTML 마커의 장점

  • CSS 애니메이션: 마커가 통통 튀거나 반짝이는 효과를 줄 수 있습니다.
  • 동적 텍스트: 마커 내부에 가격 정보나 대기 시간을 실시간으로 표시할 수 있습니다.
  • 벡터 그래픽(SVG): 어떤 확대 비율에서도 깨지지 않는 선명한 마커를 제공합니다.

4.2 구현 힌트

const priceTag = document.createElement("div");
priceTag.className = "price-tag";
priceTag.textContent = "$150";

const advancedMarker = new google.maps.marker.AdvancedMarkerElement({
    map,
    position: { lat: 37.5, lng: 126.9 },
    content: priceTag, // HTML 요소를 직접 삽입!
});

 

5. 성능 최적화 전략: 만 단위 데이터 다루기

만약 표시해야 할 마커가 10,000개가 넘는다면 어떻게 해야 할까요?

  1. 서버 사이드 클러스터링: 클라이언트(브라우저)에서 계산하기 너무 무겁다면, 서버에서 특정 격자(Grid) 내의 마커 개수를 미리 계산해 전달합니다.
  2. Lazy Loading: 현재 화면(Viewport)에 보이는 영역의 마커만 API로 요청하여 렌더링합니다.
  3. Web Workers: 클러스터링 계산 과정을 별도의 스레드에서 처리하여 지도 UI가 멈추는 현상을 방지합니다.

 

6. 에러 핸들링 및 주의사항

  • 클러스터가 안 보여요: markerClusterer 라이브러리가 로드되기 전에 코드가 실행되지 않았는지 확인하세요.
  • 아이콘이 너무 커요: scaledSize 옵션을 사용하여 원본 이미지 크기를 반드시 지도에 맞게 조정해야 합니다.
  • Map ID 필수: 최신 고급 마커 기능을 사용하려면 구글 클라우드 콘솔에서 Map ID를 생성하고 지도 객체 선언 시 할당해야 합니다.

 

#구글지도API #MarkerClusterer #마커클러스터링 #커스텀마커 #지도데이터시각화 #웹개발팁 #GoogleMapsSDK #AdvancedMarkers #데이터비주얼라이제이션 #자바스크립트지도 #마커최적화 #프론트엔드개발

반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2026/05   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31
글 보관함
반응형