import { Directive , DoCheck , EventEmitter , Input , KeyValueDiffer , KeyValueDiffers , NgZone , OnDestroy , OnInit , Output } from '@angular/core' ; import { Control , Layer } from 'leaflet' ; import { LeafletUtil } from '../../core/leaflet.util' ; import { LeafletDirective } from '../../core/leaflet.directive' ; import { LeafletDirectiveWrapper } from '../../core/leaflet.directive.wrapper' ; import { LeafletControlLayersWrapper } from '../control/leaflet-control-layers.wrapper' ; /**
 * Baselayers directive
 *
 * This directive is provided as a convenient way to add baselayers to the map. The input accepts
 * a key-value map of layer name -> layer. Mutable changed are detected. On changes, a differ is
 * used to determine what changed so that layers are appropriately added or removed. This directive
 * will also add the layers control so users can switch between available base layers.
 *
 * To specify which layer to show as the 'active' baselayer, you will want to add it to the map
 * using the layers directive. Otherwise, the plugin will use the last one it sees.
 */ @ Directive ( { selector : '[leafletBaseLayers]' } ) export class LeafletBaseLayersDirective implements DoCheck , OnDestroy , OnInit { baseLayersValue : { [ name ] : Layer ; } ; baseLayersDiffer : KeyValueDiffer < string , Layer > ; @ Input ( 'leafletBaseLayers' ) set baseLayers ( v ) { this . baseLayersValue = v ; this . updateBaseLayers ( ) ; } get baseLayers ( ) : { [ name ] : Layer ; } { return this . baseLayersValue ; } @ Input ( 'leafletLayersControlOptions' ) layersControlOptions : Control . LayersOptions ; @ Output ( 'leafletLayersControlReady' ) layersControlReady = new EventEmitter < Control . Layers > ( ) ; private baseLayer : Layer ; private leafletDirective : LeafletDirectiveWrapper ; private controlLayers : LeafletControlLayersWrapper ; constructor ( leafletDirective , private differs , private zone ) { this . leafletDirective = new LeafletDirectiveWrapper ( leafletDirective ) ; this . controlLayers = new LeafletControlLayersWrapper ( this . zone , this . layersControlReady ) ; this . baseLayersDiffer = this . differs . find ( { } ) . create < string , Layer > ( ) ; } ngOnDestroy ( ) { this . baseLayers = { } ; this . controlLayers . getLayersControl ( ) . remove ( ) ; } ngOnInit ( ) { this . leafletDirective . init ( ) ; this . zone . runOutsideAngular ( ( ) => { this . controlLayers . init ( { } , this . layersControlOptions ) . addTo ( this . leafletDirective . getMap ( ) ) ; } ) ; this . updateBaseLayers ( ) ; } ngDoCheck ( ) { this . updateBaseLayers ( ) ; } protected updateBaseLayers ( ) { const map = this . leafletDirective . getMap ( ) ; const layersControl = this . controlLayers . getLayersControl ( ) ; if ( null != map && null != layersControl && null != this . baseLayersDiffer ) { const changes = this . baseLayersDiffer . diff ( this . baseLayersValue ) ; const results = this . controlLayers . applyBaseLayerChanges ( changes ) ; if ( results . changed ( ) ) { this . syncBaseLayer ( ) ; } } } /**
     * Check the current base layer and change it to the new one if necessary
     */ protected syncBaseLayer ( ) { const map = this . leafletDirective . getMap ( ) ; const layers = LeafletUtil . mapToArray ( this . baseLayers ) ; let foundLayer ; map . eachLayer ( ( l ) => { foundLayer = layers . find ( ( bl ) => ( l === bl ) ) ; } ) ; if ( null != foundLayer ) { this . baseLayer = foundLayer ; } else { if ( layers . length > 0 ) { this . baseLayer = layers [ 0 ] ; this . zone . runOutsideAngular ( ( ) => { this . baseLayer . addTo ( map ) ; } ) ; } } } }