Angular-google-maps: Как использовать кластеризатор маркеров?

Созданный на 30 апр. 2016  ·  76Комментарии  ·  Источник: SebastianM/angular-google-maps

Привет, есть какие-нибудь указатели на использование https://github.com/googlemaps/js-marker-clusterer или любого другого кластера маркеров с этим? Спасибо!

discussion / question

Самый полезный комментарий

@ siegerx3 Это проще, чем кажется, сначала создайте собственный компонент или директиву:

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

Я использовал директиву, потому что мне не нужен шаблон, вы можете использовать компонент и указать его, если хотите.

Само собой разумеется, что вам нужно указать свой настраиваемый компонент / директиву в разделе directives компонента, в котором вы его используете. Теперь просто поместите свой компонент на карту:

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

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

Из-за того, как работает Angular2 DI, поскольку мы не указываем поставщика для службы GoogleMapsAPIWrapper, он будет подниматься по дереву компонентов, пока не найдет его. В этом случае это 1 шаг вверх, и мы используем GoogleMapsAPIWrapper, который был предоставлен в компоненте sebm-google-map

Все 76 Комментарий

нет, извините, у меня нет совета, который я мог бы дать вам прямо сейчас

@SebastianM Я думаю, что это можно сделать с доступом к объекту карты, см. Здесь: https://github.com/SebastianM/angular2-google-maps/pull/311

Кто-нибудь на самом деле это сделал? файлам markerclusterer js, похоже, не нравится объект карты, который я передаю из .getMap ()

@AbdulTheProgrammer Я ждал, когда это получится, моя самая большая надежда на то, что это сработает? Вы уверены, что вызвали getMap () в том же экземпляре службы GoggleMapsAPIWrapper, что и тот, который используется директивой map, это моя самая большая проблема на данный момент ...

Я добился этого, используя специальный компонент и включив его в sebm-google-map; он использует GoogleMapsAPIWrapper и nativeMap.

Я добавляю маркеры вручную, используя javascript api карт Google (window.google.maps), а затем создаю MarkerClusterer.

Я надеюсь, что это помогает.

@ricardojbertolin Это действительно помогает, как указал здесь Себастьян # 311, настраиваемый компонент внутри карты - это именно то, как получить доступ к собственному объекту карты, хотя, безусловно, должен быть лучший способ добавить маркеры с помощью службы диспетчера в качестве вместо того, чтобы делать это вручную через js api ...

Я также изо всех сил пытаюсь заставить работать js-marker-clusterterer. Я получаю ссылку на собственный экземпляр карты, однако мне также нужны ссылки на собственные маркеры карты. У кого-нибудь есть идеи, как получить собственные маркеры карты для моих <sebm-google-map-marker> s?

@alexweber
У вас есть пример пользовательского компонента и GoogleMapsApiWrapper?
Кажется, я не понимаю, что означает «размещение пользовательского компонента внутри компонента».

@ siegerx3 Это проще, чем кажется, сначала создайте собственный компонент или директиву:

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

Я использовал директиву, потому что мне не нужен шаблон, вы можете использовать компонент и указать его, если хотите.

Само собой разумеется, что вам нужно указать свой настраиваемый компонент / директиву в разделе directives компонента, в котором вы его используете. Теперь просто поместите свой компонент на карту:

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

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

Из-за того, как работает Angular2 DI, поскольку мы не указываем поставщика для службы GoogleMapsAPIWrapper, он будет подниматься по дереву компонентов, пока не найдет его. В этом случае это 1 шаг вверх, и мы используем GoogleMapsAPIWrapper, который был предоставлен в компоненте sebm-google-map

@jfmaeck В getNativeMarker() метод MarkerManager который вы можете использовать для этого, и вы можете получить тот же экземпляр службы диспетчера маркеров, используя метод, описанный выше для оболочки.

@alexweber
Увидев код, объяснение обретает смысл! Спасибо :)

@alexweber большое спасибо за подсказку о том, как получить собственный экземпляр маркера. Однако у меня все еще есть один вопрос: метод getNativeMarker() из MarkerManager ожидает экземпляр SebmGoogleMapMarker (компонент маркера) в качестве параметра. Вы знаете, как я могу получить этот компонент в переменной, чтобы передать его функции getNativeMarker?

@jfmaeck Нет проблем! Я не могу проверить, чтобы быть на 100% уверенным в данный момент, но вы, вероятно, можете просто использовать @ViewChild('myMarker'): SebmGoogleMapMarker в своем компоненте и ссылаться на него с помощью # в разметке: <sebm-google-map-marker #myMarker> просто помните, что ViewChild правильно разрешает только в ngAfterViewInit .

@alexweber еще раз спасибо за вашу помощь. К сожалению, мне не удалось получить доступ к маркерам с помощью @ViewChildren. Я разветвил демонстрацию на Plunkr и внес в нее некоторые изменения, чтобы результат ViewChildren регистрировался в консоли (на данный момент это пустой массив):

markers after view init []

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

Я думаю, вы очень заняты, но если у вас есть возможность взглянуть на него, я был бы очень признателен.

@jfmaeck, когда вы используете @ContentChildren (потому что вы хотите получить экземпляры, которые живут внутри вашего компонентного элемента), он работает: http://plnkr.co/edit/mukdlZ7K7CIFm6aTdDTp?p=preview

@jfmaeck Вы были близки, вот рабочая вилка вашего блока с @ViewChildren : http://plnkr.co/edit/rJMCFoX9GokturcJljLh?p=preview

Чтобы заставить его работать, используя пользовательский компонент карты, @ContentChildren (как указал @SebastianM ) будет работать, но я предполагаю, что вы создали его только для доступа к маркерам, и на самом деле нет необходимости иметь этот дополнительный компонент в первое место.

Большое спасибо @SebastianM и @alexweber!

@alexweber @SebastianM Прежде всего, как мне включить эту библиотеку, которую вы используете js-marker-clusterterer? Есть ли способ использовать кластеры на определенном уровне масштабирования? И как мне включить изображения для таких кластеров: http://i65.tinypic.com/10gxkcw.png

@ricardojbertolin есть ли шанс, что вы можете поделиться своим кодом? Я новичок в angular2 (работаю с angularjs год +), и я немного потерялся.

@alexweber , Вы тестировали добавление markerclusterer.js? любой связанный пример?

@jpcode извините, нет, давно не работал над этим ...

У меня есть рабочее решение в одном из моих проектов.
При необходимости я могу собрать plunkr с примером?
@jpcode
@alexweber

@ siegerx3 приятно, очень поможет.
Я работаю в альтернативе, просто используя Google Maps api + markerclusterer.js.

@ siegerx3 , это простой пример использования библиотеки карт Google:
https://plnkr.co/Tr1Ykkj12HCkF9InQmuW

POC ожидает рассмотрения:
В способе использования angular2-google-maps, я думаю, нужно добавить внутрь, чтобы предотвратить столкновение с глобальными объектами как «google».
Обходной путь - предотвратить загрузку Google из библиотеки.
предоставить (MapsAPILoader, {useClass: NoOpMapsAPILoader}), загрузить самостоятельно и добавить clusterterer.js.

Но лучше, если angular2-google-maps добавит директиву для поддержки кластеризатора :)

@jpcode
Я часами пытался заставить его работать в плункере ... безуспешно.
Всегда возникали какие-то ошибки, не связанные с проблемой.
Я просто покажу вам код здесь ...

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

Вы помещаете эту директиву в тег angular2-google-maps:

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

@ siegerx3 , я сделал POC, используя angular2-google-maps

Подход:

  • Добавить карты Google из index.html
  • импорт clusterterer.js
  • запретить загрузку библиотеки карт Google из angular2-google-maps (с использованием провайдера)
  • Добавьте директиву для получения экземпляра исходной карты из библиотеки
  • используйте переменные google / markercluster для использования в качестве глобальных

Вы также можете использовать другие директивы из angular-2-google-maps, но я думаю, что лучше, если что-то будет добавлено в библиотеку для поддержки кластеризации.
->

потому что не имеет смысла использовать эту библиотеку для рисования карты, а затем просто использовать карты Google, в этом случае я думаю, что лучше использовать только библиотеки Google Maps + clusterterer.js в качестве перед показом 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;
}

В способе предотвращения загрузки google maps дважды используйте провайдера из angular2-google-maps
в определении вашего компонента добавьте поставщика

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

В определение вашего шаблона вам нужно добавить директиву.

<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
Я согласен с тем, что это должно быть добавлено в библиотеку angular2-google-maps, хотя в моем решении sdk карт не загружается дважды, как вы упомянули.

Я просто позволяю agm lib делать столько, сколько может, и просто делаю необходимые части сам.

@ siegerx3
не могли бы вы поделиться рабочим примером в zip-файле?

@ hellsm83
Завтра создам, если тебе хватит :)
Вы знакомы с angular-cli? В противном случае я просто сделаю базовый.

@ siegerx3
да, немного ... я смог выполнить кластеризацию с помощью кластера google maps api + marker. Вместо этого я бы предпочел использовать angular2-google-maps ... чтобы получить полное представление о решении.
спасибо большое за вашу помощь

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

Просто npm install и ng serve . Если у вас не установлен angular-cli, сначала npm install angular-cli -g .

Помните, это не оптимальное решение. Это просто обходной путь, который я сделал, потому что директивы кластера еще нет.

редактировать:
форматирование могло быть странным, так как мой атом не работал, поэтому я использовал старый добрый редактор ^^

@ siegerx3
большое спасибо. проверю это решение :)

Есть ли какие-либо обновления, касающиеся включения этого в карты Google angular 2? Мне действительно нужно использовать его для проекта, над которым я работаю

@SteveDowsett
Вы все еще можете использовать один из примеров, которые предоставили люди, включая меня :)
Если тебе, конечно, хватит

@ hellsm83
Кстати все заработало? Вам это помогло?

@ siegerx3
Да, мне это очень помогло. Tnx!

@ siegerx3

Я сам использовал ваш пример, и он отлично работает, так что спасибо!

Но теперь моя проблема в том, что я не могу обновить маркеры. Я использовал ngOnChanges для передачи обновленного массива точек, и я вижу, как массив меняется, но когда массив становится пустым, маркеры не удаляются.

Какие-нибудь советы?

@nanomoffet
Здорово, что помогло!

На самом деле я столкнулся с той же / похожей проблемой несколько дней назад, но у меня еще не было времени, чтобы найти решение.

Я опубликую здесь, когда что-нибудь найду.

Я нашел решение проблемы с постоянными кластерами.

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

        });

Я объявил markerCluster вне Observable, а затем, если он существует в начале, он запускает функцию clearMarkers (), которая удаляет все существующие маркеры с карты, хотя и оставляет их в массиве (отсюда и другая логика для очистки массива ).

Это устранило мою проблему, может быть, это тоже поможет вам

@nanomoffet

Я проверю это, когда снова буду работать над этой частью, спасибо :)

привет, ребята, спасибо за подсказку
мне удалось получить getNativeMap с помощью подкомпонента
я реализую контекстное меню карты
<sebm-google-map> <mapmenu-component></mapmenu-component>
проблема в моем случае в том, что шаблон подкомпонента не виден
он отображается в HTML в
<div class="sebm-google-map-content" _ngcontent-rgy-8="">
который является невидимым компонентом

Могу ли я в принципе разместить html внутри sebm-google-map?
я хотел бы иметь его как html, не используя OverlayView

Я смог справиться с этим, разделив функциональность на 2 компонента (директива + компонент)
1.) тот, который должен находиться внутри sebm-google-map и служить в качестве средства доступа к api
2.) тот, который должен находиться за пределами sebm-google-map (потому что в противном случае я не вижу его сгенерированный html)

Привет, команда,
@ siegerx3 Я использовал ваш код с https://drive.google.com/open?id=0B4y4KJY7l3rPNTdqR0hyNTRqVHc
он отлично работает, но я не могу интегрироватьа также. Я пытаюсь добиться интеграции кластера + метки маркера + информационного окна. Итак, когда я нажимаю на кластер, люди должны иметь метку маркера, и при нажатии на нее должно появляться информационное окно. Любая идея, как я могу заставить это работать @SebastianM

@sprakashg
Я думаю, поскольку кластер еще не реализован в модуле, и вы не используете маркеры из модуля, вы должны использовать собственный API карт в том же пользовательском компоненте, который используется для кластеризации.
Это означает добавление метки и информационного окна вручную, как в обычном javascript.

@sprakashg

Я сам работаю над этим же. Мне пришлось переключиться на MarkerClustererPlus для библиотеки, и я использую следующий код для включения информационных окон для отдельных маркеров, а также самих кластеров:

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

        });

Единственная проблема - выяснить, как закрыть окна кластера - они закрываются, когда вы покидаете карту, но не когда вы покидаете кластер.

Кто-нибудь знает, можем ли мы использовать путевые точки в angular 2, но используя lat и lng, как указано здесь « https://developers.google.com/maps/documentation/javascript/reference#DirectionsWaypoint »?

@naranmistry, можешь немного уточнить, чем ты хочешь заниматься?

Я не понимаю, каков именно ваш план. Может еще кто поймет?

В основном я хочу иметь возможность помещать значения lng и lat в путевую точку вместо строки, возможно ли это с помощью angular2-google-maps? Поскольку я хочу отобразить маршрут с несколькими конкретными остановками, используя значения долготы и широты

Если я правильно понимаю, то я не вижу подключения к этому модулю, но в целом, если вы посмотрите документацию, там написано location Type: string|LatLng|Place . Итак, да, вы можете использовать объект LatLng карт Google, который принимает числовые значения в своем конструкторе.

Это то, что вам нужно?

В основном я хочу знать, как, поскольку я пытался передать это, как говорится в документации, но это продолжало терпеть неудачу. Есть ли рабочий пример путевых точек с использованием широты и долготы?

Извините за путаницу, я должен был быть более ясным

Я так не думаю. Но если бы вы могли привести свой код в качестве примера? Как в plunkr, я мог видеть, что могу найти :)

Хорошо, я попробую собрать один

Спасибо

Извините, могу ли я перехватить _click event_ в _infowindow_ внутри директивы _marker-cluster_ или визуализировать компонент _sebm-google-map-info_ для каждого маркера?

Спасибо!

У меня такая же проблема @fsciuti.
Вы нашли решение ?

Поскольку agm-maps прежнему не поддерживает кластеры, я взял пример @ siegerx3 , улучшение изменений маркеров и пример окна информации о маркерах @nanomoffet. Хорошая работа! Спасибо, ваши примеры очень помогли.

Чтобы что-то вернуть, я предоставляю обновленную версию примера @ siegerx3 по следующей ссылке:

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

Внесены следующие изменения:

  • обновлены зависимости, чтобы соответствовать Angular 4.1 и @agm/core
  • обновленный код для соответствия Angular 4.1 и @agm/core
  • добавлено обнаружение смены маркера
  • добавлен пример информационного окна маркера
  • фиксированный стиль кода

@andorfermichael Спасибо, молодцы ! Один вопрос, пожалуйста: если я хочу экстернализовать стиль директивы (как маркеры, так и кластеры), как мне это сделать? Я думал о том, чтобы просто сделать его компонентом, но тогда я не знаю, как правильно кормить Observable с параметрами и стилем, которые у вас есть ...

@picosam

Вам не нужен компонент, просто используйте модули ES6.

Создайте новый файл и экспортируйте конфигурацию, например:

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

а затем в _marker-cluster.ts_ импортируйте эти переменные / модули:

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

@andorfermichael danke noch mal !!!
Конечно, тогда я могу использовать сложные значки и все, что задокументировано в последней версии модуля Google Maps Javascript, верно?

@picosam Я так думаю, но еще не пробовал

@andorfermichael Это замечательная работа 👍
но у меня небольшая проблема

Мне нужно перенаправить на другой маршрут, щелкнув информационное окно, но информационное окно не имеет события щелчка. Поэтому я использовал вместо этого событие "closeclick", вот код

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

Все работает нормально, но когда я нажимаю кнопку закрытия информационного окна, событие вызывается, но выдает ошибку
this.router is undefined

_Конечно, библиотека маршрутизатора импортируется и маршрутизатор определяется в конструкторе_

Я попробовал другой метод, я использовал eventemitter (метод ввода / вывода) между родительским компонентом и директивой.
Я определил @Output() eventEmitter = new EventEmitter() вверху как переменную класса,
И мероприятие там же,

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

Также все работает нормально, но когда я нажимаю кнопку закрытия информационного окна, событие вызывается, но выдает ошибку
this.eventEmitter is undefined

Есть ли способ решить эту проблему?

@ hossam-maurice Я полагаю, что ошибка вызвана this . this в вашем случае - это элемент, который вызвал событие - информационное окно. По этой причине стрелочные функции были введены в ES6 / ECMAScript2015. Использование стрелочных функций this зависит не от того, как функция была вызвана, а от окружающей области.
Так что infowindow.addListener('closeclick', () => { this.eventEmitter(id); }); должны работать на вас.

Для получения дополнительной информации см. ExploringJS - Стрелочные функции и MDN - Стрелочные функции.

@andorfermichael Большое спасибо, это сработало: D 👍

Здравствуйте, я использовал настраиваемый кластер маркеров с диска Google, и он отлично работает.
Теперь у меня есть одна проблема: мне нужно щелкнуть маркер и открыть модальное окно начальной загрузки. Но я действительно не знаю, как я могу это сделать. Я попытался использовать прослушиватель событий при щелчке и показать предупреждение, и он работает, но я действительно не знаю, как открыть модальное окно начальной загрузки. Любые идеи?

Спасибо :)

Здравствуйте, я добавил кнопку внутри информационного окна, но мне не удается поймать событие щелчка. Вы знаете, как это сделать?

@andorfermichael
Привет, спасибо за решение. Не могли бы вы также помочь изменить цвета кластера в соответствии с маркерами внутри него. Такие как красный, желтый и синий.
С уважением

@ vugar005 Я не совсем понимаю, что вы имеете в виду под изменением цвета. Вы можете просто изменить изображение кластера в соответствии с вашими потребностями. Насколько мне известно, библиотека кластеров маркеров Google предоставляет пять разных изображений с именами от m1 до m5 (m = default), которые используются по мере роста количества маркеров на кластер. Точных порогов не знаю. Дополнительная информация на Google Developers MapsDocumentation . Итак, я бы предложил создать пять изображений с разными цветами и назвать их с кластера1 по кластер5 и поместить их в папку с ресурсами.

@AlexisNi, вы можете попытаться прослушать событие domready в информационном окне, которое запускается, когда

Содержимое InfoWindow прикрепляется к модели DOM.
google.maps.event.addListener(infoWindow, 'domready', function() {
  document.getElementById('info-window-button').addEventListener('click', function(){
    // run code here
  });
});

Для получения дополнительной информации ознакомьтесь с документацией Google Developers Maps.

@joaolbaptista, извините, но ваш вопрос о Bootstrap, хотя и в сочетании с маркерами Google Maps, на мой взгляд, не по теме. Я бы посоветовал задать тот же вопрос (чуть более подробно) на stackoverflow ;)

@andorfermichael На самом деле я имел в виду изменение значка в соответствии с количеством маркеров внутри кластера. Вот почему я перешел на собственный веб-интерфейс Google. Надеемся, что в будущем угловые карты будут предоставлять кластерные услуги.
в любом случае, спасибо

@ vugar005 Вот что я пытался объяснить. Даже собственный API карт Google предоставляет возможность только для пяти разных изображений. Каждое из этих изображений отображается при достижении определенного порога, например, cluster1 (m1) 0–10, cluster2 (m2) 11–100 и так далее.

Привет @andorfermichael , не могли бы вы понять, почему после обновления пакетов я внезапно получаю эту ошибку:

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 . У меня была эта проблема раньше. Проблема в том, что вы не импортировали файл masterclusterer js или код использует Masterclusterer до того, как будет импортирован файл masterclusterer js.

Большое спасибо @ vugar005 - дело в том, что я давно не касался этого кода! Файл .js включен в мой .angular-cli.json и это правда, что у меня нет инструкции import * as ... в моем файле .ts . Конечно, когда я попытался вручную добавить оператор import я получил ошибку, что расширения .js не разрешены!

@picosam Пожалуйста . Рад, что помог тебе.

Эта функция доступна в новом пакете @ agm / js-marker-clusterterer (# 1044).

@SebastianM Спасибо, что сделали эту функцию доступной в angular-google-maps. Я пытаюсь заставить событие щелчка работать при щелчке кластера, кажется, в настоящее время он недоступен. какое-либо обходное решение для того же?

@andorfermichael Ваш пример выглядит великолепно! спасибо за этот пример. в вашем примере я пытаюсь включить api карт Google через страницу индекса, но я продолжаю попадать в такие ошибки, как Google не найден или кластер маркеров не найден и т. д. какие-либо мысли?

@jpcode привет, спасибо за ваше решение, это работает, но проблема в том, что если я использую директиву, я не могу контролировать остальные вечера, которые у нас есть в agm-marker. есть ли способ добавить его в agm-marker? или добавить события, которые у нас есть в agm-marker по вашей директиве?

Была ли эта страница полезной?
0 / 5 - 0 рейтинги