Angular-google-maps: ¿Cómo utilizar un Marker Clusterer?

Creado en 30 abr. 2016  ·  76Comentarios  ·  Fuente: SebastianM/angular-google-maps

Hola, ¿algún consejo sobre el uso de https://github.com/googlemaps/js-marker-clusterer o cualquier otro clusterer de marcadores con esto? ¡Gracias!

discussion / question

Comentario más útil

@ siegerx3 Es más simple que

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

Usé una directiva porque no necesitaba una plantilla, puede usar un componente y especificar uno si lo desea.

No hace falta decir que necesita especificar su componente / directiva personalizada en la sección directives del componente donde lo está utilizando. Ahora simplemente suelte su componente dentro del mapa:

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

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

Debido a la forma en que funciona Angular2 DI, dado que no estamos especificando un proveedor para el servicio GoogleMapsAPIWrapper, subirá por el árbol de componentes hasta que encuentre uno. En este caso, es 1 paso y usamos GoogleMapsAPIWrapper que se proporcionó en el componente sebm-google-map

Todos 76 comentarios

no lo siento, no tengo ningún consejo que pueda darte ahora mismo

@SebastianM Creo que se puede hacer con acceso al objeto del mapa, vea aquí por favor: https://github.com/SebastianM/angular2-google-maps/pull/311

¿Alguien ha hecho esto realmente? a los archivos markerclusterer js no parece gustarles el objeto de mapa que paso desde .getMap ()

@AbdulTheProgrammer He estado esperando esto para entrar, ¿mi mayor esperanza es que funcione? Está seguro de que llamó a getMap () en la misma instancia del servicio GoggleMapsAPIWrapper que el utilizado por la directiva del mapa, ese es mi mayor problema en este momento ...

Lo logré usando un componente personalizado e incluyéndolo dentro del sebm-google-map; utiliza GoogleMapsAPIWrapper y nativeMap.

Agrego los marcadores manualmente usando la API de JavaScript de Google Maps (window.google.maps) y luego creando el MarkerClusterer.

Espero que ayude.

@ricardojbertolin Eso ayuda, como Sebastian había señalado aquí # 311, un componente personalizado dentro del mapa es exactamente cómo obtener acceso al objeto de mapa nativo, aunque seguramente debe haber una mejor manera de agregar los marcadores usando el servicio de administrador como opuesto a hacerlo manualmente a través de la api js ...

También estoy luchando para que funcione js-marker-clusterer. Obtengo una referencia a la instancia de mapas nativos, sin embargo, también necesito referencias a los marcadores de mapas nativos. ¿Alguien tiene alguna idea de cómo puedo obtener los marcadores de mapa nativos para mis <sebm-google-map-marker> s?

@alexweber
¿Tiene un ejemplo para el componente personalizado y GoogleMapsApiWrapper?
Parece que no entiendo qué significa "colocar un componente personalizado dentro del componente".

@ siegerx3 Es más simple que

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

Usé una directiva porque no necesitaba una plantilla, puede usar un componente y especificar uno si lo desea.

No hace falta decir que necesita especificar su componente / directiva personalizada en la sección directives del componente donde lo está utilizando. Ahora simplemente suelte su componente dentro del mapa:

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

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

Debido a la forma en que funciona Angular2 DI, dado que no estamos especificando un proveedor para el servicio GoogleMapsAPIWrapper, subirá por el árbol de componentes hasta que encuentre uno. En este caso, es 1 paso y usamos GoogleMapsAPIWrapper que se proporcionó en el componente sebm-google-map

@jfmaeck Hay un método getNativeMarker() en el servicio MarkerManager que puede usar para eso, y puede obtener la misma instancia de servicio del administrador de marcadores usando el método descrito anteriormente para el contenedor.

@alexweber
Al ver el código, ¡la explicación tiene sentido ahora! Gracias :)

@alexweber muchas gracias por su pista sobre cómo obtener la instancia de marcador nativo. Sin embargo, todavía tengo una pregunta: el método getNativeMarker() del MarkerManager espera una instancia SebmGoogleMapMarker (el componente marcador) como parámetro. ¿Sabes cómo puedo tomar este componente en una variable para pasarlo a la función getNativeMarker?

@jfmaeck ¡ No hay problema! No puedo verificar para estar 100% seguro en este momento, pero probablemente pueda usar @ViewChild('myMarker'): SebmGoogleMapMarker en su componente y hacer referencia a él con un # en el marcado: <sebm-google-map-marker #myMarker> solo recuerde que ViewChild solo se resuelve correctamente en ngAfterViewInit .

@alexweber gracias de nuevo por tu ayuda. Desafortunadamente, no pude acceder a los marcadores usando @ViewChildren. Bifurqué la demostración en Plunkr e hice algunos cambios para que el resultado de ViewChildren se registre en la consola (una matriz vacía en este momento):

markers after view init []

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

Supongo que estás bastante ocupado, pero si tienes la oportunidad de verlo, te lo agradecería mucho.

@jfmaeck cuando usa @ContentChildren (porque desea obtener las instancias que viven dentro de su elemento componente), funciona: http://plnkr.co/edit/mukdlZ7K7CIFm6aTdDTp?p=preview

@jfmaeck Estuviste cerca, aquí tienes una bifurcación funcional de tu plunk con @ViewChildren : http://plnkr.co/edit/rJMCFoX9GokturcJljLh?p=preview

Para que funcione usando el componente de mapa personalizado @ContentChildren (como señaló @SebastianM ) funcionaría, pero supongo que solo lo creó para obtener acceso a los marcadores y no es realmente necesario tener ese componente adicional en el primer lugar.

¡Muchas gracias @SebastianM y @alexweber!

@alexweber @SebastianM En primer lugar, ¿cómo http://i65.tinypic.com/10gxkcw.png

@ricardojbertolin ¿Alguna posibilidad de que puedas compartir tu código? Soy muy nuevo en angular2 (he estado trabajando con angularjs durante más de un año) y estoy un poco perdido.

@alexweber , ¿probaste agregar markerclusterer.js? algún ejemplo relacionado?

@jpcode lo siento, no, no he trabajado en esto en un tiempo ...

Tengo una solución funcional en uno de mis proyectos.
Si es necesario, ¿puedo armar un plunkr con un ejemplo?
@jpcode
@alexweber

@ siegerx3 agradable, ayudará mucho.
Estoy trabajando en una alternativa solo usando google maps api + markerclusterer.js.

@ siegerx3 , este es un ejemplo básico simplemente usando google maps lib:
https://plnkr.co/Tr1Ykkj12HCkF9InQmuW

POC pendiente:
En la forma de usar angular2-google-maps, creo que es necesario agregarlo adentro para evitar la colisión con objetos globales como "google".
Una solución alternativa será evitar que Google cargue desde lib.
proporcione (MapsAPILoader, {useClass: NoOpMapsAPILoader}) y cárguelo usted mismo y agregue clusterer.js.

Pero es mejor si angular2-google-maps agrega una directiva para admitir clusterer :)

@jpcode
Pasé horas tratando de que funcionara en plunker ... sin ningún éxito.
Siempre tengo algunos errores no relacionados con el problema.
Así que solo te mostraré el código aquí ...

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

Pones esta directiva en la etiqueta angular2-google-maps:

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

@ siegerx3 , hice un POC usando angular2-google-maps

Acercarse:

  • Agregar mapas de Google desde index.html
  • importar clusterer.js
  • evitar cargar google maps lib desde angular2-google-maps (usando el proveedor)
  • Agregue una directiva para obtener la instancia del mapa original de lib
  • usar variables de google / markercluster para usar como globales

También puede usar las otras directivas de angular-2-google-maps, pero creo que es mejor si se agrega algo a la biblioteca para admitir clusterer.
->

porque no tiene sentido usar esta lib para pintar un mapa y luego solo usar google maps, en este caso creo que es mejor usar solo google maps libs + clusterer.js como muestra antes 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;
}

En la forma de evitar la carga de mapas de Google, use dos veces un proveedor de angular2-google-maps
en la definición de su componente agregue un proveedor

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

En la definición de su plantilla, debe agregar la directiva.

<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
Estoy de acuerdo en que esto debería agregarse a la biblioteca angular2-google-maps, aunque en mi solución el sdk de mapas no se carga dos veces, tal como mencionaste.

Dejo que agm lib haga todo lo que pueda y yo mismo hago las partes necesarias.

@ siegerx3
¿Puede compartir un ejemplo práctico en un archivo zip?

@ hellsm83
Crearé uno mañana si eso es suficiente para ti :)
¿Está familiarizado con angular-cli? De lo contrario, solo haré uno básico.

@ siegerx3
sí, un poco ... pude ejecutar la clusterización usando google maps api + marker clusterer. Preferiría usar, en su lugar, angular2-google-maps ... para tener una vista completa de la solución.
tnx mucho por tu ayuda

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

Solo npm install y ng serve . Si no tiene instalado angular-cli npm install angular-cli -g primero.

Recuerde, esta no es la solución óptima. Es solo una solución alternativa que hice porque aún no hay una directiva de clúster.

editar:
el formateo puede ser extraño ya que mi átomo no funcionaba, así que estaba usando el viejo editor ^^

@ siegerx3
muchas gracias. Verificaré esta solución :)

¿Hay alguna actualización sobre esto que se incluye en los mapas de Google de angular 2? Realmente necesito usarlo para un proyecto en el que estoy trabajando

@SteveDowsett
Todavía puede usar uno de los ejemplos que las personas, incluido yo, han proporcionado :)
Si es suficiente para ti por supuesto

@ hellsm83
Por cierto, ¿todo funcionó? ¿Te ayudó?

@ siegerx3
Sí, me ayudó mucho. ¡Tnx!

@ siegerx3

Usé tu ejemplo yo mismo y lo hice funcionar muy bien, ¡así que felicitaciones!

Pero mi problema ahora es que parece que no puedo actualizar los marcadores. Usé ngOnChanges para pasar una matriz actualizada de puntos, y puedo ver que la matriz cambia, pero cuando la matriz se vacía, los marcadores no se eliminan.

¿Algun consejo?

@nanomoffet
¡Genial que ayudó!

En realidad, me encontré con el mismo / un problema similar hace unos días, pero aún no tenía tiempo para encontrar una solución.

Publicaré aquí cuando encuentre algo entonces.

Encontré una solución para el problema de los clústeres persistentes.

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

        });

Declaré markerCluster fuera del Observable, y luego, si existe al principio, ejecuta una función llamada clearMarkers () que eliminará cualquier marcador existente del mapa, aunque los deja en la matriz (de ahí la otra lógica para vaciar la matriz ).

Eso solucionó mi problema, tal vez también te ayude @ siegerx3

@nanomoffet

Lo comprobaré cuando vuelva a trabajar en esa parte, gracias :)

hola chicos, gracias por estas pistas
logré obtener el getNativeMap usando un subcomponente
estoy implementando un menú contextual de mapa
<sebm-google-map> <mapmenu-component></mapmenu-component>
el problema en mi caso es que la plantilla del subcomponente no es visible
se representa en el html en
<div class="sebm-google-map-content" _ngcontent-rgy-8="">
que es un componente invisible

¿Puedo colocar algo de html dentro del sebm-google-map en principio?
me gustaría tenerlo como html, sin usar OverlayView

pude manejarlo separando la funcionalidad en 2 componentes (directiva + componente)
1.) uno que tiene que estar dentro de sebm-google-map y sirve como acceso a la API
2.) uno que tiene que estar fuera de sebm-google-map (porque de lo contrario no veo su html generado)

Hola, equipo,
@ siegerx3 Usé su código de https://drive.google.com/open?id=0B4y4KJY7l3rPNTdqR0hyNTRqVHc
funciona muy bien, pero no puedo integrary. Lo que estoy tratando de lograr es integrar clúster + etiqueta de marcador + ventana de información. Entonces, cuando hago clic en el grupo, las personas deben tener una etiqueta de marcador y al hacer clic en ella debe aparecer una ventana de información. Alguna idea de cómo puedo hacer que esto funcione @SebastianM

@sprakashg
Creo que dado que el clúster aún no está implementado en el módulo y no está usando los marcadores del módulo, debe usar la API de mapas nativos en el mismo componente personalizado que se usa para el clúster.
Es decir, agregar la etiqueta y la ventana de información manualmente como lo haría en JavaScript vanilla.

@sprakashg

De hecho, estoy trabajando en esto mismo. Tuve que cambiar a MarkerClustererPlus para la biblioteca, y estoy usando el siguiente código para habilitar ventanas de información para marcadores individuales, así como para los propios clústeres:

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

        });

El único problema es averiguar cómo cerrar las ventanas del clúster: se cierran cuando abandona el mapa, pero no cuando abandona el clúster.

¿Alguien sabe si podemos usar waypoints en angular 2 pero usando lat y lng como se hace referencia aquí " https://developers.google.com/maps/documentation/javascript/reference#DirectionsWaypoint "?

@naranmistry ¿puedes especificar un poco lo que quieres hacer?

No veo cuál es exactamente tu plan. ¿Quizás alguien más lo entienda?

Básicamente, quiero poder poner valores de lng y lat en el punto de ruta en lugar de una cadena, ¿es esto posible usando angular2-google-maps? Como quiero mostrar una ruta con múltiples paradas específicas usando valores de longitud y lattidute

Si entiendo correctamente, entonces no veo el connectino a este módulo, pero en general, si miras la documentación dice location Type: string|LatLng|Place . Entonces, sí, puede usar el objeto LatLng de google maps que toma los valores numéricos en su constructor.

¿Es eso lo que necesitabas?

Básicamente, quiero saber cómo, ya que intenté pasarlo como dice la documentación, pero siguió fallando. ¿Existe un ejemplo práctico de waypoints que utilicen lat y lng?

Perdón por la confusión, debería haber sido más claro

No lo creo. ¿Pero si pudiera proporcionar su código como ejemplo? Como en un plunkr, pude ver lo que puedo encontrar :)

Está bien, intentaré armar uno

Gracias

Lo siento, ¿puedo interceptar _click event_ en una _infowindow_ dentro de la directiva _marker-cluster_ o representar un componente _sebm-google-map-info_ para cada marcador?

¡Gracias!

Tengo el mismo problema @fsciuti.
Encontraste una solución ?

Como agm-maps todavía no admite clústeres, tomé el ejemplo de @ siegerx3 , la mejora en los cambios de marcador y el ejemplo de ventanas de información de marcador de @nanomoffet. ¡Buen trabajo! Gracias, tus ejemplos ayudaron mucho.

Para devolver algo, proporciono una versión actualizada del ejemplo de @ siegerx3 en el siguiente enlace:

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

Se han realizado los siguientes cambios:

  • dependencias actualizadas para adaptarse a Angular 4.1 y @agm/core
  • código actualizado para adaptarse a Angular 4.1 y @agm/core
  • detección de cambio de marcador añadido
  • ejemplo de ventana de información de marcador añadido
  • estilo de código fijo

@andorfermichael Gracias a todos, ¡eres genial! Una pregunta, por favor: si quiero externalizar el estilo de la directiva (tanto marcadores como clústeres), ¿cómo debo hacerlo? Pensé simplemente en convertirlo en un componente, pero luego no sé cómo alimentar el Observable correctamente con las opciones y el estilo que tienes ...

@picosam

No necesita un componente, solo use módulos ES6.

Cree un nuevo archivo y exporte la configuración, por ejemplo:

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

y luego en _marker-cluster.ts_ importar esas variables / módulos:

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

@andorfermichael danke noch mal !!!
Por supuesto, puedo seguir adelante y usar íconos complejos y todo lo que está documentado en la última versión del módulo Javascript de Google Maps, ¿correcto?

@picosam Creo que sí, pero aún no lo he probado.

@andorfermichael Este es un trabajo extraordinario 👍
pero estoy enfrentando un pequeño problema

Necesito redirigir a otra ruta haciendo clic en la ventana de información, pero la ventana de información no tiene un evento de clic. En su lugar, utilicé el evento "closeclick", aquí está el código

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

Todo funciona bien, pero cuando hago clic en el botón de cierre de la ventana de información, se llama al evento pero arroja un error
this.router is undefined

_Por supuesto, la biblioteca del enrutador se importa y el enrutador se define en el constructor_

Probé otra técnica, usé el eventemitter (la técnica de entrada / salida) entre el componente principal y la directiva.
Definí el @Output() eventEmitter = new EventEmitter() en la parte superior como una variable de clase,
Y el evento en el mismo lugar,

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

También todo funciona bien, pero cuando hago clic en el botón de cierre de la ventana de información, se llama al evento pero arroja un error
this.eventEmitter is undefined

¿Hay alguna forma de solucionar este problema?

@ hossam-maurice Supongo que el error se debe al this . El this en su caso es el elemento que disparó el evento: la ventana de información. Por esa razón, las funciones de flecha se han introducido en ES6 / ECMAScript2015. Usando funciones de flecha, this no depende de cómo se llamó a la función sino del alcance circundante.
Entonces infowindow.addListener('closeclick', () => { this.eventEmitter(id); }); debería funcionar para usted.

Para mayor referencia, eche un vistazo a: ExploringJS - Funciones de flecha y MDN - Funciones de flecha

@andorfermichael Muchas gracias, funcionó: D 👍

Hola, utilicé el grupo de marcadores personalizados de Google Drive y funciona bien.
Ahora tengo un problema, necesito hacer clic en un marcador y abrir un modal de arranque. Pero realmente no sé cómo puedo hacer esto. Intenté usar un detector de eventos al hacer clic y mostrar una alerta y funciona, pero realmente no sé cómo hacer estallar un modal de arranque. ¿Algunas ideas?

Gracias :)

Hola, agregué un botón dentro de la ventana de información pero no puedo capturar el evento de clic ¿Tienes alguna idea de cómo hacerlo?

@andorfermichael
Hola, gracias por la solución. ¿Podría ayudar también a cambiar los colores del grupo de acuerdo con los marcadores que contiene? Como rojo, amarillo y azul.
Saludos cordiales

@ vugar005 No entiendo exactamente a qué te refieres con cambiar el color. Simplemente puede cambiar la imagen del clúster según sus necesidades. Hasta donde yo sé, la biblioteca de grupos de marcadores de Google proporciona cinco imágenes diferentes llamadas m1 a m5 (m = predeterminado) que se utilizan a medida que crece la cantidad de marcadores por grupo. No conozco los umbrales exactos. Más información en Google Developers MapsDocumentation . Por lo tanto, sugeriría crear cinco imágenes con diferentes colores y nombrarlas cluster1 a cluster5 y colocarlas dentro de la carpeta de activos.

@AlexisNi , podría intentar escuchar el evento domready en la ventana de información que se activa cuando el

que contiene el contenido de InfoWindow se adjunta al DOM.
google.maps.event.addListener(infoWindow, 'domready', function() {
  document.getElementById('info-window-button').addEventListener('click', function(){
    // run code here
  });
});

Para obtener más información, eche un vistazo a Google Developers Maps Documention.

@joaolbaptista lo siento, pero en mi opinión, su pregunta sobre Bootstrap, aunque se combina con los marcadores de Google Maps, está fuera de tema. Sugeriría hacer la misma pregunta (un poco más detallada) en stackoverflow ;)

@andorfermichael En realidad me refería a cambiar el icono de acuerdo con la cantidad de marcadores dentro de un clúster. Por eso cambié a la API web nativa de Google. Los mapas angulares de Hope proporcionarán servicio de clúster en el futuro.
gracias de todos modos

@ vugar005 Eso es lo que traté de explicar. Incluso la API nativa de Google Maps solo ofrece la posibilidad de cinco imágenes diferentes. Cada una de estas imágenes se muestra cuando se alcanza un umbral específico, por ejemplo, cluster1 (m1) 0 - 10, cluster2 (m2) 11 - 100 y así sucesivamente.

Hola @andorfermichael , ¿podría tener alguna idea de por qué después de actualizar los paquetes de repente

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 . Tuve este problema antes. El problema es que no importó el archivo masterclusterer js o el código usa Masterclusterer antes de importar el archivo masterclusterer js.

Muchas gracias @ vugar005 , ¡la cosa es que no he tocado ese código durante bastante tiempo! El archivo .js está incluido en mi .angular-cli.json y es cierto que no tengo una instrucción import * as ... en mi archivo .ts . Por supuesto, cuando intenté agregar manualmente la declaración import , ¡recibí un error de que las extensiones .js no están permitidas!

@picosam De

Esta función está disponible a través del nuevo paquete @ agm / js-marker-clusterer (# 1044)

@SebastianM Gracias por hacer que esta función esté disponible en angular-google-maps. Estoy tratando de que un evento de clic funcione en el clic del clúster, parece que actualmente no está disponible. alguna solución para el mismo?

@andorfermichael ¡ Tu ejemplo se ve genial! gracias por dar ese ejemplo. en su ejemplo, estoy tratando de incluir la API de Google Maps a través de la página de índice, pero sigo teniendo errores como Google no encontrado o Clusterer de marcador no encontrado, etc. ¿Alguna idea?

@jpcode hola gracias por su solución, funciona, pero el problema es que si uso la directiva no puedo controlar el resto de los evenets que tenemos en agm-marker. ¿Hay alguna forma de agregarlo a agm-marker? ¿O para agregar los eventos que tenemos en agm-marker en su directiva?

¿Fue útil esta página
0 / 5 - 0 calificaciones

Temas relacionados

maneesht picture maneesht  ·  3Comentarios

PeterSisovsky picture PeterSisovsky  ·  3Comentarios

alexweber picture alexweber  ·  4Comentarios

Halynsky picture Halynsky  ·  3Comentarios

shedar picture shedar  ·  4Comentarios