Angular-google-maps: Comment utiliser un clustereur de marqueurs?

Créé le 30 avr. 2016  ·  76Commentaires  ·  Source: SebastianM/angular-google-maps

Salut, des pointeurs sur l'utilisation de https://github.com/googlemaps/js-marker-clusterer ou de tout autre clusterer de marqueurs avec cela? Merci!

discussion / question

Commentaire le plus utile

@ siegerx3 C'est plus simple que cela

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
    });
  }
}

J'ai utilisé une directive car je n'avais pas besoin d'un modèle, vous pouvez utiliser un composant et en spécifier un si vous le souhaitez.

Il va sans dire que vous devez spécifier votre composant / directive personnalisé dans la section directives du composant où vous l'utilisez. Maintenant, déposez simplement votre composant dans la carte:

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

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

En raison du fonctionnement d'Angular2 DI, puisque nous ne spécifions pas de fournisseur pour le service GoogleMapsAPIWrapper, il remontera dans l'arborescence des composants jusqu'à ce qu'il en trouve un. Dans ce cas, c'est une étape et nous utilisons le GoogleMapsAPIWrapper qui a été fourni dans le composant sebm-google-map

Tous les 76 commentaires

non désolé, je n'ai aucun conseil que je pourrais vous donner maintenant

@SebastianM Je pense que cela peut être fait avec l'accès à l'objet de la carte, voir ici s'il vous plaît: https://github.com/SebastianM/angular2-google-maps/pull/311

Quelqu'un a-t-il réellement fait cela? les fichiers js markerclusterer ne semblent pas aimer l'objet map que je passe depuis .getMap ()

@AbdulTheProgrammer J'attendais ça pour entrer, mon plus grand espoir est que ça marche? Vous êtes sûr d'avoir appelé getMap () sur la même instance du service GoggleMapsAPIWrapper que celle utilisée par la directive map, c'est mon plus gros problème pour le moment ...

Je l'ai réalisé en utilisant un composant personnalisé et en l'incluant dans la sebm-google-map; il utilise GoogleMapsAPIWrapper et nativeMap.

J'ajoute les marqueurs manuellement à l'aide de l'api javascript de google maps (window.google.maps), puis en créant le MarkerClusterer.

J'espère que cela aide.

@ricardojbertolin Cela aide, comme Sebastian l'avait souligné ici # 311, un composant personnalisé à l'intérieur de la carte est exactement comment accéder à l'objet de carte natif, bien qu'il y ait sûrement un meilleur moyen d'ajouter les marqueurs en utilisant le service de gestion comme opposé à le faire manuellement via l'API js ...

J'ai également du mal à faire fonctionner js-marker-clusterer. J'obtiens une référence à l'instance de carte native, mais j'ai également besoin de références aux marqueurs de carte natifs. Quelqu'un a-t-il des idées sur la façon dont un peut obtenir les marqueurs de carte natifs pour mes <sebm-google-map-marker> s?

@alexweber
Avez-vous un exemple pour le composant personnalisé et GoogleMapsApiWrapper?
Je ne semble pas comprendre ce que signifie «placer un composant personnalisé à l'intérieur du composant».

@ siegerx3 C'est plus simple que cela

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
    });
  }
}

J'ai utilisé une directive car je n'avais pas besoin d'un modèle, vous pouvez utiliser un composant et en spécifier un si vous le souhaitez.

Il va sans dire que vous devez spécifier votre composant / directive personnalisé dans la section directives du composant où vous l'utilisez. Maintenant, déposez simplement votre composant dans la carte:

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

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

En raison du fonctionnement d'Angular2 DI, puisque nous ne spécifions pas de fournisseur pour le service GoogleMapsAPIWrapper, il remontera dans l'arborescence des composants jusqu'à ce qu'il en trouve un. Dans ce cas, c'est une étape et nous utilisons le GoogleMapsAPIWrapper qui a été fourni dans le composant sebm-google-map

@jfmaeck Il existe une méthode getNativeMarker() sur le service MarkerManager que vous pouvez utiliser pour cela, et vous pouvez obtenir la même instance de service de gestionnaire de marqueurs en utilisant la méthode décrite ci-dessus pour le wrapper.

@alexweber
En voyant le code, l'explication a du sens maintenant! Merci :)

@alexweber merci beaucoup pour votre indice sur la façon d'obtenir l'instance de marqueur natif. J'ai encore une question, cependant: la méthode getNativeMarker() du MarkerManager attend une instance SebmGoogleMapMarker (le composant marqueur) comme paramètre. Savez-vous comment je peux saisir ce composant dans une variable pour le transmettre à la fonction getNativeMarker?

@jfmaeck Pas de problème! Je ne peux pas vérifier pour être sûr à 100% pour le moment, mais vous pouvez probablement simplement utiliser @ViewChild('myMarker'): SebmGoogleMapMarker dans votre composant et le référencer avec un # dans le balisage: <sebm-google-map-marker #myMarker> juste rappelez-vous que ViewChild ne résout correctement que dans ngAfterViewInit .

@alexweber merci encore pour votre aide. Malheureusement, je n'ai pas réussi à accéder aux marqueurs en utilisant @ViewChildren. J'ai forké la démo sur Plunkr et y ai apporté quelques modifications afin que le résultat de ViewChildren soit enregistré dans la console (un tableau vide pour le moment):

markers after view init []

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

Je suppose que vous êtes assez occupé, mais si vous avez la chance de l'examiner, j'apprécierais vraiment cela.

@jfmaeck lorsque vous utilisez @ContentChildren (parce que vous voulez obtenir les instances qui vivent à l'intérieur de votre élément de composant), cela fonctionne: http://plnkr.co/edit/mukdlZ7K7CIFm6aTdDTp?p=preview

@jfmaeck Vous étiez proche, voici une fourchette de travail de votre plunk avec @ViewChildren : http://plnkr.co/edit/rJMCFoX9GokturcJljLh?p=preview

Pour le faire fonctionner en utilisant le composant de carte personnalisé @ContentChildren (comme @SebastianM l'a souligné) fonctionnerait mais je suppose que vous ne l'avez créé que pour accéder aux marqueurs et il n'est pas vraiment nécessaire d'avoir ce composant supplémentaire dans le première place.

Merci beaucoup @SebastianM et @alexweber!

@alexweber @SebastianM Tout d'abord, comment puis-je inclure cette bibliothèque que vous utilisez js-marker-clusterer? Existe-t-il un moyen d'utiliser des clusters à un niveau de zoom spécifique? Et comment puis-je inclure des images pour les clusters comme celui-ci: http://i65.tinypic.com/10gxkcw.png

@ricardojbertolin avez-vous une chance de partager votre code? Je suis très nouveau sur angular2 (je travaille avec angularjs depuis plus d'un an) et je suis un peu perdu.

@alexweber , avez-vous testé l'ajout de markerclusterer.js? un exemple lié?

@jpcode désolé non, je n'ai pas travaillé dessus depuis un moment ...

J'ai une solution de travail dans l'un de mes projets.
Si nécessaire, je peux monter un plunkr avec un exemple?
@jpcode
@alexweber

@ siegerx3 gentil, aidera beaucoup.
Je travaille en alternative simplement en utilisant google maps api + markerclusterer.js.

@ siegerx3 , librairie google maps:
https://plnkr.co/Tr1Ykkj12HCkF9InQmuW

POC en attente:
Dans la manière d'utiliser angular2-google-maps, je pense qu'il faut ajouter à l'intérieur pour éviter la collision avec des objets globaux comme "google".
Une solution de contournement sera d'empêcher le chargement de google à partir de la lib.
fournir (MapsAPILoader, {useClass: NoOpMapsAPILoader}) et charger par vous-même et ajouter clusterer.js.

Mais c'est mieux si angular2-google-maps ajoute une directive pour prendre en charge le clusterer :)

@jpcode
J'ai passé des heures à essayer de le faire fonctionner dans plunker ... sans aucun succès.
J'ai toujours eu des erreurs sans rapport avec le problème.
Donc je vais juste vous montrer le code ici ...

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);
          }
        })
    });
  }
}

Vous mettez cette directive dans la balise angular2-google-maps:

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

@ siegerx3 , j'ai créé un POC en utilisant angular2-google-maps

Approcher:

  • Ajouter des google maps à partir de index.html
  • import clusterer.js
  • empêcher le chargement de la bibliothèque de google maps depuis angular2-google-maps (en utilisant le fournisseur)
  • Ajouter une directive pour obtenir l'instance de la carte orignal à partir de la lib
  • utiliser des variables google / markercluster à utiliser comme globales

Vous pouvez également utiliser les autres directives d'angular-2-google-maps, mais je pense que c'est mieux si quelque chose est ajouté à la bibliothèque pour prendre en charge le clusterer.
->

parce que cela n'a pas de sens d'utiliser cette lib pour peindre une carte et ensuite simplement utiliser google maps, dans ce cas, je pense qu'il vaut mieux utiliser simplement google maps libs + clusterer.js comme avant le montre plunkr.

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;
}

Pour éviter de charger google maps deux fois, utilisez un fournisseur angular2-google-maps
dans la définition de votre composant, ajoutez un fournisseur

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
    }
  ],
})

Dans votre définition de modèle, vous devez ajouter la directive.

<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
Je suis d'accord que cela devrait être ajouté à la bibliothèque angular2-google-maps, bien que dans ma solution le sdk de cartes ne soit pas chargé deux fois, comme vous l'avez mentionné.

Je laisse simplement l'agm lib faire tout ce qu'il peut et je fais moi-même les pièces nécessaires.

@ siegerx3
pouvez-vous s'il vous plaît partager un exemple de travail dans un fichier zip?

@ hellsm83
J'en créerai un demain si ça te suffit :)
Connaissez-vous angular-cli? Sinon, je ferai juste un basique.

@ siegerx3
oui, un peu ... j'ai pu exécuter la mise en cluster à l'aide de google maps api + marker clusterer. je préférerais utiliser, à la place, angular2-google-maps ... afin d'avoir une vue complète de la solution.
tnx beaucoup pour votre aide

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

Juste npm install et ng serve . Si vous n'avez pas installé angular-cli en premier, npm install angular-cli -g .

N'oubliez pas que ce n'est pas la solution optimale. C'est juste une solution de contournement que j'ai faite car il n'y a pas encore de directive de cluster.

Éditer:
le formatage peut être bizarre car mon atome ne fonctionnait pas, donc j'utilisais le bon vieil éditeur ^^

@ siegerx3
Merci beaucoup. je vais vérifier cette solution :)

Y a-t-il une mise à jour sur ce qui est inclus dans angular 2 google maps? J'ai vraiment besoin de l'utiliser pour un projet sur lequel je travaille

@SteveDowsett
Vous pouvez toujours utiliser l'un des exemples fournis par des personnes dont moi :)
Si cela vous suffit bien sûr

@ hellsm83
Btw est-ce que tout a fonctionné? Cela vous a-t-il aidé?

@ siegerx3
Oui, cela m'a beaucoup aidé. Tnx!

@ siegerx3

J'ai utilisé votre exemple moi-même et je l'ai fait fonctionner à merveille, alors bravo!

Mais mon problème maintenant est que je n'arrive pas à mettre à jour les marqueurs. J'ai utilisé ngOnChanges pour transmettre un tableau de points mis à jour, et je peux voir le tableau changer, mais lorsque le tableau devient vide, les marqueurs ne sont pas supprimés.

Des conseils?

@nanomoffet
Super que cela ait aidé!

En fait, j'ai rencontré le même problème / un problème similaire il y a quelques jours, mais je n'avais pas encore le temps de trouver une solution.

Je posterai ici quand j'aurai trouvé quelque chose alors.

J'ai trouvé une solution au problème des clusters persistants.

        .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);

        });

J'ai déclaré markerCluster en dehors de l'Observable, puis s'il existe au début, il exécute une fonction appelée clearMarkers () qui supprimera tous les marqueurs existants de la carte, bien qu'il les laisse dans le tableau (d'où l'autre logique pour vider le tableau ).

Cela a résolu mon problème, peut-être que cela vous aidera aussi @ siegerx3

@nanomoffet

Je le vérifierai quand je travaillerai à nouveau sur cette partie, merci :)

salut les gars, merci pour ces conseils
j'ai réussi à obtenir le getNativeMap en utilisant un sous-composant
j'implémente un menu contextuel de carte
<sebm-google-map> <mapmenu-component></mapmenu-component>
le problème dans mon cas est que le modèle de sous-composant n'est pas visible
il est rendu dans le html en
<div class="sebm-google-map-content" _ngcontent-rgy-8="">
qui est un composant invisible

Suis-je capable de placer du HTML dans la sebm-google-map en principe?
je voudrais l'avoir au format HTML, sans utiliser OverlayView

j'ai pu le gérer en séparant la fonctionnalité en 2 composants (directive + composant)
1.) celui qui doit être à l'intérieur de sebm-google-map et sert d'accesseur à l'API
2.) celui qui doit être en dehors de sebm-google-map (car sinon je ne vois pas son html généré)

Salut l'équipe,
@ siegerx3 J'ai utilisé votre code de https://drive.google.com/open?id=0B4y4KJY7l3rPNTdqR0hyNTRqVHc
cela fonctionne très bien, mais je ne parviens pas à intégreret. Ce que j'essaie de réaliser, c'est d'intégrer le cluster + l'étiquette du marqueur + la fenêtre d'informations. Ainsi, lorsque je clique sur le cluster, les individus doivent avoir une étiquette de marqueur et en cliquant dessus, une fenêtre d'informations apparaît. Toute idée de comment je peux faire fonctionner cela @SebastianM

@sprakashg
Je pense que comme le cluster n'est pas encore implémenté dans le module et que vous n'utilisez pas les marqueurs du module, vous devez utiliser l'API native maps dans le même composant personnalisé qui est utilisé pour le clustering.
Ce qui signifie, ajouter le libellé et la fenêtre d'informations manuellement comme vous le feriez en javascript vanille.

@sprakashg

Je travaille moi-même sur cette même chose. J'ai dû passer à MarkerClustererPlus pour la bibliothèque, et j'utilise le code suivant pour activer les fenêtres d'informations pour les marqueurs individuels ainsi que les clusters eux-mêmes:

        .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(); });
          });

        });

Le seul problème est de savoir comment fermer les fenêtres du cluster - elles se ferment lorsque vous quittez la carte, mais pas lorsque vous quittez le cluster.

Est-ce que quelqu'un sait si nous pouvons utiliser des waypoints dans angular 2 mais en utilisant lat et lng comme référencé ici " https://developers.google.com/maps/documentation/javascript/reference#DirectionsWaypoint "?

@naranmistry pouvez-vous préciser un peu ce que vous voulez faire?

Je ne vois pas exactement quel est votre plan. Peut-être que quelqu'un d'autre comprend?

Fondamentalement, je veux pouvoir mettre des valeurs lng et lat dans le waypoint au lieu d'une chaîne, est-ce possible en utilisant angular2-google-maps? Comme je veux afficher un itinéraire avec plusieurs arrêts spécifiques en utilisant des valeurs de longitude et de lattidute

Si je comprends bien, alors je ne vois pas le connectino à ce module, mais en général, si vous regardez la documentation, il dit location Type: string|LatLng|Place . Donc oui, vous pouvez utiliser l'objet google maps LatLng qui prend les valeurs numériques dans son constructeur.

Est-ce ce dont vous aviez besoin?

Fondamentalement, je veux savoir comment, car j'ai essayé de le transmettre comme le dit la documentation, mais cela a continué à échouer. Existe-t-il un exemple fonctionnel de waypoints utilisant lat et lng?

Désolé pour la confusion, j'aurais dû être plus clair

Je ne pense pas. Mais si vous pouviez fournir votre code à titre d'exemple? Comme dans un plunkr, je pourrais voir ce que je peux trouver :)

D'accord, je vais essayer d'en mettre un ensemble

Merci

Pardon, puis-je intercepter _click event_ dans une _infowindow_ dans la directive _marker-cluster_ ou afficher un composant _sebm-google-map-info_ pour chaque marqueur?

Merci!

J'ai le même problème @fsciuti.
Avez-vous trouvé une solution ?

Puisque agm-maps ne prend toujours pas en charge les clusters, j'ai pris l'exemple de @ siegerx3 , l'amélioration des changements de marqueurs et l'exemple des fenêtres d'informations sur les marqueurs de @nanomoffet. Bon travail! Merci, vos exemples ont beaucoup aidé.

Pour rendre quelque chose en retour, je fournis une version mise à jour de l'exemple @ siegerx3 sous le lien suivant:

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

Les modifications suivantes ont été apportées:

  • dépendances mises à jour pour s'adapter à Angular 4.1 et @agm/core
  • code mis à jour pour s'adapter à Angular 4.1 et @agm/core
  • détection de changement de marqueur ajoutée
  • ajout d'un exemple de fenêtre d'informations sur les marqueurs
  • style de code fixe

@andorfermichael Merci beaucoup, vous êtes génial! Une question s'il vous plaît: si je veux externaliser le style de la directive (à la fois les marqueurs et les clusters), comment dois-je le faire? J'ai pensé à en faire simplement un composant, mais je ne sais pas comment alimenter correctement l'Observable avec les options et le style que vous avez ...

@picosam

Vous n'avez pas besoin d'un composant à la place, utilisez simplement des modules ES6.

Créez un nouveau fichier et exportez la configuration, par exemple:

_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]
};

puis dans _marker-cluster.ts_ importez ces variables / modules:

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

@andorfermichael danke noch mal !!!
Bien sûr, je peux alors utiliser des icônes complexes et tout ce qui est documenté dans la dernière version du module Javascript de Google Maps, n'est-ce pas?

@picosam je le pense mais je n'ai pas encore essayé

@andorfermichael C'est un travail remarquable 👍
mais je suis confronté à un petit problème

J'ai besoin de rediriger vers une autre route en cliquant sur l'infowindow, mais infowindow n'a pas d'événement de clic. J'ai donc utilisé à la place l'événement "closeclick", voici le code

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

Tout fonctionne bien mais lorsque je clique sur le bouton de fermeture de l'infowindow, l'événement est appelé mais il génère une erreur
this.router is undefined

_Bien sûr, la bibliothèque du routeur est importée et le routeur est défini dans le constructeur_

J'ai essayé une autre technique, j'ai utilisé l'émetteur d'événement (la technique d'entrée / sortie) entre le composant parent et la directive.
J'ai défini le @Output() eventEmitter = new EventEmitter() en haut comme une variable de classe,
Et l'événement au même endroit,

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

De plus, tout fonctionne bien mais lorsque je clique sur le bouton de fermeture de la fenêtre infowindow, l'événement est appelé mais il génère une erreur
this.eventEmitter is undefined

Existe-t-il un moyen de résoudre ce problème?

@ hossam-maurice Je suppose que l'erreur est causée par le this . Le this dans votre cas est l'élément qui a déclenché l'événement - l'infowindow. Pour cette raison, des fonctions fléchées ont été introduites dans ES6 / ECMAScript2015. En utilisant les fonctions fléchées, this ne dépend pas de la façon dont la fonction a été appelée mais de la portée environnante.
Donc infowindow.addListener('closeclick', () => { this.eventEmitter(id); }); devrait fonctionner pour vous.

Pour plus d'informations, consultez: ExploringJS - Fonctions fléchées et MDN - Fonctions fléchées

@andorfermichael Merci beaucoup, cela a fonctionné: D 👍

Bonjour, j'ai utilisé le cluster de marqueurs personnalisés de Google Drive et cela fonctionne très bien.
Maintenant, j'ai un problème, je dois cliquer sur un marqueur et ouvrir un modal bootstrap. Mais je ne sais pas vraiment comment je peux faire ça. J'ai essayé d'utiliser un écouteur d'événements en cliquant et en affichant une alerte et cela fonctionne, mais je ne sais pas vraiment comment faire apparaître un modal bootstrap. Des idées?

Merci :)

Bonjour, j'ai ajouté un bouton dans la fenêtre d'informations mais je ne parviens pas à attraper l'événement de clic.Avez-vous une idée sur la façon de le faire?

@andorfermichael
Salut merci pour la solution. Pourriez-vous s'il vous plaît également aider à changer les couleurs du cluster en fonction des marqueurs à l'intérieur. Tels que le rouge, le jaune et le bleu.
Cordialement

@ vugar005 Je ne comprends pas exactement ce que vous entendez par changer la couleur. Vous pouvez simplement changer l'image du cluster en fonction de vos besoins. Pour autant que je sache, la bibliothèque de clusters de marqueurs de Google fournit cinq images différentes nommées m1 à m5 (m = par défaut) qui sont utilisées à mesure que le nombre de marqueurs par cluster augmente. Je ne connais pas les seuils exacts. Plus d'informations sur Google Developers MapsDocumentation . Donc, je suggérerais de créer cinq images avec des couleurs différentes et de les nommer cluster1 à cluster5 et de les placer dans le dossier des actifs.

@AlexisNi vous pouvez essayer d'écouter l'événement domready sur infoWindow qui est déclenché lorsque le

contenant le contenu d'InfoWindow est attaché au DOM.
google.maps.event.addListener(infoWindow, 'domready', function() {
  document.getElementById('info-window-button').addEventListener('click', function(){
    // run code here
  });
});

Pour plus d'informations, consultez la documentation Google Developers Maps

@joaolbaptista désolé, mais votre question sur Bootstrap, même si elle est combinée avec des marqueurs Google Maps, est hors sujet à mon avis. Je suggérerais de poser la même question (un peu plus détaillée) à stackoverflow ;)

@andorfermichael Je voulais en fait dire changer l'icône en fonction du nombre de marqueurs à l'intérieur d'un cluster. C'est pourquoi je suis passé à l'API Web native de Google. Les cartes angulaires Hope fourniront un service de cluster à l'avenir.
Merci quand même

@ vugar005 C'est ce que j'ai essayé d'expliquer. Même l'API native de google maps ne donne la possibilité que de cinq images différentes. Chacune de ces images est affichée lorsqu'un seuil spécifique est atteint, par exemple, cluster1 (m1) 0 - 10, cluster2 (m2) 11 - 100 et ainsi de suite.

Bonjour @andorfermichael , pourriez-vous avoir une idée de la raison pour laquelle après la mise à niveau des packages, j'obtiens soudainement cette erreur:

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 . J'ai eu ce problème avant. Le problème est que vous n'avez pas importé le fichier js masterclusterer ou que le code utilise Masterclusterer avant l'importation du fichier js masterclusterer.

Merci beaucoup @ vugar005 - le fait est que je n'ai pas touché à ce code depuis un bon moment! Le fichier .js est inclus dans mon fichier .angular-cli.json et il est vrai que je n'ai pas import * as ... relevé .ts . Bien sûr, lorsque j'ai essayé d'ajouter manuellement l'instruction import , j'ai eu une erreur indiquant que les extensions .js ne sont pas autorisées!

@picosam Vous êtes les bienvenus. Heureux que cela vous ait aidé.

Cette fonctionnalité est disponible via le nouveau package @ agm / js-marker-clusterer (# 1044)

@SebastianM Merci d'avoir rendu cette fonctionnalité disponible dans angular-google-maps. J'essaie de faire fonctionner un événement de clic sur le clic du cluster, il semble actuellement indisponible. une solution de contournement pour le même?

@andorfermichael Votre exemple est superbe! merci pour cet exemple. dans votre exemple, j'essaie d'inclure l'API de google maps via la page d'index mais je continue à entrer dans des erreurs comme google non trouvé ou clusterer de marqueurs non trouvé, etc. des pensées?

@jpcode salut merci pour votre solution, ça marche, mais le problème que si j'utilise la directive je ne peux pas contrôler le reste des evenets que nous avons dans agm-marker. y a-t-il un moyen de l'ajouter à agm-marker? ou pour ajouter les événements que nous avons dans agm-marker sur votre directive?

Cette page vous a été utile?
0 / 5 - 0 notes

Questions connexes

shedar picture shedar  ·  4Commentaires

nthonymiller picture nthonymiller  ·  4Commentaires

alexweber picture alexweber  ·  4Commentaires

stot3 picture stot3  ·  3Commentaires

supran2811 picture supran2811  ·  4Commentaires