153 lines
4.2 KiB
TypeScript
153 lines
4.2 KiB
TypeScript
import { Directive, OnChanges, SimpleChanges, EventEmitter, Input, Output, OnInit } from '@angular/core';
|
|
import { Map, Control, MapOptions, LatLngBoundsExpression, tileLayer } from 'leaflet';
|
|
// import { MarkerService } from '../services/marker.service';
|
|
import { LayerOptions, LayerMap } from './map-options';
|
|
|
|
const DEFAULT_BASE_LAYER_NAME = 'BaseLayer';
|
|
const DEFAULT_BASE_LAYER_URL = 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png';
|
|
const DEFAULT_BASE_LAYER_ATTRIBUTION = '© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors';
|
|
|
|
// @Component({
|
|
// selector: 'app-map',
|
|
// templateUrl: './map.component.html',
|
|
// styleUrls: ['./map.component.css'],
|
|
// // providers: [MarkerService]
|
|
// })
|
|
// https://52north.github.io/helgoland-toolbox/classes/CachedMapComponent.html#source
|
|
|
|
@Directive()
|
|
export abstract class BaseMapComponent implements OnChanges, OnInit {
|
|
|
|
/**
|
|
* A map with the given ID is created inside this component. This ID can be used the get the map instance over the map cache service.
|
|
*/
|
|
@Input()
|
|
public mapId: string;
|
|
|
|
/**
|
|
* @input The serviceUrl, where the selection should be loaded.
|
|
*/
|
|
@Input()
|
|
public serviceUrl: string;
|
|
|
|
/**
|
|
* The corresponding leaflet map options (see: https://leafletjs.com/reference-1.3.4.html#map-option)
|
|
*/
|
|
@Input()
|
|
public mapOptions: MapOptions;
|
|
|
|
// markerService: MarkerService
|
|
/**
|
|
* Bounds for the map
|
|
*/
|
|
@Input()
|
|
public fitBounds: LatLngBoundsExpression;
|
|
|
|
/**
|
|
* Describes the the zoom control options (see: https://leafletjs.com/reference-1.3.4.html#control-zoom)
|
|
*/
|
|
@Input()
|
|
public zoomControlOptions: Control.ZoomOptions;
|
|
|
|
@Input()
|
|
public baseMaps: LayerMap;
|
|
|
|
/**
|
|
* Informs when initialization is done with map id.
|
|
*/
|
|
@Output()
|
|
public onMapInitializedEvent: EventEmitter<string> = new EventEmitter();
|
|
|
|
protected oldBaseLayer: Control.LayersObject = {};
|
|
protected map: Map;
|
|
protected zoomControl: Control.Zoom;
|
|
|
|
constructor() { }
|
|
// constructor(private markerService: MarkerService) { }
|
|
// constructor(markerService: MarkerService) {
|
|
// this.markerService = markerService;
|
|
// }
|
|
|
|
public ngOnInit(): void {
|
|
if (this.mapId === undefined || this.mapId === null) {
|
|
this.mapId = this.generateUUID();
|
|
}
|
|
}
|
|
|
|
private generateUUID(): string {
|
|
function s4() {
|
|
return Math.floor((1 + Math.random()) * 0x10000)
|
|
.toString(16)
|
|
.substring(1);
|
|
}
|
|
return s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + s4() + s4();
|
|
}
|
|
|
|
protected initMap(): void {
|
|
this.map = new Map(this.mapId, {
|
|
center: [48.208174, 16.373819],
|
|
zoom: 3
|
|
});
|
|
|
|
this.onMapInitializedEvent.emit(this.mapId);
|
|
if (this.baseMaps && this.baseMaps.size > 0) {
|
|
this.baseMaps.forEach((layerOptions, key) => this.addBaseMap(layerOptions));
|
|
} else {
|
|
this.addBaseMap();
|
|
}
|
|
|
|
|
|
if (this.fitBounds) {
|
|
this.map.fitBounds(this.fitBounds);
|
|
}
|
|
}
|
|
|
|
private addBaseMap(layerOptions?: LayerOptions) {
|
|
if (this.map) {
|
|
if (!this.baseMaps || this.baseMaps.size === 0) {
|
|
// let tiles = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
|
|
// maxZoom: 18,
|
|
// minZoom: 3,
|
|
// attribution: '© <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>'
|
|
// });
|
|
// tiles.addTo(this.map);
|
|
layerOptions = {
|
|
label: DEFAULT_BASE_LAYER_NAME,
|
|
visible: true,
|
|
layer: tileLayer(DEFAULT_BASE_LAYER_URL, {
|
|
attribution: DEFAULT_BASE_LAYER_ATTRIBUTION
|
|
})
|
|
};
|
|
}
|
|
if (!this.oldBaseLayer.hasOwnProperty[layerOptions.label]) {
|
|
this.oldBaseLayer[layerOptions.label] = layerOptions.layer;
|
|
if (layerOptions.visible) { layerOptions.layer.addTo(this.map); }
|
|
}
|
|
}
|
|
}
|
|
|
|
// if data-bound properties have been changed
|
|
public ngOnChanges(changes: SimpleChanges): void {
|
|
if (this.map) {
|
|
if (changes.fitBounds) {
|
|
this.map.fitBounds(this.fitBounds);
|
|
}
|
|
if (changes.zoomControlOptions) {
|
|
this.updateZoomControl();
|
|
}
|
|
}
|
|
}
|
|
|
|
// ngAfterViewInit(): void {
|
|
// this.initMap();
|
|
// // this.markerService.makeCapitalMarkers(this.map);
|
|
// this.markerService.makeCapitalCircleMarkers(this.map);
|
|
// }
|
|
private updateZoomControl() {
|
|
if (this.zoomControl) { this.map.removeControl(this.zoomControl); }
|
|
if (this.zoomControlOptions) {
|
|
this.zoomControl = new Control.Zoom(this.zoomControlOptions).addTo(this.map);
|
|
}
|
|
}
|
|
|
|
}
|