Skip to content
This repository was archived by the owner on Jun 23, 2025. It is now read-only.

Add clustered markers#1044

Closed
jigfox wants to merge 10 commits into
sebholstein:masterfrom
inovex:add-clustered-markers
Closed

Add clustered markers#1044
jigfox wants to merge 10 commits into
sebholstein:masterfrom
inovex:add-clustered-markers

Conversation

@jigfox

@jigfox jigfox commented Jun 12, 2017

Copy link
Copy Markdown
Contributor

This adds a new directive <agm-cluster> which allows to group markers into clusters if they are near each other like described and requested in #307. It uses the https://github.com/googlemaps/js-marker-clusterer to achieve this goal.

@hismethod hismethod left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What a Good Feature what I want!!!!

@sebholstein sebholstein left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jigfox wow, thank you, this looks really good!

One note: I would like to keep the @agm/core package as a place for core Google Maps API features, so this package has no other external dependencies (like js-marker-clusterer).

We need to think about how we can structure this repo so that we can host multiple packages (like in the official angular repo).

I would propose the following package name: @agm/js-marker-clusterer

Comment thread src/core/directives/cluster.ts Outdated
selector: 'agm-cluster',
providers: [ClusterManager, {provide: MarkerManager, useExisting: ClusterManager}]
})
export class AgmCluster implements OnDestroy, OnChanges, OnInit {

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AgmMarkerCluster

providers: [ClusterManager, {provide: MarkerManager, useExisting: ClusterManager}]
})
export class AgmCluster implements OnDestroy, OnChanges, OnInit {
@Input() gridSize: number;

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we add a description for the inputs and outputs?

@Input() imagePath: string;
@Input() imageExtension: string;

constructor(private cluster: ClusterManager) {}

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

private _markerClusterManager: MarkerClusterManager

import {Marker} from '../google-maps-types';

@Injectable()
export class ClusterManager extends MarkerManager {

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MarkerClusterManager

});
}

init(options:{}) {

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we add a concrete type here for options?

Comment thread package.json Outdated
"@angular/common": "^4.0.0 || ^2.0.0",
"@angular/core": "^4.0.0 || ^2.0.0"
"@angular/core": "^4.0.0 || ^2.0.0",
"js-marker-clusterer": "^1.0.0"

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to have a separate @agm package to handle the different dependencies. (See my last comment)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That should be possible, what name would you suggest? I will try with @agm/cluster, if this is okay with you

Comment thread src/core/services/google-maps-types.ts Outdated
export type CalculateFunction = (marker: Marker[], count: number) => CalculatorResult;

export interface MarkerClusterer {
export interface IMarkerClusterer {

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MarklerClusterer

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That ist not that easy because tslint doesn't like it. The js-marker-clusterer package will create a global var called MarkerClusterer, which I have to declare src/core/services/managers/cluster-manager.ts:12

import {AgmCluster} from './../../directives/cluster';
// tslint:disable-next-line: no-use-before-declare
import {Marker, MarkerClusterer, IClusterOptions} from '../google-maps-types';
import {Marker, IMarkerClusterer, IClusterOptions} from '../google-maps-types';

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ClusterOptions

Comment thread src/core/services/google-maps-types.ts Outdated
imageExtension_:string;
}

export interface IClusterOptions {

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ClusterOptions

@jigfox

jigfox commented Jun 12, 2017

Copy link
Copy Markdown
Contributor Author

Hi, thanks for your Feedback. What name would you suggest your message seems like it was cut off:

I would propose the following package name:

I will Change all other things like requested

@sebholstein

sebholstein commented Jun 18, 2017

Copy link
Copy Markdown
Owner

@jigfox oh yeah, missed that. I would propose "@ agm/js-marker-clusterer".

So in the src folder, we would have another folder @ agm/js-marker-clusterer and we would rename the core folder to @ agm/core.

Please let me know when the changes are done. Thank you!

@jigfox jigfox changed the title Add clustered markers WIP: Add clustered markers Jun 20, 2017
@jigfox

jigfox commented Jun 20, 2017

Copy link
Copy Markdown
Contributor Author

@SebastianM I have some trouble with dependencies while splitting the cluster into its own module: https://github.com/inovex/angular-google-maps/pull/1/files

So I need some help here, integrating this. Another much simpler option would be to create a completely new repo for the clusterer. It would not be the same as in angular itself, but it would be easier to maintain. What do you think?

@sebholstein

Copy link
Copy Markdown
Owner

@jigfox thx. I worked on a multi-package solution yesterday in this PR (#1051) to support Snazzy Info Window. It's nearly done - I will merge this tomorrow. Afterwards, I can do the package modifications or you can also do this if you want to.

The important part is that the manager cannot be in the providers array of the AgmMap class, so we need a solution for this.

@sebholstein

Copy link
Copy Markdown
Owner

@jigfox #1051 is merged. There should be everything you need to create another package. Let me know if there are any questions.

@jigfox

jigfox commented Jun 22, 2017

Copy link
Copy Markdown
Contributor Author

okay, I will try this approach, thank you

@jigfox jigfox force-pushed the add-clustered-markers branch from a58dba2 to 28c05ea Compare June 22, 2017 13:15
@jigfox jigfox changed the title WIP: Add clustered markers Add clustered markers Jun 23, 2017
@jigfox

jigfox commented Jun 26, 2017

Copy link
Copy Markdown
Contributor Author

@SebastianM: I have created a new package like the already existing. Is this okay, the way it is? Or should I change something?

@sebholstein

Copy link
Copy Markdown
Owner

@jigfox thx. I will review it tomorrow.

@ekaitzht

Copy link
Copy Markdown

Any time planing to merge this to master? Thanks

@nelsonBlack

Copy link
Copy Markdown

Also patiently waiting for the merge to be done

@reginbald

reginbald commented Jul 11, 2017

Copy link
Copy Markdown

@SebastianM When do you think this will be merged and released?

@jigfox

jigfox commented Aug 23, 2017

Copy link
Copy Markdown
Contributor Author

@SebastianM Congrats, I totally understand

@quedicesebas

Copy link
Copy Markdown
Contributor

Please, a demo of this? and complete docs

@pauljosephatay

Copy link
Copy Markdown

@sebrojas14, I believe you can follow the snazzy window guide

  1. npm install js-marker-clusterer @agm/js-marker-clusterer
  • depends on js-marker-clusterer
  1. import the module
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';

// add these imports
import { AgmCoreModule } from '@agm/core';
import { AgmJsMarkerClustererModule } from '@agm/js-marker-clusterer';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    AgmCoreModule.forRoot({
      apiKey: ['YOUR_API_KEY_HERE']
    }),
    AgmJsMarkerClustererModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }
  1. is should be available in the template, note the selector is agm-marker-cluster as of beta1
<agm-map style="height: 300px" [latitude]="51.673858" [longitude]="7.815982">
  <agm-marker-cluster
  imagePath="https://raw.githubusercontent.com/googlemaps/v3-utility-library/master/markerclustererplus/images/m">
    <agm-marker [latitude]="51.673858" [longitude]="7.815982">
    </agm-marker><!-- multiple markers -->
  </agm-marker-cluster>
</agm-map>

@jigfox

jigfox commented Sep 1, 2017

Copy link
Copy Markdown
Contributor Author

thanks @pauljosephatay I took your example Code and put it into the README

@jigfox jigfox deleted the add-clustered-markers branch September 1, 2017 05:25
@sadeajayi

Copy link
Copy Markdown

On compilation im getting
EXCEPTION: Uncaught (in promise): Error: Error in ./MapPageComponent class MapPageComponent - inline template:19:12 caused by: No provider for GoogleMapsAPIWrapper!

@kuncevic kuncevic mentioned this pull request Sep 4, 2017
@kuncevic

kuncevic commented Sep 4, 2017

Copy link
Copy Markdown

@pauljosephatay getting error as mentioned here #1124 (comment) any thoughts?

@sadeajayi

Copy link
Copy Markdown

What i'm basically trying to do is add markers on clicking the map, and clustering them in real time, i don't even know if logically speaking, this feature is possible?

@pauljosephatay

Copy link
Copy Markdown

@kuncevic probably dependency with js-marker-clusterer. please check out README installation and usage
npm install js-marker-clusterer @agm/js-marker-clusterer --save
or
yarn add js-marker-clusterer @agm/js-marker-clusterer

@sadeajayi, i believe no special treatment needed, like this

template:
<agm-map style="height: 300px" [latitude]="51.673858" [longitude]="7.815982"
  (mapClick)="addMarker($event)">
  <agm-marker-cluster
  imagePath="https://raw.githubusercontent.com/googlemaps/v3-utility-library/master/markerclustererplus/images/m">
    <agm-marker *ngFor="let marker of markers"
      [latitude]="marker.lat"
      [longitude]="marker.lng">
    </agm-marker>
  </agm-marker-cluster>
</agm-map>

=============
component:

markers = [];

addMarker($event){
this.markers.push($event.coords);
}

@kuncevic

kuncevic commented Sep 4, 2017

Copy link
Copy Markdown

@pauljosephatay I done the install thing as I pinted in comment I can see the files listed in my node_modules . Also I tried to just reinstall the whole node_modules and getting caught by the same error.

image

image

image

My env:

@angular/cli: 1.3.2
node: 7.8.0
os: win32 x64
@angular/animations: 4.3.5

html:

<agm-map style="height: 300px" [latitude]=lat [longitude]=lng>
  <agm-marker-cluster [imagePath]="'https://googlemaps.github.io/js-marker-clusterer/images/m'">
    <agm-marker *ngFor="let marker of markers" [latitude]="marker.lat" [longitude]="marker.lng"></agm-marker>
  </agm-marker-cluster>
</agm-map>

app.module

import { AgmCoreModule } from '@agm/core';
import { AgmJsMarkerClustererModule, ClusterManager } from '@agm/js-marker-clusterer';

@NgModule({
  declarations: [
    AppComponent,
    MapsComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    AgmCoreModule.forRoot({
      apiKey: 'key'
    }),
    AgmJsMarkerClustererModule
  ],
  providers: [
    ClusterManager
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

@pauljosephatay

Copy link
Copy Markdown

@kuncevic sorry, i guess if you already installed both 1) js-marker-clusterer and 2) @agm/js-marker-clusterer then im not sure what could be the problem. you may create a new clean app with ng cli and install agm map then follow the README and see if it works.

@kuncevic

kuncevic commented Sep 4, 2017

Copy link
Copy Markdown

@pauljosephatay all good now. I was actually missing the js-marker-clusterer module. Thanks for help.

@sadeajayi

Copy link
Copy Markdown

@kuncevic how did you include the js-marker-clusterer module in the app module?

@sadeajayi

Copy link
Copy Markdown

im still getting
On compilation im getting
EXCEPTION: Uncaught (in promise): Error: Error in ./MapPageComponent class MapPageComponent - inline template:19:12 caused by: No provider for GoogleMapsAPIWrapper!

error on compilation even after including the wrapper as a provider and importing that.
This is what i have

The imports im making in my map-page.component.ts

import { Component, NgModule, NgZone, OnInit, ViewChild, ElementRef } from '@angular/core';
import {MarkerService} from "../../services/marker.service";

import { AgmCoreModule, MapsAPILoader } from 'angular2-google-maps/core';
import { FormControl, FormsModule, ReactiveFormsModule } from "@angular/forms";
import { MapCluster } from '../../map-cluster';
import { AgmJsMarkerClustererModule } from "@agm/js-marker-clusterer";

import 'js-marker-clusterer/src/markerclusterer.js';

import {Http, HttpModule} from '@angular/http';

//Importing socket-io services for real-time interactions
import { SocketService } from '../shared/socket.service';
import {GoogleMapsAPIWrapper} from "angular2-google-maps/core/services/google-maps-api-wrapper";

Imports in my app module.ts

import {  AgmCoreModule, MapsAPILoader } from "angular2-google-maps/core";
import { AgmJsMarkerClustererModule } from "@agm/js-marker-clusterer";
import { MapCluster } from './map-cluster';

import {GoogleMapsAPIWrapper} from "angular2-google-maps/core/services/google-maps-api-wrapper";

import { AppComponent } from './app.component';
import { MapPageComponent } from './components/map-page/map-page.component';
import 'js-marker-clusterer/src/markerclusterer.js';

imports: [
    BrowserModule,
    FormsModule,
    FacebookModule.forRoot(),
    AgmCoreModule.forRoot({
      apiKey: 'AIzaSyBfW8ETNs6vnLAlGqcqHIZg52NI9lupHxM',
      libraries: ["places"]
    }),
    AgmJsMarkerClustererModule,
  ],
  providers: [ValidateService, MarkerService, SocketService, GoogleMapsAPIWrapper],

@kuncevic

kuncevic commented Sep 4, 2017

Copy link
Copy Markdown

@sadeajayi check my app.module code just in a comment above

But you have an issue with GoogleMapsAPIWrapper you need to provide that thing.
Also why you are mixing angular2-google-maps (old) and @agm (new) modules? check the docs.

@sadeajayi

Copy link
Copy Markdown

Oh okay, I did just that and im still getting the same errors

@kuncevic

kuncevic commented Sep 4, 2017

Copy link
Copy Markdown

@sadeajayi are you importing GoogleMapsAPIWrapper from @agm/core like:

import { GoogleMapsAPIWrapper } from '@agm/core';

@sadeajayi

Copy link
Copy Markdown

@kuncevic Oh my God. Youre a life saver.
This whole time i was importing my googlemapsAPI wrapper with the
"angular2-google-maps/core" module i installed 2 months ago instead of using @agm/core.
I was importing agmCoreModule and MapsAPILoader with that same module as well.
I was wondering what was causing my bugs for the last 3 weeks and I couldn't understand what was wrong.
Thanks man

@BayardSmart

Copy link
Copy Markdown

Hi, I have this error when trying to compile : ERROR in C:/....../node_modules/@agm/js-marker-clusterer/services/managers/cluster-manager.d.ts (8,22): Class 'ClusterManager' incorrectly extends base class 'MarkerManager'.
Property '_mapsWrapper' is private in type 'MarkerManager' but not in type 'ClusterManager'.

Any Idea ?

@MarKco

MarKco commented Sep 8, 2017

Copy link
Copy Markdown

I'm experiencing the same issue: added the library following the readme instructions and can't compile because of the following

ERROR in C:/.../node_modules/@agm/js-marker-clusterer/services/managers/cluster-manager.d.ts (8,22): Class 'ClusterManager' incorrectly extends base class 'MarkerManager'. Property '_mapsWrapper' is private in type 'MarkerManager' but not in type 'ClusterManager'.

@jigfox

jigfox commented Sep 8, 2017

Copy link
Copy Markdown
Contributor Author

@uakgul-talis @MarKco
which version of @agm/core are you running? It should be working in 1.0.0-beta.1 as you can see here the property _mapsWrapper isn't private but protected as it should be: https://github.com/SebastianM/angular-google-maps/blob/c16295d331cbb74841585cf433ab7af3d7e415d5/packages/core/services/managers/marker-manager.ts#L15

@MarKco

MarKco commented Sep 8, 2017

Copy link
Copy Markdown

I installed with npm install js-marker-clusterer @agm/js-marker-clusterer --save, in the installation log I see the following: @agm/js-marker-clusterer@1.0.0-beta.1

So it seems I'm already running the beta.1. Any chance the change was not deployed?

@jigfox

jigfox commented Sep 8, 2017

Copy link
Copy Markdown
Contributor Author

@agm/js-marker-clusterer@1.0.0-beta.1 is not the same as @agm/core@1.0.0-beta.1 what version of @agm/core are you running?

@MarKco

MarKco commented Sep 8, 2017

Copy link
Copy Markdown

You were right!
Since I had agm/core installed for a long time it wasn't updated. I performed an npm update , version @agm/core@1.0.0-beta.1 was installed and now clustering works as expected! :)

I guess this could probably be the way to solve the issue for @uakgul-talis as well! Thank you!

@BayardSmart

Copy link
Copy Markdown

@jigfox Thanks man !!! It's working properly now.
I also performed a npm update like @MarKco did .

Thank you again!

@sadeajayi

Copy link
Copy Markdown

Hi guys, I have another issue
I'm trying to write a method in my component.ts file to handle deletion of markers.
Basically, if a user drops a marker at location 'x', but moves out of a set radius for that location, their marker should get deleted.
So if there's a cluster showing 45 markers at a location, and one user leaves that location, the number of markers will reduce by 1.
I just don't know how to go about implementing deletion in my component.ts file please help

srwebdev3627 added a commit to srwebdev3627/angular-google-maps that referenced this pull request Apr 29, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.