Skip to content

Commit

Permalink
Improve handling of map internal state
Browse files Browse the repository at this point in the history
  • Loading branch information
holgerstolzenberg committed Mar 6, 2024
1 parent 91177ff commit 9865de6
Show file tree
Hide file tree
Showing 6 changed files with 93 additions and 39 deletions.
30 changes: 30 additions & 0 deletions src/app/map/geo.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { Injectable } from '@angular/core';
import { catchError, Observable, tap, throwError } from 'rxjs';
import { NGXLogger } from 'ngx-logger';

@Injectable()
export class GeoService {
constructor(private readonly log: NGXLogger) {}

myCurrentLocation() {
return new Observable<GeolocationCoordinates>(observer => {
window.navigator.geolocation.getCurrentPosition(
position => {
observer.next(position.coords);
observer.complete();
},
err => observer.error(err),
{ enableHighAccuracy: false, timeout: 5000 }
);
}).pipe(
tap(d => {
this.log.debug('Got your location', d);
}),
// it will be invoked if our source observable emits an error.
catchError(error => {
this.log.error('failed to get your location', error);
return throwError(() => error);
})
);
}
}
4 changes: 3 additions & 1 deletion src/app/map/map.component.scss
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ div.metrics {

span.label {
@include typography.prevent-select;
@include typography.default;
color: typography.$tertiary;
display: inline-block;
width: 70pt;
padding: 5pt;
Expand All @@ -28,7 +30,7 @@ div.metrics {

div.map {
@include typography.prevent-select;
background-color: $accent;
background-color: $dark-matter-bg;
position: absolute;
top: 0;
bottom: 0;
Expand Down
8 changes: 4 additions & 4 deletions src/app/map/map.constants.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { ScatterplotLayer } from '@deck.gl/layers/typed';

export const DEFAULT_ZOOM = 3;
export const DEFAULT_TRANSITION_DURATION_MS= 2000
export const DEFAULT_TRANSITION_DURATION_MS= 'auto';

export const FLY_TO_ZOOM = 7;

Expand Down Expand Up @@ -46,7 +46,7 @@ export const CAPITOLS_LAYER = new ScatterplotLayer({
});

export enum LayerIndices {
MAP_LAYER_INDEX = 0,
EU_LAYER_INDEX = 1,
CAPITOLS_LAYER_INDEX = 2
MAP_LAYER = 0,
EU_BORDERS_LAYER = 1,
CAPITOLS_LAYER = 2
}
3 changes: 2 additions & 1 deletion src/app/map/map.module.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { NgModule } from '@angular/core';
import { MapService } from './map.service';
import { GeoService } from './geo.service';

@NgModule({
providers: [MapService]
providers: [GeoService, MapService]
})
export class MapModule {}
86 changes: 53 additions & 33 deletions src/app/map/map.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,18 @@ import {
CAPITOLS_LAYER,
CENTER_OF_EUROPE,
DEFAULT_TRANSITION_DURATION_MS,
DEFAULT_ZOOM,
FLY_TO_ZOOM,
INITIAL_VIEW_STATE,
LayerIndices
} from './map.constants';
import { NotificationService } from '../notifications/notification.service';
import { Deck, FlyToInterpolator, Layer } from '@deck.gl/core/typed';
import { Deck, FlyToInterpolator, Layer, TRANSITION_EVENTS } from '@deck.gl/core/typed';
import { BitmapLayer, GeoJsonLayer } from '@deck.gl/layers/typed';
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';
import { GeoService } from './geo.service';

@Injectable()
export class MapService {
Expand All @@ -26,11 +26,13 @@ export class MapService {
private readonly euBordersLayer: Promise<GeoJsonLayer>;
private readonly layers: Promise<Layer[]>;

private map?: Deck;
private theMap?: Deck;
private geoPosition?: GeolocationCoordinates;

constructor(
private readonly http: HttpClient,
private readonly log: NGXLogger,
private readonly geoService: GeoService,
private readonly notificationService: NotificationService
) {
this.mapLayer = this.initMapLayer();
Expand All @@ -39,54 +41,72 @@ export class MapService {
}

async loadAllLayers(): Promise<Layer[]> {
return Promise.all([this.getMapLayer(), this.getEuBordersLayer(), this.getCapitolsLayer()]);
return Promise.all([this.getMapLayer(), this.getEuBordersLayer(), this.getCapitolsLayer()]).then(
([map, euBorder, capitols]) => {
//doing this for full control over ordering
const layers = new Array<Layer>(3);
layers[LayerIndices.MAP_LAYER] = map;
layers[LayerIndices.EU_BORDERS_LAYER] = euBorder;
layers[LayerIndices.CAPITOLS_LAYER] = capitols;
return layers;
}
);
}

async resetMapToEuropeanCenter() {
this.map!.setProps({
// FIXME deck.gl - find out why resetting theMap is unreliable
console.log('--- Lat', this.theMap!.props.initialViewState.latitude);
console.log('--- Lon', this.theMap!.props.initialViewState.longitude);
console.log('--- Lat-S', CENTER_OF_EUROPE[0]);
console.log('--- Lon-S', CENTER_OF_EUROPE[1]);

this.theMap!.setProps({
initialViewState: {
latitude: CENTER_OF_EUROPE[0],
longitude: CENTER_OF_EUROPE[1],
zoom: DEFAULT_ZOOM,
transitionInterpolator: new FlyToInterpolator(),
transitionDuration: DEFAULT_TRANSITION_DURATION_MS
...Object.assign(this, INITIAL_VIEW_STATE),
transitionInterpolator: new FlyToInterpolator({ speed: 1.5 }),
transitionDuration: DEFAULT_TRANSITION_DURATION_MS,
transitionInterruption: TRANSITION_EVENTS.IGNORE
}
});
}

async moveMapToMyLocation() {
navigator.geolocation.getCurrentPosition(
position => {
this.map!.setProps({
initialViewState: {
latitude: position.coords.latitude,
longitude: position.coords.longitude,
zoom: FLY_TO_ZOOM,
transitionInterpolator: new FlyToInterpolator(),
transitionDuration: DEFAULT_TRANSITION_DURATION_MS
}
});
},
err => this.notificationService.showError('Could not get geolocation', err),
{
enableHighAccuracy: false
if (!this.geoPosition) {
firstValueFrom(this.geoService.myCurrentLocation()).then(p => {
this.geoPosition = p;
this.flyMapTo(p);
});
} else {
this.flyMapTo(this.geoPosition);
}
}

private flyMapTo(p: GeolocationCoordinates) {
this.theMap!.setProps({
initialViewState: {
...Object.assign(this, INITIAL_VIEW_STATE),
latitude: p.latitude,
longitude: p.longitude,
zoom: FLY_TO_ZOOM,
transitionInterpolator: new FlyToInterpolator(),
transitionDuration: DEFAULT_TRANSITION_DURATION_MS
}
);
});
}

async doShowEuBorders(value: boolean) {
this.changeLayerVisibility(LayerIndices.EU_LAYER_INDEX, value).then(() => this.log.trace('Show EU borders', value));
this.changeLayerVisibility(LayerIndices.EU_BORDERS_LAYER, value).then(() =>
this.log.trace('Show EU borders', value)
);
}

async doShowCapitols(value: boolean) {
this.changeLayerVisibility(LayerIndices.CAPITOLS_LAYER_INDEX, value).then(() =>
this.log.trace('Show capitols', value)
);
this.changeLayerVisibility(LayerIndices.CAPITOLS_LAYER, value).then(() => this.log.trace('Show capitols', value));
}

initDeckGlMap(mapDiv: ElementRef<HTMLDivElement>, metricsRef: Subject<DeckMetrics>) {
this.layers.then(layers => {
this.map = new Deck({
this.theMap = new Deck({
parent: mapDiv.nativeElement,
initialViewState: INITIAL_VIEW_STATE,
style: { position: 'relative', top: '0', bottom: '0' },
Expand All @@ -108,7 +128,7 @@ export class MapService {

private async initMapLayer() {
return new TileLayer({
id: 'map-layer',
id: 'theMap-layer',
data: environment.tileServerUrls,
maxRequests: 20,
pickable: false,
Expand Down Expand Up @@ -169,7 +189,7 @@ export class MapService {
this.layers.then(layers => {
const clonedLayers = layers.slice();
clonedLayers[layerIndex] = layers[layerIndex].clone({ visible: value });
this.map!.setProps({ layers: clonedLayers });
this.theMap!.setProps({ layers: clonedLayers });
});
}

Expand Down
1 change: 1 addition & 0 deletions src/assets/styles/variables.scss
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ $tertiary: #fff;
$accent: #404040;
$accent-dark: #463A05FF;
$accent-bright: #ffd617;
$dark-matter-bg: #262627;

0 comments on commit 9865de6

Please sign in to comment.