import { Coordinates } from '../../../geography/domain/entities/coordinates'; import { Route } from '../../../geography/domain/entities/route'; import { IFindTimezone } from '../../../geography/domain/interfaces/timezone-finder.interface'; import { Role } from '../types/role.enum'; import { IGeorouter } from '../../../geography/domain/interfaces/georouter.interface'; import { Path } from '../../../geography/domain/types/path.type'; import { Timezoner } from '../../../geography/domain/types/timezoner'; export class Geography { private points: Coordinates[]; timezones: string[]; driverRoute: Route; passengerRoute: Route; timezoneFinder: IFindTimezone; constructor(points: Coordinates[], timezoner: Timezoner) { this.points = points; this.timezones = [timezoner.timezone]; this.timezoneFinder = timezoner.finder; this.setTimezones(); } createRoutes = async ( roles: Role[], georouter: IGeorouter, ): Promise => { const paths: Path[] = []; if (roles.includes(Role.DRIVER) && roles.includes(Role.PASSENGER)) { if (this.points.length == 2) { // 2 points => same route for driver and passenger const commonPath: Path = { key: RouteKey.COMMON, points: this.points, }; paths.push(commonPath); } else { const driverPath: Path = { key: RouteKey.DRIVER, points: this.points, }; const passengerPath: Path = { key: RouteKey.PASSENGER, points: [this.points[0], this.points[this.points.length - 1]], }; paths.push(driverPath, passengerPath); } } else if (roles.includes(Role.DRIVER)) { const driverPath: Path = { key: RouteKey.DRIVER, points: this.points, }; paths.push(driverPath); } else if (roles.includes(Role.PASSENGER)) { const passengerPath: Path = { key: RouteKey.PASSENGER, points: [this.points[0], this.points[this.points.length - 1]], }; paths.push(passengerPath); } const routes = await georouter.route(paths, { withDistance: false, withPoints: false, withTime: false, }); if (routes.some((route) => route.key == RouteKey.COMMON)) { this.driverRoute = routes.find( (route) => route.key == RouteKey.COMMON, ).route; this.passengerRoute = routes.find( (route) => route.key == RouteKey.COMMON, ).route; } else { if (routes.some((route) => route.key == RouteKey.DRIVER)) { this.driverRoute = routes.find( (route) => route.key == RouteKey.DRIVER, ).route; } if (routes.some((route) => route.key == RouteKey.PASSENGER)) { this.passengerRoute = routes.find( (route) => route.key == RouteKey.PASSENGER, ).route; } } }; private setTimezones = (): void => { this.timezones = this.timezoneFinder.timezones( this.points[0].lat, this.points[0].lon, ); }; } export enum RouteKey { COMMON = 'common', DRIVER = 'driver', PASSENGER = 'passenger', }