import {Component, OnInit, ViewChild} from '@angular/core'; import {AgmMap} from '@agm/core'; import {RestService} from '../../services/rest.service'; import {NGXLogger} from 'ngx-logger'; import {interval, Subscription} from 'rxjs'; import {startWith, switchMap} from 'rxjs/operators'; import { Car, CarEntity, CarEvent, GeoCoordinates, TrafficLight, TrafficLightEntity, TrafficLightEvent } from '../../interfaces/interface'; @Component({ selector: 'app-landing', templateUrl: './landing.component.html', styleUrls: ['./landing.component.css'] }) export class LandingComponent implements OnInit { constructor( private restService: RestService, private logger: NGXLogger ) { } @ViewChild('map') map: AgmMap; zoom = 14; center = {lat: 47.90620, lng: 16.20785}; traffic_light_markers = new Map(); car_markers = new Map(); infoWindows = new Map(); timeInterval: Subscription; TL_RED_IMAGE = 'assets/pictures/traffic_light_red.png'; TL_GREEN_IMAGE = 'assets/pictures/traffic_light_green.png'; CAR_IMAGE = 'assets/pictures/car.png'; CAR_IMAGE_NCE = 'assets/pictures/car_orange.png'; NCE_SOUND = 'assets/sound/crash.mp3'; ngOnInit() { this.getTrafficLights(); this.getCars(); } getCarEvents(vin) { this.timeInterval = interval(1000) .pipe( startWith(0), switchMap(() => this.restService.getCarEvents(vin)) ).subscribe((data: any) => { const carEvent = data.body as CarEvent; const car = this.car_markers.get(vin) as Car; car.carEvent = carEvent; this.car_markers.set(car['vin'], car); }, err => this.logger.error(err), () => { this.logger.debug('loaded car events'); } ); } getTrafficLightEvents(tlid) { this.timeInterval = interval(1000) .pipe( startWith(0), switchMap(() => this.restService.getTrafficLightEvents(tlid)) ).subscribe( (data: any) => { const trafficLightEvent = data.body as TrafficLightEvent; const trafficLight = this.traffic_light_markers.get(tlid) as TrafficLight; trafficLight.trafficLightEvent = trafficLightEvent; this.traffic_light_markers.set(tlid, trafficLight); }, err => this.logger.error(err), () => { this.logger.debug('loaded traffic light events'); } ); } getTrafficLights() { this.restService.getTrafficLights().subscribe( (data: TrafficLightEntity[]) => { for (const trafficLightEntity of data) { const trafficLight: TrafficLight = { trafficLightEntity: trafficLightEntity, trafficLightEvent: this.getEmptyTrafficLightEvent() }; this.traffic_light_markers.set(trafficLightEntity['id'], trafficLight); } }, err => this.logger.error(err), () => { this.logger.debug('loaded traffic lights'); for (const value of this.traffic_light_markers.values()) { this.getTrafficLightEvents(value.trafficLightEntity['id']); } } ); } getCars() { this.restService.getCars().subscribe( (data: CarEntity[]) => { for (const carEntity of data) { const car: Car = { carEntity: carEntity, carEvent: this.getEmptyCarEvent() }; this.car_markers.set(carEntity['vin'], car); } }, err => this.logger.error(err), () => { this.logger.debug('loaded cars'); for (const value of this.car_markers.values()) { this.getCarEvents(value.carEntity['vin']); } } ); } trafficLightToImage(trafficLight) { return (trafficLight === 'RED') ? this.TL_RED_IMAGE : this.TL_GREEN_IMAGE; } getIconUrlCar(near_crash_event) { if (near_crash_event === true) { this.playCrashSound(); return this.CAR_IMAGE_NCE; } else { return this.CAR_IMAGE; } } openInfoWindow(id) { this.infoWindows.set(id, true); } closeInfoWindow(id) { this.infoWindows.delete(id); } isInfoWindowOpen(id) { return this.infoWindows.has(id); } playCrashSound() { const audio = new Audio(); audio.src = this.NCE_SOUND; audio.load(); audio.play(); } private getEmptyGeoCoordinates(): GeoCoordinates { return { latitude: 0, longitude: 0 }; } private getEmptyCarEvent(): CarEvent { return { near_crash_event: false, gps_location: this.getEmptyGeoCoordinates(), timestamp: '', velocity: 0 }; } private getEmptyTrafficLightEvent(): TrafficLightEvent { return { last_switch: 0, color: '', tlid: 0 }; } }