1 | import {AfterContentInit, ContentChild, Directive, EventEmitter, OnChanges, OnDestroy, SimpleChange} from '@angular/core';
|
2 | import {Subscription} from 'rxjs/Subscription';
|
3 |
|
4 | import {MouseEvent} from '../map-types';
|
5 | import * as mapTypes from '../services/google-maps-types';
|
6 | import {MarkerManager} from '../services/managers/marker-manager';
|
7 |
|
8 | import {SebmGoogleMapInfoWindow} from './google-map-info-window';
|
9 |
|
10 | let markerId = 0;
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 |
|
22 |
|
23 |
|
24 |
|
25 |
|
26 |
|
27 |
|
28 |
|
29 |
|
30 |
|
31 |
|
32 |
|
33 |
|
34 |
|
35 |
|
36 |
|
37 | @Directive({
|
38 | selector: 'sebm-google-map-marker',
|
39 | inputs: [
|
40 | 'latitude', 'longitude', 'title', 'label', 'draggable: markerDraggable', 'iconUrl',
|
41 | 'openInfoWindow', 'opacity', 'visible', 'zIndex'
|
42 | ],
|
43 | outputs: ['markerClick', 'dragEnd', 'mouseOver', 'mouseOut']
|
44 | })
|
45 | export class SebmGoogleMapMarker implements OnDestroy, OnChanges, AfterContentInit {
|
46 | |
47 |
|
48 |
|
49 | latitude: number;
|
50 |
|
51 | |
52 |
|
53 |
|
54 | longitude: number;
|
55 |
|
56 | |
57 |
|
58 |
|
59 | title: string;
|
60 |
|
61 | |
62 |
|
63 |
|
64 | label: string;
|
65 |
|
66 | |
67 |
|
68 |
|
69 | draggable: boolean = false;
|
70 |
|
71 | |
72 |
|
73 |
|
74 | iconUrl: string;
|
75 |
|
76 | |
77 |
|
78 |
|
79 | visible: boolean = true;
|
80 |
|
81 | |
82 |
|
83 |
|
84 | openInfoWindow: boolean = true;
|
85 |
|
86 | |
87 |
|
88 |
|
89 | opacity: number = 1;
|
90 |
|
91 | |
92 |
|
93 |
|
94 |
|
95 |
|
96 |
|
97 | zIndex: number = 1;
|
98 |
|
99 | |
100 |
|
101 |
|
102 | markerClick: EventEmitter<void> = new EventEmitter<void>();
|
103 |
|
104 | |
105 |
|
106 |
|
107 | dragEnd: EventEmitter<MouseEvent> = new EventEmitter<MouseEvent>();
|
108 |
|
109 | |
110 |
|
111 |
|
112 | mouseOver: EventEmitter<MouseEvent> = new EventEmitter<MouseEvent>();
|
113 |
|
114 | |
115 |
|
116 |
|
117 | mouseOut: EventEmitter<MouseEvent> = new EventEmitter<MouseEvent>();
|
118 |
|
119 | |
120 |
|
121 |
|
122 | @ContentChild(SebmGoogleMapInfoWindow) infoWindow: SebmGoogleMapInfoWindow;
|
123 |
|
124 | private _markerAddedToManger: boolean = false;
|
125 | private _id: string;
|
126 | private _observableSubscriptions: Subscription[] = [];
|
127 |
|
128 | constructor(private _markerManager: MarkerManager) { this._id = (markerId++).toString(); }
|
129 |
|
130 |
|
131 | ngAfterContentInit() {
|
132 | if (this.infoWindow != null) {
|
133 | this.infoWindow.hostMarker = this;
|
134 | }
|
135 | }
|
136 |
|
137 |
|
138 | ngOnChanges(changes: {[key: string]: SimpleChange}) {
|
139 | if (typeof this.latitude !== 'number' || typeof this.longitude !== 'number') {
|
140 | return;
|
141 | }
|
142 | if (!this._markerAddedToManger) {
|
143 | this._markerManager.addMarker(this);
|
144 | this._markerAddedToManger = true;
|
145 | this._addEventListeners();
|
146 | return;
|
147 | }
|
148 | if (changes['latitude'] || changes['longitude']) {
|
149 | this._markerManager.updateMarkerPosition(this);
|
150 | }
|
151 | if (changes['title']) {
|
152 | this._markerManager.updateTitle(this);
|
153 | }
|
154 | if (changes['label']) {
|
155 | this._markerManager.updateLabel(this);
|
156 | }
|
157 | if (changes['draggable']) {
|
158 | this._markerManager.updateDraggable(this);
|
159 | }
|
160 | if (changes['iconUrl']) {
|
161 | this._markerManager.updateIcon(this);
|
162 | }
|
163 | if (changes['opacity']) {
|
164 | this._markerManager.updateOpacity(this);
|
165 | }
|
166 | if (changes['visible']) {
|
167 | this._markerManager.updateVisible(this);
|
168 | }
|
169 | if (changes['zIndex']) {
|
170 | this._markerManager.updateZIndex(this);
|
171 | }
|
172 | }
|
173 |
|
174 | private _addEventListeners() {
|
175 | const cs = this._markerManager.createEventObservable('click', this).subscribe(() => {
|
176 | if (this.openInfoWindow && this.infoWindow != null) {
|
177 | this.infoWindow.open();
|
178 | }
|
179 | this.markerClick.emit(null);
|
180 | });
|
181 | this._observableSubscriptions.push(cs);
|
182 |
|
183 | const ds =
|
184 | this._markerManager.createEventObservable<mapTypes.MouseEvent>('dragend', this)
|
185 | .subscribe((e: mapTypes.MouseEvent) => {
|
186 | this.dragEnd.emit(<MouseEvent>{coords: {lat: e.latLng.lat(), lng: e.latLng.lng()}});
|
187 | });
|
188 | this._observableSubscriptions.push(ds);
|
189 |
|
190 | const mover =
|
191 | this._markerManager.createEventObservable<mapTypes.MouseEvent>('mouseover', this)
|
192 | .subscribe((e: mapTypes.MouseEvent) => {
|
193 | this.mouseOver.emit(<MouseEvent>{coords: {lat: e.latLng.lat(), lng: e.latLng.lng()}});
|
194 | });
|
195 | this._observableSubscriptions.push(mover);
|
196 |
|
197 | const mout =
|
198 | this._markerManager.createEventObservable<mapTypes.MouseEvent>('mouseout', this)
|
199 | .subscribe((e: mapTypes.MouseEvent) => {
|
200 | this.mouseOut.emit(<MouseEvent>{coords: {lat: e.latLng.lat(), lng: e.latLng.lng()}});
|
201 | });
|
202 | this._observableSubscriptions.push(mout);
|
203 | }
|
204 |
|
205 |
|
206 | id(): string { return this._id; }
|
207 |
|
208 |
|
209 | toString(): string { return 'SebmGoogleMapMarker-' + this._id.toString(); }
|
210 |
|
211 |
|
212 | ngOnDestroy() {
|
213 | this._markerManager.deleteMarker(this);
|
214 |
|
215 | this._observableSubscriptions.forEach((s) => s.unsubscribe());
|
216 | }
|
217 | }
|