New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How to use a Marker Clusterer? #307
Comments
no sorry, I have no advice I could give you right now |
@SebastianM I think it can be done with access to the map object, see here please: #311 |
Has anybody actually done this? the markerclusterer js files do not seem to like the map object that I pass in from .getMap() |
@abdultheprogrammer I've been waiting on this to get in, my biggest hope is that it'd work? You sure you called getMap() on the same instance of the GoggleMapsAPIWrapper service as the one used by the map directive, that's my biggest issue at the moment.... |
I've achieved it using a custom component and including it inside the sebm-google-map; it uses the GoogleMapsAPIWrapper and the nativeMap. I add the markers manually using the google maps javascript api (window.google.maps) and then creating the MarkerClusterer. I hope it helps. |
@ricardojbertolin That does help, like Sebastian had pointed out here #311, a custom component inside the map is exactly how to get access to the native map object, although surely there's gotta be a better way to add the markers using the manager service as opposed to doing it manually via the js api... |
I am also struggling to get js-marker-clusterer working. I get a reference to the native maps instance, however I also need references to the native map markers. Anyone any ideas how a can get the native map markers for my |
@alexweber |
@siegerx3 It's simpler that it sounds, first create a custom component or directive: 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
});
}
} I used a directive cause I didn't need a template, you can use a component and specify one if you want. Goes without saying you need to specify your custom component/directive in the <sebm-google-map>
<!-- markers, info windows, etc -->
<custom-directive></custom-directive>
</sebm-google-map> Due to the way Angular2 DI works, since we're not specifying a provider for the GoogleMapsAPIWrapper service, it will go up the component tree until it finds one. In this case, it's 1 step up and we use the GoogleMapsAPIWrapper that was provided in the |
@jfmaeck There's a |
@alexweber |
@alexweber thank you very much for your hint on how to get the native marker instance. I still have one question, though: the |
@jfmaeck No problem! I can't check to be 100% sure at the moment but you can probably just use |
@alexweber thank you again for your help. Unfortunately, I could not manage to access the markers using @ViewChildren. I forked the demo on Plunkr and made some changes to it so that the ViewChildren result gets logged in the console (an empty array at the moment):
http://plnkr.co/edit/7rdOz3QswDL0pik7SmAS?p=preview I guess you are pretty busy but if you have a chance to look at it, I would really appreciate that. |
@jfmaeck when you use @ContentChildren (because you want to get the instances that live inside your component element), it works: http://plnkr.co/edit/mukdlZ7K7CIFm6aTdDTp?p=preview |
@jfmaeck You were close, here's a working fork of your plunk with To get it to work using the custom map component |
Thank you very much @SebastianM and @alexweber! |
@alexweber @SebastianM First of all, how do I include this library which you use js-marker-clusterer? Is there a way to use clusters on a specific zoom-level? And how do I include images for the clusters like this: http://i65.tinypic.com/10gxkcw.png |
@ricardojbertolin any chance you can share your code? I'm very new to angular2 (have been working with angularjs for a year+) and I'm a bit lost. |
@alexweber , Did you test adding markerclusterer.js ? any example related? |
@jpcode sorry nope, haven't worked on this in a while... |
I have a working solution in one of my projects. |
@siegerx3 nice, will help a lot. |
@siegerx3 , this is a basic example just using google maps lib: POC pending: But is better if angular2-google-maps add a directive to support clusterer :) |
@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);
}
})
});
}
} You put this directive into the angular2-google-maps tag: <sebm-google-map>
<custom-map></custom-map>
</sebm-google-map> |
@siegerx3 , i made a POC using angular2-google-maps Approach:
You can also will use the other directives from angular-2-google-maps, but i think is better if something is added to the lib to support clusterer. because not make sense to use this lib to paint a map and next just use google maps, in this case i think is better use just google maps libs + clusterer.js as a before plunkr shows. 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;
} In the way to prevent load google maps twice use a provider from 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
}
],
}) In your template definition you need to add the directive. <sebm-google-map #sitemap
[disableDefaultUI]="false"
[zoom] = "zoom"
[zoomControl]="true"
[latitude]="lat" [longitude]="lng">
<!--
<sebm-google-map-marker
*ngFor="let m of markers; let i = index"
(markerClick)="openDetail(m)"
[latitude]="m.lat"
[longitude]="m.lng"
[label]="m.label"
[markerDraggable]="m.draggable"
[iconUrl]="'assets/img/marker.png'"
(dragEnd)="markerDragEnd(m, $event)">
<sebm-google-map-info-window [disableAutoPan]="true" (infoWindowClose)="onCloseDetail.emit()">
<h5>{{m.address}}</h5>
<div>{{m.city}}, {{m.state}}, {{m.country}}</div>
</sebm-google-map-info-window>
</sebm-google-map-marker>
-->
<googlemap-directive></googlemap-directive>
</sebm-google-map> |
@jpcode I just let the agm lib do as much as it can and just do the necessary parts myself. |
I don't think so. But if you could provide your code as an example? Like in a plunkr, i could see what i can find :) |
Okay i'll try and put one together Thanks |
Sorry, can i intercept click event in a infowindow inside marker-cluster directive or rendere an sebm-google-map-info component for each markers? Thank you! |
I have the same issue @fsciuti. |
Since To give something back, I provide a updated version of @siegerx3 example under the following link: https://drive.google.com/open?id=0B51AX67ezltoOFdSNTQ1NlQ4SU0 The following changes have been made:
|
@andorfermichael Thanks a bunch man, you're great! One question please: if I want to externalize the styling of the directive (both markers and clusters), how should I do so? I thought about simply making it a component, but then I don't know how to feed the Observable correctly with the options and style that you have... |
You do not need a component instead just use ES6 modules. Create a new file and export the configuration, for example: google-maps.config.ts
and then in marker-cluster.ts import those variables/modules:
|
@andorfermichael danke noch mal!!! |
@picosam I think so but have not tried that yet |
@andorfermichael This is a remarkable job 👍 I need to redirect to another route by a click on the infowindow, but infowindow doesn't have a click event. So I used instead the "closeclick" event, here is the code
Everything works fine but when I click on the infowindow close button, the event is called but it throws an error Of course the router library is imported and the router is defined in the constructor I tried another technique, I used the eventemitter (the Input/Output technique) between the parent component and the directive.
Also everything works fine but when I click on the infowindow close button, the event is called but it throws an error Is there a way to fix this issue? |
@hossam-maurice I suppose that the error is caued by the For further reference have a look at: ExploringJS - Arrow Functions and MDN - Arrow Functions |
@andorfermichael Thank you so much, it did work :D 👍 |
Hello, i used the custom marker cluster from google drive and it works just fine. Thanks :) |
Hello,i added a button inside info window but i am unable to catch the click event.Do you have any idea on how to do it? |
@andorfermichael |
@vugar005 I do not understand exactly what you mean by changing the color. You could simply change the image of the cluster according to your needs. As far as I know, Google's marker cluster library provides five different images named m1 to m5 (m = default) which are used as the number of markers per cluster grows. I do not know the exact thresholds. More information at Google Developers MapsDocumentation. So, I would suggest to create five images with different colors and naming them cluster1 to cluster5 and placing them inside the assets folder. |
@AlexisNi you could try to listen to the domready event on the infoWindow which is is fired when the containing the InfoWindow's content is attached to the DOM.
For more info have a look at Google Developers Maps Documention |
@joaolbaptista sorry, but your question about Bootstrap even though combined with Google Maps markers is off-topic in my opinion. I would suggest to ask the same question (a little bit more detailed) at stackoverflow ;) |
@andorfermichael I actually meant change the icon according to number of markers inside a cluster. So thats why I switched to native google web api . Hope angular maps will provide cluster service in the future. |
@vugar005 That's what I tried to explain. Even the native google maps api only provides the possibility for five different images. Each of these images is displayed when a specific threshold is reached, for example, cluster1 (m1) 0 - 10, cluster2 (m2) 11 - 100 and so on. |
Hello @andorfermichael, might you have any idea why after upgrading packages I suddenly get this error:
|
@picosam . I had this issue before. The problem is that you do did not import masterclusterer js file or the code uses Masterclusterer before masterclusterer js file is imported. |
Thanks a lot @vugar005 -- the thing is, I haven't touched that code for quite a while! The |
@picosam You are welcome. Glad it helped you. |
This feature is available via the new @ agm/js-marker-clusterer package (#1044) |
@SebastianM Thanks for making this feature available in angular-google-maps. I am trying to get a click event to work on click of cluster, it seems currently its not available. any workaround for the same? @andorfermichael Your example looks great! thanks for providing that example. in your example I am trying to include the google maps api through index page but i keep on getting into errors like google not found or marker clusterer not found etc. any thoughts? |
@jpcode hi thanks for your solution, it's work, but the problem that if i use the directive i cant contol the rest of the evenets that we have in agm-marker. is there any way to add it to agm-marker? or to the add the events we have in agm-marker on your directive? |
Hi, any pointers on using https://github.com/googlemaps/js-marker-clusterer or any other marker clusterer with this? Thanks!
The text was updated successfully, but these errors were encountered: