remove waypoints where not relevant
This commit is contained in:
parent
c65a5b50c2
commit
f69afc4481
|
@ -1,7 +1,7 @@
|
|||
import { Frequency } from '@modules/ad/core/domain/ad.types';
|
||||
import { Command, CommandProps } from '@mobicoop/ddd-library';
|
||||
import { ScheduleItem } from '../../types/schedule-item.type';
|
||||
import { Waypoint } from '../../types/waypoint.type';
|
||||
import { Address } from '../../types/address.type';
|
||||
|
||||
export class CreateAdCommand extends Command {
|
||||
readonly id: string;
|
||||
|
@ -14,7 +14,7 @@ export class CreateAdCommand extends Command {
|
|||
readonly seatsProposed: number;
|
||||
readonly seatsRequested: number;
|
||||
readonly strict: boolean;
|
||||
readonly waypoints: Waypoint[];
|
||||
readonly waypoints: Address[];
|
||||
|
||||
constructor(props: CommandProps<CreateAdCommand>) {
|
||||
super(props);
|
||||
|
|
|
@ -14,9 +14,9 @@ import {
|
|||
PathType,
|
||||
TypedRoute,
|
||||
} from '@modules/ad/core/domain/path-creator.service';
|
||||
import { Point } from '../../types/point.type';
|
||||
import { Waypoint } from '../../types/waypoint.type';
|
||||
import { Waypoint as WaypointValueObject } from '@modules/ad/core/domain/value-objects/waypoint.value-object';
|
||||
import { Point as PointValueObject } from '@modules/ad/core/domain/value-objects/point.value-object';
|
||||
import { Point } from '@modules/geography/core/domain/route.types';
|
||||
|
||||
@CommandHandler(CreateAdCommand)
|
||||
export class CreateAdService implements ICommandHandler {
|
||||
|
@ -35,8 +35,7 @@ export class CreateAdService implements ICommandHandler {
|
|||
roles,
|
||||
command.waypoints.map(
|
||||
(waypoint: Waypoint) =>
|
||||
new WaypointValueObject({
|
||||
position: waypoint.position,
|
||||
new PointValueObject({
|
||||
lon: waypoint.lon,
|
||||
lat: waypoint.lat,
|
||||
}),
|
||||
|
@ -58,21 +57,34 @@ export class CreateAdService implements ICommandHandler {
|
|||
let driverDuration: number | undefined;
|
||||
let passengerDistance: number | undefined;
|
||||
let passengerDuration: number | undefined;
|
||||
let points: Point[] | undefined;
|
||||
let points: PointValueObject[] | undefined;
|
||||
let fwdAzimuth: number | undefined;
|
||||
let backAzimuth: number | undefined;
|
||||
typedRoutes.forEach((typedRoute: TypedRoute) => {
|
||||
if (typedRoute.type !== PathType.PASSENGER) {
|
||||
driverDistance = typedRoute.route.distance;
|
||||
driverDuration = typedRoute.route.duration;
|
||||
points = typedRoute.route.points;
|
||||
points = typedRoute.route.points.map(
|
||||
(point: Point) =>
|
||||
new PointValueObject({
|
||||
lon: point.lon,
|
||||
lat: point.lat,
|
||||
}),
|
||||
);
|
||||
fwdAzimuth = typedRoute.route.fwdAzimuth;
|
||||
backAzimuth = typedRoute.route.backAzimuth;
|
||||
}
|
||||
if (typedRoute.type !== PathType.DRIVER) {
|
||||
passengerDistance = typedRoute.route.distance;
|
||||
passengerDuration = typedRoute.route.duration;
|
||||
if (!points) points = typedRoute.route.points;
|
||||
if (!points)
|
||||
points = typedRoute.route.points.map(
|
||||
(point: Point) =>
|
||||
new PointValueObject({
|
||||
lon: point.lon,
|
||||
lat: point.lat,
|
||||
}),
|
||||
);
|
||||
if (!fwdAzimuth) fwdAzimuth = typedRoute.route.fwdAzimuth;
|
||||
if (!backAzimuth) backAzimuth = typedRoute.route.backAzimuth;
|
||||
}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import { Route } from '@modules/geography/core/domain/route.types';
|
||||
import { Waypoint } from '../../domain/value-objects/waypoint.value-object';
|
||||
import { Point } from '../types/point.type';
|
||||
|
||||
export interface RouteProviderPort {
|
||||
/**
|
||||
* Get a basic route with points and overall duration / distance
|
||||
*/
|
||||
getBasic(waypoints: Waypoint[]): Promise<Route>;
|
||||
getBasic(waypoints: Point[]): Promise<Route>;
|
||||
}
|
||||
|
|
|
@ -1,58 +1,55 @@
|
|||
import { CandidateEntity } from '@modules/ad/core/domain/candidate.entity';
|
||||
import { Completer } from './completer.abstract';
|
||||
import { Role } from '@modules/ad/core/domain/ad.types';
|
||||
import {
|
||||
Waypoint as WaypointValueObject,
|
||||
WaypointProps,
|
||||
} from '@modules/ad/core/domain/value-objects/waypoint.value-object';
|
||||
import { Waypoint } from '../../../types/waypoint.type';
|
||||
import { WayStepsCreator } from '@modules/ad/core/domain/waysteps-creator.service';
|
||||
import { CarpoolPathCreator } from '@modules/ad/core/domain/carpool-path-creator.service';
|
||||
import {
|
||||
Point,
|
||||
PointProps,
|
||||
} from '@modules/ad/core/domain/value-objects/point.value-object';
|
||||
|
||||
/**
|
||||
* Complete candidates by setting driver and crew waypoints
|
||||
* Complete candidates with crew carpool path
|
||||
*/
|
||||
export class PassengerOrientedWayStepsCompleter extends Completer {
|
||||
export class PassengerOrientedCarpoolPathCompleter extends Completer {
|
||||
complete = async (
|
||||
candidates: CandidateEntity[],
|
||||
): Promise<CandidateEntity[]> => {
|
||||
candidates.forEach((candidate: CandidateEntity) => {
|
||||
const carpoolPathCreator = new WayStepsCreator(
|
||||
const carpoolPathCreator = new CarpoolPathCreator(
|
||||
candidate.getProps().role == Role.DRIVER
|
||||
? candidate.getProps().waypoints.map(
|
||||
(waypoint: WaypointProps) =>
|
||||
new WaypointValueObject({
|
||||
position: waypoint.position,
|
||||
? candidate.getProps().driverWaypoints.map(
|
||||
(waypoint: PointProps) =>
|
||||
new Point({
|
||||
lon: waypoint.lon,
|
||||
lat: waypoint.lat,
|
||||
}),
|
||||
)
|
||||
: this.query.waypoints.map(
|
||||
(waypoint: Waypoint) =>
|
||||
new WaypointValueObject({
|
||||
position: waypoint.position,
|
||||
new Point({
|
||||
lon: waypoint.lon,
|
||||
lat: waypoint.lat,
|
||||
}),
|
||||
),
|
||||
candidate.getProps().role == Role.PASSENGER
|
||||
? candidate.getProps().waypoints.map(
|
||||
(waypoint: WaypointProps) =>
|
||||
new WaypointValueObject({
|
||||
position: waypoint.position,
|
||||
? candidate.getProps().driverWaypoints.map(
|
||||
(waypoint: PointProps) =>
|
||||
new Point({
|
||||
lon: waypoint.lon,
|
||||
lat: waypoint.lat,
|
||||
}),
|
||||
)
|
||||
: this.query.waypoints.map(
|
||||
(waypoint: Waypoint) =>
|
||||
new WaypointValueObject({
|
||||
position: waypoint.position,
|
||||
new Point({
|
||||
lon: waypoint.lon,
|
||||
lat: waypoint.lat,
|
||||
}),
|
||||
),
|
||||
);
|
||||
candidate.setWaySteps(carpoolPathCreator.getCrewCarpoolPath());
|
||||
candidate.setCarpoolPath(carpoolPathCreator.createCarpoolPath());
|
||||
console.log(JSON.stringify(candidate, null, 2));
|
||||
});
|
||||
return candidates;
|
||||
};
|
|
@ -12,7 +12,7 @@ import {
|
|||
PathType,
|
||||
TypedRoute,
|
||||
} from '@modules/ad/core/domain/path-creator.service';
|
||||
import { Waypoint as WaypointValueObject } from '@modules/ad/core/domain/value-objects/waypoint.value-object';
|
||||
import { Point } from '@modules/ad/core/domain/value-objects/point.value-object';
|
||||
|
||||
export class MatchQuery extends QueryBase {
|
||||
driver?: boolean;
|
||||
|
@ -186,8 +186,7 @@ export class MatchQuery extends QueryBase {
|
|||
roles,
|
||||
this.waypoints.map(
|
||||
(waypoint: Waypoint) =>
|
||||
new WaypointValueObject({
|
||||
position: waypoint.position,
|
||||
new Point({
|
||||
lon: waypoint.lon,
|
||||
lat: waypoint.lat,
|
||||
}),
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { Algorithm } from './algorithm.abstract';
|
||||
import { MatchQuery } from './match.query';
|
||||
import { PassengerOrientedWayStepsCompleter } from './completer/passenger-oriented-waysteps.completer';
|
||||
import { PassengerOrientedCarpoolPathCompleter } from './completer/passenger-oriented-carpool-path.completer';
|
||||
import { PassengerOrientedGeoFilter } from './filter/passenger-oriented-geo.filter';
|
||||
import { AdRepositoryPort } from '../../ports/ad.repository.port';
|
||||
import { PassengerOrientedSelector } from './selector/passenger-oriented.selector';
|
||||
|
@ -13,7 +13,7 @@ export class PassengerOrientedAlgorithm extends Algorithm {
|
|||
super(query, repository);
|
||||
this.selector = new PassengerOrientedSelector(query, repository);
|
||||
this.processors = [
|
||||
new PassengerOrientedWayStepsCompleter(query),
|
||||
new PassengerOrientedCarpoolPathCompleter(query),
|
||||
new PassengerOrientedGeoFilter(query),
|
||||
];
|
||||
}
|
||||
|
|
|
@ -35,8 +35,31 @@ export class PassengerOrientedSelector extends Selector {
|
|||
adsRole.ads.map((adEntity: AdEntity) =>
|
||||
CandidateEntity.create({
|
||||
id: adEntity.id,
|
||||
role: adsRole.role,
|
||||
waypoints: adEntity.getProps().waypoints,
|
||||
role: adsRole.role == Role.DRIVER ? Role.PASSENGER : Role.DRIVER,
|
||||
driverWaypoints:
|
||||
adsRole.role == Role.PASSENGER
|
||||
? adEntity.getProps().waypoints
|
||||
: this.query.waypoints.map((waypoint: Waypoint) => ({
|
||||
position: waypoint.position,
|
||||
lon: waypoint.lon,
|
||||
lat: waypoint.lat,
|
||||
})),
|
||||
passengerWaypoints:
|
||||
adsRole.role == Role.DRIVER
|
||||
? adEntity.getProps().waypoints
|
||||
: this.query.waypoints.map((waypoint: Waypoint) => ({
|
||||
position: waypoint.position,
|
||||
lon: waypoint.lon,
|
||||
lat: waypoint.lat,
|
||||
})),
|
||||
driverDistance:
|
||||
adsRole.role == Role.PASSENGER
|
||||
? (adEntity.getProps().driverDistance as number)
|
||||
: (this.query.driverRoute?.distance as number),
|
||||
driverDuration:
|
||||
adsRole.role == Role.PASSENGER
|
||||
? (adEntity.getProps().driverDuration as number)
|
||||
: (this.query.driverRoute?.duration as number),
|
||||
}),
|
||||
),
|
||||
)
|
||||
|
@ -67,10 +90,10 @@ export class PassengerOrientedSelector extends Selector {
|
|||
].join();
|
||||
|
||||
private _selectAsDriver = (): string =>
|
||||
`${this.query.driverRoute?.duration} as duration,${this.query.driverRoute?.distance} as distance`;
|
||||
`${this.query.driverRoute?.duration} as driverDuration,${this.query.driverRoute?.distance} as driverDistance`;
|
||||
|
||||
private _selectAsPassenger = (): string =>
|
||||
`"driverDuration" as duration,"driverDistance" as distance`;
|
||||
`"driverDuration","driverDistance"`;
|
||||
|
||||
private _createFrom = (): string =>
|
||||
'FROM ad LEFT JOIN schedule_item si ON ad.uuid = si."adUuid"';
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { Waypoint } from '@modules/geography/core/domain/route.types';
|
||||
import { Role } from '../../domain/ad.types';
|
||||
import { Point } from '../../domain/value-objects/point.value-object';
|
||||
|
||||
export enum AlgorithmType {
|
||||
PASSENGER_ORIENTED = 'PASSENGER_ORIENTED',
|
||||
|
@ -11,8 +11,8 @@ export enum AlgorithmType {
|
|||
export type Candidate = {
|
||||
ad: Ad;
|
||||
role: Role;
|
||||
driverWaypoints: Waypoint[];
|
||||
crewWaypoints: Waypoint[];
|
||||
driverWaypoints: Point[];
|
||||
crewWaypoints: Point[];
|
||||
};
|
||||
|
||||
export type Ad = {
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import { PointProps } from './value-objects/point.value-object';
|
||||
import { ScheduleItemProps } from './value-objects/schedule-item.value-object';
|
||||
import { WaypointProps } from './value-objects/waypoint.value-object';
|
||||
|
||||
// All properties that an Ad has
|
||||
export interface AdProps {
|
||||
|
@ -17,7 +16,7 @@ export interface AdProps {
|
|||
driverDistance?: number;
|
||||
passengerDuration?: number;
|
||||
passengerDistance?: number;
|
||||
waypoints: WaypointProps[];
|
||||
waypoints: PointProps[];
|
||||
points: PointProps[];
|
||||
fwdAzimuth: number;
|
||||
backAzimuth: number;
|
||||
|
@ -35,7 +34,7 @@ export interface CreateAdProps {
|
|||
seatsProposed: number;
|
||||
seatsRequested: number;
|
||||
strict: boolean;
|
||||
waypoints: WaypointProps[];
|
||||
waypoints: PointProps[];
|
||||
driverDuration?: number;
|
||||
driverDistance?: number;
|
||||
passengerDuration?: number;
|
||||
|
|
|
@ -10,8 +10,8 @@ export class CandidateEntity extends AggregateRoot<CandidateProps> {
|
|||
return new CandidateEntity({ id: create.id, props });
|
||||
};
|
||||
|
||||
setWaySteps = (waySteps: WayStepProps[]): void => {
|
||||
this.props.waySteps = waySteps;
|
||||
setCarpoolPath = (waySteps: WayStepProps[]): void => {
|
||||
this.props.carpoolSteps = waySteps;
|
||||
};
|
||||
|
||||
validate(): void {
|
||||
|
|
|
@ -1,19 +1,25 @@
|
|||
import { Role } from './ad.types';
|
||||
import { WaypointProps } from './value-objects/waypoint.value-object';
|
||||
import { PointProps } from './value-objects/point.value-object';
|
||||
import { WayStepProps } from './value-objects/waystep.value-object';
|
||||
|
||||
// All properties that a Candidate has
|
||||
export interface CandidateProps {
|
||||
role: Role;
|
||||
waypoints: WaypointProps[]; // waypoints of the original Ad
|
||||
waySteps?: WayStepProps[]; // carpool path for the crew (driver + passenger)
|
||||
driverWaypoints: PointProps[];
|
||||
passengerWaypoints: PointProps[];
|
||||
driverDistance: number;
|
||||
driverDuration: number;
|
||||
carpoolSteps?: WayStepProps[]; // carpool path for the crew (driver + passenger)
|
||||
}
|
||||
|
||||
// Properties that are needed for a Candidate creation
|
||||
export interface CreateCandidateProps {
|
||||
id: string;
|
||||
role: Role;
|
||||
waypoints: WaypointProps[];
|
||||
driverDistance: number;
|
||||
driverDuration: number;
|
||||
driverWaypoints: PointProps[];
|
||||
passengerWaypoints: PointProps[];
|
||||
}
|
||||
|
||||
export type Spacetime = {
|
||||
|
|
|
@ -0,0 +1,76 @@
|
|||
import { Role } from './ad.types';
|
||||
import { Target } from './candidate.types';
|
||||
import { Actor } from './value-objects/actor.value-object';
|
||||
import { Point } from './value-objects/point.value-object';
|
||||
import { WayStep } from './value-objects/waystep.value-object';
|
||||
|
||||
export class CarpoolPathCreator {
|
||||
constructor(
|
||||
private readonly driverWaypoints: Point[],
|
||||
private readonly passengerWaypoints: Point[],
|
||||
) {}
|
||||
|
||||
public createCarpoolPath = (): WayStep[] => {
|
||||
const passengerWaysteps: WayStep[] = this._createPassengerWaysteps();
|
||||
if (this.driverWaypoints.length == 2) {
|
||||
}
|
||||
return passengerWaysteps;
|
||||
};
|
||||
|
||||
private _createDriverWaysteps = (): WayStep[] =>
|
||||
this.driverWaypoints.map(
|
||||
(waypoint: Point, index: number) =>
|
||||
new WayStep({
|
||||
lon: waypoint.lon,
|
||||
lat: waypoint.lat,
|
||||
actors: [
|
||||
new Actor({
|
||||
role: Role.DRIVER,
|
||||
target: this._getTarget(index, this.driverWaypoints),
|
||||
}),
|
||||
],
|
||||
}),
|
||||
);
|
||||
|
||||
private _createPassengerWaysteps = (): WayStep[] => {
|
||||
const waysteps: WayStep[] = [];
|
||||
this.passengerWaypoints.forEach(
|
||||
(passengerWaypoint: Point, index: number) => {
|
||||
const waystep: WayStep = new WayStep({
|
||||
lon: passengerWaypoint.lon,
|
||||
lat: passengerWaypoint.lat,
|
||||
actors: [
|
||||
new Actor({
|
||||
role: Role.PASSENGER,
|
||||
target: this._getTarget(index, this.passengerWaypoints),
|
||||
}),
|
||||
],
|
||||
});
|
||||
if (
|
||||
this.driverWaypoints.filter((driverWaypoint: Point) =>
|
||||
this._isSamePoint(driverWaypoint, passengerWaypoint),
|
||||
).length > 0
|
||||
) {
|
||||
waystep.actors.push(
|
||||
new Actor({
|
||||
role: Role.DRIVER,
|
||||
target: Target.NEUTRAL,
|
||||
}),
|
||||
);
|
||||
}
|
||||
waysteps.push(waystep);
|
||||
},
|
||||
);
|
||||
return waysteps;
|
||||
};
|
||||
|
||||
private _isSamePoint = (point1: Point, point2: Point): boolean =>
|
||||
point1.lon === point2.lon && point1.lat === point2.lat;
|
||||
|
||||
private _getTarget = (index: number, waypoints: Point[]): Target =>
|
||||
index == 0
|
||||
? Target.START
|
||||
: index == waypoints.length - 1
|
||||
? Target.FINISH
|
||||
: Target.INTERMEDIATE;
|
||||
}
|
|
@ -1,11 +1,11 @@
|
|||
import { Route } from '@modules/geography/core/domain/route.types';
|
||||
import { Role } from './ad.types';
|
||||
import { Waypoint } from './value-objects/waypoint.value-object';
|
||||
import { Point } from './value-objects/point.value-object';
|
||||
|
||||
export class PathCreator {
|
||||
constructor(
|
||||
private readonly roles: Role[],
|
||||
private readonly waypoints: Waypoint[],
|
||||
private readonly waypoints: Point[],
|
||||
) {}
|
||||
|
||||
public getBasePaths = (): Path[] => {
|
||||
|
@ -40,21 +40,12 @@ export class PathCreator {
|
|||
PathType.PASSENGER,
|
||||
);
|
||||
|
||||
private _firstWaypoint = (): Waypoint =>
|
||||
this.waypoints.find(
|
||||
(waypoint: Waypoint) => waypoint.position == 0,
|
||||
) as Waypoint;
|
||||
private _firstWaypoint = (): Point => this.waypoints[0];
|
||||
|
||||
private _lastWaypoint = (): Waypoint =>
|
||||
this.waypoints.find(
|
||||
(waypoint: Waypoint) =>
|
||||
waypoint.position ==
|
||||
Math.max(
|
||||
...this.waypoints.map((waypoint: Waypoint) => waypoint.position),
|
||||
),
|
||||
) as Waypoint;
|
||||
private _lastWaypoint = (): Point =>
|
||||
this.waypoints[this.waypoints.length - 1];
|
||||
|
||||
private _createPath = (waypoints: Waypoint[], type: PathType): Path => ({
|
||||
private _createPath = (waypoints: Point[], type: PathType): Path => ({
|
||||
type,
|
||||
waypoints,
|
||||
});
|
||||
|
@ -62,7 +53,7 @@ export class PathCreator {
|
|||
|
||||
export type Path = {
|
||||
type: PathType;
|
||||
waypoints: Waypoint[];
|
||||
waypoints: Point[];
|
||||
};
|
||||
|
||||
export type TypedRoute = {
|
||||
|
|
|
@ -1,32 +0,0 @@
|
|||
import { ArgumentInvalidException, ValueObject } from '@mobicoop/ddd-library';
|
||||
import { PointProps } from './point.value-object';
|
||||
|
||||
/** Note:
|
||||
* Value Objects with multiple properties can contain
|
||||
* other Value Objects inside if needed.
|
||||
* */
|
||||
|
||||
export interface WaypointProps extends PointProps {
|
||||
position: number;
|
||||
}
|
||||
|
||||
export class Waypoint extends ValueObject<WaypointProps> {
|
||||
get position(): number {
|
||||
return this.props.position;
|
||||
}
|
||||
|
||||
get lon(): number {
|
||||
return this.props.lon;
|
||||
}
|
||||
|
||||
get lat(): number {
|
||||
return this.props.lat;
|
||||
}
|
||||
|
||||
protected validate(props: WaypointProps): void {
|
||||
if (props.position < 0)
|
||||
throw new ArgumentInvalidException(
|
||||
'position must be greater than or equal to 0',
|
||||
);
|
||||
}
|
||||
}
|
|
@ -2,24 +2,20 @@ import {
|
|||
ArgumentOutOfRangeException,
|
||||
ValueObject,
|
||||
} from '@mobicoop/ddd-library';
|
||||
import { WaypointProps } from './waypoint.value-object';
|
||||
import { Actor } from './actor.value-object';
|
||||
import { Role } from '../ad.types';
|
||||
import { PointProps } from './point.value-object';
|
||||
|
||||
/** Note:
|
||||
* Value Objects with multiple properties can contain
|
||||
* other Value Objects inside if needed.
|
||||
* */
|
||||
|
||||
export interface WayStepProps extends WaypointProps {
|
||||
export interface WayStepProps extends PointProps {
|
||||
actors: Actor[];
|
||||
}
|
||||
|
||||
export class WayStep extends ValueObject<WayStepProps> {
|
||||
get position(): number {
|
||||
return this.props.position;
|
||||
}
|
||||
|
||||
get lon(): number {
|
||||
return this.props.lon;
|
||||
}
|
||||
|
|
|
@ -1,62 +0,0 @@
|
|||
import { Role } from './ad.types';
|
||||
import { Target } from './candidate.types';
|
||||
import { Actor } from './value-objects/actor.value-object';
|
||||
import { Waypoint } from './value-objects/waypoint.value-object';
|
||||
import { WayStep } from './value-objects/waystep.value-object';
|
||||
|
||||
export class WayStepsCreator {
|
||||
constructor(
|
||||
private readonly driverWaypoints: Waypoint[],
|
||||
private readonly passengerWaypoints: Waypoint[],
|
||||
) {}
|
||||
|
||||
public getCrewCarpoolPath = (): WayStep[] => this._createPassengerWaysteps();
|
||||
|
||||
private _createPassengerWaysteps = (): WayStep[] => {
|
||||
const waysteps: WayStep[] = [];
|
||||
this.passengerWaypoints.forEach((passengerWaypoint: Waypoint) => {
|
||||
const waystep: WayStep = new WayStep({
|
||||
lon: passengerWaypoint.lon,
|
||||
lat: passengerWaypoint.lat,
|
||||
position: passengerWaypoint.position,
|
||||
actors: [
|
||||
new Actor({
|
||||
role: Role.PASSENGER,
|
||||
target: this._getTarget(
|
||||
passengerWaypoint.position,
|
||||
this.passengerWaypoints,
|
||||
),
|
||||
}),
|
||||
],
|
||||
});
|
||||
if (
|
||||
this.driverWaypoints.filter((driverWaypoint: Waypoint) =>
|
||||
this._isSameWaypoint(driverWaypoint, passengerWaypoint),
|
||||
).length > 0
|
||||
) {
|
||||
waystep.actors.push(
|
||||
new Actor({
|
||||
role: Role.DRIVER,
|
||||
target: Target.NEUTRAL,
|
||||
}),
|
||||
);
|
||||
}
|
||||
waysteps.push(waystep);
|
||||
});
|
||||
return waysteps;
|
||||
};
|
||||
|
||||
private _isSameWaypoint = (
|
||||
waypoint1: Waypoint,
|
||||
waypoint2: Waypoint,
|
||||
): boolean =>
|
||||
waypoint1.lon === waypoint2.lon && waypoint1.lat === waypoint2.lat;
|
||||
|
||||
private _getTarget = (position: number, waypoints: Waypoint[]): Target =>
|
||||
position == 0
|
||||
? Target.START
|
||||
: position ==
|
||||
Math.max(...waypoints.map((waypoint: Waypoint) => waypoint.position))
|
||||
? Target.FINISH
|
||||
: Target.INTERMEDIATE;
|
||||
}
|
|
@ -30,7 +30,7 @@ export type AdModel = {
|
|||
};
|
||||
|
||||
/**
|
||||
* The record as returned by the peristence system
|
||||
* The record as returned by the persistence system
|
||||
*/
|
||||
export type AdReadModel = AdModel & {
|
||||
waypoints: string;
|
||||
|
|
|
@ -2,7 +2,7 @@ import { Inject, Injectable } from '@nestjs/common';
|
|||
import { RouteProviderPort } from '../core/application/ports/route-provider.port';
|
||||
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, Waypoint } from '@modules/geography/core/domain/route.types';
|
||||
import { Point, Route } from '@modules/geography/core/domain/route.types';
|
||||
|
||||
@Injectable()
|
||||
export class RouteProvider implements RouteProviderPort {
|
||||
|
@ -11,7 +11,7 @@ export class RouteProvider implements RouteProviderPort {
|
|||
private readonly getBasicRouteController: GetBasicRouteControllerPort,
|
||||
) {}
|
||||
|
||||
getBasic = async (waypoints: Waypoint[]): Promise<Route> =>
|
||||
getBasic = async (waypoints: Point[]): Promise<Route> =>
|
||||
await this.getBasicRouteController.get({
|
||||
waypoints,
|
||||
});
|
||||
|
|
|
@ -28,12 +28,10 @@ const adEntity: AdEntity = new AdEntity({
|
|||
],
|
||||
waypoints: [
|
||||
{
|
||||
position: 0,
|
||||
lat: 48.689445,
|
||||
lon: 6.1765102,
|
||||
},
|
||||
{
|
||||
position: 1,
|
||||
lat: 48.8566,
|
||||
lon: 2.3522,
|
||||
},
|
||||
|
|
|
@ -1,14 +1,12 @@
|
|||
import { AdEntity } from '@modules/ad/core/domain/ad.entity';
|
||||
import { CreateAdProps, Frequency } from '@modules/ad/core/domain/ad.types';
|
||||
import { WaypointProps } from '@modules/ad/core/domain/value-objects/waypoint.value-object';
|
||||
import { PointProps } from '@modules/ad/core/domain/value-objects/point.value-object';
|
||||
|
||||
const originWaypointProps: WaypointProps = {
|
||||
position: 0,
|
||||
const originPointProps: PointProps = {
|
||||
lat: 48.689445,
|
||||
lon: 6.17651,
|
||||
};
|
||||
const destinationWaypointProps: WaypointProps = {
|
||||
position: 1,
|
||||
const destinationPointProps: PointProps = {
|
||||
lat: 48.8566,
|
||||
lon: 2.3522,
|
||||
};
|
||||
|
@ -30,7 +28,7 @@ const createAdProps: CreateAdProps = {
|
|||
seatsProposed: 3,
|
||||
seatsRequested: 1,
|
||||
strict: false,
|
||||
waypoints: [originWaypointProps, destinationWaypointProps],
|
||||
waypoints: [originPointProps, destinationPointProps],
|
||||
driverDistance: 23000,
|
||||
driverDuration: 900,
|
||||
passengerDistance: 23000,
|
||||
|
|
|
@ -7,16 +7,14 @@ import { CreateAdProps, Frequency } from '@modules/ad/core/domain/ad.types';
|
|||
import { CreateAdService } from '@modules/ad/core/application/commands/create-ad/create-ad.service';
|
||||
import { CreateAdCommand } from '@modules/ad/core/application/commands/create-ad/create-ad.command';
|
||||
import { AdAlreadyExistsException } from '@modules/ad/core/domain/ad.errors';
|
||||
import { WaypointProps } from '@modules/ad/core/domain/value-objects/waypoint.value-object';
|
||||
import { RouteProviderPort } from '@modules/ad/core/application/ports/route-provider.port';
|
||||
import { PointProps } from '@modules/ad/core/domain/value-objects/point.value-object';
|
||||
|
||||
const originWaypoint: WaypointProps = {
|
||||
position: 0,
|
||||
const originWaypoint: PointProps = {
|
||||
lat: 48.689445,
|
||||
lon: 6.17651,
|
||||
};
|
||||
const destinationWaypoint: WaypointProps = {
|
||||
position: 1,
|
||||
const destinationWaypoint: PointProps = {
|
||||
lat: 48.8566,
|
||||
lon: 2.3522,
|
||||
};
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { PassengerOrientedWayStepsCompleter } from '@modules/ad/core/application/queries/match/completer/passenger-oriented-waysteps.completer';
|
||||
import { PassengerOrientedCarpoolPathCompleter } from '@modules/ad/core/application/queries/match/completer/passenger-oriented-carpool-path.completer';
|
||||
import { MatchQuery } from '@modules/ad/core/application/queries/match/match.query';
|
||||
import { AlgorithmType } from '@modules/ad/core/application/types/algorithm.types';
|
||||
import { Waypoint } from '@modules/ad/core/application/types/waypoint.type';
|
||||
|
@ -44,43 +44,63 @@ const candidates: CandidateEntity[] = [
|
|||
CandidateEntity.create({
|
||||
id: 'cc260669-1c6d-441f-80a5-19cd59afb777',
|
||||
role: Role.DRIVER,
|
||||
waypoints: [
|
||||
driverWaypoints: [
|
||||
{
|
||||
position: 0,
|
||||
lat: 48.678454,
|
||||
lon: 6.189745,
|
||||
},
|
||||
{
|
||||
position: 1,
|
||||
lat: 48.84877,
|
||||
lon: 2.398457,
|
||||
},
|
||||
],
|
||||
}),
|
||||
CandidateEntity.create({
|
||||
id: '5600ccfb-ab69-4d03-aa30-0fbe84fcedc0',
|
||||
role: Role.PASSENGER,
|
||||
waypoints: [
|
||||
passengerWaypoints: [
|
||||
{
|
||||
position: 0,
|
||||
lat: 48.689445,
|
||||
lon: 6.17651,
|
||||
},
|
||||
{
|
||||
position: 1,
|
||||
lat: 48.8566,
|
||||
lon: 2.3522,
|
||||
},
|
||||
],
|
||||
driverDistance: 350145,
|
||||
driverDuration: 13548,
|
||||
}),
|
||||
CandidateEntity.create({
|
||||
id: '5600ccfb-ab69-4d03-aa30-0fbe84fcedc0',
|
||||
role: Role.PASSENGER,
|
||||
driverWaypoints: [
|
||||
{
|
||||
lat: 48.689445,
|
||||
lon: 6.17651,
|
||||
},
|
||||
{
|
||||
lat: 48.8566,
|
||||
lon: 2.3522,
|
||||
},
|
||||
],
|
||||
passengerWaypoints: [
|
||||
{
|
||||
lat: 48.689445,
|
||||
lon: 6.17651,
|
||||
},
|
||||
{
|
||||
lat: 48.8566,
|
||||
lon: 2.3522,
|
||||
},
|
||||
],
|
||||
driverDistance: 350145,
|
||||
driverDuration: 13548,
|
||||
}),
|
||||
];
|
||||
|
||||
describe('Passenger oriented waysteps completer', () => {
|
||||
describe('Passenger oriented carpool path completer', () => {
|
||||
it('should complete candidates', async () => {
|
||||
const passengerOrientedWaypointsCompleter: PassengerOrientedWayStepsCompleter =
|
||||
new PassengerOrientedWayStepsCompleter(matchQuery);
|
||||
const passengerOrientedCarpoolPathCompleter: PassengerOrientedCarpoolPathCompleter =
|
||||
new PassengerOrientedCarpoolPathCompleter(matchQuery);
|
||||
const completedCandidates: CandidateEntity[] =
|
||||
await passengerOrientedWaypointsCompleter.complete(candidates);
|
||||
await passengerOrientedCarpoolPathCompleter.complete(candidates);
|
||||
expect(completedCandidates.length).toBe(2);
|
||||
});
|
||||
});
|
|
@ -44,34 +44,54 @@ const candidates: CandidateEntity[] = [
|
|||
CandidateEntity.create({
|
||||
id: 'cc260669-1c6d-441f-80a5-19cd59afb777',
|
||||
role: Role.DRIVER,
|
||||
waypoints: [
|
||||
driverWaypoints: [
|
||||
{
|
||||
position: 0,
|
||||
lat: 48.678454,
|
||||
lon: 6.189745,
|
||||
},
|
||||
{
|
||||
position: 1,
|
||||
lat: 48.84877,
|
||||
lon: 2.398457,
|
||||
},
|
||||
],
|
||||
passengerWaypoints: [
|
||||
{
|
||||
lat: 48.689445,
|
||||
lon: 6.17651,
|
||||
},
|
||||
{
|
||||
lat: 48.8566,
|
||||
lon: 2.3522,
|
||||
},
|
||||
],
|
||||
driverDistance: 350145,
|
||||
driverDuration: 13548,
|
||||
}),
|
||||
CandidateEntity.create({
|
||||
id: '5600ccfb-ab69-4d03-aa30-0fbe84fcedc0',
|
||||
role: Role.PASSENGER,
|
||||
waypoints: [
|
||||
driverWaypoints: [
|
||||
{
|
||||
position: 0,
|
||||
lat: 48.668487,
|
||||
lon: 6.178457,
|
||||
lat: 48.689445,
|
||||
lon: 6.17651,
|
||||
},
|
||||
{
|
||||
position: 1,
|
||||
lat: 48.897457,
|
||||
lon: 2.3688487,
|
||||
lat: 48.8566,
|
||||
lon: 2.3522,
|
||||
},
|
||||
],
|
||||
passengerWaypoints: [
|
||||
{
|
||||
lat: 48.689445,
|
||||
lon: 6.17651,
|
||||
},
|
||||
{
|
||||
lat: 48.8566,
|
||||
lon: 2.3522,
|
||||
},
|
||||
],
|
||||
driverDistance: 350145,
|
||||
driverDuration: 13548,
|
||||
}),
|
||||
];
|
||||
|
||||
|
|
|
@ -4,28 +4,20 @@ import {
|
|||
PathCreator,
|
||||
PathType,
|
||||
} from '@modules/ad/core/domain/path-creator.service';
|
||||
import { Waypoint } from '@modules/ad/core/domain/value-objects/waypoint.value-object';
|
||||
import { Point } from '@modules/ad/core/domain/value-objects/point.value-object';
|
||||
|
||||
const originWaypoint: Waypoint = new Waypoint({
|
||||
position: 0,
|
||||
const originWaypoint: Point = new Point({
|
||||
lat: 48.689445,
|
||||
lon: 6.17651,
|
||||
});
|
||||
const destinationWaypoint: Waypoint = new Waypoint({
|
||||
position: 1,
|
||||
const destinationWaypoint: Point = new Point({
|
||||
lat: 48.8566,
|
||||
lon: 2.3522,
|
||||
});
|
||||
const intermediateWaypoint: Waypoint = new Waypoint({
|
||||
position: 1,
|
||||
const intermediateWaypoint: Point = new Point({
|
||||
lat: 48.74488,
|
||||
lon: 4.8972,
|
||||
});
|
||||
const destinationWaypointWithIntermediateWaypoint: Waypoint = new Waypoint({
|
||||
position: 2,
|
||||
lat: 48.8566,
|
||||
lon: 2.3522,
|
||||
});
|
||||
|
||||
describe('Path Creator Service', () => {
|
||||
it('should create a path for a driver only', () => {
|
||||
|
@ -58,11 +50,7 @@ describe('Path Creator Service', () => {
|
|||
it('should create two different paths for a driver and passenger with intermediate waypoint', () => {
|
||||
const pathCreator: PathCreator = new PathCreator(
|
||||
[Role.DRIVER, Role.PASSENGER],
|
||||
[
|
||||
originWaypoint,
|
||||
intermediateWaypoint,
|
||||
destinationWaypointWithIntermediateWaypoint,
|
||||
],
|
||||
[originWaypoint, intermediateWaypoint, destinationWaypoint],
|
||||
);
|
||||
const paths: Path[] = pathCreator.getBasePaths();
|
||||
expect(paths).toHaveLength(2);
|
||||
|
|
|
@ -1,69 +0,0 @@
|
|||
import {
|
||||
ArgumentInvalidException,
|
||||
ArgumentOutOfRangeException,
|
||||
} from '@mobicoop/ddd-library';
|
||||
import { Waypoint } from '@modules/ad/core/domain/value-objects/waypoint.value-object';
|
||||
|
||||
describe('Waypoint value object', () => {
|
||||
it('should create a waypoint value object', () => {
|
||||
const waypointVO = new Waypoint({
|
||||
position: 0,
|
||||
lat: 48.689445,
|
||||
lon: 6.17651,
|
||||
});
|
||||
expect(waypointVO.position).toBe(0);
|
||||
expect(waypointVO.lat).toBe(48.689445);
|
||||
expect(waypointVO.lon).toBe(6.17651);
|
||||
});
|
||||
it('should throw an exception if position is invalid', () => {
|
||||
try {
|
||||
new Waypoint({
|
||||
position: -1,
|
||||
lat: 48.689445,
|
||||
lon: 6.17651,
|
||||
});
|
||||
} catch (e: any) {
|
||||
expect(e).toBeInstanceOf(ArgumentInvalidException);
|
||||
}
|
||||
});
|
||||
it('should throw an exception if longitude is invalid', () => {
|
||||
try {
|
||||
new Waypoint({
|
||||
position: 0,
|
||||
lat: 48.689445,
|
||||
lon: 186.17651,
|
||||
});
|
||||
} catch (e: any) {
|
||||
expect(e).toBeInstanceOf(ArgumentOutOfRangeException);
|
||||
}
|
||||
try {
|
||||
new Waypoint({
|
||||
position: 0,
|
||||
lat: 48.689445,
|
||||
lon: -186.17651,
|
||||
});
|
||||
} catch (e: any) {
|
||||
expect(e).toBeInstanceOf(ArgumentOutOfRangeException);
|
||||
}
|
||||
});
|
||||
it('should throw an exception if latitude is invalid', () => {
|
||||
try {
|
||||
new Waypoint({
|
||||
position: 0,
|
||||
lat: 148.689445,
|
||||
lon: 6.17651,
|
||||
});
|
||||
} catch (e: any) {
|
||||
expect(e).toBeInstanceOf(ArgumentOutOfRangeException);
|
||||
}
|
||||
try {
|
||||
new Waypoint({
|
||||
position: 0,
|
||||
lat: -148.689445,
|
||||
lon: 6.17651,
|
||||
});
|
||||
} catch (e: any) {
|
||||
expect(e).toBeInstanceOf(ArgumentOutOfRangeException);
|
||||
}
|
||||
});
|
||||
});
|
|
@ -9,7 +9,6 @@ describe('WayStep value object', () => {
|
|||
const wayStepVO = new WayStep({
|
||||
lat: 48.689445,
|
||||
lon: 6.17651,
|
||||
position: 0,
|
||||
actors: [
|
||||
new Actor({
|
||||
role: Role.DRIVER,
|
||||
|
@ -21,7 +20,6 @@ describe('WayStep value object', () => {
|
|||
}),
|
||||
],
|
||||
});
|
||||
expect(wayStepVO.position).toBe(0);
|
||||
expect(wayStepVO.lon).toBe(6.17651);
|
||||
expect(wayStepVO.lat).toBe(48.689445);
|
||||
expect(wayStepVO.actors).toHaveLength(2);
|
||||
|
@ -31,7 +29,6 @@ describe('WayStep value object', () => {
|
|||
new WayStep({
|
||||
lat: 48.689445,
|
||||
lon: 6.17651,
|
||||
position: 0,
|
||||
actors: [],
|
||||
});
|
||||
} catch (e: any) {
|
||||
|
@ -43,7 +40,6 @@ describe('WayStep value object', () => {
|
|||
new WayStep({
|
||||
lat: 48.689445,
|
||||
lon: 6.17651,
|
||||
position: 0,
|
||||
actors: [
|
||||
new Actor({
|
||||
role: Role.DRIVER,
|
||||
|
|
|
@ -61,14 +61,8 @@ describe('Route provider', () => {
|
|||
|
||||
it('should provide a route', async () => {
|
||||
const route: Route = await routeProvider.getBasic([
|
||||
{
|
||||
position: 0,
|
||||
...originPoint,
|
||||
},
|
||||
{
|
||||
position: 1,
|
||||
...destinationPoint,
|
||||
},
|
||||
originPoint,
|
||||
destinationPoint,
|
||||
]);
|
||||
expect(route.distance).toBe(350101);
|
||||
expect(route.duration).toBe(14422);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { Route, Waypoint } from '../../domain/route.types';
|
||||
import { Route, Point } from '../../domain/route.types';
|
||||
import { GeorouterSettings } from '../types/georouter-settings.type';
|
||||
|
||||
export interface GeorouterPort {
|
||||
route(waypoints: Waypoint[], settings: GeorouterSettings): Promise<Route>;
|
||||
route(waypoints: Point[], settings: GeorouterSettings): Promise<Route>;
|
||||
}
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
import { QueryBase } from '@mobicoop/ddd-library';
|
||||
import { GeorouterSettings } from '../../types/georouter-settings.type';
|
||||
import { Waypoint } from '@modules/geography/core/domain/route.types';
|
||||
import { Point } from '@modules/geography/core/domain/route.types';
|
||||
|
||||
export class GetRouteQuery extends QueryBase {
|
||||
readonly waypoints: Waypoint[];
|
||||
readonly waypoints: Point[];
|
||||
readonly georouterSettings: GeorouterSettings;
|
||||
|
||||
constructor(waypoints: Waypoint[], georouterSettings: GeorouterSettings) {
|
||||
constructor(waypoints: Point[], georouterSettings: GeorouterSettings) {
|
||||
super();
|
||||
this.waypoints = waypoints;
|
||||
this.georouterSettings = georouterSettings;
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import { GeorouterPort } from '../application/ports/georouter.port';
|
||||
import { GeorouterSettings } from '../application/types/georouter-settings.type';
|
||||
import { PointProps } from './value-objects/point.value-object';
|
||||
import { WaypointProps } from './value-objects/waypoint.value-object';
|
||||
|
||||
// All properties that a Route has
|
||||
export interface RouteProps {
|
||||
|
@ -15,7 +14,7 @@ export interface RouteProps {
|
|||
|
||||
// Properties that are needed for a Route creation
|
||||
export interface CreateRouteProps {
|
||||
waypoints: WaypointProps[];
|
||||
waypoints: PointProps[];
|
||||
georouter: GeorouterPort;
|
||||
georouterSettings: GeorouterSettings;
|
||||
}
|
||||
|
@ -36,13 +35,7 @@ export type Point = {
|
|||
lat: number;
|
||||
};
|
||||
|
||||
export type Waypoint = Point & {
|
||||
position: number;
|
||||
};
|
||||
|
||||
export type Spacetime = {
|
||||
export type Step = Point & {
|
||||
duration: number;
|
||||
distance?: number;
|
||||
};
|
||||
|
||||
export type Step = Point & Spacetime;
|
||||
|
|
|
@ -1,32 +0,0 @@
|
|||
import { ArgumentInvalidException, ValueObject } from '@mobicoop/ddd-library';
|
||||
import { PointProps } from './point.value-object';
|
||||
|
||||
/** Note:
|
||||
* Value Objects with multiple properties can contain
|
||||
* other Value Objects inside if needed.
|
||||
* */
|
||||
|
||||
export interface WaypointProps extends PointProps {
|
||||
position: number;
|
||||
}
|
||||
|
||||
export class Waypoint extends ValueObject<WaypointProps> {
|
||||
get position(): number {
|
||||
return this.props.position;
|
||||
}
|
||||
|
||||
get lon(): number {
|
||||
return this.props.lon;
|
||||
}
|
||||
|
||||
get lat(): number {
|
||||
return this.props.lat;
|
||||
}
|
||||
|
||||
protected validate(props: WaypointProps): void {
|
||||
if (props.position < 0)
|
||||
throw new ArgumentInvalidException(
|
||||
'position must be greater than or equal to 0',
|
||||
);
|
||||
}
|
||||
}
|
|
@ -2,7 +2,7 @@ import { Inject, Injectable } from '@nestjs/common';
|
|||
import { HttpService } from '@nestjs/axios';
|
||||
import { GeorouterPort } from '../core/application/ports/georouter.port';
|
||||
import { GeorouterSettings } from '../core/application/types/georouter-settings.type';
|
||||
import { Route, Step, Waypoint } from '../core/domain/route.types';
|
||||
import { Route, Step, Point } from '../core/domain/route.types';
|
||||
import { DefaultParamsProviderPort } from '../core/application/ports/default-params-provider.port';
|
||||
import { GEODESIC, PARAMS_PROVIDER } from '../geography.di-tokens';
|
||||
import { catchError, lastValueFrom, map } from 'rxjs';
|
||||
|
@ -31,7 +31,7 @@ export class GraphhopperGeorouter implements GeorouterPort {
|
|||
}
|
||||
|
||||
route = async (
|
||||
waypoints: Waypoint[],
|
||||
waypoints: Point[],
|
||||
settings: GeorouterSettings,
|
||||
): Promise<Route> => {
|
||||
this._setDefaultUrlArgs();
|
||||
|
@ -57,12 +57,12 @@ export class GraphhopperGeorouter implements GeorouterPort {
|
|||
}
|
||||
};
|
||||
|
||||
private _getRoute = async (waypoints: Waypoint[]): Promise<Route> => {
|
||||
private _getRoute = async (waypoints: Point[]): Promise<Route> => {
|
||||
const url: string = [
|
||||
this.getUrl(),
|
||||
'&point=',
|
||||
waypoints
|
||||
.map((waypoint: Waypoint) => [waypoint.lat, waypoint.lon].join('%2C'))
|
||||
.map((point: Point) => [point.lat, point.lon].join('%2C'))
|
||||
.join('&point='),
|
||||
].join('');
|
||||
return await lastValueFrom(
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { Waypoint } from '@modules/geography/core/domain/route.types';
|
||||
import { Point } from '@modules/geography/core/domain/route.types';
|
||||
|
||||
export type GetRouteRequestDto = {
|
||||
waypoints: Waypoint[];
|
||||
waypoints: Point[];
|
||||
};
|
||||
|
|
|
@ -2,17 +2,15 @@ import { GeorouterPort } from '@modules/geography/core/application/ports/georout
|
|||
import { GetRouteQuery } from '@modules/geography/core/application/queries/get-route/get-route.query';
|
||||
import { GetRouteQueryHandler } from '@modules/geography/core/application/queries/get-route/get-route.query-handler';
|
||||
import { RouteEntity } from '@modules/geography/core/domain/route.entity';
|
||||
import { Waypoint } from '@modules/geography/core/domain/route.types';
|
||||
import { Point } from '@modules/geography/core/domain/route.types';
|
||||
import { GEOROUTER } from '@modules/geography/geography.di-tokens';
|
||||
import { Test, TestingModule } from '@nestjs/testing';
|
||||
|
||||
const originWaypoint: Waypoint = {
|
||||
position: 0,
|
||||
const originWaypoint: Point = {
|
||||
lat: 48.689445,
|
||||
lon: 6.17651,
|
||||
};
|
||||
const destinationWaypoint: Waypoint = {
|
||||
position: 1,
|
||||
const destinationWaypoint: Point = {
|
||||
lat: 48.8566,
|
||||
lon: 2.3522,
|
||||
};
|
||||
|
|
|
@ -44,16 +44,7 @@ const mockGeorouter: GeorouterPort = {
|
|||
};
|
||||
|
||||
const createRouteProps: CreateRouteProps = {
|
||||
waypoints: [
|
||||
{
|
||||
position: 0,
|
||||
...originPoint,
|
||||
},
|
||||
{
|
||||
position: 1,
|
||||
...destinationPoint,
|
||||
},
|
||||
],
|
||||
waypoints: [originPoint, destinationPoint],
|
||||
georouter: mockGeorouter,
|
||||
georouterSettings: {
|
||||
points: true,
|
||||
|
|
|
@ -1,69 +0,0 @@
|
|||
import {
|
||||
ArgumentInvalidException,
|
||||
ArgumentOutOfRangeException,
|
||||
} from '@mobicoop/ddd-library';
|
||||
import { Waypoint } from '@modules/geography/core/domain/value-objects/waypoint.value-object';
|
||||
|
||||
describe('Waypoint value object', () => {
|
||||
it('should create a waypoint value object', () => {
|
||||
const waypointVO = new Waypoint({
|
||||
position: 0,
|
||||
lat: 48.689445,
|
||||
lon: 6.17651,
|
||||
});
|
||||
expect(waypointVO.position).toBe(0);
|
||||
expect(waypointVO.lat).toBe(48.689445);
|
||||
expect(waypointVO.lon).toBe(6.17651);
|
||||
});
|
||||
it('should throw an exception if position is invalid', () => {
|
||||
try {
|
||||
new Waypoint({
|
||||
position: -1,
|
||||
lat: 48.689445,
|
||||
lon: 6.17651,
|
||||
});
|
||||
} catch (e: any) {
|
||||
expect(e).toBeInstanceOf(ArgumentInvalidException);
|
||||
}
|
||||
});
|
||||
it('should throw an exception if longitude is invalid', () => {
|
||||
try {
|
||||
new Waypoint({
|
||||
position: 0,
|
||||
lat: 48.689445,
|
||||
lon: 186.17651,
|
||||
});
|
||||
} catch (e: any) {
|
||||
expect(e).toBeInstanceOf(ArgumentOutOfRangeException);
|
||||
}
|
||||
try {
|
||||
new Waypoint({
|
||||
position: 0,
|
||||
lat: 48.689445,
|
||||
lon: -186.17651,
|
||||
});
|
||||
} catch (e: any) {
|
||||
expect(e).toBeInstanceOf(ArgumentOutOfRangeException);
|
||||
}
|
||||
});
|
||||
it('should throw an exception if latitude is invalid', () => {
|
||||
try {
|
||||
new Waypoint({
|
||||
position: 0,
|
||||
lat: 148.689445,
|
||||
lon: 6.17651,
|
||||
});
|
||||
} catch (e: any) {
|
||||
expect(e).toBeInstanceOf(ArgumentOutOfRangeException);
|
||||
}
|
||||
try {
|
||||
new Waypoint({
|
||||
position: 0,
|
||||
lat: -148.689445,
|
||||
lon: 6.17651,
|
||||
});
|
||||
} catch (e: any) {
|
||||
expect(e).toBeInstanceOf(ArgumentOutOfRangeException);
|
||||
}
|
||||
});
|
||||
});
|
|
@ -297,12 +297,10 @@ describe('Graphhopper Georouter', () => {
|
|||
graphhopperGeorouter.route(
|
||||
[
|
||||
{
|
||||
position: 0,
|
||||
lon: 0,
|
||||
lat: 0,
|
||||
},
|
||||
{
|
||||
position: 1,
|
||||
lon: 1,
|
||||
lat: 1,
|
||||
},
|
||||
|
@ -321,12 +319,10 @@ describe('Graphhopper Georouter', () => {
|
|||
graphhopperGeorouter.route(
|
||||
[
|
||||
{
|
||||
position: 0,
|
||||
lon: 0,
|
||||
lat: 0,
|
||||
},
|
||||
{
|
||||
position: 1,
|
||||
lon: 1,
|
||||
lat: 1,
|
||||
},
|
||||
|
@ -344,12 +340,10 @@ describe('Graphhopper Georouter', () => {
|
|||
const route: Route = await graphhopperGeorouter.route(
|
||||
[
|
||||
{
|
||||
position: 0,
|
||||
lon: 0,
|
||||
lat: 0,
|
||||
},
|
||||
{
|
||||
position: 1,
|
||||
lon: 10,
|
||||
lat: 10,
|
||||
},
|
||||
|
@ -367,12 +361,10 @@ describe('Graphhopper Georouter', () => {
|
|||
const route: Route = await graphhopperGeorouter.route(
|
||||
[
|
||||
{
|
||||
position: 0,
|
||||
lon: 0,
|
||||
lat: 0,
|
||||
},
|
||||
{
|
||||
position: 1,
|
||||
lon: 10,
|
||||
lat: 10,
|
||||
},
|
||||
|
@ -394,12 +386,10 @@ describe('Graphhopper Georouter', () => {
|
|||
const route: Route = await graphhopperGeorouter.route(
|
||||
[
|
||||
{
|
||||
position: 0,
|
||||
lon: 0,
|
||||
lat: 0,
|
||||
},
|
||||
{
|
||||
position: 1,
|
||||
lon: 10,
|
||||
lat: 10,
|
||||
},
|
||||
|
@ -419,17 +409,14 @@ describe('Graphhopper Georouter', () => {
|
|||
const route: Route = await graphhopperGeorouter.route(
|
||||
[
|
||||
{
|
||||
position: 0,
|
||||
lon: 0,
|
||||
lat: 0,
|
||||
},
|
||||
{
|
||||
position: 1,
|
||||
lon: 5,
|
||||
lat: 5,
|
||||
},
|
||||
{
|
||||
position: 2,
|
||||
lon: 10,
|
||||
lat: 10,
|
||||
},
|
||||
|
@ -452,12 +439,10 @@ describe('Graphhopper Georouter', () => {
|
|||
const route: Route = await graphhopperGeorouter.route(
|
||||
[
|
||||
{
|
||||
position: 0,
|
||||
lon: 0,
|
||||
lat: 0,
|
||||
},
|
||||
{
|
||||
position: 1,
|
||||
lon: 10,
|
||||
lat: 10,
|
||||
},
|
||||
|
|
|
@ -49,12 +49,10 @@ describe('Get Basic Route Controller', () => {
|
|||
await getBasicRouteController.get({
|
||||
waypoints: [
|
||||
{
|
||||
position: 0,
|
||||
lat: 48.689445,
|
||||
lon: 6.17651,
|
||||
},
|
||||
{
|
||||
position: 1,
|
||||
lat: 48.8566,
|
||||
lon: 2.3522,
|
||||
},
|
||||
|
|
Loading…
Reference in New Issue