Angular-google-maps: Como usar um Marker Clusterer?

Criado em 30 abr. 2016  ·  76Comentários  ·  Fonte: SebastianM/angular-google-maps

Olá, alguma indicação sobre como usar https://github.com/googlemaps/js-marker-clusterer ou qualquer outro clusterer de marcador com isso? Obrigado!

discussion / question

Comentários muito úteis

@ siegerx3 É mais simples do que parece, primeiro crie um componente ou diretiva personalizada:

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

Usei uma diretiva porque não precisava de um template, você pode usar um componente e especificar um se quiser.

Nem é preciso dizer que você precisa especificar seu componente / diretiva personalizada na seção directives do componente em que está usando. Agora, basta soltar seu componente dentro do mapa:

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

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

Devido à forma como o Angular2 DI funciona, já que não estamos especificando um provedor para o serviço GoogleMapsAPIWrapper, ele irá subir na árvore de componentes até encontrar um. Neste caso, é 1 etapa acima e usamos o GoogleMapsAPIWrapper que foi fornecido no componente sebm-google-map

Todos 76 comentários

não, desculpe, não tenho nenhum conselho que possa lhe dar agora

@SebastianM Acho que pode ser feito com acesso ao objeto do mapa, veja aqui: https://github.com/SebastianM/angular2-google-maps/pull/311

Alguém realmente fez isso? os arquivos markerclusterer js não parecem gostar do objeto de mapa que passei de .getMap ()

@AbdulTheProgrammer Estou esperando por isso, minha maior esperança é que funcione? Você tem certeza que chamou getMap () na mesma instância do serviço GoggleMapsAPIWrapper que o usado pela diretiva do mapa, esse é o meu maior problema no momento ...

Consegui isso usando um componente personalizado e incluindo-o dentro do sebm-google-map; ele usa o GoogleMapsAPIWrapper e o nativeMap.

Eu adiciono os marcadores manualmente usando o google maps javascript api (window.google.maps) e, em seguida, crio o MarkerClusterer.

Espero que ajude.

@ricardojbertolin Isso ajuda, como Sebastian havia apontado aqui # 311, um componente personalizado dentro do mapa é exatamente como obter acesso ao objeto do mapa nativo, embora certamente deva haver uma maneira melhor de adicionar os marcadores usando o serviço de gerenciamento como opõe-se a fazê-lo manualmente através da API js ...

Também estou lutando para fazer o js-marker-clusterer funcionar. Recebo uma referência para a instância de mapas nativos, no entanto, também preciso de referências para os marcadores de mapa nativos. Alguém tem alguma ideia de como posso obter os marcadores de mapa nativos para meus <sebm-google-map-marker> s?

@alexweber
Você tem um exemplo para o componente personalizado e o GoogleMapsApiWrapper?
Não pareço entender o que significa "colocar um componente personalizado dentro do componente".

@ siegerx3 É mais simples do que parece, primeiro crie um componente ou diretiva personalizada:

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

Usei uma diretiva porque não precisava de um template, você pode usar um componente e especificar um se quiser.

Nem é preciso dizer que você precisa especificar seu componente / diretiva personalizada na seção directives do componente em que está usando. Agora, basta soltar seu componente dentro do mapa:

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

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

Devido à forma como o Angular2 DI funciona, já que não estamos especificando um provedor para o serviço GoogleMapsAPIWrapper, ele irá subir na árvore de componentes até encontrar um. Neste caso, é 1 etapa acima e usamos o GoogleMapsAPIWrapper que foi fornecido no componente sebm-google-map

@jfmaeck Há um método getNativeMarker() no serviço MarkerManager que você pode usar para isso e pode obter a mesma instância de serviço do gerenciador de marcadores usando o método descrito acima para o wrapper.

@alexweber
Vendo o código, a explicação faz sentido agora! Obrigado :)

@alexweber muito obrigado por sua dica sobre como obter a instância do marcador nativo. Ainda tenho uma pergunta, porém: o método getNativeMarker() do MarkerManager espera uma instância SebmGoogleMapMarker (o componente marcador) como seu parâmetro. Você sabe como posso pegar esse componente em uma variável para passá-lo para a função getNativeMarker?

@jfmaeck Não tem problema! Não posso verificar para ter 100% de certeza no momento, mas você provavelmente pode apenas usar @ViewChild('myMarker'): SebmGoogleMapMarker em seu componente e referenciá-lo com # na marcação: <sebm-google-map-marker #myMarker> apenas lembre-se de que ViewChild só resolve corretamente em ngAfterViewInit .

@alexweber, obrigado novamente por sua ajuda. Infelizmente, não consegui acessar os marcadores usando @ViewChildren. Eu fiz um fork da demonstração no Plunkr e fiz algumas alterações para que o resultado ViewChildren seja registrado no console (uma matriz vazia no momento):

markers after view init []

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

Acho que você está muito ocupado, mas se tiver a chance de dar uma olhada, eu realmente apreciaria.

@jfmaeck quando você usa @ContentChildren (porque deseja obter as instâncias que residem dentro de seu elemento de componente), funciona: http://plnkr.co/edit/mukdlZ7K7CIFm6aTdDTp?p=preview

@jfmaeck Você estava perto, aqui está uma bifurcação funcional do seu golpe com @ViewChildren : http://plnkr.co/edit/rJMCFoX9GokturcJljLh?p=preview

Para fazê-lo funcionar usando o componente de mapa personalizado @ContentChildren (como @SebastianM apontou) funcionaria, mas presumo que você o criou apenas para obter acesso aos marcadores e não é realmente necessário ter esse componente extra no primeiro lugar.

Muito obrigado @SebastianM e @alexweber!

@alexweber @SebastianM Em primeiro lugar, como faço para incluir esta biblioteca que você usa js-marker-clusterer? Existe uma maneira de usar clusters em um nível de zoom específico? E como faço para incluir imagens para os clusters como este: http://i65.tinypic.com/10gxkcw.png

@ricardojbertolin alguma chance de você compartilhar seu código? Sou muito novo no angular2 (trabalho com o angularjs há mais de um ano) e estou um pouco perdido.

@alexweber , você testou a adição de markerclusterer.js? algum exemplo relacionado?

@jpcode desculpe não, não trabalho nisso há um tempo ...

Tenho uma solução de trabalho em um dos meus projetos.
Se necessário, posso montar um plunkr com um exemplo?
@jpcode
@alexweber

@ siegerx3 legal, vai ajudar muito.
estou trabalhando em alternativa apenas usando google maps api + markerclusterer.js.

@ siegerx3 , este é um exemplo básico usando apenas o lib do google maps:
https://plnkr.co/Tr1Ykkj12HCkF9InQmuW

POC pendente:
Na forma de usar o angular2-google-maps, acho que precisa ser adicionado dentro para evitar a colisão com objetos globais como "google".
Uma solução alternativa será impedir o carregamento do google da lib.
forneça (MapsAPILoader, {useClass: NoOpMapsAPILoader}) e carregue você mesmo e adicione clusterer.js.

Mas é melhor se angular2-google-maps adicionar uma diretiva para oferecer suporte a clusterer :)

@jpcode
Passei horas tentando fazê-lo funcionar no êmbolo ... sem sucesso.
Sempre recebo alguns erros não relacionados ao assunto.
Então, vou apenas mostrar o código aqui ...

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

Você coloca esta diretiva na tag angular2-google-maps:

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

@ siegerx3 , fiz um POC usando angular2-google-maps

Abordagem:

  • Adicione mapas do google de index.html
  • import clusterer.js
  • evitar carregar lib do google maps do angular2-google-maps (usando o provedor)
  • Adicione uma diretiva para obter a instância do mapa original de lib
  • use variáveis ​​google / markercluster para usar como globais

Você também pode usar as outras diretivas do angular-2-google-maps, mas acho melhor se algo for adicionado à biblioteca para oferecer suporte ao clusterer.
->

porque não faz sentido usar esta lib para pintar um mapa e em seguida usar apenas o google maps, neste caso eu acho melhor usar apenas libs do google maps + clusterer.js como antes do plunkr mostrar

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

Para evitar o carregamento do google maps duas vezes, use um provedor do angular2-google-maps
em sua definição de componente, adicione um provedor

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

Em sua definição de modelo, você precisa adicionar a diretiva.

<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
Concordo que isso deve ser adicionado à biblioteca angular2-google-maps, embora na minha solução o sdk de mapas não seja carregado duas vezes, como você mencionou.

Eu apenas deixo o agm lib fazer o máximo possível e faço as partes necessárias sozinho.

@ siegerx3
você pode compartilhar um exemplo funcional em um arquivo zip?

@ hellsm83
Vou criar um amanhã se isso for suficiente para você :)
Você está familiarizado com o angular-cli? Caso contrário, farei apenas um básico.

@ siegerx3
sim, um pouco ... consegui executar a clusterização usando google maps api + marker clusterer. Eu preferiria usar, em vez disso, angular2-google-maps ... para ter uma visão completa da solução.
Muito obrigado pela sua ajuda

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

Apenas npm install e ng serve . Se você não instalou o angular-cli npm install angular-cli -g primeiro.

Lembre-se de que esta não é a solução ideal. É apenas uma solução alternativa que fiz porque ainda não há uma diretiva de cluster.

editar:
a formatação pode ser estranha, já que meu átomo não estava funcionando, então eu estava usando o bom e velho editor ^^

@ siegerx3
Muito obrigado. Vou verificar esta solução :)

Existe alguma atualização sobre isso ser incluído no angular 2 google maps? Eu realmente preciso usá-lo para um projeto em que estou trabalhando

@SteveDowsett
Você ainda pode usar um dos exemplos que pessoas incluindo eu fornecemos :)
Se for suficiente para você é claro

@ hellsm83
A propósito, tudo funcionou? Isso te ajudou?

@ siegerx3
Sim, me ajudou muito. Tnx!

@ siegerx3

Eu usei seu exemplo e fiz com que funcionasse muito bem, parabéns!

Mas meu problema agora é que não consigo atualizar os marcadores. Eu usei ngOnChanges para passar um array atualizado de pontos e posso ver o array mudando, mas quando o array fica vazio, os marcadores não são removidos.

Alguma dica?

@nanomoffet
Que bom que ajudou!

Na verdade, encontrei o mesmo / um problema semelhante há alguns dias, mas ainda não tive tempo para encontrar uma solução.

Vou postar aqui quando encontrar algo então.

Encontrei uma solução para o problema de clusters 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);

        });

Eu declarei o markerCluster fora do Observable e, se ele existir no início, ele executa uma função chamada clearMarkers () que removerá quaisquer marcadores existentes do mapa, embora os deixe na matriz (daí a outra lógica para esvaziar a matriz )

Isso resolveu meu problema, talvez ajude você também @ siegerx3

@nanomoffet

Vou verificar quando trabalhar nessa parte novamente, obrigado :)

oi pessoal, obrigado por essas dicas
consegui obter o getNativeMap usando um subcomponente
estou implementando um menu de contexto de mapa
<sebm-google-map> <mapmenu-component></mapmenu-component>
o problema no meu caso é que o modelo de subcomponente não é visível
é processado em html em
<div class="sebm-google-map-content" _ngcontent-rgy-8="">
que é um componente invisível

consigo colocar algum html dentro do sebm-google-map em princípio?
eu gostaria de tê-lo como html, não usando OverlayView

Consegui lidar com isso separando a funcionalidade em 2 componentes (diretiva + componente)
1.) um que deve estar dentro do sebm-google-map e serve como acessador de API
2.) um que deve estar fora do sebm-google-map (caso contrário, não vejo o html gerado)

Oi equipe,
@ siegerx3 Usei seu código de https://drive.google.com/open?id=0B4y4KJY7l3rPNTdqR0hyNTRqVHc
funciona muito bem, mas não consigo integrare. O que estou tentando alcançar é integrar cluster + rótulo de marcador + janela de informações. Assim, quando eu clicar no cluster, os indivíduos deverão ter um rótulo de marcador e ao clicar nele deverá aparecer uma janela de informações. Alguma ideia de como posso fazer isso funcionar @SebastianM

@sprakashg
Acho que, como o cluster ainda não está implementado no módulo e você não está usando os marcadores do módulo, é necessário usar a API de mapas nativos no mesmo componente personalizado usado para o clustering.
Ou seja, adicionar o rótulo e a janela de informações manualmente, como faria no javascript vanilla.

@sprakashg

Na verdade, estou trabalhando na mesma coisa. Tive que mudar para MarkerClustererPlus para a biblioteca e estou usando o seguinte código para habilitar janelas de informações para marcadores individuais, bem como para os próprios clusters:

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

        });

O único problema é descobrir como fechar as janelas do cluster - elas fecham quando você sai do mapa, mas não quando você sai do cluster.

Alguém sabe se podemos usar pontos de referência no angular 2, mas usando lat e lng conforme referenciado aqui " https://developers.google.com/maps/documentation/javascript/reference#DirectionsWaypoint "?

@naranmistry você pode especificar um pouco o que deseja fazer?

não vejo qual é exatamente o seu plano. Talvez outra pessoa entenda?

Basicamente, eu quero ser capaz de colocar os valores lng e lat no waypoint em vez de uma string. Isso é possível usando o angular2-google-maps? Como eu quero exibir uma rota com várias paradas específicas usando valores de longitude e lattidute

Se bem entendi, então não vejo o connectino para este módulo, mas em geral, se você olhar a documentação diz location Type: string|LatLng|Place . Então, sim, você pode usar o objeto LatLng do google maps que usa os valores numéricos em seu construtor.

É disso que você precisava?

Basicamente, quero saber como, pois tentei passar como diz a documentação, mas continuou falhando. Existe um exemplo funcional de pontos de referência usando lat e lng?

Desculpe pela confusão, eu deveria ter sido mais claro

Acho que não. Mas se você pudesse fornecer seu código como exemplo? Como em um plunkr, eu pude ver o que posso encontrar :)

Ok, vou tentar montar um

Obrigado

Posso interceptar _click event_ em um _infowindow_ dentro da diretiva _marker-cluster_ ou renderizar um componente _sebm-google-map-info_ para cada marcador?

Obrigada!

Eu tenho o mesmo problema @fsciuti.
Você encontrou uma solução ?

Como agm-maps ainda não suporta clusters, peguei o exemplo de @ siegerx3 , a melhoria nas mudanças de marcador e o exemplo de janela de informações de marcador de @nanomoffet. Bom trabalho! Obrigado, seus exemplos ajudaram muito.

Para retribuir, ofereço uma versão atualizada do exemplo

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

As seguintes alterações foram feitas:

  • dependências atualizadas para caber no Angular 4.1 e @agm/core
  • código atualizado para se adequar ao Angular 4.1 e @agm/core
  • adicionado detecção de mudança de marcador
  • adicionado exemplo de janela de informações de marcador
  • estilo de código fixo

@andorfermichael Obrigado cara, você é ótimo! Uma pergunta, por favor: se eu quiser externalizar o estilo da diretiva (marcadores e clusters), como devo fazer isso? Pensei em simplesmente torná-lo um componente, mas não sei como alimentar o Observable corretamente com as opções e o estilo que você tem ...

@picosam

Você não precisa de um componente, em vez disso, apenas use os módulos ES6.

Crie um novo arquivo e exporte a configuração, por exemplo:

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

e então em _marker-cluster.ts_ importe essas variáveis ​​/ módulos:

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

@andorfermichael danke noch mal !!!
Claro que posso prosseguir e usar ícones complexos e tudo o que está documentado na versão mais recente do módulo Javascript do Google Maps, correto?

@picosam acho que sim, mas ainda não tentei isso

@andorfermichael Este é um trabalho notável 👍
mas estou enfrentando um probleminha

Preciso redirecionar para outra rota por um clique na janela de informações, mas a janela de informações não tem um evento de clique. Então, eu usei o evento "closeclick", aqui está o código

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

Tudo funciona bem, mas quando clico no botão Fechar da janela de informações, o evento é chamado, mas gera um erro
this.router is undefined

_Claro que a biblioteca do roteador é importada e o roteador é definido no construtor_

Tentei outra técnica, usei o gerador de eventos (a técnica de entrada / saída) entre o componente pai e a diretiva.
Eu defini @Output() eventEmitter = new EventEmitter() no topo como uma variável de classe,
E o evento no mesmo lugar,

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

Além disso, tudo funciona bem, mas quando clico no botão Fechar da janela de informações, o evento é chamado, mas gera um erro
this.eventEmitter is undefined

Existe uma maneira de corrigir esse problema?

@ hossam-maurice Suponho que o erro seja causado por this . O this no seu caso é o elemento que disparou o evento - a janela de informações. Por esse motivo, as funções de seta foram introduzidas no ES6 / ECMAScript2015. Usando funções de seta, this não depende de como a função foi chamada, mas do escopo circundante.
Portanto, infowindow.addListener('closeclick', () => { this.eventEmitter(id); }); deve funcionar para você.

Para referência futura, dê uma olhada em: ExploringJS - Funções de seta e MDN - Funções de seta

@andorfermichael Muito obrigado, funcionou: D 👍

Olá, usei o cluster de marcador personalizado do Google Drive e funciona muito bem.
Agora eu tenho um problema, preciso clicar em um marcador e abrir um modal de bootstrap. Mas eu realmente não sei como posso fazer isso. Tentei usar um ouvinte de evento no clique e mostrar um alerta e funcionou, mas não sei como abrir um modal de bootstrap. Alguma ideia?

Obrigado :)

Olá, adicionei um botão dentro da janela de informações, mas não consigo capturar o evento de clique. Você tem alguma ideia de como fazer isso?

@andorfermichael
Oi, obrigado pela solução. Você também poderia ajudar a mudar as cores do cluster de acordo com os marcadores dentro dele. Como vermelho, amarelo e azul.
Atenciosamente

@ vugar005 Não entendo exatamente o que quer dizer com mudança de cor. Você pode simplesmente alterar a imagem do cluster de acordo com suas necessidades. Até onde eu sei, a biblioteca de cluster de marcadores do Google fornece cinco imagens diferentes chamadas m1 a m5 (m = padrão) que são usadas conforme o número de marcadores por cluster aumenta. Não sei os limites exatos. Mais informações em Google Developers MapsDocumentation . Então, eu sugeriria criar cinco imagens com cores diferentes e nomeá-las cluster1 a cluster5 e colocá-las dentro da pasta de ativos.

@AlexisNi você pode tentar ouvir o evento domready na infoWindow que é disparado quando o

contendo o conteúdo da InfoWindow é anexado ao DOM.
google.maps.event.addListener(infoWindow, 'domready', function() {
  document.getElementById('info-window-button').addEventListener('click', function(){
    // run code here
  });
});

Para obter mais informações, dê uma olhada na documentação do Google Developers Maps

@joaolbaptista , desculpe, mas sua pergunta sobre o Bootstrap, embora combinado com os marcadores do Google Maps, está fora do assunto, na minha opinião. Eu sugeriria fazer a mesma pergunta (um pouco mais detalhada) em stackoverflow ;)

@andorfermichael Na verdade, quis dizer alterar o ícone de acordo com o número de marcadores dentro de um cluster. É por isso que mudei para a API da web nativa do Google. Espero que os mapas angulares forneçam serviços de cluster no futuro.
obrigado mesmo assim

@ vugar005 Foi o que tentei explicar. Mesmo a API nativa do Google Maps oferece apenas a possibilidade de cinco imagens diferentes. Cada uma dessas imagens é exibida quando um limite específico é atingido, por exemplo, cluster1 (m1) 0 - 10, cluster2 (m2) 11 - 100 e assim por diante.

Olá @andorfermichael , você pode ter alguma ideia porque depois de atualizar os pacotes recebo de repente este erro:

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 . Eu tive esse problema antes. O problema é que você não importou o arquivo masterclusterer js ou o código usa o Masterclusterer antes da importação do arquivo masterclusterer js.

Muito obrigado @ vugar005 - o que acontece é que não .js está incluído em meu .angular-cli.json e é verdade que não tenho uma instrução import * as ... em meu arquivo .ts . É claro que, quando tentei adicionar manualmente a instrução import , recebi um erro informando que .js extensões não são permitidas!

@picosam De nada. Que bom que ajudou você.

Este recurso está disponível por meio do novo pacote @ agm / js-marker-clusterer (# 1044)

@SebastianM Obrigado por disponibilizar este recurso no angular-google-maps. Estou tentando fazer com que um evento de clique funcione no clique do cluster, parece que não está disponível no momento. alguma solução alternativa para o mesmo?

@andorfermichael Seu exemplo parece ótimo! obrigado por fornecer esse exemplo. no seu exemplo, estou tentando incluir a API de mapas do google por meio da página de índice, mas continuo recebendo erros como google não encontrado ou clusterer de marcador não encontrado etc. alguma ideia?

@jpcode oi obrigado pela sua solução, está funcionando, mas o problema é que se eu usar a diretiva, não consigo controlar o resto dos eventos que temos no agm-marker. existe alguma maneira de adicioná-lo ao marcador agm? ou para adicionar os eventos que temos em agm-marker em sua diretiva?

Esta página foi útil?
0 / 5 - 0 avaliações

Questões relacionadas

smcardle picture smcardle  ·  27Comentários

SteveDowsett picture SteveDowsett  ·  23Comentários

DoyeonOhTravelHow picture DoyeonOhTravelHow  ·  31Comentários

ramnes picture ramnes  ·  54Comentários

philippeboyd picture philippeboyd  ·  76Comentários