如何在 Angular 10+ 中使用标记聚类

问题描述 投票:0回答:3

以下代码受到此官方文档的启发,并且在我的 Angular 10 应用程序中运行良好: https://developers.google.com/maps/documentation/javascript/marker-clustering?hl=en

import { AfterViewInit, ChangeDetectionStrategy, Component, ElementRef, ViewChild } from '@angular/core'
import { Coordinates } from '@shared/models/coordinates.model';
import MarkerClusterer from '@googlemaps/markerclustererplus'

@Component({
  selector: 'store-map',
  template: `<div id="map" style="height: 500px"></div>`,
  styleUrls: ['./store-map.component.scss'],
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class StoreMapComponent implements AfterViewInit {

  @ViewChild('map', {static: false}) info: ElementRef;

  ngAfterViewInit() {
    const locations = [
      { lat: -31.56391, lng: 147.154312 },
      { lat: -33.718234, lng: 150.363181 },
      { lat: -33.727111, lng: 150.371124 },
      { lat: -33.848588, lng: 151.209834 },
      { lat: -33.851702, lng: 151.216968 },
      { lat: -34.671264, lng: 150.863657 },
      { lat: -35.304724, lng: 148.662905 },
      { lat: -36.817685, lng: 175.699196 },
      { lat: -36.828611, lng: 175.790222 },
      { lat: -37.75, lng: 145.116667 },
      { lat: -37.759859, lng: 145.128708 },
      { lat: -37.765015, lng: 145.133858 },
      { lat: -37.770104, lng: 145.143299 },
      { lat: -37.7737, lng: 145.145187 },
      { lat: -37.774785, lng: 145.137978 },
      { lat: -37.819616, lng: 144.968119 },
      { lat: -38.330766, lng: 144.695692 },
      { lat: -39.927193, lng: 175.053218 },
      { lat: -41.330162, lng: 174.865694 },
      { lat: -42.734358, lng: 147.439506 },
      { lat: -42.734358, lng: 147.501315 },
      { lat: -42.735258, lng: 147.438 },
      { lat: -43.999792, lng: 170.463352 },
    ];
    const map = new google.maps.Map(document.getElementById("map") as HTMLElement, {
        zoom: 3,
        center: { lat: -28.024, lng: 140.887 },
      }
    )

    const labels = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    
    const markers = locations.map((location, i) => {
      return new google.maps.Marker({
        position: location,
        label: labels[i % labels.length],
      });
    });

    new MarkerClusterer(map, markers, {
      imagePath:
        "https://developers.google.com/maps/documentation/javascript/examples/markerclusterer/m",
    });

  }
}

标记聚类在这里运行良好。不幸的是,这并不是真正实现我想要的“角度方式”。我想要的是使用 Angular 中的“新”原生 Google 地图组件。所以这就是我所做的(没有标记聚类):

成分:

@Component({
  selector: 'store-map',
  templateUrl: './store-map.component.html',
  styleUrls: ['./store-map.component.scss'],
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class StoreMapComponent {

  @Input()
  coordinates: Coordinates

  @Input()
  zoom: number

  @Input()
  set stores(value: Store[]) {
    // Allow time for the map to load before showing markers
    if (this.isFirstLoad && value.length > 0) {
      this.isFirstLoad = false
      setTimeout(() => {
        this._stores = value
        this.changeDetector.markForCheck() // Needed because of setTimeout()
      }, 1000)
    } else {
      this._stores = value
    }

  }

  private isFirstLoad = true

  _stores: Store[] = []
  markerOptions: google.maps.MarkerOptions = {
    animation: Animation.DROP,
    icon: {
      url: '/assets/img/yarn.png',
      size: new google.maps.Size(32, 32)
    }
  }

  constructor(private changeDetector: ChangeDetectorRef) { }

  getStoreLatLngLiteral(store: Store): google.maps.LatLngLiteral {
    return this.mapCoordinatesToLatLngLiteral({
      latitude: store.lat,
      longitude: store.lng
    })
  }

  mapCoordinatesToLatLngLiteral(coordinates: Coordinates): google.maps.LatLngLiteral {
    return {
      lat: coordinates.latitude,
      lng: coordinates.longitude
    }
  }

模板:

<google-map [center]="mapCoordinatesToLatLngLiteral(coordinates)" [zoom]="zoom" width="auto">
  <map-marker *ngFor="let store of _stores" [position]="getStoreLatLngLiteral(store)"
              [title]="store.name"
              [options]="markerOptions">
  </map-marker>
</google-map>

问题是,此时,我不知道如何以“Angular-way”方式设置标记聚类。

angular google-maps
3个回答
3
投票

如果你想使用官方文档,你可以直接在index.html文件上加载JS脚本,而不是依赖有自己文档的第三方模块/包。

这里有一个示例供您参考:https://stackblitz.com/edit/angular-marker-cluster-64960574

index.html

<script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY"></script>
<script src="https://unpkg.com/@google/[email protected]/dist/markerclustererplus.min.js"></script>
<my-app>loading</my-app>

样式.css

html, body {
  height: 100%;
  margin: 0;
  padding: 0;
}

.map {
  height:100%;
}

map-with-marker.component.html

<div #map class="map"></div>

map-with-marker.component.ts

import { Component, OnInit, ViewChild } from "@angular/core";
declare const google: any;

@Component({
  selector: "my-maps",
  templateUrl: "./map-with-marker.component.html",
  styleUrls: ["./map-with-marker.component.css"]
})
export class MapComponent implements OnInit {
  @ViewChild("map", { static: true }) mapElement: any;
  map: any;

  constructor() {}

  ngOnInit() {
    const locations = [
      { lat: -31.56391, lng: 147.154312 },
      { lat: -33.718234, lng: 150.363181 },
      { lat: -33.727111, lng: 150.371124 },
      { lat: -33.848588, lng: 151.209834 },
      { lat: -33.851702, lng: 151.216968 },
      { lat: -34.671264, lng: 150.863657 },
      { lat: -35.304724, lng: 148.662905 },
      { lat: -36.817685, lng: 175.699196 },
      { lat: -36.828611, lng: 175.790222 },
      { lat: -37.75, lng: 145.116667 },
      { lat: -37.759859, lng: 145.128708 },
      { lat: -37.765015, lng: 145.133858 },
      { lat: -37.770104, lng: 145.143299 },
      { lat: -37.7737, lng: 145.145187 },
      { lat: -37.774785, lng: 145.137978 },
      { lat: -37.819616, lng: 144.968119 },
      { lat: -38.330766, lng: 144.695692 },
      { lat: -39.927193, lng: 175.053218 },
      { lat: -41.330162, lng: 174.865694 },
      { lat: -42.734358, lng: 147.439506 },
      { lat: -42.734358, lng: 147.501315 },
      { lat: -42.735258, lng: 147.438 },
      { lat: -43.999792, lng: 170.463352 }
    ];

    const labels = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    var center = { lat: -33.8569, lng: 151.2152 };
    const mapProperties = {
      center: center,
      zoom: 11,
      mapTypeId: google.maps.MapTypeId.ROADMAP
    };
    this.map = new google.maps.Map(
      this.mapElement.nativeElement,
      mapProperties
    );

    this.addMarker(locations, labels);
  }
  addMarker(locations, labels) {
    const markers = locations.map((location, i) => {
      return new google.maps.Marker({
        position: location,
        label: labels[i % labels.length],
        map: this.map
      });
    });
    new MarkerClusterer(this.map, markers, {
      imagePath:
        "https://developers.google.com/maps/documentation/javascript/examples/markerclusterer/m"
    });
  }
}

如果遇到

google is not defined
,只需在代码的任何部分(即 .ts 文件上)添加一个空格,因为 Stackblitz 似乎在那里有问题。


3
投票

使用 Angular 的 Google 地图包 (

@angular/google-maps
),您可以按照与上面示例类似的方式使用标记集群;

组件.ts

import {Component} from '@angular/core';

@Component({
  selector: 'google-map-demo',
  templateUrl: 'google-map-demo.html',
})
export class GoogleMapDemo {
  center: google.maps.LatLngLiteral = {lat: 24, lng: 12};
  zoom = 4;
  markerPositions: google.maps.LatLngLiteral[] = [];
  markerClustererImagePath =
      'https://developers.google.com/maps/documentation/javascript/examples/markerclusterer/m';

  addMarker(event: google.maps.MouseEvent) {
    this.markerPositions.push(event.latLng.toJSON());
  }
}

组件.html

<google-map height="400px"
            width="750px"
            [center]="center"
            [zoom]="zoom"
            (mapClick)="addMarker($event)">
  <map-marker-clusterer [imagePath]="markerClustererImagePath">
    <map-marker *ngFor="let markerPosition of markerPositions"
                [position]="markerPosition"></map-marker>
  </map-marker-clusterer>
</google-map>

其文档的完整链接以及如何加载库此处

这将在版本 11.1.0 中推出(如 here),或者您可以立即下载 build


0
投票

与您类似,您添加了集群组件我们是否有 oms 重叠标记 spidifer 的集群?

© www.soinside.com 2019 - 2024. All rights reserved.