Skip to content

Commit

Permalink
Prevent sending empty options and add marker clustering (#86)
Browse files Browse the repository at this point in the history
* fix(google-maps-api): prevent sending empty options

* feat(marker-cluster): add marker clustering

* fix(marker-clustering): pass object straight into function
  • Loading branch information
VMBindraban authored and Vheissu committed Feb 3, 2018
1 parent 2dc1c14 commit 216b359
Show file tree
Hide file tree
Showing 5 changed files with 91 additions and 9 deletions.
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,12 @@ export function configure(aurelia) {
options: { panControl: true, panControlOptions: { position: 9 } }, //add google.maps.MapOptions on construct (https://developers.google.com/maps/documentation/javascript/3.exp/reference#MapOptions)
language:'' | 'en', // default: uses browser configuration (recommended). Set this parameter to set another language (https://developers.google.com/maps/documentation/javascript/localization)
region: '' | 'US' // default: it applies a default bias for application behavior towards the United States. (https://developers.google.com/maps/documentation/javascript/localization)
markerCluster: {
enable: false,
src: 'https://cdn.rawgit.com/googlemaps/v3-utility-library/99a385c1/markerclusterer/src/markerclusterer.js', // self-hosting this file is highly recommended. (https://developers.google.com/maps/documentation/javascript/marker-clustering)
imagePath: 'https://cdn.rawgit.com/googlemaps/v3-utility-library/tree/master/markerclusterer/images/m', // the base URL where the images representing the clusters will be found. The full URL will be: `{imagePath}{[1-5]}`.`{imageExtension}` e.g. `foo/1.png`. Self-hosting these images is highly recommended. (https://developers.google.com/maps/documentation/javascript/marker-clustering)
imageExtension: 'png',
}
});
})
}
Expand Down Expand Up @@ -195,6 +201,12 @@ var myMarkers = [
* `custom` (optional) - store arbitrary data (e.g. an `id` field) in this object, retrieve it from the `googlemap:marker:click` event payload
* `infoWindow` (optional) - object - If set, the `googlemap:marker:click` evetn will not be called, instead an infowindow containing the given content will show up - see [docs](https://developers.google.com/maps/documentation/javascript/infowindows)


### Marker clustering

This options allows the clustering of markers that are near each other.
All the config and styling options can be found [here](https://github.com/googlemaps/v3-utility-library/blob/master/markerclusterer/src/markerclusterer.js#L40).

### <a name="drawing-mode"></a>Drawing Mode

Allows usage of Google Maps' Drawing API to add Markers, Polylines, Polygons, Rectangles and Circles to the map instance. To allow this, simply set the defaults as below:
Expand Down
13 changes: 11 additions & 2 deletions src/configure.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ export interface ConfigInterface {
apiKey: string;
apiLibraries: string;
options: any;
markerCluster: {enable: boolean, src?: string, imagePath?: string, imageExtension?: string}
}

export class Configure {
Expand All @@ -15,12 +16,20 @@ export class Configure {
apiLibraries: '',
region: '',
language: '',
options: {}
options: {},
markerCluster: {
enable: false,
src: 'https://cdn.rawgit.com/googlemaps/v3-utility-library/99a385c1/markerclusterer/src/markerclusterer.js',
imagePath: 'https://raw.githubusercontent.com/googlemaps/v3-utility-library/99a385c1/markerclusterer/images/m',
imageExtension: 'png',
}
};
}

options(obj: ConfigInterface) {
Object.assign(this._config, obj);
Object.assign(this._config, obj, {
markerCluster: Object.assign({}, this._config.markerCluster, obj.markerCluster)
});
}

get(key: string) {
Expand Down
10 changes: 9 additions & 1 deletion src/google-maps-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,18 @@ export class GoogleMapsAPI {
// google has not been defined yet
let script = document.createElement('script');

let params = [
this.config.get('apiKey') ? `key=${this.config.get('apiKey')}&` : '',
this.config.get('apiLibraries') ? `libraries=${this.config.get('apiLibraries')}` : '',
this.config.get('language') ? `language=${this.config.get('language')}` : '',
this.config.get('region') ? `region=${this.config.get('region')}` : '',
'callback=aureliaGoogleMapsCallback',
];

script.type = 'text/javascript';
script.async = true;
script.defer = true;
script.src = `${this.config.get('apiScript')}?key=${this.config.get('apiKey')}&libraries=${this.config.get('apiLibraries')}&language=${this.config.get('language')}&region=${this.config.get('region')}&callback=aureliaGoogleMapsCallback`;
script.src = `${this.config.get('apiScript')}?${params.join('&')}`;
document.body.appendChild(script);

this._scriptPromise = new Promise((resolve, reject) => {
Expand Down
30 changes: 24 additions & 6 deletions src/google-maps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { getLogger } from 'aurelia-logging';

import { Configure } from './configure';
import { GoogleMapsAPI } from './google-maps-api';
import { MarkerClustering } from './marker-clustering';

import { Events } from './events';

Expand All @@ -26,13 +27,14 @@ export interface Marker {

@noView()
@customElement('google-map')
@inject(Element, TaskQueue, Configure, BindingEngine, GoogleMapsAPI)
@inject(Element, TaskQueue, Configure, BindingEngine, GoogleMapsAPI, MarkerClustering)
export class GoogleMaps {
private element: Element;
private taskQueue: TaskQueue;
private config: any;
private bindingEngine: BindingEngine;
private googleMapsApi: GoogleMapsAPI;
private markerClustering: MarkerClustering;
private _currentInfoWindow: any = null;

@bindable longitude: number = 0;
Expand Down Expand Up @@ -61,12 +63,20 @@ export class GoogleMaps {
public _renderedPolygons: any = [];
public _polygonsSubscription: any = null;

constructor(element: Element, taskQueue: TaskQueue, config: Configure, bindingEngine: BindingEngine, googleMapsApi: GoogleMapsAPI) {
constructor(
element: Element,
taskQueue: TaskQueue,
config: Configure,
bindingEngine: BindingEngine,
googleMapsApi: GoogleMapsAPI,
markerClustering: MarkerClustering,
) {
this.element = element;
this.taskQueue = taskQueue;
this.config = config;
this.bindingEngine = bindingEngine;
this.googleMapsApi = googleMapsApi;
this.markerClustering = markerClustering;

if (!config.get('apiScript')) {
logger.error('No API script is defined.');
Expand All @@ -75,7 +85,8 @@ export class GoogleMaps {
if (!config.get('apiKey') && config.get('apiKey') !== false) {
logger.error('No API key has been specified.');
}


this.markerClustering.loadScript();
this._scriptPromise = this.googleMapsApi.getMapsInstance();

let self: GoogleMaps = this;
Expand Down Expand Up @@ -120,6 +131,7 @@ export class GoogleMaps {
});

this._renderedMarkers = [];
this.markerClustering.renderClusters(this.map, []);
}

attached() {
Expand Down Expand Up @@ -289,6 +301,8 @@ export class GoogleMaps {

// Send up and event to let the parent know a new marker has been rendered
dispatchEvent(Events.MARKERRENDERED, { createdMarker, marker }, this.element);
}).then(() => {
this.markerClustering.renderClusters(this.map, this._renderedMarkers);
});
});
}
Expand Down Expand Up @@ -389,6 +403,8 @@ export class GoogleMaps {
// Wait until all of the renderMarker calls have been resolved
return Promise.all(markerPromises);
}).then(() => {
this.markerClustering.renderClusters(this.map, this._renderedMarkers);

/**
* We queue up a task to update the bounds, because in the case of multiple bound properties changing all at once,
* we need to let Aurelia handle updating the other properties before we actually trigger a re-render of the map
Expand Down Expand Up @@ -457,6 +473,8 @@ export class GoogleMaps {
* Wait for all of the promises to resolve for rendering markers
*/
Promise.all(renderPromises).then(() => {
this.markerClustering.renderClusters(this.map, this._renderedMarkers);

/**
* We queue up a task to update the bounds, because in the case of multiple bound properties changing all at once,
* we need to let Aurelia handle updating the other properties before we actually trigger a re-render of the map
Expand Down Expand Up @@ -568,7 +586,7 @@ export class GoogleMaps {

/**
* Get the given constant that Google's library uses. Defaults to MARKER
* @param type
* @param type
*/
getOverlayType(type: any = '') {
switch (type.toUpperCase()) {
Expand Down Expand Up @@ -605,7 +623,7 @@ export class GoogleMaps {

/**
* Update the drawing mode, called by aurelia binding
* @param newval
* @param newval
*/
drawModeChanged(newval: any = '') {
this.initDrawingManager()
Expand Down Expand Up @@ -821,4 +839,4 @@ function dispatchEvent(name: string, detail: any, target: Element, bubbles = tru
}

target.dispatchEvent(changeEvent);
}
}
35 changes: 35 additions & 0 deletions src/marker-clustering.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { inject } from 'aurelia-dependency-injection';
import { Configure } from './configure';

@inject(Configure)
export class MarkerClustering {
private config: Configure;

constructor(config) {
this.config = config;
}

isEnabled() {
return this.config.get('markerCluster') && this.config.get('markerCluster').enable;
}

loadScript() {
if (!this.isEnabled()) {
return;
}

let script = document.createElement('script');

script.type = 'text/javascript';
script.src = this.config.get('markerCluster').src;
document.body.appendChild(script);
}

renderClusters(map, markers) {
if (!this.isEnabled()) {
return;
}

new (<any>window).MarkerClusterer(map, markers, this.config.get('markerCluster'));
}
}

0 comments on commit 216b359

Please sign in to comment.