import { GoogleMap , GoogleMapsMarkerOptions , GoogleMapsMarker , GoogleMapsLatLng , GoogleMapsPolylineOptions , GoogleMapsPolyline } from 'ionic-native' ; import { ColorUtils } from '../../core/utils' ; import { Bus } from '../../models/bus' ; import { Itinerary , Spot } from '../../models/itinerary' ; /**
 * Bus icon paths
 */ class BusIcon { private static BASE : string = 'www/assets/img' ; public static GOOD : string = `${ BusIcon . BASE }/bus_green.png` ; public static AVG : string = `${ BusIcon . BASE }/bus_yellow.png` ; public static BAD : string = `${ BusIcon . BASE }/bus_red.png` ; public static WIDTH : number = 36 ; public static HEIGHT : number = 42 ; } class export class MarkerController { private map : GoogleMap ; private markers : any = { } ; private locations : GoogleMapsMarker [ ] = [ ] ; private trajectory : GoogleMapsPolyline ; public constructor ( map ) { this . map = map ; } param { Bus } bus return { void } public setMarker ( bus ) { if ( this . markers [ bus . Order ] ) this . updatePosition ( bus ) ; else this . map . addMarker ( this . getMarkerData ( bus ) ) . then ( marker => this . addMarker ( bus , marker ) ) ; } return { void } public removeMarkers ( ) { Object . keys ( this . markers ) . forEach ( ( key ) => this . removeMarker ( key ) ) ; this . locations = [ ] ; } param { Itinerary } trajectory return { void } public showTrajectory ( trajectory ) { let positions = [ ] ; let spotFrom = null , spotTo = null ; trajectory . Spots . forEach ( spot => { if ( ! spot . isReturning ) { if ( ! spotFrom ) spotFrom = spot ; else spotTo = spot ; } positions . push ( new GoogleMapsLatLng ( spot . Latitude , spot . Longitude ) ) ; } ) ; let color = `#${ ColorUtils . randomColor ( ( r , g , b ) => r <= ( g + b ) && g <= ( r + b ) ) }` ; if ( spotFrom !== null && spotTo !== null ) { this . map . addMarker ( this . getMarkerSpotData ( spotFrom , false , color ) ) . then ( markerFrom => { this . markers [ 'from' ] = markerFrom ; return this . map . addMarker ( this . getMarkerSpotData ( spotTo , true , color ) ) ; } ) . then ( markerTo => this . markers [ 'to' ] = markerTo ) ; } this . map . addPolyline ( this . getTrajectoryConfiguration ( positions , color ) ) . then ( ( polyline ) => this . trajectory = polyline ) ; } return { void } public hideTrajectory ( ) { if ( this . trajectory ) this . trajectory . remove ( ) ; } private param { Bus } bus return { void } private updatePosition ( bus ) { this . markers [ bus . Order ] . setPosition ( new GoogleMapsLatLng ( bus . Latitude , bus . Longitude ) ) ; } private param { Bus } bus return { void } private addMarker ( bus , marker ) { this . markers [ bus . Order ] = marker ; this . fitBounds ( marker ) ; } private param { string } key return { void } private removeMarker ( key ) { this . markers [ key ] . remove ( ) ; delete this . markers [ key ] ; } private param { GoogleMapsLatLng [ ] } points return { GoogleMapsPolylineOptions } private getTrajectoryConfiguration ( points , color ) { return { points : points , color : color , width : 6 , zIndex : 4 } ; } private param { Bus } bus return { GoogleMapsMarkerOptions } private getMarkerData ( bus ) { return { position : new GoogleMapsLatLng ( bus . Latitude , bus . Longitude ) , icon : { url : this . getIconPath ( bus . Timestamp ) , size : { width : BusIcon . WIDTH , height : BusIcon . HEIGHT } } , title : this . formatInfoWindow ( bus ) , } ; } private param { Spot } spot param { boolean } returning return { GoogleMapsMarkerOptions } private getMarkerSpotData ( spot , returning , color ) { let obj = { position : new GoogleMapsLatLng ( spot . Latitude , spot . Longitude ) } ; obj . title = ( ! returning ) ? 'PONTO INICIAL' : 'PONTO FINAL' ; obj . icon = color ; return obj ; } private param { GoogleMapsMarker } location return { void } private fitBounds ( location ) { this . locations . push ( location ) ; this . map . animateCamera ( { target : this . locations } ) ; } private param { Date } datetime return { string } private getIconPath ( datetime ) { let minutes = ( ( new Date ( ) ) . getTime ( ) - datetime . getTime ( ) ) / 1000 / 60 ; if ( minutes > 10 ) return BusIcon . BAD ; else if ( minutes >= 5 && minutes < 10 ) return BusIcon . AVG ; else return BusIcon . GOOD ; } private param { Date } datetime return { string } private prepareTimestamp ( datetime ) { let timeSinceUpdate = ( new Date ( ) ) . getTime ( ) - datetime . getTime ( ) ; timeSinceUpdate = timeSinceUpdate / 1000 ; if ( timeSinceUpdate < 60 ) { return `${ timeSinceUpdate . toFixed ( 0 ) } segundos` ; } timeSinceUpdate = timeSinceUpdate / 60 ; if ( timeSinceUpdate < 60 ) { return `${ timeSinceUpdate . toFixed ( 0 ) } minutos` ; } timeSinceUpdate = timeSinceUpdate / 60 ; if ( timeSinceUpdate < 24 ) { return `${ timeSinceUpdate . toFixed ( 0 ) } horas` ; } timeSinceUpdate = timeSinceUpdate / 24 ; return `${ timeSinceUpdate . toFixed ( 0 ) } dias` ; } private parem return { string } private formatInfoWindow ( bus ) { return `
            ${ bus . Order } (${ bus . Line })
            Velocidade: ${ bus . Speed . toFixed ( 0 ) } Km/h
            Direção: ${ bus . Direction }
            Atualizado há ${ this . prepareTimestamp ( bus . Timestamp ) }
        ` ; } }