1 | import {Directive, EventEmitter, OnChanges, OnDestroy, OnInit, SimpleChange} from '@angular/core';
|
2 | import {Subscription} from 'rxjs/Subscription';
|
3 |
|
4 | import {MouseEvent} from '../map-types';
|
5 | import {LatLng, LatLngBounds, LatLngLiteral} from '../services/google-maps-types';
|
6 | import {MouseEvent as MapMouseEvent} from '../services/google-maps-types';
|
7 | import {CircleManager} from '../services/managers/circle-manager';
|
8 |
|
9 | @Directive({
|
10 | selector: 'sebm-google-map-circle',
|
11 | inputs: [
|
12 | 'latitude', 'longitude', 'clickable', 'draggable: circleDraggable', 'editable', 'fillColor',
|
13 | 'fillOpacity', 'radius', 'strokeColor', 'strokeOpacity', 'strokePosition', 'strokeWeight',
|
14 | 'visible', 'zIndex'
|
15 | ],
|
16 | outputs: [
|
17 | 'centerChange', 'circleClick', 'circleDblClick', 'drag', 'dragEnd', 'dragStart', 'mouseDown',
|
18 | 'mouseMove', 'mouseOut', 'mouseOver', 'mouseUp', 'radiusChange', 'rightClick'
|
19 | ]
|
20 | })
|
21 | export class SebmGoogleMapCircle implements OnInit, OnChanges, OnDestroy {
|
22 | |
23 |
|
24 |
|
25 | latitude: number;
|
26 |
|
27 | |
28 |
|
29 |
|
30 | longitude: number;
|
31 |
|
32 | |
33 |
|
34 |
|
35 | clickable: boolean = true;
|
36 |
|
37 | |
38 |
|
39 |
|
40 | draggable: boolean = false;
|
41 |
|
42 | |
43 |
|
44 |
|
45 |
|
46 | editable: boolean = false;
|
47 |
|
48 | |
49 |
|
50 |
|
51 | fillColor: string;
|
52 |
|
53 | |
54 |
|
55 |
|
56 | fillOpacity: number;
|
57 |
|
58 | |
59 |
|
60 |
|
61 | radius: number = 0;
|
62 |
|
63 | |
64 |
|
65 |
|
66 | strokeColor: string;
|
67 |
|
68 | |
69 |
|
70 |
|
71 | strokeOpacity: number;
|
72 |
|
73 | |
74 |
|
75 |
|
76 |
|
77 | strokePosition: 'CENTER'|'INSIDE'|'OUTSIDE' = 'CENTER';
|
78 |
|
79 | |
80 |
|
81 |
|
82 | strokeWeight: number = 0;
|
83 |
|
84 | |
85 |
|
86 |
|
87 | visible: boolean = true;
|
88 |
|
89 | |
90 |
|
91 |
|
92 | zIndex: number;
|
93 |
|
94 | |
95 |
|
96 |
|
97 | centerChange: EventEmitter<LatLngLiteral> = new EventEmitter<LatLngLiteral>();
|
98 |
|
99 | |
100 |
|
101 |
|
102 | circleClick: EventEmitter<MouseEvent> = new EventEmitter<MouseEvent>();
|
103 |
|
104 | |
105 |
|
106 |
|
107 | circleDblClick: EventEmitter<MouseEvent> = new EventEmitter<MouseEvent>();
|
108 |
|
109 | |
110 |
|
111 |
|
112 | drag: EventEmitter<MouseEvent> = new EventEmitter<MouseEvent>();
|
113 |
|
114 | |
115 |
|
116 |
|
117 | dragEnd: EventEmitter<MouseEvent> = new EventEmitter<MouseEvent>();
|
118 |
|
119 | |
120 |
|
121 |
|
122 | dragStart: EventEmitter<MouseEvent> = new EventEmitter<MouseEvent>();
|
123 |
|
124 | |
125 |
|
126 |
|
127 | mouseDown: EventEmitter<MouseEvent> = new EventEmitter<MouseEvent>();
|
128 |
|
129 | |
130 |
|
131 |
|
132 | mouseMove: EventEmitter<MouseEvent> = new EventEmitter<MouseEvent>();
|
133 |
|
134 | |
135 |
|
136 |
|
137 | mouseOut: EventEmitter<MouseEvent> = new EventEmitter<MouseEvent>();
|
138 |
|
139 | |
140 |
|
141 |
|
142 | mouseOver: EventEmitter<MouseEvent> = new EventEmitter<MouseEvent>();
|
143 |
|
144 | |
145 |
|
146 |
|
147 | mouseUp: EventEmitter<MouseEvent> = new EventEmitter<MouseEvent>();
|
148 |
|
149 | |
150 |
|
151 |
|
152 | radiusChange: EventEmitter<number> = new EventEmitter<number>();
|
153 |
|
154 | |
155 |
|
156 |
|
157 | rightClick: EventEmitter<MouseEvent> = new EventEmitter<MouseEvent>();
|
158 |
|
159 | private _circleAddedToManager: boolean = false;
|
160 |
|
161 | private static _mapOptions: string[] = [
|
162 | 'fillColor', 'fillOpacity', 'strokeColor', 'strokeOpacity', 'strokePosition', 'strokeWeight',
|
163 | 'visible', 'zIndex'
|
164 | ];
|
165 |
|
166 | private _eventSubscriptions: Subscription[] = [];
|
167 |
|
168 | constructor(private _manager: CircleManager) {}
|
169 |
|
170 |
|
171 | ngOnInit() {
|
172 | this._manager.addCircle(this);
|
173 | this._circleAddedToManager = true;
|
174 | this._registerEventListeners();
|
175 | }
|
176 |
|
177 |
|
178 | ngOnChanges(changes: {[key: string]: SimpleChange}) {
|
179 | if (!this._circleAddedToManager) {
|
180 | return;
|
181 | }
|
182 | if (changes['latitude'] || changes['longitude']) {
|
183 | this._manager.setCenter(this);
|
184 | }
|
185 | if (changes['editable']) {
|
186 | this._manager.setEditable(this);
|
187 | }
|
188 | if (changes['draggable']) {
|
189 | this._manager.setDraggable(this);
|
190 | }
|
191 | if (changes['visible']) {
|
192 | this._manager.setVisible(this);
|
193 | }
|
194 | if (changes['radius']) {
|
195 | this._manager.setRadius(this);
|
196 | }
|
197 | this._updateCircleOptionsChanges(changes);
|
198 | }
|
199 |
|
200 | private _updateCircleOptionsChanges(changes: {[propName: string]: SimpleChange}) {
|
201 | let options: {[propName: string]: any} = {};
|
202 | let optionKeys =
|
203 | Object.keys(changes).filter(k => SebmGoogleMapCircle._mapOptions.indexOf(k) !== -1);
|
204 | optionKeys.forEach((k) => { options[k] = changes[k].currentValue; });
|
205 | if (optionKeys.length > 0) {
|
206 | this._manager.setOptions(this, options);
|
207 | }
|
208 | }
|
209 |
|
210 | private _registerEventListeners() {
|
211 | let events: Map<string, EventEmitter<any>> = new Map<string, EventEmitter<any>>();
|
212 | events.set('center_changed', this.centerChange);
|
213 | events.set('click', this.circleClick);
|
214 | events.set('dblclick', this.circleDblClick);
|
215 | events.set('drag', this.drag);
|
216 | events.set('dragend', this.dragEnd);
|
217 | events.set('dragStart', this.dragStart);
|
218 | events.set('mousedown', this.mouseDown);
|
219 | events.set('mousemove', this.mouseMove);
|
220 | events.set('mouseout', this.mouseOut);
|
221 | events.set('mouseover', this.mouseOver);
|
222 | events.set('mouseup', this.mouseUp);
|
223 | events.set('radius_changed', this.radiusChange);
|
224 | events.set('rightclick', this.rightClick);
|
225 |
|
226 | events.forEach((eventEmitter, eventName) => {
|
227 | this._eventSubscriptions.push(
|
228 | this._manager.createEventObservable<MapMouseEvent>(eventName, this).subscribe((value) => {
|
229 | switch (eventName) {
|
230 | case 'radius_changed':
|
231 | this._manager.getRadius(this).then((radius) => eventEmitter.emit(radius));
|
232 | break;
|
233 | case 'center_changed':
|
234 | this._manager.getCenter(this).then(
|
235 | (center) =>
|
236 | eventEmitter.emit(<LatLngLiteral>{lat: center.lat(), lng: center.lng()}));
|
237 | break;
|
238 | default:
|
239 | eventEmitter.emit(
|
240 | <MouseEvent>{coords: {lat: value.latLng.lat(), lng: value.latLng.lng()}});
|
241 | }
|
242 | }));
|
243 | });
|
244 | }
|
245 |
|
246 | /** @internal */
|
247 | ngOnDestroy() {
|
248 | this._eventSubscriptions.forEach(function(s: Subscription) { s.unsubscribe(); });
|
249 | this._eventSubscriptions = null;
|
250 | this._manager.removeCircle(this);
|
251 | }
|
252 |
|
253 | /**
|
254 | * Gets the LatLngBounds of this Circle.
|
255 | */
|
256 | getBounds(): Promise<LatLngBounds> { return this._manager.getBounds(this); }
|
257 |
|
258 | getCenter(): Promise<LatLng> { return this._manager.getCenter(this); }
|
259 | }
|
260 |
|
\ | No newline at end of file |