133 lines
4.1 KiB
TypeScript
133 lines
4.1 KiB
TypeScript
import { Inject, Injectable } from '@nestjs/common';
|
|
import { CarpoolRouteProviderPort } from '../core/application/ports/carpool-route-provider.port';
|
|
import { CarpoolRoute } from '../core/application/types/carpool-route.type';
|
|
import { Waypoint } from '../core/application/types/waypoint.type';
|
|
import { Role } from '../core/domain/ad.types';
|
|
import { GetBasicRouteControllerPort } from '@modules/geography/core/application/ports/get-basic-route-controller.port';
|
|
import { AD_GET_BASIC_ROUTE_CONTROLLER } from '../ad.di-tokens';
|
|
import { Route } from '@modules/geography/core/domain/route.types';
|
|
|
|
@Injectable()
|
|
export class CarpoolRouteProvider implements CarpoolRouteProviderPort {
|
|
constructor(
|
|
@Inject(AD_GET_BASIC_ROUTE_CONTROLLER)
|
|
private readonly getBasicRouteController: GetBasicRouteControllerPort,
|
|
) {}
|
|
|
|
getBasic = async (
|
|
roles: Role[],
|
|
waypoints: Waypoint[],
|
|
): Promise<CarpoolRoute> => {
|
|
const paths: Path[] = this.getPaths(roles, waypoints);
|
|
const typeRoutes: TypeRoute[] = await Promise.all(
|
|
paths.map(
|
|
async (path: Path) =>
|
|
<TypeRoute>{
|
|
type: path.type,
|
|
route: await this.getBasicRouteController.get({
|
|
waypoints,
|
|
}),
|
|
},
|
|
),
|
|
);
|
|
return this._toCarpoolRoute(typeRoutes);
|
|
};
|
|
|
|
private _toCarpoolRoute = (typeRoutes: TypeRoute[]): CarpoolRoute => {
|
|
let baseRoute: Route;
|
|
let driverRoute: Route | undefined;
|
|
let passengerRoute: Route | undefined;
|
|
if (
|
|
typeRoutes.some(
|
|
(typeRoute: TypeRoute) => typeRoute.type == PathType.GENERIC,
|
|
)
|
|
) {
|
|
driverRoute = passengerRoute = typeRoutes.find(
|
|
(typeRoute: TypeRoute) => typeRoute.type == PathType.GENERIC,
|
|
)?.route;
|
|
} else {
|
|
driverRoute = typeRoutes.some(
|
|
(typeRoute: TypeRoute) => typeRoute.type == PathType.DRIVER,
|
|
)
|
|
? typeRoutes.find(
|
|
(typeRoute: TypeRoute) => typeRoute.type == PathType.DRIVER,
|
|
)?.route
|
|
: undefined;
|
|
passengerRoute = typeRoutes.some(
|
|
(typeRoute: TypeRoute) => typeRoute.type == PathType.PASSENGER,
|
|
)
|
|
? typeRoutes.find(
|
|
(typeRoute: TypeRoute) => typeRoute.type == PathType.PASSENGER,
|
|
)?.route
|
|
: undefined;
|
|
}
|
|
if (driverRoute) {
|
|
baseRoute = driverRoute;
|
|
} else {
|
|
baseRoute = passengerRoute as Route;
|
|
}
|
|
return {
|
|
driverDistance: driverRoute?.distance,
|
|
driverDuration: driverRoute?.duration,
|
|
passengerDistance: passengerRoute?.distance,
|
|
passengerDuration: passengerRoute?.duration,
|
|
fwdAzimuth: baseRoute.fwdAzimuth,
|
|
backAzimuth: baseRoute.backAzimuth,
|
|
points: baseRoute.points,
|
|
};
|
|
};
|
|
|
|
private getPaths = (roles: Role[], waypoints: Waypoint[]): Path[] => {
|
|
const paths: Path[] = [];
|
|
if (roles.includes(Role.DRIVER) && roles.includes(Role.PASSENGER)) {
|
|
if (waypoints.length == 2) {
|
|
// 2 points => same route for driver and passenger
|
|
paths.push(this.createGenericPath(waypoints));
|
|
} else {
|
|
paths.push(
|
|
this.createDriverPath(waypoints),
|
|
this.createPassengerPath(waypoints),
|
|
);
|
|
}
|
|
} else if (roles.includes(Role.DRIVER)) {
|
|
paths.push(this.createDriverPath(waypoints));
|
|
} else if (roles.includes(Role.PASSENGER)) {
|
|
paths.push(this.createPassengerPath(waypoints));
|
|
}
|
|
return paths;
|
|
};
|
|
|
|
private createGenericPath = (waypoints: Waypoint[]): Path =>
|
|
this.createPath(waypoints, PathType.GENERIC);
|
|
|
|
private createDriverPath = (waypoints: Waypoint[]): Path =>
|
|
this.createPath(waypoints, PathType.DRIVER);
|
|
|
|
private createPassengerPath = (waypoints: Waypoint[]): Path =>
|
|
this.createPath(
|
|
[waypoints[0], waypoints[waypoints.length - 1]],
|
|
PathType.PASSENGER,
|
|
);
|
|
|
|
private createPath = (waypoints: Waypoint[], type: PathType): Path => ({
|
|
type,
|
|
waypoints,
|
|
});
|
|
}
|
|
|
|
type Path = {
|
|
type: PathType;
|
|
waypoints: Waypoint[];
|
|
};
|
|
|
|
type TypeRoute = {
|
|
type: PathType;
|
|
route: Route;
|
|
};
|
|
|
|
enum PathType {
|
|
GENERIC = 'generic',
|
|
DRIVER = 'driver',
|
|
PASSENGER = 'passenger',
|
|
}
|