import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core'; import { Observable } from 'rxjs/Rx'; import { MapboxService } from '../services/mapbox.service'; import { mapEvent } from './enums'; import { Layer, Source, sourceType, Marker } from '../class/class'; import { Control } from '../interface/control'; @Component({ selector: 'ng-mapbox', templateUrl: './mapbox.component.html', styleUrls: ['./mapbox.component.css'] }) export class MapboxComponent implements OnInit { @Input() config: any; @Input() instructions: Observable<{ instruction: mapEvent, data: any }>; @Output() map: EventEmitter; @Output() informations: EventEmitter; private _map: any; private navigationControl: Control; private scaleCotnrol: Control; private sources: Array; private layers: Array; private markers: Array; constructor(private mapboxService: MapboxService) { this.map = new EventEmitter(); this.informations = new EventEmitter(); } ngOnInit() { // make options parametre if (!this.config) { this.config = { container: 'map', style: 'mapbox://styles/mapbox/streets-v10', center: [2.8011015372085524, 47.22019371754817], zoom: 5, pitch: 0, bearing: 0, } } this.sources = []; this.layers = []; this.markers = []; this._map = this.mapboxService.createMap(this.config); this._map.on('load', () => { this.map.emit(this._map); }); if (this.instructions) { this.instructions.subscribe(setUp => this.handleInstruction(setUp)); } } /** * Handle event flow */ private handleInstruction(setUp: { instruction: mapEvent, data: any }) { switch (setUp.instruction) { // Handle controls case 'addControl': this.mapboxService.addControl(this._map, setUp.data.control, setUp.data.position); break; case 'removeControl': this.mapboxService.addControl(this._map, setUp.data.control); break; case 'addNavigationControl': if (!this.navigationControl) { this.navigationControl = this.mapboxService.addNavigationControl(this._map, setUp.data.position); } break; case 'removeNavigationControl': if (this.navigationControl) { this.mapboxService.removeControl(this._map, this.navigationControl); this.navigationControl = null; } break; case 'addScaleControl': if (!this.scaleCotnrol) { this.scaleCotnrol = this.mapboxService.addScaleControl(this._map, setUp.data.position, setUp.data.options); } break; case 'removeScaleControl': if (this.scaleCotnrol) { this.mapboxService.removeControl(this._map, this.scaleCotnrol); this.scaleCotnrol = null; } break; // handle Sources case 'addSource': if ((setUp.data.id && !this.sources.find((source: Source) => source.id === setUp.data.id)) || !setUp.data.id) { let source if (setUp.data instanceof Source) { source = setUp.data; } else { source = new Source(setUp.data); } this.mapboxService.addSource(this._map, source); this.sources.push(source); this.informations.emit({ information: 'source', data: source }); } break; case 'removeSource': let source = this.sources.find((source: Source) => source.id === setUp.data.id); let isSourceNotUsed = this.layers.findIndex((layer: Layer) => source.id === layer.source) === -1; if (source && isSourceNotUsed) { this.mapboxService.removeSource(this._map, source); let index = this.sources.findIndex((source: Source) => source.id === setUp.data.id); this.sources.splice(index, 1); } break; // handle Layers case 'addLayer': let layerNotExist = this.layers.findIndex((layer: Layer) => setUp.data.id === layer.id) === -1; let sourceExist = this.sources.findIndex((source: Source) => source.id === setUp.data.source) !== -1; if (layerNotExist && sourceExist) { if (setUp.data instanceof Layer) { this.mapboxService.addLayer(this._map, setUp.data); this.layers.push(setUp.data); } else { this.mapboxService.addLayer(this._map, new Layer(setUp.data)); this.layers.push(new Layer(setUp.data)); } } break; case 'removeLayer': let layer = this.layers.find((layer: Layer) => layer.id === setUp.data.id) if (layer) { this.mapboxService.removeLayer(this._map, layer); let index = this.layers.findIndex((layer: Layer) => layer.id === setUp.data.id); this.layers.splice(index); } break; // handle Markers case 'addMarker': let marker: Marker; if (setUp.data instanceof Marker) { marker = setUp.data; } else { marker = new Marker(setUp.data); } marker.addTo(this._map); this.markers.push(marker); this.informations.emit({ information: 'marker', data: marker }); break; case 'removeMarker': let markerToRemove: Marker; if (setUp.data instanceof Marker) { markerToRemove = setUp.data; } else { markerToRemove = this.markers.find((marker: Marker) => marker.id === setUp.data.id); if (!markerToRemove) { return; } } markerToRemove.remove(); this.markers.splice(this.markers.findIndex((marker: Marker) => marker.id === setUp.data.id), 1); break; case 'addListener': this.mapboxService.addListener(this._map, setUp.data.event, setUp.data.listener); break; case 'addListenerOnce': this.mapboxService.addListenerOnce(this._map, setUp.data.event, setUp.data.listener); break; case 'removeListener': this.mapboxService.removeListener(this._map, setUp.data.event, setUp.data.listener); break; default: break; } } }