UNPKG

8.28 kBPlain TextView Raw
1import {AfterContentInit, ContentChildren, Directive, EventEmitter, OnChanges, OnDestroy, QueryList, SimpleChanges} from '@angular/core';
2import {Subscription} from 'rxjs/Subscription';
3
4import {PolyMouseEvent} from '../services/google-maps-types';
5import {PolylineManager} from '../services/managers/polyline-manager';
6
7import {SebmGoogleMapPolylinePoint} from './google-map-polyline-point';
8
9let polylineId = 0;
10/**
11 * SebmGoogleMapPolyline renders a polyline on a {@link SebmGoogleMap}
12 *
13 * ### Example
14 * ```typescript
15 * import { Component } from 'angular2/core';
16 * import { SebmGoogleMap, SebmGooglePolyline, SebmGooglePolylinePoint } from
17 * 'angular2-google-maps/core';
18 *
19 * @Component({
20 * selector: 'my-map-cmp',
21 * directives: [SebmGoogleMap, SebmGooglePolyline, SebmGooglePolylinePoint],
22 * styles: [`
23 * .sebm-google-map-container {
24 * height: 300px;
25 * }
26 * `],
27 * template: `
28 * <sebm-google-map [latitude]="lat" [longitude]="lng" [zoom]="zoom">
29 * <sebm-google-map-polyline>
30 * <sebm-google-map-polyline-point [latitude]="latA" [longitude]="lngA">
31 * </sebm-google-map-polyline-point>
32 * <sebm-google-map-polyline-point [latitude]="latB" [longitude]="lngB">
33 * </sebm-google-map-polyline-point>
34 * </sebm-google-map-polyline>
35 * </sebm-google-map>
36 * `
37 * })
38 * ```
39 */
40@Directive({
41 selector: 'sebm-google-map-polyline',
42 inputs: [
43 'clickable', 'draggable: polylineDraggable', 'editable', 'geodesic', 'strokeColor',
44 'strokeWeight', 'strokeOpacity', 'visible', 'zIndex'
45 ],
46 outputs: [
47 'lineClick', 'lineDblClick', 'lineDrag', 'lineDragEnd', 'lineMouseDown', 'lineMouseMove',
48 'lineMouseOut', 'lineMouseOver', 'lineMouseUp', 'lineRightClick'
49 ]
50})
51export class SebmGoogleMapPolyline implements OnDestroy, OnChanges, AfterContentInit {
52 /**
53 * Indicates whether this Polyline handles mouse events. Defaults to true.
54 */
55 clickable: boolean = true;
56
57 /**
58 * If set to true, the user can drag this shape over the map. The geodesic property defines the
59 * mode of dragging. Defaults to false.
60 */
61 draggable: boolean = false;
62
63 /**
64 * If set to true, the user can edit this shape by dragging the control points shown at the
65 * vertices and on each segment. Defaults to false.
66 */
67 editable: boolean = false;
68
69 /**
70 * When true, edges of the polygon are interpreted as geodesic and will follow the curvature of
71 * the Earth. When false, edges of the polygon are rendered as straight lines in screen space.
72 * Note that the shape of a geodesic polygon may appear to change when dragged, as the dimensions
73 * are maintained relative to the surface of the earth. Defaults to false.
74 */
75 geodesic: boolean = false;
76
77 /**
78 * The stroke color. All CSS3 colors are supported except for extended named colors.
79 */
80 strokeColor: string;
81
82 /**
83 * The stroke opacity between 0.0 and 1.0.
84 */
85 strokeOpacity: number;
86
87 /**
88 * The stroke width in pixels.
89 */
90 strokeWeight: number;
91
92 /**
93 * Whether this polyline is visible on the map. Defaults to true.
94 */
95 visible: boolean = true;
96
97 /**
98 * The zIndex compared to other polys.
99 */
100 zIndex: number;
101
102 /**
103 * This event is fired when the DOM click event is fired on the Polyline.
104 */
105 lineClick: EventEmitter<PolyMouseEvent> = new EventEmitter<PolyMouseEvent>();
106
107 /**
108 * This event is fired when the DOM dblclick event is fired on the Polyline.
109 */
110 lineDblClick: EventEmitter<PolyMouseEvent> = new EventEmitter<PolyMouseEvent>();
111
112 /**
113 * This event is repeatedly fired while the user drags the polyline.
114 */
115 lineDrag: EventEmitter<MouseEvent> = new EventEmitter<MouseEvent>();
116
117 /**
118 * This event is fired when the user stops dragging the polyline.
119 */
120 lineDragEnd: EventEmitter<MouseEvent> = new EventEmitter<MouseEvent>();
121
122 /**
123 * This event is fired when the user starts dragging the polyline.
124 */
125 lineDragStart: EventEmitter<MouseEvent> = new EventEmitter<MouseEvent>();
126
127 /**
128 * This event is fired when the DOM mousedown event is fired on the Polyline.
129 */
130 lineMouseDown: EventEmitter<PolyMouseEvent> = new EventEmitter<PolyMouseEvent>();
131
132 /**
133 * This event is fired when the DOM mousemove event is fired on the Polyline.
134 */
135 lineMouseMove: EventEmitter<PolyMouseEvent> = new EventEmitter<PolyMouseEvent>();
136
137 /**
138 * This event is fired on Polyline mouseout.
139 */
140 lineMouseOut: EventEmitter<PolyMouseEvent> = new EventEmitter<PolyMouseEvent>();
141
142 /**
143 * This event is fired on Polyline mouseover.
144 */
145 lineMouseOver: EventEmitter<PolyMouseEvent> = new EventEmitter<PolyMouseEvent>();
146
147 /**
148 * This event is fired whe the DOM mouseup event is fired on the Polyline
149 */
150 lineMouseUp: EventEmitter<PolyMouseEvent> = new EventEmitter<PolyMouseEvent>();
151
152 /**
153 * This even is fired when the Polyline is right-clicked on.
154 */
155 lineRightClick: EventEmitter<PolyMouseEvent> = new EventEmitter<PolyMouseEvent>();
156
157 /**
158 * @internal
159 */
160 @ContentChildren(SebmGoogleMapPolylinePoint) points: QueryList<SebmGoogleMapPolylinePoint>;
161
162 private static _polylineOptionsAttributes: Array<string> = [
163 'draggable', 'editable', 'visible', 'geodesic', 'strokeColor', 'strokeOpacity', 'strokeWeight',
164 'zIndex'
165 ];
166
167 private _id: string;
168 private _polylineAddedToManager: boolean = false;
169 private _subscriptions: Subscription[] = [];
170
171 constructor(private _polylineManager: PolylineManager) { this._id = (polylineId++).toString(); }
172
173 /** @internal */
174 ngAfterContentInit() {
175 if (this.points.length) {
176 this.points.forEach((point: SebmGoogleMapPolylinePoint) => {
177 const s = point.positionChanged.subscribe(
178 () => { this._polylineManager.updatePolylinePoints(this); });
179 this._subscriptions.push(s);
180 });
181 }
182 if (!this._polylineAddedToManager) {
183 this._init();
184 }
185 const s = this.points.changes.subscribe(() => this._polylineManager.updatePolylinePoints(this));
186 this._subscriptions.push(s);
187 this._polylineManager.updatePolylinePoints(this);
188 }
189
190 ngOnChanges(changes: SimpleChanges): any {
191 if (!this._polylineAddedToManager) {
192 this._init();
193 return;
194 }
195
196 let options: {[propName: string]: any} = {};
197 const optionKeys = Object.keys(changes).filter(
198 k => SebmGoogleMapPolyline._polylineOptionsAttributes.indexOf(k) !== -1);
199 optionKeys.forEach(k => options[k] = changes[k].currentValue);
200 this._polylineManager.setPolylineOptions(this, options);
201 }
202
203 private _init() {
204 this._polylineManager.addPolyline(this);
205 this._polylineAddedToManager = true;
206 this._addEventListeners();
207 }
208
209 private _addEventListeners() {
210 const handlers = [
211 {name: 'click', handler: (ev: PolyMouseEvent) => this.lineClick.emit(ev)},
212 {name: 'dbclick', handler: (ev: PolyMouseEvent) => this.lineDblClick.emit(ev)},
213 {name: 'drag', handler: (ev: MouseEvent) => this.lineDrag.emit(ev)},
214 {name: 'dragend', handler: (ev: MouseEvent) => this.lineDragEnd.emit(ev)},
215 {name: 'dragstart', handler: (ev: MouseEvent) => this.lineDragStart.emit(ev)},
216 {name: 'mousedown', handler: (ev: PolyMouseEvent) => this.lineMouseDown.emit(ev)},
217 {name: 'mousemove', handler: (ev: PolyMouseEvent) => this.lineMouseMove.emit(ev)},
218 {name: 'mouseout', handler: (ev: PolyMouseEvent) => this.lineMouseOut.emit(ev)},
219 {name: 'mouseover', handler: (ev: PolyMouseEvent) => this.lineMouseOver.emit(ev)},
220 {name: 'mouseup', handler: (ev: PolyMouseEvent) => this.lineMouseUp.emit(ev)},
221 {name: 'rightclick', handler: (ev: PolyMouseEvent) => this.lineRightClick.emit(ev)},
222 ];
223 handlers.forEach((obj) => {
224 const os = this._polylineManager.createEventObservable(obj.name, this).subscribe(obj.handler);
225 this._subscriptions.push(os);
226 });
227 }
228
229 /** @internal */
230 _getPoints(): Array<SebmGoogleMapPolylinePoint> {
231 if (this.points) {
232 return this.points.toArray();
233 }
234 return [];
235 }
236
237 /** @internal */
238 id(): string { return this._id; }
239
240 /** @internal */
241 ngOnDestroy() {
242 this._polylineManager.deletePolyline(this);
243 // unsubscribe all registered observable subscriptions
244 this._subscriptions.forEach((s) => s.unsubscribe());
245 }
246}