技術情報ブログ
Angular
2021.10.27

AngularでGoogle Maps マーカークラスタリングライブラリの利用(2)

こんにちは。アーティサン株式会社の木戸です。

前回に引き続き、Angular で Google Maps を利用した時の、大量のマーカー表示によるユーザーエクスペリエンスの低下を回避する方法についてご紹介します。

前編では、マーカークラスタリングライブラリの Angular への導入、設定方法等、基本的な部分に触れました。
本記事では、より実践的な内容としてクラスターマーカーの表示・非表示の切り替え、マーカーアニメーション使用時の注意点を記載致します。

Angular でマーカークラスタリングライブラリ(js-markerclustererplus)を利用し、クラスターマーカーの表示・非表示の切り替えを行いたい方に向けた記事となります。

 

Google Maps マーカークラスタリングライブラリ
(js-markerclustererplus)とは

表示されている Google Maps を一定のサイズの正方形で区切り、各正方形内に含まれているマーカーを統合し、1 つのクラスターマーカーで表示するライブラリです。

マーカーを統合して表示する事によって、ユーザーエクスペリエンスを改善する事ができます。 また、大量のマーカーを一度に扱わずにすむため、処理負荷を軽減する事もできます。

 

環境

  • Node: 14.17.0
  • npm: 6.14.13
  • Angular: 12.1.1
  • @angular/google-maps: 12.1.1
  • @googlemaps/markerclustererplus: 1.2.0
  • TypeScript: 4.3.5

 

クラスターマーカーの表示・非表示の切り替え

クラスターマーカーを表示しているコンポーネント自体に表示切り替えの設定がないため、下記の実装手順で切り替えを行います。
今回の例ではマップのクリックイベントにマーカーの表示切り替えを行う関数を設定する形で実装します。

 

実装手順

  • クラスターマーカーの ignoreHidden プロパティを true に設定
  • クラスターマーカー内にある、各マーカーコンポーネントの visible プロパティを更新
  • クラスターマーカーの repaint メソッドを呼び出す

 

クラスターマーカーに ignoreHidden を設定

ignoreHidden プロパティを true に設定します。(6 行目)

ignoreHidden とは

クラスターマーカー内にある、非表示のマーカーコンポーネント(visible プロパティが false)を無視するかどうかを設定します。
true に設定する事によって、visible プロパティが false のマーカーコンポーネントがクラスターマーカーに含まれなくなります。

<!-- sample.component.html -->
<google-map (mapClick)="toggleMarkers()">
  <map-marker-clusterer
    #markerClusterer="mapMarkerClusterer"
    imagePath="assets/images/m"
    [ignoreHidden]="true"
  >
    <ng-container *ngFor="let position of markerPositions">
      <map-marker [position]="position"></map-marker>
    </ng-container>
  </map-marker-clusterer>
</google-map>

 

クラスタマーカー内にある、各マーカーコンポーネントの visible を更新

typescript ファイル内で@ViewChild を使用し、html ファイルにある map-marker-cluster コンポーネントを取得します。(10 行目)

クラスターマーカー内にある各マーカーコンポーネントの visible プロパティを更新し、表示切り替えを行います。(15, 16 行目)

// sample.component.ts
import { Component } from "@angular/core";

@Component({
  selector: "app-sample",
  templateUrl: "./sample.component.html",
  styleUrls: ["./sample.component.scss"],
})
export class SampleComponent {
  @ViewChild("markerClusterer") markerClusterer!: MapMarkerClusterer;

  public markerPositions: google.maps.LatLngLiteral[] = [];

  public toggleMarkers(): void {
    const markers = this.markerClusterer?.markerClusterer?.getMarkers() ?? [];
    for (const marker of markers) marker.setVisible(!marker.getVisible());
    this.markerClusterer?.markerClusterer?.repaint();
  }
}

 

クラスターマーカーの repaint メソッドを呼び出す

各マーカーコンポーネントの visible プロパティ更新後、画面表示の更新をするため、repaint メソッドを呼び出します。(17 行目)

全てのマーカーを非表示にする事によって、クラスターマーカーにマーカーが含まれなくなり、画面表示の更新後クラスターマーカー自体が表示されなくなります。

下図は「repaint メソッド呼び出し前」と「repaint メソッド呼び出し後」の画像になります。

repaint メソッド呼び出し前
repaint メソッド呼び出し前
repaint メソッド呼び出し後
repaint メソッド呼び出し後
// sample.component.ts
import { Component } from "@angular/core";

@Component({
  selector: "app-sample",
  templateUrl: "./sample.component.html",
  styleUrls: ["./sample.component.scss"],
})
export class SampleComponent {
  @ViewChild("markerClusterer") markerClusterer!: MapMarkerClusterer;

  public markerPositions: google.maps.LatLngLiteral[] = [];

  public toggleMarkers(): void {
    const markers = this.markerClusterer?.markerClusterer?.getMarkers() ?? [];
    for (const marker of markers) marker.setVisible(!marker.getVisible());
    this.markerClusterer?.markerClusterer?.repaint();
  }
}

 

マーカーアニメーション使用時の注意点

マーカーアニメーションを利用している場合に visible プロパティの変更や、クラスタリングライブラリを利用してクラスターマーカーとの表示切り替えを行うと、再表示時にアニメーションが再生されません。

そのため、下記のような形で明示的にアニメーションを再設定する必要があります。

 

マーカーアニメーションとは

マーカーコンポーネントの options.animation プロパティにgoogle.maps.Animation.BOUNCE等の値を代入することにより、マーカーをアニメーションさせる機能です。

google.maps.Animation.BOUNCEを代入した場合、マーカーが上下に動きます。

 

実装手順

  • マーカーコンポーネントの visibleChanged イベント、クラスターマーカーコンポーネントの clusteringend イベントにアニメーションを再設定する関数を設定
  • 設定した関数内で setAnimation メソッドを呼び出す

 

マーカーコンポーネントの visibleChanged イベント、クラスターマーカーコンポーネントの clusteringend イベントに関数を設定

visibleChanged イベント、clusteringend イベントにアニメーションを再設定する関数を呼び出す処理を設定します。(7、13 行目)

visible プロパティが変更される、またはクラスタリングの処理が終了した際に、設定した関数が呼び出されます。

<!-- sample.component.html -->
<google-map>
  <map-marker-clusterer
    #markerClusterer="mapMarkerClusterer"
    imagePath="assets/images/m"
    [ignoreHidden]="true"
    (clusteringend)="setMarkersAnimation()"
  >
    <ng-container *ngFor="let position of markerPositions">
      <map-marker
        #marker="mapMarker"
        [position]="position"
        (visibleChanged)="setMarkerAnimation(marker)"
      ></map-marker>
    </ng-container>
  </map-marker-clusterer>
</google-map>

 

設定した関数内で setAnimation メソッドを呼び出す

typescript ファイル内で@ViewChild を使用し、html ファイルにある map-marker コンポーネント、map-marker-clusterer コンポーネントを取得します。(10、11 行目)

マーカーに対して setAnimation メソッドを呼び出し、アニメーションを再設定します。(16、22 行目)

// sample.component.ts
import { Component } from "@angular/core";

@Component({
  selector: "app-sample",
  templateUrl: "./sample.component.html",
  styleUrls: ["./sample.component.scss"],
})
export class SampleComponent {
  @ViewChild("markerClusterer") markerClusterer!: MapMarkerClusterer;
  @ViewChild("mapMarker") marker!: MapMarker;

  public markerPositions: google.maps.LatLngLiteral[] = [];

  public setMarkerAnimation(marker: MapMarker): void {
    this.marker.marker?.setAnimation(google.maps.Animation.BOUNCE);
  }

  public setMarkersAnimation(): void {
    const markers = this.markerClusterer?.markerClusterer?.getMarkers() ?? [];
    for (const marker of markers)
      marker.setAnimation(google.maps.Animation.BOUNCE);
  }
}

 

あとがき

本記事でご紹介した設定以外にクラスターマーカーのフォント等、表示面でも細かく設定することが可能です。 下記関連リンクのClusterIconStyleから確認できますので、ぜひ試してみて下さい。

 

にTypeScriptでのフロントエンド開発を担当:木戸裕貴

木戸裕貴

私は主にTypeScriptでのフロントエンド開発を担当しております。

シェアする
記事カテゴリ
最新記事
Power Apps
2021.12.08

Power AppsアプリをPCとスマホで操作したい時の対応方針

Power Apps
2021.12.01

Dataverse for Teams・Power Apps:ドロップダウンメニューの順番を並び替えたい

Power Apps
2021.11.24

Automateのベストプラクティス・アンチパターン(1)【アクション名は変更すべき?Power】

Angular
2021.11.17

Angularでマルチテナント対応(2)

Angular
2021.11.10

Angularでマルチテナント対応(1)

人気記事ランキング
1
Power PlatformPower Apps
2020.10.02

世界に広がる「モデル駆動型アプリ」のココがスゴイ!【第1回】

2
Power PlatformPower AutomateSharePointExcel
2021.07.14

Power AutomateでExcelデータをSharePointにインポートするために考えること(第2回)

3
Power PlatformPower AutomateSharePointExcel
2021.06.23

Power AutomateでExcelデータをSharePointにインポートするために考えること(第1回)

4
Power PlatformPower AppsSharePoint
2021.07.16

Power AppsとSharePoint連携:SortByColumns関数で日本語列をソートする際の注意点

5
Power PlatformPower AutomateSharePointExcel
2021.08.11

Power AutomateでExcelデータをSharePointにインポートするために考えること(第5回)

PageTop
ページトップに戻る