コンテンツにスキップ

マーカークラスタリング

このページでは以下の方法について説明しています。

  • マーカークラスタリングを表示する方法

対象クラス

対象関数

実装サンプル

こちらをご覧ください。

実装方法

実装手順

  1. script タグを用いて/v2/map_script を呼び出し、地図を初期化します
  2. mapscript.value.GLMarkerClusteringCondition オブジェクトを生成します
  3. クリックリスナーを設定します
  4. 2 で生成した condition に GLMarker を追加します
  5. addGLMarkerClusteringCondition()関数を用いてマーカークラスタリング機能を有効にします
サンプルコード
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF-8" />
    <title>地図の表示</title>
    <!-- (1) APIの呼び出し -->
    <script src="https://{HOST}/{CID}/v2/map_script?host={example.com}&signature={XXXXXXXXX}&request_code={YYYYYYYYY}"></script>
    <script>
      function initMap() {
        // (1) 地図を初期化
        const map = new mapscript.Map("{CID}", {
          target: "#map",
          center: new mapscript.value.LatLng(35.667395, 139.714896),
          zoomLevel: 13,
        });

        // (2) GLMarkerClusteringConditionを生成
        const condition = new mapscript.value.GLMarkerClusteringCondition({
          distance: 70,                                    // 70px以内のマーカーはクラスタリング対象
          zoomRange: new mapscript.value.ZoomRange(0, 17), // 指定された範囲のズームレベルでのみクラスタリングを行う
          label: {                                         // 自身と子のマーカーの総個数を表示するラベルの設定
            fontSize: 15,                                           // 文字サイズ
            fontColor: new mapscript.value.Color(1, 0, 1, 1),       // 文字色
            fontWeight: "bold",                                     // フォントの重み
            backgroundColor: new mapscript.value.Color(1, 1, 1, 1), // 背景色
            borderRadius: 6,                                        // 角丸の半径
            borderColor: new mapscript.value.Color(1, 0, 1, 1),     // 縁線の色
            borderWidth: 2,                                         // 縁線の色
            offset: new mapscript.value.Point(10, 45),              // オフセット(右方向,上方向)
          },
          // (3) クリックリスナーを設定
          clickListener: (event, element) => {
            const glMarker = element.getGLMarker(); // 代表マーカーを取得
            const children = element.getChildren(); // 子マーカーリストを取得(子がなければ空配列[])
            if (children.length > 0) {
              // 子を含む場合は、地図中心を移動して独立になるズームレベルにアニメーションする
              map.setCenter(glMarker.getPosition());
              map.setZoomLevel(element.getBeAloneZoomLevel(), true);
              return;
            }
            // 子がない独立な場合は、そのマーカーのプロパティ(緯度経度)を表示
            alert(`緯度: ${glMarker.getProperties().lat}\n経度: ${glMarker.getProperties().lon}`)
          },
        });

        // (4) conditionにGLMarkerを追加する
        // 本サンプルでは、ランダムで決めた位置に対してGLMarkerを生成します
        // APIから取得した地点にマーカーを配置する場合は、レスポンスに含まれる緯度経度をGLMarker生成時に指定してください
        const max = 20; // 20x20=400個のGLMarkerを追加する
        const markerHeight = 50;
        const markerWidth = 40;
        for (let y = 0; y < max; y++) {
          for (let x = 0; x < max; x++)
            // ランダムで位置を決める
            const coord = getRandomLocation(35.667395, 139.714896, 2500);
            const latLng = new mapscript.value.LatLng(
              coord.latitude,
              coord.longitude
            );
            // GLMarkerを生成する
            const glMarker = new mapscript.object.GLMarker({
              info: new mapscript.value.GLMarkerIconInfo({
                icon: 'image/pin.png',                                     // 画像パス(base64文字列も可)
                size: new mapscript.value.Size(markerHeight, markerWidth), // サイズを指定(高さ,幅)
              }),
              position: latLng,
            });
            // クリックされた時に分かりやすいようにプロパティを設定
            glMarker.setProperties({
              lat: latLng.lat,
              lon: latLng.lng,
            });
            condition.addGLMarker(glMarker);
          }
        }
        // (5) GLMarkerのクラスタリング機能を有効にする
        map.addGLMarkerClusteringCondition(condition);
      }

      function getRandomLocation(centerLat, centerLng, radius) {
        const earthRadius = 6378137; // 地球の半径(メートル)

        // ランダムな距離と角度を生成
        const randomDistance = Math.random() * radius; // 距離を均等に分布させる
        const randomAngle = Math.random() * 2 * Math.PI; // 0から2πのランダムな角度

        // 中心点からのオフセットを計算
        const offsetLat = (randomDistance / earthRadius) * (180 / Math.PI);
        const offsetLng =
          ((randomDistance / earthRadius) * (180 / Math.PI)) /
          Math.cos((centerLat * Math.PI) / 180);

        // 新しい緯度経度を計算
        const randomLat = centerLat + offsetLat * Math.cos(randomAngle);
        const randomLng = centerLng + offsetLng * Math.sin(randomAngle);

        return {
          latitude: randomLat,
          longitude: randomLng,
        };
      }
    </script>
  </head>

  <body onload="initMap()">
    <div id="map" style="height: 500px; width: 500px;"></div>
  </body>
</html>

関連ページ