diff --git a/src/app/map/map.component.ts b/src/app/map/map.component.ts index 57d4749..665d942 100644 --- a/src/app/map/map.component.ts +++ b/src/app/map/map.component.ts @@ -3,8 +3,6 @@ import { MapService } from './map.service'; import { NGXLogger } from 'ngx-logger'; import { Subject, takeUntil } from 'rxjs'; import { NotificationService } from '../notifications/notification.service'; -import { Deck } from '@deck.gl/core/typed'; -import { INITIAL_VIEW_STATE, LayerIndices } from './map.constants'; import { DeckMetrics } from '@deck.gl/core/typed/lib/deck'; @Component({ @@ -13,29 +11,30 @@ import { DeckMetrics } from '@deck.gl/core/typed/lib/deck'; styleUrl: './map.component.scss' }) export class MapComponent implements OnInit, AfterViewInit, OnDestroy { + @ViewChild('deckGlMap', { static: false }) private mapDiv?: ElementRef; + showLoader: boolean = false; showMetrics: boolean = true; loadedTileId: string = ''; - readonly metrics$?: Subject = new Subject(); + readonly metrics$: Subject = new Subject(); private readonly onUnsubscribe$: Subject = new Subject(); - @ViewChild('deckGlMap', { static: false }) private mapDiv?: ElementRef; - private map?: Deck; - constructor( private log: NGXLogger, private mapService: MapService, private notificationService: NotificationService - ) {} + ) { + this.metrics$.pipe(takeUntil(this.onUnsubscribe$)); + } ngOnInit(): void { this.initAllSubscriptions(); } ngAfterViewInit() { - this.initDeckGlMap(); + this.mapService.initDeckGlMap(this.mapDiv!, this.metrics$!); } ngOnDestroy(): void { @@ -43,33 +42,11 @@ export class MapComponent implements OnInit, AfterViewInit, OnDestroy { this.disposeMap(); } - initDeckGlMap() { - this.mapService.getLayers().then(layers => { - this.map = new Deck({ - parent: this.mapDiv!.nativeElement, - initialViewState: INITIAL_VIEW_STATE, - style: { position: 'relative', top: '0', bottom: '0' }, - controller: true, - useDevicePixels: false, - layers: [layers], - - onWebGLInitialized: gl => { - gl.blendFuncSeparate(gl.SRC_ALPHA, gl.ONE, gl.ONE_MINUS_DST_ALPHA, gl.ONE); - gl.blendEquation(gl.FUNC_ADD); - }, - - _onMetrics: metrics => { - this.metrics$!.next(metrics); - } - }); - }); - } - private initAllSubscriptions() { // prettier-ignore this.mapService.loading$ - .pipe(takeUntil(this.onUnsubscribe$)) - .subscribe(tileId => this.showHideLoader(tileId)); + .pipe(takeUntil(this.onUnsubscribe$)) + .subscribe(tileId => this.showHideLoader(tileId)); // TODO deck.gl: this.resetMap(); this.mapService.resetMap$.pipe(takeUntil(this.onUnsubscribe$)).subscribe(() => { @@ -80,29 +57,18 @@ export class MapComponent implements OnInit, AfterViewInit, OnDestroy { this.mapService.toMyLocation$.pipe(takeUntil(this.onUnsubscribe$)).subscribe(() => { this.notificationService.showWarnLocalized('common.not-implemented'); }); - - this.mapService.showEuBorders$.pipe(takeUntil(this.onUnsubscribe$)).subscribe(value => { - this.mapService.changeLayerVisibility(this.map!, LayerIndices.EU_LAYER_INDEX, value); - }); - - this.mapService.showCapitols$.pipe(takeUntil(this.onUnsubscribe$)).subscribe(value => { - this.mapService.changeLayerVisibility(this.map!, LayerIndices.CAPITOLS_LAYER_INDEX, value); - }); } private showHideLoader(tileId: string) { this.loadedTileId = tileId; this.showLoader = true; - setTimeout(() => (this.showLoader = false), 500); + setTimeout(() => (this.showLoader = false), 1000); } private unsubscribeAll() { this.onUnsubscribe$.next(true); this.onUnsubscribe$.complete(); this.onUnsubscribe$!.unsubscribe(); - - this.metrics$!.complete(); - this.metrics$!.unsubscribe(); } // TODO deck.gl: dispose deck map diff --git a/src/app/map/map.service.ts b/src/app/map/map.service.ts index 659b50f..526bb10 100644 --- a/src/app/map/map.service.ts +++ b/src/app/map/map.service.ts @@ -1,26 +1,27 @@ -import { EventEmitter, Injectable } from '@angular/core'; +import { ElementRef, EventEmitter, Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { NGXLogger } from 'ngx-logger'; -import { CAPITOLS_LAYER, CENTER_OF_EUROPE } from './map.constants'; +import { CAPITOLS_LAYER, CENTER_OF_EUROPE, INITIAL_VIEW_STATE, LayerIndices } from './map.constants'; import { NotificationService } from '../notifications/notification.service'; import { Deck, Layer } from '@deck.gl/core/typed'; import { BitmapLayer, GeoJsonLayer } from '@deck.gl/layers/typed'; -import { firstValueFrom } from 'rxjs'; +import { firstValueFrom, Subject } from 'rxjs'; import { TileLayer } from '@deck.gl/geo-layers/typed'; import { environment } from '../../environments/environment'; +import { DeckMetrics } from '@deck.gl/core/typed/lib/deck'; @Injectable() export class MapService { resetMap$ = new EventEmitter(); toMyLocation$ = new EventEmitter(); - showEuBorders$ = new EventEmitter(); - showCapitols$ = new EventEmitter(); loading$ = new EventEmitter(); private readonly mapLayer: Promise; private readonly euBordersLayer: Promise; private readonly layers: Promise; + private map?: Deck; + constructor( private readonly http: HttpClient, private readonly log: NGXLogger, @@ -31,22 +32,10 @@ export class MapService { this.layers = this.loadAllLayers(); } - getLayers() { - return this.layers; - } - async loadAllLayers(): Promise { return Promise.all([this.getMapLayer(), this.getEuBordersLayer(), this.getCapitolsLayer()]); } - changeLayerVisibility(map: Deck, layerIndex: number, value: boolean) { - this.layers.then(layers => { - const clonedLayers = layers.slice(); - clonedLayers[layerIndex] = layers[layerIndex].clone({ visible: value }); - map.setProps({ layers: clonedLayers }); - }); - } - async resetMapToEuropeanCenter() { this.log.debug('Reset map'); this.resetMap$.emit(); @@ -58,13 +47,35 @@ export class MapService { } async doShowEuBorders(value: boolean) { - this.log.trace('Show EU borders', value); - this.showEuBorders$.emit(value); + this.changeLayerVisibility(LayerIndices.EU_LAYER_INDEX, value).then(() => this.log.trace('Show EU borders', value)); } async doShowCapitols(value: boolean) { - this.log.trace('Show capitols', value); - this.showCapitols$.emit(value); + this.changeLayerVisibility(LayerIndices.CAPITOLS_LAYER_INDEX, value).then(() => + this.log.trace('Show capitols', value) + ); + } + + initDeckGlMap(mapDiv: ElementRef, metricsRef: Subject) { + this.layers.then(layers => { + this.map = new Deck({ + parent: mapDiv.nativeElement, + initialViewState: INITIAL_VIEW_STATE, + style: { position: 'relative', top: '0', bottom: '0' }, + controller: true, + useDevicePixels: false, + layers: [layers], + + onWebGLInitialized: gl => { + gl.blendFuncSeparate(gl.SRC_ALPHA, gl.ONE, gl.ONE_MINUS_DST_ALPHA, gl.ONE); + gl.blendEquation(gl.FUNC_ADD); + }, + + _onMetrics: metrics => { + metricsRef.next(metrics); + } + }); + }); } private async initMapLayer() { @@ -121,6 +132,14 @@ export class MapService { }); } + private async changeLayerVisibility(layerIndex: number, value: boolean) { + this.layers.then(layers => { + const clonedLayers = layers.slice(); + clonedLayers[layerIndex] = layers[layerIndex].clone({ visible: value }); + this.map!.setProps({ layers: clonedLayers }); + }); + } + // TODO deck.gl: do not forget this method private async getCenterOfEurope() { return CENTER_OF_EUROPE;