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