0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Google Maps API × Next.js でマップクラスターを実装する方法

Posted at

はじめに

Google Maps に多くのマーカーを表示すると、以下の問題が発生します。

  • アイコンが重なり、視認性が悪くなる
  • パフォーマンスの低下
  • ユーザーが情報を把握しにくい

こうした問題を解決するのが Google Maps API の MarkerClusterer です!
本記事では、Next.js + Google Maps API を使い、マーカーをクラスター化する方法 を解説します。

参考

実際の例

Image from Gyazo

必要なライブラリのインストール

まずは、Google Maps API 用のライブラリをインストールしましょう。

npm install @googlemaps/markerclusterer

また、Google Maps API を使うには Google Cloud Console で APIキーを取得 してください。

既存のマーカーをクラスター化する

ここでは、適当な座標データを使い、Google Maps にマーカーを表示し、クラスターを適用 します。

AddMarkers.tsx
import { MarkerClusterer, DefaultRenderer } from '@googlemaps/markerclusterer';
import { useEffect, useRef } from 'react';

const AddMarkersContainer = ({ map }: { map: google.maps.Map | null }) => {
  const markersRef = useRef<google.maps.Marker[]>([]);
  const clustererRef = useRef<MarkerClusterer | null>(null);

  useEffect(() => {
    if (!map) return;

    // ダミーデータ(適当な座標リスト)
    const locations = [
      { lat: 35.6895, lng: 139.6917, title: '新宿' },
      { lat: 35.6586, lng: 139.7454, title: '東京タワー' },
      { lat: 35.7101, lng: 139.8107, title: '浅草' },
      { lat: 35.6764, lng: 139.6503, title: '渋谷' },
    ];

    // マーカーを作成
    const markers: google.maps.Marker[] = locations.map(({ lat, lng, title }) => {
      return new google.maps.Marker({
        position: { lat, lng },
        title,
        map,
      });
    });

    markersRef.current = markers;

    // クラスターのカスタムレンダラーを作成
    class CustomClusterRenderer extends DefaultRenderer {
      render({ count, position }: { count: number; position: google.maps.LatLng }) {
        const color = count > 10 ? 'red' : count > 5 ? 'orange' : 'blue';
        const size = count > 10 ? 80 : count > 5 ? 60 : 40;

        const svg = window.btoa(`
          <svg fill="${color}" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 240 240">
            <circle cx="120" cy="120" opacity=".8" r="70" />
          </svg>
        `);

        return new google.maps.Marker({
          position,
          icon: {
            url: `data:image/svg+xml;base64,${svg}`,
            scaledSize: new google.maps.Size(size, size),
          },
          label: {
            text: String(count),
            color: 'white',
            fontSize: '18px',
          },
          zIndex: 100000,
        });
      }
    }

    // 既存のクラスターをクリア
    if (clustererRef.current) {
      clustererRef.current.clearMarkers();
    }

    // クラスターを適用
    clustererRef.current = new MarkerClusterer({
      map,
      markers,
      renderer: new CustomClusterRenderer(),
    });
  }, [map]);

  return null;
};

export default AddMarkersContainer;

参考

マーカーはデフォルト以外にもカスタマイズ可能です。

まとめ

本記事では、Next.js と Google Maps API を使ってマーカーをクラスター化する方法 を解説しました。MarkerClusterer を活用し、マーカーの整理やカスタムデザインの適用、zIndex の調整による描画順序の管理を行いました。これにより、大量のマーカーでも見やすく、パフォーマンスの良い地図アプリ を構築できます!

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?