tests and refactor for ad geography

This commit is contained in:
sbriat
2023-05-22 11:25:09 +02:00
parent e950efe221
commit 17acaa449c
14 changed files with 264 additions and 80 deletions

View File

@@ -12,7 +12,7 @@ import {
IsString,
} from 'class-validator';
import { Frequency } from '../types/frequency.enum';
import { Coordinates } from '../../../geography/domain/entities/coordinates';
import { Coordinate } from '../../../geography/domain/entities/coordinate';
import { Type } from 'class-transformer';
import { HasTruthyWith } from './has-truthy-with.validator';
@@ -115,11 +115,11 @@ export class CreateAdRequest {
@AutoMap()
sunMargin: number;
@Type(() => Coordinates)
@Type(() => Coordinate)
@IsArray()
@ArrayMinSize(2)
@AutoMap(() => [Coordinates])
waypoints: Coordinates[];
@AutoMap(() => [Coordinate])
waypoints: Coordinate[];
@IsNumber()
@AutoMap()

View File

@@ -1,24 +1,17 @@
import { Coordinates } from '../../../geography/domain/entities/coordinates';
import { Coordinate } from '../../../geography/domain/entities/coordinate';
import { Route } from '../../../geography/domain/entities/route';
import { IFindTimezone } from '../../../geography/domain/interfaces/timezone-finder.interface';
import { Role } from '../types/role.enum';
import { IGeorouter } from '../../../geography/domain/interfaces/georouter.interface';
import { Path } from '../../../geography/domain/types/path.type';
import { Timezoner } from '../../../geography/domain/types/timezoner';
import { GeorouterSettings } from '../../../geography/domain/types/georouter-settings.type';
export class Geography {
private points: Coordinates[];
timezones: string[];
private coordinates: Coordinate[];
driverRoute: Route;
passengerRoute: Route;
timezoneFinder: IFindTimezone;
constructor(points: Coordinates[], timezoner: Timezoner) {
this.points = points;
this.timezones = [timezoner.timezone];
this.timezoneFinder = timezoner.finder;
this.setTimezones();
constructor(coordinates: Coordinate[]) {
this.coordinates = coordinates;
}
createRoutes = async (
@@ -26,39 +19,7 @@ export class Geography {
georouter: IGeorouter,
settings: GeorouterSettings,
): Promise<void> => {
const paths: Path[] = [];
if (roles.includes(Role.DRIVER) && roles.includes(Role.PASSENGER)) {
if (this.points.length == 2) {
// 2 points => same route for driver and passenger
const commonPath: Path = {
key: RouteKey.COMMON,
points: this.points,
};
paths.push(commonPath);
} else {
const driverPath: Path = {
key: RouteKey.DRIVER,
points: this.points,
};
const passengerPath: Path = {
key: RouteKey.PASSENGER,
points: [this.points[0], this.points[this.points.length - 1]],
};
paths.push(driverPath, passengerPath);
}
} else if (roles.includes(Role.DRIVER)) {
const driverPath: Path = {
key: RouteKey.DRIVER,
points: this.points,
};
paths.push(driverPath);
} else if (roles.includes(Role.PASSENGER)) {
const passengerPath: Path = {
key: RouteKey.PASSENGER,
points: [this.points[0], this.points[this.points.length - 1]],
};
paths.push(passengerPath);
}
const paths: Path[] = this.getPaths(roles);
const routes = await georouter.route(paths, settings);
if (routes.some((route) => route.key == RouteKey.COMMON)) {
this.driverRoute = routes.find(
@@ -81,11 +42,46 @@ export class Geography {
}
};
private setTimezones = (): void => {
this.timezones = this.timezoneFinder.timezones(
this.points[0].lat,
this.points[0].lon,
);
private getPaths = (roles: Role[]): Path[] => {
const paths: Path[] = [];
if (roles.includes(Role.DRIVER) && roles.includes(Role.PASSENGER)) {
if (this.coordinates.length == 2) {
// 2 points => same route for driver and passenger
const commonPath: Path = {
key: RouteKey.COMMON,
points: this.coordinates,
};
paths.push(commonPath);
} else {
const driverPath: Path = this.createDriverPath();
const passengerPath: Path = this.createPassengerPath();
paths.push(driverPath, passengerPath);
}
} else if (roles.includes(Role.DRIVER)) {
const driverPath: Path = this.createDriverPath();
paths.push(driverPath);
} else if (roles.includes(Role.PASSENGER)) {
const passengerPath: Path = this.createPassengerPath();
paths.push(passengerPath);
}
return paths;
};
private createDriverPath = (): Path => {
return {
key: RouteKey.DRIVER,
points: this.coordinates,
};
};
private createPassengerPath = (): Path => {
return {
key: RouteKey.PASSENGER,
points: [
this.coordinates[0],
this.coordinates[this.coordinates.length - 1],
],
};
};
}

View File

@@ -15,6 +15,7 @@ import { Role } from '../types/role.enum';
import { Geography } from '../entities/geography';
import { IEncodeDirection } from '../../../geography/domain/interfaces/direction-encoder.interface';
import { TimeConverter } from '../entities/time-converter';
import { Coordinate } from 'src/modules/geography/domain/entities/coordinate';
@CommandHandler(CreateAdCommand)
export class CreateAdUseCase {
@@ -38,7 +39,6 @@ export class CreateAdUseCase {
private readonly directionEncoder: IEncodeDirection,
) {
this.defaultParams = defaultParamsProvider.getParams();
this.timezone = this.defaultParams.DEFAULT_TIMEZONE;
this.georouter = georouterCreator.create(
this.defaultParams.GEOROUTER_TYPE,
this.defaultParams.GEOROUTER_URL,
@@ -48,8 +48,9 @@ export class CreateAdUseCase {
async execute(command: CreateAdCommand): Promise<Ad> {
try {
this.ad = this.mapper.map(command.createAdRequest, CreateAdRequest, Ad);
this.setTimezone(command.createAdRequest.waypoints);
this.setGeography(command.createAdRequest.waypoints);
this.setRoles(command.createAdRequest);
this.setGeography(command.createAdRequest);
await this.geography.createRoutes(this.roles, this.georouter, {
withDistance: false,
withPoints: true,
@@ -112,18 +113,24 @@ export class CreateAdUseCase {
}
}
private setTimezone = (coordinates: Coordinate[]): void => {
this.timezone = this.defaultParams.DEFAULT_TIMEZONE;
try {
const timezones = this.timezoneFinder.timezones(
coordinates[0].lat,
coordinates[0].lon,
);
if (timezones.length > 0) this.timezone = timezones[0];
} catch (e) {}
};
private setRoles = (createAdRequest: CreateAdRequest): void => {
this.roles = [];
if (createAdRequest.driver) this.roles.push(Role.DRIVER);
if (createAdRequest.passenger) this.roles.push(Role.PASSENGER);
};
private setGeography = (createAdRequest: CreateAdRequest): void => {
this.geography = new Geography(createAdRequest.waypoints, {
timezone: this.defaultParams.DEFAULT_TIMEZONE,
finder: this.timezoneFinder,
});
if (this.geography.timezones.length > 0)
this.timezone = this.geography.timezones[0];
private setGeography = (coordinates: Coordinate[]): void => {
this.geography = new Geography(coordinates);
};
}