Angular-google-maps: Wie benutze ich einen Marker Clusterer?

Erstellt am 30. Apr. 2016  ·  76Kommentare  ·  Quelle: SebastianM/angular-google-maps

Hallo, gibt es Hinweise zur Verwendung von https://github.com/googlemaps/js-marker-clusterer oder einem anderen Marker-Clusterer? Vielen Dank!

discussion / question

Hilfreichster Kommentar

@ siegerx3 Es ist einfacher, als es sich anhört.

import { Directive } from '@angular/core';
import { GoogleMapsAPIWrapper } from 'angular2-google-maps/core';

@Directive({
  selector: 'custom-directive'
})
export class CustomMapDirective {
  constructor (private gmapsApi: GoogleMapsAPIWrapper) {
    this.gmapsApi.getNativeMap().then(map => {
      // map is the native google map object and the wrapper is the same instance as the one on the map
    });
  }
}

Ich habe eine Direktive verwendet, weil ich keine Vorlage benötigte. Sie können eine Komponente verwenden und eine angeben, wenn Sie möchten.

Selbstverständlich müssen Sie Ihre benutzerdefinierte Komponente / Direktive im Abschnitt directives der Komponente angeben, in der Sie sie verwenden. Legen Sie jetzt einfach Ihre Komponente in der Karte ab:

<sebm-google-map>
  <!-- markers, info windows, etc -->

  <custom-directive></custom-directive>
</sebm-google-map>

Aufgrund der Funktionsweise von Angular2 DI wird, da wir keinen Anbieter für den GoogleMapsAPIWrapper-Dienst angeben, der Komponentenbaum nach oben verschoben, bis einer gefunden wird. In diesem Fall ist es 1 Schritt nach oben und wir verwenden den GoogleMapsAPIWrapper, der in der Komponente sebm-google-map bereitgestellt wurde

Alle 76 Kommentare

Nein, tut mir leid, ich habe keinen Rat, den ich dir jetzt geben könnte

@SebastianM Ich denke, dies kann mit Zugriff auf das Kartenobjekt erfolgen. Siehe hier: https://github.com/SebastianM/angular2-google-maps/pull/311

Hat das tatsächlich jemand gemacht? Die js-Dateien von markerclusterer scheinen das Kartenobjekt, das ich von .getMap () übergebe, nicht zu mögen.

@AbdulTheProgrammer Ich habe darauf gewartet, dass ich

Ich habe es mit einer benutzerdefinierten Komponente erreicht und in die sebm-google-map aufgenommen. Es verwendet den GoogleMapsAPIWrapper und die nativeMap.

Ich füge die Markierungen manuell mithilfe der Javascript-API von Google Maps (window.google.maps) hinzu und erstelle dann den MarkerClusterer.

Ich hoffe, es hilft.

@ricardojbertolin Das hilft, wie Sebastian hier # 311 hervorgehoben hatte. Eine benutzerdefinierte Komponente in der Karte ist genau, wie man auf das native Kartenobjekt zugreift, obwohl es sicherlich eine bessere Möglichkeit geben muss, die Markierungen mithilfe des Manager-Dienstes als hinzuzufügen im Gegensatz dazu manuell über die js api ...

Ich kämpfe auch darum, js-marker-clusterer zum Laufen zu bringen. Ich erhalte einen Verweis auf die native Karteninstanz, benötige jedoch auch Verweise auf die nativen Kartenmarkierungen. Hat jemand eine Idee, wie man die nativen Kartenmarkierungen für meine <sebm-google-map-marker> s bekommen kann?

@alexweber
Haben Sie ein Beispiel für die benutzerdefinierte Komponente und den GoogleMapsApiWrapper?
Ich verstehe anscheinend nicht, was "Platzieren einer benutzerdefinierten Komponente in der Komponente" bedeutet.

@ siegerx3 Es ist einfacher, als es sich anhört.

import { Directive } from '@angular/core';
import { GoogleMapsAPIWrapper } from 'angular2-google-maps/core';

@Directive({
  selector: 'custom-directive'
})
export class CustomMapDirective {
  constructor (private gmapsApi: GoogleMapsAPIWrapper) {
    this.gmapsApi.getNativeMap().then(map => {
      // map is the native google map object and the wrapper is the same instance as the one on the map
    });
  }
}

Ich habe eine Direktive verwendet, weil ich keine Vorlage benötigte. Sie können eine Komponente verwenden und eine angeben, wenn Sie möchten.

Selbstverständlich müssen Sie Ihre benutzerdefinierte Komponente / Direktive im Abschnitt directives der Komponente angeben, in der Sie sie verwenden. Legen Sie jetzt einfach Ihre Komponente in der Karte ab:

<sebm-google-map>
  <!-- markers, info windows, etc -->

  <custom-directive></custom-directive>
</sebm-google-map>

Aufgrund der Funktionsweise von Angular2 DI wird, da wir keinen Anbieter für den GoogleMapsAPIWrapper-Dienst angeben, der Komponentenbaum nach oben verschoben, bis einer gefunden wird. In diesem Fall ist es 1 Schritt nach oben und wir verwenden den GoogleMapsAPIWrapper, der in der Komponente sebm-google-map bereitgestellt wurde

@jfmaeck Es gibt eine getNativeMarker() -Methode für den MarkerManager -Dienst, die Sie dafür verwenden können, und Sie können dieselbe Markierungsmanager-Dienstinstanz mit der oben für den Wrapper beschriebenen Methode erhalten.

@alexweber
Wenn man den Code sieht, macht die Erklärung jetzt Sinn! Vielen Dank :)

@alexweber Vielen Dank für Ihren Hinweis, wie Sie die native Marker-Instanz erhalten. Ich habe jedoch noch eine Frage: Die getNativeMarker() -Methode der MarkerManager erwartet eine SebmGoogleMapMarker -Instanz (die Markierungskomponente) als Parameter. Wissen Sie, wie ich diese Komponente in einer Variablen erfassen kann, um sie an die Funktion getNativeMarker zu übergeben?

@jfmaeck Kein Problem! Ich kann im Moment nicht überprüfen, ob ich 100% sicher bin, aber Sie können wahrscheinlich einfach @ViewChild('myMarker'): SebmGoogleMapMarker in Ihrer Komponente verwenden und mit einem # im Markup darauf verweisen: <sebm-google-map-marker #myMarker> just Denken Sie daran, dass ViewChild nur in ngAfterViewInit korrekt aufgelöst wird.

@alexweber Nochmals vielen Dank für Ihre Hilfe. Leider konnte ich mit @ViewChildren nicht auf die Markierungen zugreifen. Ich habe die Demo auf Plunkr gegabelt und einige Änderungen daran vorgenommen, damit das ViewChildren-Ergebnis in der Konsole protokolliert wird (derzeit ein leeres Array):

markers after view init []

http://plnkr.co/edit/7rdOz3QswDL0pik7SmAS?p=preview

Ich denke, Sie sind ziemlich beschäftigt, aber wenn Sie die Gelegenheit haben, es sich anzusehen, würde ich das wirklich schätzen.

@jfmaeck Wenn Sie @ContentChildren verwenden (weil Sie die Instanzen http://plnkr.co/edit/mukdlZ7K7CIFm6aTdDTp?p=preview

@jfmaeck Du warst nah dran, hier ist eine funktionierende Abzweigung deines Plunks mit @ViewChildren : http://plnkr.co/edit/rJMCFoX9GokturcJljLh?p=preview

Damit es mit der benutzerdefinierten Kartenkomponente funktioniert @ContentChildren (wie @SebastianM hervorhob ), würde es funktionieren, aber ich

Vielen Dank @SebastianM und @alexweber!

@alexweber @SebastianM Wie füge ich zunächst diese Bibliothek ein, die Sie mit js-marker-clusterer verwenden? Gibt es eine Möglichkeit, Cluster auf einer bestimmten Zoomstufe zu verwenden? Und wie füge ich Bilder für die Cluster wie folgt hinzu :

@ricardojbertolin Gibt es eine Chance, dass Sie Ihren Code teilen können? Ich bin sehr neu in angular2 (arbeite seit über einem Jahr mit angularjs) und bin ein bisschen verloren.

@alexweber , Haben Sie das Hinzufügen von markerclusterer.js getestet? irgendein Beispiel im Zusammenhang?

@jpcode sorry nein, ich habe schon eine Weile nicht mehr daran gearbeitet ...

Ich habe eine funktionierende Lösung in einem meiner Projekte.
Kann ich bei Bedarf einen Plunkr mit einem Beispiel zusammenstellen?
@jpcode
@alexweber

@ siegerx3 schön, wird viel helfen.
Ich arbeite alternativ nur mit Google Maps api + markerclusterer.js.

@ siegerx3 , dies ist ein einfaches Beispiel für die Verwendung von Google Maps lib:
https://plnkr.co/Tr1Ykkj12HCkF9InQmuW

POC ausstehend:
In der Art und Weise, wie Angular2-Google-Maps verwendet werden, muss es meiner Meinung nach hinzugefügt werden, um eine Kollision mit globalen Objekten als "Google" zu verhindern.
Eine Problemumgehung besteht darin, das Laden von Google aus der Bibliothek zu verhindern.
Geben Sie (MapsAPILoader, {useClass: NoOpMapsAPILoader}) ein, laden Sie es selbst und fügen Sie clusterer.js hinzu.

Aber ist besser, wenn angle2-google-maps eine Direktive zur Unterstützung von Clusterer hinzufügt :)

@jpcode
Ich habe stundenlang versucht, es im Plunker zum Laufen zu bringen ... ohne Erfolg.
Ich habe immer einige Fehler erhalten, die nichts mit dem Problem zu tun haben.
Also zeige ich dir hier nur den Code ...

import { Directive, OnDestroy, OnInit } from '@angular/core';
import { GoogleMapsAPIWrapper } from 'angular2-google-maps/core';
import { GoogleMap, Marker } from 'angular2-google-maps/core/services/google-maps-types';
import { AppService } from '../../../services/index';
import { Observable } from 'rxjs';

declare const google;
declare const MarkerClusterer;

@Directive({
  selector: 'custom-map'
})
export class CustomMapDirective implements OnInit, OnDestroy {

  private map: GoogleMap;

  constructor(private gmapsApi: GoogleMapsAPIWrapper, private appService: AppService) {
  }

  ngOnInit() {

    this.gmapsApi.getNativeMap().then(map => {
      this.map = map;

      let shopMarker = {
        url: "assets/img/marker_shop.svg", // url
        scaledSize: new google.maps.Size(50, 50)
      }
      let loungeMarker = {
        url: "assets/img/marker_lounge.svg", // url
        scaledSize: new google.maps.Size(50, 50)
      }

      let markers = [];

      let style = {
        url: "/assets/img/marker.svg",
        height: 50,
        width: 50,
        anchor: [-14, 0],
        textColor: '#bd0b1d',
        textSize: 11,
        backgroundPosition: "center center"
      };

      var options = {
        imagePath: "/assets/img/marker",
        gridSize: 70,
        styles: [style, style, style]
      };

      Observable
        .interval(500)
        .skipWhile((s) => this.appService.Shops == null || this.appService.Shops.length <= 0)
        .take(1)
        .subscribe(() => {
          for (let shop of this.appService.Shops) {
            var marker = new google.maps.Marker({
              position: new google.maps.LatLng(shop.Latitude, shop.Longitude),
              icon: shop.Lounge ? loungeMarker : shopMarker
            });
            google.maps.event.addListener(marker, 'click', () => {
              this.appService.SelectedShop = shop;
            });
            markers.push(marker);

          }

          var markerCluster = new MarkerClusterer(map, markers, options);
          }
        })
    });
  }
}

Sie fügen diese Anweisung in das Tag angle2-google-maps ein:

<sebm-google-map>
      <custom-map></custom-map>
</sebm-google-map>

@ siegerx3 , ich habe einen POC mit angle2-google-maps erstellt

Ansatz:

  • Fügen Sie Google Maps aus index.html hinzu
  • import clusterer.js
  • Verhindern Sie, dass Google Maps lib von angle2-google-maps geladen wird (mithilfe des Anbieters)
  • Fügen Sie eine Direktive hinzu, um die ursprüngliche Karteninstanz von lib abzurufen
  • Verwenden Sie Google / Markercluster-Variablen, um sie als global zu verwenden

Sie können auch die anderen Anweisungen von Angular-2-Google-Maps verwenden, aber ich denke, es ist besser, wenn der Bibliothek etwas hinzugefügt wird, um Clusterer zu unterstützen.
->

Da es keinen Sinn macht, diese Bibliothek zum Malen einer Karte zu verwenden und als nächstes nur Google Maps zu verwenden, denke ich, ist es besser, nur Google Maps libs + clusterer.js zu verwenden, wie es vor plunkr zeigt.

import { Directive } from '@angular/core';
import { GoogleMapsAPIWrapper } from 'angular2-google-maps/core';
import { GoogleMap, Marker } from 'angular2-google-maps/core/services/google-maps-types';
// npm install js-marker-clusterer --save
import 'js-marker-clusterer/src/markerclusterer.js';

declare const google;
declare const MarkerClusterer;

@Directive({
  selector: 'googlemap-directive'
})



export class GoogleMapDirective {

  googleMarkers : any;
  _map: any;

  zoom: number = 3;
  lat: number = 51.673858;
  lng: number = 7.815982;

  markers: marker[] = [
      {
          lat: 51.673858,
          lng: 7.815982
      },
      {
          lat: 51.373858,
          lng: 7.215982
      },
      {
          lat: 51.723858,
          lng: 7.895982
      }
  ]

   initMarkers(){
    let i = 0;
    let markers = this.markers;
    var result = [];
    for ( ; i < markers.length; ++i ){
       result.push( new google.maps.Marker({
            position : markers[ i ] 
        })
       );
    }
    return result;
  }



  constructor (private gmapsApi: GoogleMapsAPIWrapper) {
    var me = this;
    this.gmapsApi.getNativeMap().then(map => {
      // instance of the map.
      me._map = map;
      me.initializeMap();
    });
  }

  initializeMap(){
      var me = this;
      me.googleMarkers = me.initMarkers();
      var mc = new MarkerClusterer( me._map, me.googleMarkers, { imagePath: 'https://googlemaps.github.io/js-marker-clusterer/images/m' } );
  }

}

interface marker {
    lat: number;
    lng: number;
}

Um zu verhindern, dass Google Maps zweimal geladen wird, verwenden Sie einen Anbieter von angle2-google-maps
Fügen Sie in Ihrer Komponentendefinition einen Anbieter hinzu

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

import { SebmGoogleMap, MapsAPILoader, NoOpMapsAPILoader  } from 'angular2-google-maps/core';

@Component({
    selector: 'site-map',
    templateUrl: './site-map.component.html',
    styleUrls: ['./site-map.component.css'],
  providers: [
    {
      provide: MapsAPILoader, useClass: NoOpMapsAPILoader
    }
  ],
})

In Ihrer Vorlagendefinition müssen Sie die Direktive hinzufügen.

<sebm-google-map #sitemap
  [disableDefaultUI]="false"
  [zoom] = "zoom"
  [zoomControl]="true" 
  [latitude]="lat" [longitude]="lng">
  <!--
  <sebm-google-map-marker 
      *ngFor="let m of markers; let i = index"
      (markerClick)="openDetail(m)"
      [latitude]="m.lat"
      [longitude]="m.lng"
      [label]="m.label"

      [markerDraggable]="m.draggable"
      [iconUrl]="'assets/img/marker.png'"
      (dragEnd)="markerDragEnd(m, $event)">

    <sebm-google-map-info-window [disableAutoPan]="true" (infoWindowClose)="onCloseDetail.emit()">
      <h5>{{m.address}}</h5>
      <div>{{m.city}}, {{m.state}}, {{m.country}}</div>
    </sebm-google-map-info-window>    
  </sebm-google-map-marker>
  -->
  <googlemap-directive></googlemap-directive>
</sebm-google-map>

image

@jpcode
Ich bin damit einverstanden, dass dies zur Angular2-Google-Maps-Bibliothek hinzugefügt wird, obwohl in meiner Lösung das Maps SDK nicht zweimal geladen wird, wie Sie bereits erwähnt haben.

Ich lasse die agm lib einfach so viel wie möglich machen und mache einfach die notwendigen Teile selbst.

@ siegerx3
Können Sie bitte ein funktionierendes Beispiel in einer Zip-Datei teilen?

@ hellsm83
Ich werde morgen eine erstellen, wenn das für dich ausreicht :)
Kennen Sie Angular-Cli? Ansonsten mache ich einfach eine einfache.

@ siegerx3
Ja, ein bisschen ... Ich konnte die Clusterisierung mit Google Maps API + Marker Clusterer ausführen. Ich würde stattdessen lieber angle2-google-maps verwenden ... um einen vollständigen Überblick über die Lösung zu erhalten.
tnx viel für deine hilfe

@ hellsm83
https://drive.google.com/open?id=0B4y4KJY7l3rPNTdqR0hyNTRqVHc

Nur npm install und ng serve . Wenn Sie Angular-Cli nicht installiert haben, müssen Sie zuerst npm install angular-cli -g installieren.

Denken Sie daran, dies ist nicht die optimale Lösung. Es ist nur eine Problemumgehung, die ich gemacht habe, weil es noch keine Cluster-Direktive gibt.

bearbeiten:
Die Formatierung könnte seltsam sein, da mein Atom nicht funktionierte, also habe ich den guten alten Editor verwendet ^^

@ siegerx3
Vielen Dank. Ich werde diese Lösung überprüfen :)

Gibt es ein Update dazu, das in Angular 2 Google Maps enthalten ist? Ich muss es wirklich für ein Projekt verwenden, an dem ich arbeite

@SteveDowsett
Sie können immer noch eines der Beispiele verwenden, die Leute, einschließlich mir, zur Verfügung gestellt haben :)
Wenn es dir natürlich reicht

@ hellsm83
Übrigens hat alles funktioniert? Hat es dir geholfen?

@ siegerx3
Ja, es hat mir sehr geholfen. Tnx!

@ siegerx3

Ich habe Ihr Beispiel selbst verwendet und es großartig zum Laufen gebracht, also ein großes Lob!

Aber mein Problem ist jetzt, dass ich die Marker nicht zum Aktualisieren bringen kann. Ich habe ngOnChanges verwendet, um ein aktualisiertes Array von Punkten zu übergeben, und ich kann sehen, wie sich das Array ändert, aber wenn das Array leer wird, werden die Markierungen nicht entfernt.

Irgendwelche Tipps?

@nanomoffet
Schön, dass es geholfen hat!

Eigentlich bin ich vor ein paar Tagen auf dasselbe / ein ähnliches Problem gestoßen, aber ich hatte noch keine Zeit, eine Lösung zu finden.

Ich werde hier posten, wenn ich dann etwas gefunden habe.

Ich habe eine Lösung für das Problem der persistenten Cluster gefunden.

        .interval(100)
        .take(1)
        .subscribe(() => {
        if(this.markerCluster) {
          this.markerCluster.clearMarkers();
        }
          if (this.points.length > 0) {
            for (let point of this.points) {
              let marker = new google.maps.Marker({
                position: new google.maps.LatLng(point.Latitude, point.Longitude),
                icon : markerIcon
              });
              this.markers.push(marker);
            }
          } else {
            this.markers = [];
          }
          this.markerCluster = new MarkerClusterer(map, this.markers, options);

        });

Ich habe markerCluster außerhalb des Observable deklariert. Wenn es zu Beginn vorhanden ist, wird eine Funktion namens clearMarkers () ausgeführt, die alle vorhandenen Marker aus der Karte entfernt, obwohl sie im Array verbleiben (daher die andere Logik zum Leeren des Arrays) ).

Das hat mein Problem behoben, vielleicht hilft es dir auch bei siegerx3

@nanomoffet

Ich werde es überprüfen, wenn ich wieder an diesem Teil arbeite, danke :)

Hallo Leute, danke für diese Hinweise
Ich habe es geschafft, die getNativeMap mithilfe einer Unterkomponente zu erhalten
Ich implementiere ein Kartenkontextmenü
<sebm-google-map> <mapmenu-component></mapmenu-component>
Das Problem in meinem Fall ist, dass die Unterkomponentenvorlage nicht sichtbar ist
es wird in den HTML-Code gerendert
<div class="sebm-google-map-content" _ngcontent-rgy-8="">
Das ist eine unsichtbare Komponente

Kann ich im Prinzip etwas HTML in die sebm-google-map einfügen?
Ich möchte es als HTML haben, ohne OverlayView zu verwenden

Ich konnte damit umgehen, indem ich die Funktionalität in 2 Komponenten aufteilte (Direktive + Komponente).
1.) eine, die sich in sebm-google-map befinden muss und als API-Accessor dient
2.) eine, die außerhalb von sebm-google-map sein muss (weil ich sonst das generierte HTML nicht sehe)

Hallo Team,
@ siegerx3 Ich habe Ihren Code von https://drive.google.com/open?id=0B4y4KJY7l3rPNTdqR0hyNTRqVHc verwendet
es funktioniert super, aber ich kann mich nicht integrierenund. Was ich erreichen möchte, ist die Integration von Cluster + Markierungsbezeichnung + Infofenster. Wenn ich also auf Cluster klicke, sollten die Personen eine Markierungsbezeichnung haben und beim Klicken darauf sollte ein Infofenster angezeigt werden. Irgendeine Idee, wie ich das @SebastianM zum Laufen bringen kann

@sprakashg
Ich denke, da der Cluster noch nicht im Modul implementiert ist und Sie die Markierungen aus dem Modul nicht verwenden, müssen Sie die native Maps-API in derselben benutzerdefinierten Komponente verwenden, die für das Clustering verwendet wird.
Das heißt, Sie fügen das Etiketten- und Infofenster manuell hinzu, wie Sie es in Vanille-Javascript tun würden.

@sprakashg

Ich arbeite tatsächlich selbst an derselben Sache. Ich musste für die Bibliothek zu MarkerClustererPlus wechseln und verwende den folgenden Code, um Infofenster für einzelne Marker sowie für die Cluster selbst zu aktivieren:

        .interval(100)
        .take(1)
        .subscribe(() => {
        if (this.markerCluster) {
          this.markerCluster.clearMarkers();
          this.markers = [];
        }
          if (this.points.length > 0) {
            for (let point of this.points) {
              let marker = new google.maps.Marker({
                position: new google.maps.LatLng(point.Latitude, point.Longitude),
                icon : markerIcon,
                title: 'this is a title'
              });
              marker.addListener('mouseover', function() {
                infowindow.open(map, marker);
              });
              marker.addListener('mouseout', function() {
                infowindow.close(map, marker);
              });
              this.markers.push(marker);
            }
          } else {
            this.markers = [];
            if (this.markerCluster) {
              this.markerCluster.clearMarkers();
            }
          }
          this.markerCluster = new MarkerClusterer(map, this.markers, options);
          google.maps.event.addListener(this.markerCluster, 'mouseover', function(cluster) {
            let content = 'Cluster Window';
            let info = new google.maps.MVCObject;
            let clusterInfowindow = new google.maps.InfoWindow();

            clusterInfowindow.setContent(content);
            clusterInfowindow.open(map, info);
            clusterInfowindow.setPosition(cluster.getCenter());
            google.maps.event.addListener(map, 'zoom_changed', function() { clusterInfowindow.close(); });
          });

        });

Das einzige Problem besteht darin, herauszufinden, wie die Clusterfenster geschlossen werden. Sie werden geschlossen, wenn Sie die Karte verlassen, nicht jedoch, wenn Sie den Cluster verlassen.

Weiß jemand, ob wir Wegpunkte in Winkel 2 verwenden können, aber lat und lng verwenden, wie hier angegeben " https://developers.google.com/maps/documentation/javascript/reference#DirectionsWaypoint "?

@naranmistry Kannst du ein bisschen angeben, was du tun möchtest?

Ich verstehe nicht, was genau dein Plan ist. Vielleicht versteht jemand anderes?

Grundsätzlich möchte ich in der Lage sein, lng- und lat-Werte anstelle einer Zeichenfolge in den Wegpunkt einzufügen. Ist dies mit angle2-google-maps möglich? Da ich eine Route mit mehreren spezifischen Zwischenstopps unter Verwendung von Längen- und Gitterwerten anzeigen möchte

Wenn ich das richtig verstehe, sehe ich die Verbindung zu diesem Modul nicht, aber im Allgemeinen, wenn Sie sich die Dokumentation ansehen, steht dort location Type: string|LatLng|Place . Ja, Sie können das LatLng-Objekt von Google Maps verwenden, das die numerischen Werte in seinem Konstruktor übernimmt.

Hast du das gebraucht?

Grundsätzlich möchte ich wissen, wie, als ich versuchte, es weiterzugeben, wie es in der Dokumentation steht, aber es schlug immer wieder fehl. Gibt es ein funktionierendes Beispiel für Wegpunkte mit lat und lng?

Entschuldigung für die Verwirrung, ich hätte klarer sein sollen

Das glaube ich nicht. Aber wenn Sie Ihren Code als Beispiel angeben könnten? Wie in einem Plunkr konnte ich sehen, was ich finden kann :)

Okay, ich werde versuchen, eine zusammenzustellen

Vielen Dank

Entschuldigung, kann ich _click event_ in einem _infowindow_ innerhalb der _marker-cluster_-Direktive abfangen oder eine _sebm-google-map-info_-Komponente für jeden Marker rendern?

Vielen Dank!

Ich habe das gleiche Problem @fsciuti.
Hast du eine Lösung gefunden?

Da agm-maps Cluster immer noch nicht unterstützt, habe ich das Beispiel von @ siegerx3 , die Verbesserung der Markeränderungen und das Beispiel für Markerinfo-Fenster von @nanomoffet genommen. Gute Arbeit! Vielen Dank, Ihre Beispiele haben sehr geholfen.

Um etwas zurückzugeben, stelle ich eine aktualisierte Version des Beispiels

https://drive.google.com/open?id=0B51AX67ezltoOFdSNTQ1NlQ4SU0

Die folgenden Änderungen wurden vorgenommen:

  • Aktualisierte Abhängigkeiten für Angular 4.1 und @agm/core
  • Der Code wurde an Angular 4.1 und @agm/core
  • Erkennung von Markeränderungen hinzugefügt
  • Beispiel für ein Marker-Info-Fenster hinzugefügt
  • fester Codestil

@andorfermichael Danke ein Haufen Mann, du bist großartig! Eine Frage bitte: Wenn ich das Styling der Direktive (sowohl Marker als auch Cluster) externalisieren möchte, wie soll ich das tun? Ich habe darüber nachgedacht, es einfach zu einer Komponente zu machen, aber dann weiß ich nicht, wie ich das Observable mit den Optionen und dem Stil, die Sie haben, richtig füttern kann ...

@ Picosam

Sie benötigen keine Komponente, sondern verwenden nur ES6-Module.

Erstellen Sie eine neue Datei und exportieren Sie die Konfiguration, zum Beispiel:

_google-maps.config.ts_

export const markerIcon = {
  url: '/assets/marker.png', // url
  scaledSize: new google.maps.Size(35, 35)
};

const style = {
  url: '/assets/cluster.png',
  height: 40,
  width: 40,
  textColor: '#FFF',
  textSize: 11,
  backgroundPosition: 'center center'
};

export const options = {
  imagePath: '/assets/cluster',
  gridSize: 70,
  styles: [style, style, style]
};

und dann in _marker-cluster.ts_ diese Variablen / Module importieren:

import { markerIcon, options } from './google-maps.config';

@andorfermichael danke noch mal !!!
Natürlich kann ich dann komplexe Symbole verwenden und alles, was in der neuesten Version des Google Maps Javascript-Moduls dokumentiert ist, richtig?

@picosam Ich denke schon, habe das aber noch nicht ausprobiert

@andorfermichael Dies ist ein bemerkenswerter Job 👍
aber ich stehe vor einem kleinen Problem

Ich muss durch Klicken auf das Infofenster zu einer anderen Route umleiten, aber das Infofenster hat kein Klickereignis. Also habe ich stattdessen das "closeclick" -Ereignis verwendet, hier ist der Code

infowindow.addListener('closeclick', function () { this.router.navigate(['/blabla', id]); });

Alles funktioniert gut, aber wenn ich auf die Schaltfläche zum Schließen des Infofensters klicke, wird das Ereignis aufgerufen, aber es wird ein Fehler ausgegeben
this.router is undefined

Natürlich wird die Router-Bibliothek importiert und der Router im Konstruktor definiert

Ich habe eine andere Technik ausprobiert und den Eventemitter (die Input / Output-Technik) zwischen der übergeordneten Komponente und der Direktive verwendet.
Ich habe das @Output() eventEmitter = new EventEmitter() oben als Klassenvariable definiert.
Und die Veranstaltung am selben Ort,

infowindow.addListener('closeclick', function () { this.eventEmitter(id); });

Auch alles funktioniert gut, aber wenn ich auf die Schaltfläche zum Schließen des Infofensters klicke, wird das Ereignis aufgerufen, aber es wird ein Fehler ausgegeben
this.eventEmitter is undefined

Gibt es eine Möglichkeit, dieses Problem zu beheben?

@ hossam-maurice Ich nehme an, dass der Fehler durch this . Das this in Ihrem Fall ist das Element, das das Ereignis ausgelöst hat - das Infofenster. Aus diesem Grund wurden in ES6 / ECMAScript2015 Pfeilfunktionen eingeführt. Bei Verwendung von Pfeilfunktionen hängt this nicht davon ab, wie die Funktion aufgerufen wurde, sondern vom umgebenden Bereich.
Also sollte infowindow.addListener('closeclick', () => { this.eventEmitter(id); }); für Sie funktionieren.

Weitere Informationen finden Sie unter: ExploringJS - Arrow Functions und MDN - Arrow Functions

@andorfermichael Vielen Dank, es hat funktioniert: D 👍

Hallo, ich habe den benutzerdefinierten Markierungscluster von Google Drive verwendet und er funktioniert einwandfrei.
Jetzt habe ich ein Problem, ich muss in eine Markierung klicken und ein Bootstrap-Modal öffnen. Aber ich weiß nicht wirklich, wie ich das machen kann. Ich habe versucht, einen Ereignis-Listener beim Klicken zu verwenden und eine Warnung anzuzeigen, und es funktioniert, aber ich weiß nicht wirklich, wie man ein Bootstrap-Modal einfügt. Irgendwelche Ideen?

Vielen Dank :)

Hallo, ich habe eine Schaltfläche im Infofenster hinzugefügt, aber ich kann das Klickereignis nicht abfangen. Haben Sie eine Idee, wie es geht?

@andorfermichael
Hallo, danke für die Lösung. Könnten Sie bitte auch helfen, die Clusterfarben entsprechend den darin enthaltenen Markierungen zu ändern? Wie rot, gelb und blau.
Mit freundlichen Grüßen

@ vugar005 Ich verstehe nicht genau, was du mit dem Ändern der Farbe meinst. Sie können das Image des Clusters einfach entsprechend Ihren Anforderungen ändern. Soweit ich weiß, bietet die Marker-Cluster-Bibliothek von Google fünf verschiedene Bilder mit den Namen m1 bis m5 (m = Standard), die verwendet werden, wenn die Anzahl der Marker pro Cluster zunimmt. Ich kenne die genauen Schwellenwerte nicht. Weitere Informationen finden Sie unter Google Developers MapsDocumentation . Daher würde ich vorschlagen, fünf Bilder mit unterschiedlichen Farben zu erstellen und sie Cluster1 bis Cluster5 zu benennen und sie im Assets-Ordner abzulegen.

@AlexisNi Sie könnten versuchen, das domready-Ereignis im infoWindow anzuhören, das ausgelöst wird, wenn das

Der Inhalt des InfoWindows wird an das DOM angehängt.
google.maps.event.addListener(infoWindow, 'domready', function() {
  document.getElementById('info-window-button').addEventListener('click', function(){
    // run code here
  });
});

Weitere Informationen finden Sie in der Google Developers Maps-Dokumentation

@joaolbaptista Entschuldigung, aber Ihre Frage zu Bootstrap, obwohl in Kombination mit Google Maps-Markern, ist meiner Meinung nach nicht zum Thema. Ich würde vorschlagen, die gleiche Frage (etwas detaillierter) bei stackoverflow zu stellen ;)

@andorfermichael Eigentlich wollte ich das Symbol entsprechend der Anzahl der Marker in einem Cluster ändern. Deshalb habe ich auf die native Google Web-API umgestellt. Hope Angular Maps wird in Zukunft einen Cluster-Service bieten.
trotzdem danke

@ vugar005 Das habe ich versucht zu erklären. Selbst die native Google Maps-API bietet nur die Möglichkeit für fünf verschiedene Bilder. Jedes dieser Bilder wird angezeigt, wenn ein bestimmter Schwellenwert erreicht ist, z. B. Cluster1 (m1) 0 - 10, Cluster2 (m2) 11 - 100 usw.

Hallo @andorfermichael , haben Sie vielleicht eine Idee, warum nach dem Upgrade von Paketen plötzlich folgende Fehlermeldung

ReferenceError: MarkerClusterer is not defined
    at SafeSubscriber._next (marker-clusterer.ts:106)
    at SafeSubscriber.webpackJsonp.../../../../rxjs/Subscriber.js.SafeSubscriber.__tryOrUnsub (Subscriber.js:238)
    at SafeSubscriber.webpackJsonp.../../../../rxjs/Subscriber.js.SafeSubscriber.next (Subscriber.js:185)
    at Subscriber.webpackJsonp.../../../../rxjs/Subscriber.js.Subscriber._next (Subscriber.js:125)
    at Subscriber.webpackJsonp.../../../../rxjs/Subscriber.js.Subscriber.next (Subscriber.js:89)
    at SkipWhileSubscriber.webpackJsonp.../../../../rxjs/operator/skipWhile.js.SkipWhileSubscriber._next (skipWhile.js:52)
    at SkipWhileSubscriber.webpackJsonp.../../../../rxjs/Subscriber.js.Subscriber.next (Subscriber.js:89)
    at TakeSubscriber.webpackJsonp.../../../../rxjs/operator/take.js.TakeSubscriber._next (take.js:80)
    at TakeSubscriber.webpackJsonp.../../../../rxjs/Subscriber.js.Subscriber.next (Subscriber.js:89)
    at AsyncAction.webpackJsonp.../../../../rxjs/observable/IntervalObservable.js.IntervalObservable.dispatch (IntervalObservable.js:70)

@ Picosam . Ich hatte dieses Problem schon einmal. Das Problem ist, dass Sie keine Masterclusterer-JS-Datei importiert haben oder der Code Masterclusterer verwendet, bevor die Masterclusterer-JS-Datei importiert wird.

Vielen Dank @ vugar005 - die Sache ist, ich habe diesen Code schon eine ganze Weile nicht mehr berührt! Die .js -Datei ist in meiner .angular-cli.json und es ist wahr, dass ich keine import * as ... -Anweisung in meiner .ts -Datei habe. Als ich versuchte, die import -Anweisung manuell hinzuzufügen, wurde natürlich die Fehlermeldung angezeigt, dass .js -Erweiterungen nicht zulässig sind!

@picosam Gern geschehen . Ich bin froh, dass es dir geholfen hat.

Diese Funktion ist über das neue Paket @ agm / js-marker-clusterer (# 1044) verfügbar.

@SebastianM Vielen Dank, dass Sie diese Funktion in

@andorfermichael Dein Beispiel sieht gut aus! Vielen Dank für dieses Beispiel. In Ihrem Beispiel versuche ich, die Google Maps-API über die Indexseite einzuschließen, aber ich gerate immer wieder in Fehler wie Google nicht gefunden oder Marker-Clusterer nicht gefunden usw. Irgendwelche Gedanken?

@jpcode Hallo, danke für deine Lösung, es funktioniert, aber das Problem, dass ich, wenn ich die Direktive verwende, den Rest der Evenets, die wir in agm-marker haben, nicht kontrollieren kann. Gibt es eine Möglichkeit, es dem Agm-Marker hinzuzufügen? oder um die Ereignisse hinzuzufügen, die wir in agm-marker auf Ihrer Direktive haben?

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen