Skip to content
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

feat(*): support Circle #449

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/core/directives-const.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {SebmGoogleMap} from './directives/google-map';
import {SebmGoogleMapCircle} from './directives/google-map-circle';
import {SebmGoogleMapInfoWindow} from './directives/google-map-info-window';
import {SebmGoogleMapMarker} from './directives/google-map-marker';

export const GOOGLE_MAPS_DIRECTIVES: any[] =
[SebmGoogleMap, SebmGoogleMapMarker, SebmGoogleMapInfoWindow];
[SebmGoogleMap, SebmGoogleMapMarker, SebmGoogleMapInfoWindow, SebmGoogleMapCircle];
1 change: 1 addition & 0 deletions src/core/directives.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export {GOOGLE_MAPS_DIRECTIVES} from './directives-const';
export {SebmGoogleMap} from './directives/google-map';
export {SebmGoogleMapCircle} from './directives/google-map-circle';
export {SebmGoogleMapInfoWindow} from './directives/google-map-info-window';
export {SebmGoogleMapMarker} from './directives/google-map-marker';
259 changes: 259 additions & 0 deletions src/core/directives/google-map-circle.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,259 @@
import {Directive, EventEmitter, OnChanges, OnDestroy, OnInit, SimpleChange} from '@angular/core';
import {Subscription} from 'rxjs/Subscription';

import {MouseEvent} from '../events';
import {LatLng, LatLngBounds, LatLngLiteral} from '../services/google-maps-types';
import {MouseEvent as MapMouseEvent} from '../services/google-maps-types';
import {CircleManager} from '../services/managers/circle-manager';

@Directive({
selector: 'sebm-google-map-circle',
inputs: [
'latitude', 'longitude', 'clickable', 'draggable: circleDraggable', 'editable', 'fillColor',
'fillOpacity', 'radius', 'strokeColor', 'strokeOpacity', 'strokePosition', 'strokeWeight',
'visible', 'zIndex'
],
outputs: [
'centerChange', 'circleClick', 'circleDblclick', 'drag', 'dragEnd', 'dragStart', 'mouseDown',
'mouseMove', 'mouseOut', 'mouseOver', 'mouseUp', 'radiusChange', 'rightClick'
]
})
export class SebmGoogleMapCircle implements OnInit,
OnChanges, OnDestroy {
/**
* The latitude position of the circle (required).
*/
latitude: number;

/**
* The clickable position of the circle (required).
*/
longitude: number;

/**
* Indicates whether this Circle handles mouse events. Defaults to true.
*/
clickable: boolean = true;

/**
* If set to true, the user can drag this circle over the map. Defaults to false.
*/
draggable: boolean = false;

/**
* If set to true, the user can edit this circle by dragging the control points shown at
* the center and around the circumference of the circle. Defaults to false.
*/
editable: boolean = false;

/**
* The fill color. All CSS3 colors are supported except for extended named colors.
*/
fillColor: string;

/**
* The fill opacity between 0.0 and 1.0.
*/
fillOpacity: number;

/**
* The radius in meters on the Earth's surface.
*/
radius: number = 0;

/**
* The stroke color. All CSS3 colors are supported except for extended named colors.
*/
strokeColor: string;

/**
* The stroke opacity between 0.0 and 1.0
*/
strokeOpacity: number;

/**
* The stroke position. Defaults to CENTER.
* This property is not supported on Internet Explorer 8 and earlier.
*/
strokePosition: 'CENTER'|'INSIDE'|'OUTSIDE' = 'CENTER';

/**
* The stroke width in pixels.
*/
strokeWeight: number = 0;

/**
* Whether this circle is visible on the map. Defaults to true.
*/
visible: boolean = true;

/**
* The zIndex compared to other polys.
*/
zIndex: number;

/**
* This event is fired when the circle's center is changed.
*/
centerChange: EventEmitter<LatLngLiteral> = new EventEmitter<LatLngLiteral>();

/**
* This event emitter gets emitted when the user clicks on the circle.
*/
circleClick: EventEmitter<MouseEvent> = new EventEmitter<MouseEvent>();

/**
* This event emitter gets emitted when the user clicks on the circle.
*/
circleDblClick: EventEmitter<MouseEvent> = new EventEmitter<MouseEvent>();

/**
* This event is repeatedly fired while the user drags the circle.
*/
drag: EventEmitter<MouseEvent> = new EventEmitter<MouseEvent>();

/**
* This event is fired when the user stops dragging the circle.
*/
dragEnd: EventEmitter<MouseEvent> = new EventEmitter<MouseEvent>();

/**
* This event is fired when the user starts dragging the circle.
*/
dragStart: EventEmitter<MouseEvent> = new EventEmitter<MouseEvent>();

/**
* This event is fired when the DOM mousedown event is fired on the circle.
*/
mouseDown: EventEmitter<MouseEvent> = new EventEmitter<MouseEvent>();

/**
* This event is fired when the DOM mousemove event is fired on the circle.
*/
mouseMove: EventEmitter<MouseEvent> = new EventEmitter<MouseEvent>();

/**
* This event is fired on circle mouseout.
*/
mouseOut: EventEmitter<MouseEvent> = new EventEmitter<MouseEvent>();

/**
* This event is fired on circle mouseover.
*/
mouseOver: EventEmitter<MouseEvent> = new EventEmitter<MouseEvent>();

/**
* This event is fired when the DOM mouseup event is fired on the circle.
*/
mouseUp: EventEmitter<MouseEvent> = new EventEmitter<MouseEvent>();

/**
* This event is fired when the circle's radius is changed.
*/
radiusChange: EventEmitter<number> = new EventEmitter<number>();

/**
* This event is fired when the circle is right-clicked on.
*/
rightClick: EventEmitter<MouseEvent> = new EventEmitter<MouseEvent>();

private _circleAddedToManager: boolean = false;

private static _mapOptions: string[] = [
'fillColor', 'fillOpacity', 'strokeColor', 'strokeOpacity', 'strokePosition', 'strokeWeight',
'visible', 'zIndex'
];

private _eventSubscriptions: Subscription[] = [];

constructor(private _manager: CircleManager) {}

/** @internal */
ngOnInit() {
this._manager.addCircle(this);
this._circleAddedToManager = true;
this._registerEventListeners();
}

/** @internal */
ngOnChanges(changes: {[key: string]: SimpleChange}) {
if (!this._circleAddedToManager) {
return;
}
if (changes['latitude'] || changes['longitude']) {
this._manager.setCenter(this);
}
if (changes['editable']) {
this._manager.setEditable(this);
}
if (changes['draggable']) {
this._manager.setDraggable(this);
}
if (changes['visible']) {
this._manager.setVisible(this);
}
if (changes['radius']) {
this._manager.setRadius(this);
}
this._updateCircleOptionsChanges(changes);
}

private _updateCircleOptionsChanges(changes: {[propName: string]: SimpleChange}) {
let options: {[propName: string]: any} = {};
let optionKeys =
Object.keys(changes).filter(k => SebmGoogleMapCircle._mapOptions.indexOf(k) !== -1);
optionKeys.forEach((k) => { options[k] = changes[k].currentValue; });
if (optionKeys.length > 0) {
this._manager.setOptions(this, options);
}
}

private _registerEventListeners() {
let events: Map<string, EventEmitter<any>> = new Map<string, EventEmitter<any>>();
events.set('center_changed', this.centerChange);
events.set('click', this.circleClick);
events.set('dblclick', this.circleDblClick);
events.set('drag', this.drag);
events.set('dragend', this.dragEnd);
events.set('dragStart', this.dragStart);
events.set('mousedown', this.mouseDown);
events.set('mousemove', this.mouseMove);
events.set('mouseout', this.mouseOut);
events.set('mouseover', this.mouseOver);
events.set('mouseup', this.mouseUp);
events.set('radius_changed', this.radiusChange);
events.set('rightclick', this.rightClick);

events.forEach((eventEmitter, eventName) => {
this._eventSubscriptions.push(
this._manager.createEventObservable<MapMouseEvent>(eventName, this).subscribe((value) => {
switch (eventName) {
case 'radius_changed':
this._manager.getRadius(this).then((radius) => eventEmitter.emit(radius));
break;
case 'center_changed':
this._manager.getCenter(this).then(
(center) =>
eventEmitter.emit(<LatLngLiteral>{lat: center.lat(), lng: center.lng()}));
break;
default:
eventEmitter.emit(
<MouseEvent>{coords: {lat: value.latLng.lat(), lng: value.latLng.lng()}});
}
}));
});
}

/** @internal */
ngOnDestroy() {
this._eventSubscriptions.forEach(function(s: Subscription) { s.unsubscribe(); });
this._eventSubscriptions = null;
}

/**
* Gets the LatLngBounds of this Circle.
*/
getBounds(): Promise<LatLngBounds> { return this._manager.getBounds(this); }

getCenter(): Promise<LatLng> { return this._manager.getCenter(this); }
}
2 changes: 1 addition & 1 deletion src/core/directives/google-map-info-window.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {Component, ElementRef, EventEmitter, OnChanges, OnDestroy, SimpleChange} from '@angular/core';

import {InfoWindowManager} from '../services/info-window-manager';
import {InfoWindowManager} from '../services/managers/info-window-manager';

import {SebmGoogleMapMarker} from './google-map-marker';

Expand Down
2 changes: 1 addition & 1 deletion src/core/directives/google-map-marker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import {AfterContentInit, ContentChild, Directive, EventEmitter, OnChanges, OnDe

import {MouseEvent} from '../events';
import * as mapTypes from '../services/google-maps-types';
import {MarkerManager} from '../services/marker-manager';
import {MarkerManager} from '../services/managers/marker-manager';

import {SebmGoogleMapInfoWindow} from './google-map-info-window';

Expand Down
7 changes: 4 additions & 3 deletions src/core/directives/google-map.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ import {MouseEvent} from '../events';
import {GoogleMapsAPIWrapper} from '../services/google-maps-api-wrapper';
import {LatLng, LatLngLiteral} from '../services/google-maps-types';
import {MapTypeStyle} from '../services/google-maps-types';
import {InfoWindowManager} from '../services/info-window-manager';
import {MarkerManager} from '../services/marker-manager';
import {CircleManager} from '../services/managers/circle-manager';
import {InfoWindowManager} from '../services/managers/info-window-manager';
import {MarkerManager} from '../services/managers/marker-manager';

/**
* SebMGoogleMap renders a Google Map.
Expand Down Expand Up @@ -35,7 +36,7 @@ import {MarkerManager} from '../services/marker-manager';
*/
@Component({
selector: 'sebm-google-map',
providers: [GoogleMapsAPIWrapper, MarkerManager, InfoWindowManager],
providers: [GoogleMapsAPIWrapper, MarkerManager, InfoWindowManager, CircleManager],
inputs: [
'longitude', 'latitude', 'zoom', 'disableDoubleClickZoom', 'disableDefaultUI', 'scrollwheel',
'backgroundColor', 'draggableCursor', 'draggingCursor', 'keyboardShortcuts', 'zoomControl',
Expand Down
5 changes: 3 additions & 2 deletions src/core/services.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
export {GoogleMapsAPIWrapper} from './services/google-maps-api-wrapper';
export {InfoWindowManager} from './services/info-window-manager';
export {CircleManager} from './services/managers/circle-manager';
export {InfoWindowManager} from './services/managers/info-window-manager';
export {MarkerManager} from './services/managers/marker-manager';
export {GoogleMapsScriptProtocol, LazyMapsAPILoader, LazyMapsAPILoaderConfig, LazyMapsAPILoaderConfigLiteral, provideLazyMapsAPILoaderConfig} from './services/maps-api-loader/lazy-maps-api-loader';
export {MapsAPILoader} from './services/maps-api-loader/maps-api-loader';
export {NoOpMapsAPILoader} from './services/maps-api-loader/noop-maps-api-loader';
export {MarkerManager} from './services/marker-manager';
10 changes: 10 additions & 0 deletions src/core/services/google-maps-api-wrapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,16 @@ export class GoogleMapsAPIWrapper {
return this._map.then(() => { return new google.maps.InfoWindow(options); });
}

/**
* Creates a google.map.Circle for the current map.
*/
createCircle(options: mapTypes.CircleOptions): Promise<mapTypes.Circle> {
return this._map.then((map: mapTypes.GoogleMap) => {
options.map = map;
return new google.maps.Circle(options);
});
}

subscribeToMapEvent<E>(eventName: string): Observable<E> {
return Observable.create((observer: Observer<E>) => {
this._map.then((m: mapTypes.GoogleMap) => {
Expand Down
Loading