This commit is contained in:
sbriat 2023-04-26 14:14:46 +02:00
parent 5865464c53
commit 96577e119f
34 changed files with 100 additions and 98 deletions

View File

@ -22,6 +22,7 @@ export class AdMessagerController {
try { try {
// parse message to conform to CreateAdRequest (not a real instance yet) // parse message to conform to CreateAdRequest (not a real instance yet)
const parsedMessage: CreateAdRequest = JSON.parse(message); const parsedMessage: CreateAdRequest = JSON.parse(message);
console.log(parsedMessage);
// create a real instance of CreateAdRequest from parsed message // create a real instance of CreateAdRequest from parsed message
const createAdRequest: CreateAdRequest = this.mapper.map( const createAdRequest: CreateAdRequest = this.mapper.map(
parsedMessage, parsedMessage,

View File

@ -8,11 +8,10 @@ import {
IsNumber, IsNumber,
IsOptional, IsOptional,
IsString, IsString,
ValidateNested,
} from 'class-validator'; } from 'class-validator';
import { PointType } from '../../../geography/domain/types/point-type.enum'; import { PointType } from '../../../geography/domain/types/point-type.enum';
import { Frequency } from '../types/frequency.enum'; import { Frequency } from '../types/frequency.enum';
import { Point } from '../../../geography/domain/types/point.type'; import { Coordinates } from '../../../geography/domain/types/coordinates.type';
export class CreateAdRequest { export class CreateAdRequest {
@IsString() @IsString()
@ -114,9 +113,8 @@ export class CreateAdRequest {
@IsArray() @IsArray()
@ArrayMinSize(2) @ArrayMinSize(2)
@ValidateNested({ each: true }) @AutoMap(() => [Coordinates])
@AutoMap() waypoints: Coordinates[];
waypoints: Array<Point>;
@IsNumber() @IsNumber()
@AutoMap() @AutoMap()

View File

@ -1,7 +1,6 @@
import { AutoMap } from '@automapper/classes'; import { AutoMap } from '@automapper/classes';
import { ArrayMinSize, IsArray, IsEnum, ValidateNested } from 'class-validator';
import { PointType } from '../../../geography/domain/types/point-type.enum'; import { PointType } from '../../../geography/domain/types/point-type.enum';
import { Point } from '../../../geography/domain/types/point.type'; import { Coordinates } from '../../../geography/domain/types/coordinates.type';
export class Ad { export class Ad {
@AutoMap() @AutoMap()
@ -76,19 +75,14 @@ export class Ad {
@AutoMap() @AutoMap()
passengerDistance: number; passengerDistance: number;
@IsEnum(PointType)
@AutoMap() @AutoMap()
originType: PointType; originType: PointType;
@IsEnum(PointType)
@AutoMap() @AutoMap()
destinationType: PointType; destinationType: PointType;
@IsArray() @AutoMap(() => [Coordinates])
@ArrayMinSize(2) waypoints: Coordinates[];
@ValidateNested({ each: true })
@AutoMap()
waypoints: Array<Point>;
@AutoMap() @AutoMap()
direction: string; direction: string;

View File

@ -57,7 +57,7 @@ export class ConfigurationMessagerController {
name: 'propagateConfiguration', name: 'propagateConfiguration',
}) })
public async propagateConfigurationsHandler(message: string) { public async propagateConfigurationsHandler(message: string) {
const configurations: Array<Configuration> = JSON.parse(message); const configurations: Configuration[] = JSON.parse(message);
configurations.forEach(async (configuration) => { configurations.forEach(async (configuration) => {
if ( if (
configuration.domain == configuration.domain ==

View File

@ -187,13 +187,13 @@ export abstract class PrismaRepository<T> implements IRepository<T> {
} }
async findAllByQuery( async findAllByQuery(
include: Array<string>, include: string[],
where: Array<string>, where: string[],
): Promise<ICollection<T>> { ): Promise<ICollection<T>> {
const query = `SELECT ${include.join(',')} FROM ${ const query = `SELECT ${include.join(',')} FROM ${
this._model this._model
} WHERE ${where.join(' AND ')}`; } WHERE ${where.join(' AND ')}`;
const data: Array<T> = await this._prisma.$queryRawUnsafe(query); const data: T[] = await this._prisma.$queryRawUnsafe(query);
return Promise.resolve({ return Promise.resolve({
data, data,
total: data.length, total: data.length,

View File

@ -4,5 +4,5 @@ import { find } from 'geo-tz';
@Injectable() @Injectable()
export class GeoTimezoneFinder implements IFindTimezone { export class GeoTimezoneFinder implements IFindTimezone {
timezones = (lon: number, lat: number): Array<string> => find(lat, lon); timezones = (lon: number, lat: number): string[] => find(lat, lon);
} }

View File

@ -1,3 +1,3 @@
export interface IFindTimezone { export interface IFindTimezone {
timezones(lon: number, lat: number): Array<string>; timezones(lon: number, lat: number): string[];
} }

View File

@ -1,4 +1,21 @@
export type Coordinates = { import { AutoMap } from '@automapper/classes';
import { IsNumber, Max, Min } from 'class-validator';
export class Coordinates {
constructor(lon: number, lat: number) {
this.lon = lon;
this.lat = lat;
}
@IsNumber()
@Min(-180)
@Max(180)
@AutoMap()
lon: number; lon: number;
@IsNumber()
@Min(-90)
@Max(90)
@AutoMap()
lat: number; lat: number;
}; }

View File

@ -17,11 +17,11 @@ import {
@Injectable() @Injectable()
export class GraphhopperGeorouter implements IGeorouter { export class GraphhopperGeorouter implements IGeorouter {
private url: string; private url: string;
private urlArgs: Array<string>; private urlArgs: string[];
private withTime: boolean; private withTime: boolean;
private withPoints: boolean; private withPoints: boolean;
private withDistance: boolean; private withDistance: boolean;
private paths: Array<Path>; private paths: Path[];
private httpService: HttpService; private httpService: HttpService;
private geodesic: IGeodesic; private geodesic: IGeodesic;
@ -32,9 +32,9 @@ export class GraphhopperGeorouter implements IGeorouter {
} }
route = async ( route = async (
paths: Array<Path>, paths: Path[],
settings: GeorouterSettings, settings: GeorouterSettings,
): Promise<Array<NamedRoute>> => { ): Promise<NamedRoute[]> => {
this.setDefaultUrlArgs(); this.setDefaultUrlArgs();
this.setWithTime(settings.withTime); this.setWithTime(settings.withTime);
this.setWithPoints(settings.withPoints); this.setWithPoints(settings.withPoints);
@ -70,7 +70,7 @@ export class GraphhopperGeorouter implements IGeorouter {
} }
}; };
private getRoutes = async (): Promise<Array<NamedRoute>> => { private getRoutes = async (): Promise<NamedRoute[]> => {
const routes = Promise.all( const routes = Promise.all(
this.paths.map(async (path) => { this.paths.map(async (path) => {
const url: string = [ const url: string = [
@ -125,7 +125,7 @@ export class GraphhopperGeorouter implements IGeorouter {
shortestPath.snapped_waypoints && shortestPath.snapped_waypoints &&
shortestPath.snapped_waypoints.coordinates shortestPath.snapped_waypoints.coordinates
) { ) {
let instructions: Array<GraphhopperInstruction> = []; let instructions: GraphhopperInstruction[] = [];
if (shortestPath.instructions) if (shortestPath.instructions)
instructions = shortestPath.instructions; instructions = shortestPath.instructions;
route.setSpacetimePoints( route.setSpacetimePoints(
@ -143,11 +143,11 @@ export class GraphhopperGeorouter implements IGeorouter {
}; };
private generateSpacetimePoints = ( private generateSpacetimePoints = (
points: Array<Array<number>>, points: Array<number[]>,
snappedWaypoints: Array<Array<number>>, snappedWaypoints: Array<number[]>,
durations: Array<Array<number>>, durations: Array<number[]>,
instructions: Array<GraphhopperInstruction>, instructions: GraphhopperInstruction[],
): Array<SpacetimePoint> => { ): SpacetimePoint[] => {
const indices = this.getIndices(points, snappedWaypoints); const indices = this.getIndices(points, snappedWaypoints);
const times = this.getTimes(durations, indices); const times = this.getTimes(durations, indices);
const distances = this.getDistances(instructions, indices); const distances = this.getDistances(instructions, indices);
@ -162,9 +162,9 @@ export class GraphhopperGeorouter implements IGeorouter {
}; };
private getIndices = ( private getIndices = (
points: Array<Array<number>>, points: Array<number[]>,
snappedWaypoints: Array<Array<number>>, snappedWaypoints: Array<number[]>,
): Array<number> => { ): number[] => {
const indices = snappedWaypoints.map((waypoint) => const indices = snappedWaypoints.map((waypoint) =>
points.findIndex( points.findIndex(
(point) => point[0] == waypoint[0] && point[1] == waypoint[1], (point) => point[0] == waypoint[0] && point[1] == waypoint[1],
@ -178,7 +178,7 @@ export class GraphhopperGeorouter implements IGeorouter {
{ {
index: number; index: number;
originIndex: number; originIndex: number;
waypoint: Array<number>; waypoint: number[];
nearest: number; nearest: number;
distance: number; distance: number;
} }
@ -212,8 +212,8 @@ export class GraphhopperGeorouter implements IGeorouter {
}; };
private getTimes = ( private getTimes = (
durations: Array<Array<number>>, durations: Array<number[]>,
indices: Array<number>, indices: number[],
): Array<{ index: number; duration: number }> => { ): Array<{ index: number; duration: number }> => {
const times: Array<{ index: number; duration: number }> = []; const times: Array<{ index: number; duration: number }> = [];
let duration = 0; let duration = 0;
@ -262,8 +262,8 @@ export class GraphhopperGeorouter implements IGeorouter {
}; };
private getDistances = ( private getDistances = (
instructions: Array<GraphhopperInstruction>, instructions: GraphhopperInstruction[],
indices: Array<number>, indices: number[],
): Array<{ index: number; distance: number }> => { ): Array<{ index: number; distance: number }> => {
let distance = 0; let distance = 0;
const distances: Array<{ index: number; distance: number }> = [ const distances: Array<{ index: number; distance: number }> = [
@ -296,26 +296,26 @@ type GraphhopperResponse = {
weight: number; weight: number;
time: number; time: number;
points_encoded: boolean; points_encoded: boolean;
bbox: Array<number>; bbox: number[];
points: GraphhopperCoordinates; points: GraphhopperCoordinates;
snapped_waypoints: GraphhopperCoordinates; snapped_waypoints: GraphhopperCoordinates;
details: { details: {
time: Array<Array<number>>; time: Array<number[]>;
}; };
instructions: Array<GraphhopperInstruction>; instructions: GraphhopperInstruction[];
}, },
]; ];
}; };
type GraphhopperCoordinates = { type GraphhopperCoordinates = {
coordinates: Array<Array<number>>; coordinates: Array<number[]>;
}; };
type GraphhopperInstruction = { type GraphhopperInstruction = {
distance: number; distance: number;
heading: number; heading: number;
sign: GraphhopperSign; sign: GraphhopperSign;
interval: Array<number>; interval: number[];
text: string; text: string;
}; };

View File

@ -6,6 +6,6 @@ import { IFindTimezone } from '../../../geography/domain/interfaces/timezone-fin
export class TimezoneFinder implements IFindTimezone { export class TimezoneFinder implements IFindTimezone {
constructor(private readonly geoTimezoneFinder: GeoTimezoneFinder) {} constructor(private readonly geoTimezoneFinder: GeoTimezoneFinder) {}
timezones = (lon: number, lat: number): Array<string> => timezones = (lon: number, lat: number): string[] =>
this.geoTimezoneFinder.timezones(lon, lat); this.geoTimezoneFinder.timezones(lon, lat);
} }

View File

@ -30,7 +30,7 @@ export class MatchRequest
{ {
@IsArray() @IsArray()
@AutoMap() @AutoMap()
waypoints: Array<Point>; waypoints: Point[];
@IsOptional() @IsOptional()
@IsString() @IsString()
@ -138,7 +138,7 @@ export class MatchRequest
@IsOptional() @IsOptional()
@IsArray() @IsArray()
exclusions: Array<number>; exclusions: number[];
@IsOptional() @IsOptional()
@IsInt() @IsInt()

View File

@ -19,10 +19,10 @@ import { Timezoner } from './timezoner';
export class Geography { export class Geography {
private geographyRequest: IRequestGeography; private geographyRequest: IRequestGeography;
private person: Person; private person: Person;
private points: Array<Point>; private points: Point[];
originType: PointType; originType: PointType;
destinationType: PointType; destinationType: PointType;
timezones: Array<string>; timezones: string[];
driverRoute: Route; driverRoute: Route;
passengerRoute: Route; passengerRoute: Route;
timezoneFinder: IFindTimezone; timezoneFinder: IFindTimezone;
@ -48,12 +48,12 @@ export class Geography {
}; };
createRoutes = async ( createRoutes = async (
roles: Array<Role>, roles: Role[],
georouter: IGeorouter, georouter: IGeorouter,
): Promise<void> => { ): Promise<void> => {
let driverWaypoints: Array<Waypoint> = []; let driverWaypoints: Waypoint[] = [];
let passengerWaypoints: Array<Waypoint> = []; let passengerWaypoints: Waypoint[] = [];
const paths: Array<Path> = []; const paths: Path[] = [];
if (roles.includes(Role.DRIVER) && roles.includes(Role.PASSENGER)) { if (roles.includes(Role.DRIVER) && roles.includes(Role.PASSENGER)) {
if (this.points.length == 2) { if (this.points.length == 2) {
// 2 points => same route for driver and passenger // 2 points => same route for driver and passenger
@ -174,10 +174,7 @@ export class Geography {
private isValidLatitude = (latitude: number): boolean => private isValidLatitude = (latitude: number): boolean =>
latitude >= -90 && latitude <= 90; latitude >= -90 && latitude <= 90;
private createWaypoints = ( private createWaypoints = (points: Point[], role: Role): Waypoint[] => {
points: Array<Point>,
role: Role,
): Array<Waypoint> => {
return points.map((point, index) => { return points.map((point, index) => {
const waypoint = new Waypoint(point); const waypoint = new Waypoint(point);
if (index == 0) { if (index == 0) {

View File

@ -5,7 +5,7 @@ export class Person {
private defaultIdentifier: number; private defaultIdentifier: number;
private defaultMarginDuration: number; private defaultMarginDuration: number;
identifier: number; identifier: number;
marginDurations: Array<number>; marginDurations: number[];
constructor( constructor(
personRequest: IRequestPerson, personRequest: IRequestPerson,
@ -34,7 +34,7 @@ export class Person {
this.identifier = identifier; this.identifier = identifier;
}; };
setMarginDurations = (marginDurations: Array<number>): void => { setMarginDurations = (marginDurations: number[]): void => {
this.marginDurations = marginDurations; this.marginDurations = marginDurations;
}; };
} }

View File

@ -9,9 +9,9 @@ export class Route {
fwdAzimuth: number; fwdAzimuth: number;
backAzimuth: number; backAzimuth: number;
distanceAzimuth: number; distanceAzimuth: number;
waypoints: Array<Waypoint>; waypoints: Waypoint[];
points: Array<Point>; points: Point[];
spacetimePoints: Array<SpacetimePoint>; spacetimePoints: SpacetimePoint[];
private geodesic: IGeodesic; private geodesic: IGeodesic;
constructor(geodesic: IGeodesic) { constructor(geodesic: IGeodesic) {
@ -26,21 +26,21 @@ export class Route {
this.geodesic = geodesic; this.geodesic = geodesic;
} }
setWaypoints = (waypoints: Array<Waypoint>): void => { setWaypoints = (waypoints: Waypoint[]): void => {
this.waypoints = waypoints; this.waypoints = waypoints;
this.setAzimuth(waypoints.map((waypoint) => waypoint.point)); this.setAzimuth(waypoints.map((waypoint) => waypoint.point));
}; };
setPoints = (points: Array<Point>): void => { setPoints = (points: Point[]): void => {
this.points = points; this.points = points;
this.setAzimuth(points); this.setAzimuth(points);
}; };
setSpacetimePoints = (spacetimePoints: Array<SpacetimePoint>): void => { setSpacetimePoints = (spacetimePoints: SpacetimePoint[]): void => {
this.spacetimePoints = spacetimePoints; this.spacetimePoints = spacetimePoints;
}; };
private setAzimuth = (points: Array<Point>): void => { private setAzimuth = (points: Point[]): void => {
const inverse = this.geodesic.inverse( const inverse = this.geodesic.inverse(
points[0].lon, points[0].lon,
points[0].lat, points[0].lat,

View File

@ -3,7 +3,7 @@ import { Actor } from './actor';
export class Waypoint { export class Waypoint {
point: Point; point: Point;
actors: Array<Actor>; actors: Actor[];
constructor(point: Point) { constructor(point: Point) {
this.point = point; this.point = point;

View File

@ -5,7 +5,7 @@ import { Selector } from '../selector/selector.abstract';
export abstract class AlgorithmFactory { export abstract class AlgorithmFactory {
protected matchQuery: MatchQuery; protected matchQuery: MatchQuery;
private candidates: Array<Candidate>; private candidates: Candidate[];
constructor(matchQuery: MatchQuery) { constructor(matchQuery: MatchQuery) {
this.matchQuery = matchQuery; this.matchQuery = matchQuery;
@ -13,5 +13,5 @@ export abstract class AlgorithmFactory {
} }
abstract createSelector(): Selector; abstract createSelector(): Selector;
abstract createProcessors(): Array<Processor>; abstract createProcessors(): Processor[];
} }

View File

@ -10,7 +10,7 @@ import { ClassicSelector } from '../selector/classic.selector';
export class ClassicAlgorithmFactory extends AlgorithmFactory { export class ClassicAlgorithmFactory extends AlgorithmFactory {
createSelector = (): Selector => new ClassicSelector(this.matchQuery); createSelector = (): Selector => new ClassicSelector(this.matchQuery);
createProcessors = (): Array<Processor> => [ createProcessors = (): Processor[] => [
new ClassicWaypointsCompleter(this.matchQuery), new ClassicWaypointsCompleter(this.matchQuery),
new RouteCompleter(this.matchQuery, true, true, true), new RouteCompleter(this.matchQuery, true, true, true),
new ClassicGeoFilter(this.matchQuery), new ClassicGeoFilter(this.matchQuery),

View File

@ -11,10 +11,10 @@ export class Matcher {
private readonly algorithmFactoryCreator: AlgorithmFactoryCreator, private readonly algorithmFactoryCreator: AlgorithmFactoryCreator,
) {} ) {}
match = async (matchQuery: MatchQuery): Promise<Array<Match>> => { match = async (matchQuery: MatchQuery): Promise<Match[]> => {
const algorithmFactory: AlgorithmFactory = const algorithmFactory: AlgorithmFactory =
this.algorithmFactoryCreator.create(matchQuery); this.algorithmFactoryCreator.create(matchQuery);
let candidates: Array<Candidate> = await algorithmFactory let candidates: Candidate[] = await algorithmFactory
.createSelector() .createSelector()
.select(); .select();
for (const processor of algorithmFactory.createProcessors()) { for (const processor of algorithmFactory.createProcessors()) {

View File

@ -2,7 +2,7 @@ import { Candidate } from '../../candidate';
import { Completer } from './completer.abstract'; import { Completer } from './completer.abstract';
export class ClassicWaypointsCompleter extends Completer { export class ClassicWaypointsCompleter extends Completer {
complete = (candidates: Array<Candidate>): Array<Candidate> => { complete = (candidates: Candidate[]): Candidate[] => {
return candidates; return candidates;
}; };
} }

View File

@ -2,8 +2,7 @@ import { Candidate } from '../../candidate';
import { Processor } from '../processor.abstract'; import { Processor } from '../processor.abstract';
export abstract class Completer extends Processor { export abstract class Completer extends Processor {
execute = (candidates: Array<Candidate>): Array<Candidate> => execute = (candidates: Candidate[]): Candidate[] => this.complete(candidates);
this.complete(candidates);
abstract complete(candidates: Array<Candidate>): Array<Candidate>; abstract complete(candidates: Candidate[]): Candidate[];
} }

View File

@ -2,7 +2,7 @@ import { Candidate } from '../../candidate';
import { Completer } from './completer.abstract'; import { Completer } from './completer.abstract';
export class JourneyCompleter extends Completer { export class JourneyCompleter extends Completer {
complete = (candidates: Array<Candidate>): Array<Candidate> => { complete = (candidates: Candidate[]): Candidate[] => {
return candidates; return candidates;
}; };
} }

View File

@ -19,7 +19,7 @@ export class RouteCompleter extends Completer {
this.withDistance = withDistance; this.withDistance = withDistance;
} }
complete = (candidates: Array<Candidate>): Array<Candidate> => { complete = (candidates: Candidate[]): Candidate[] => {
return candidates; return candidates;
}; };
} }

View File

@ -2,8 +2,7 @@ import { Candidate } from '../../candidate';
import { Processor } from '../processor.abstract'; import { Processor } from '../processor.abstract';
export abstract class Filter extends Processor { export abstract class Filter extends Processor {
execute = (candidates: Array<Candidate>): Array<Candidate> => execute = (candidates: Candidate[]): Candidate[] => this.filter(candidates);
this.filter(candidates);
abstract filter(candidates: Array<Candidate>): Array<Candidate>; abstract filter(candidates: Candidate[]): Candidate[];
} }

View File

@ -2,7 +2,7 @@ import { Candidate } from '../../../candidate';
import { Filter } from '../filter.abstract'; import { Filter } from '../filter.abstract';
export class ClassicGeoFilter extends Filter { export class ClassicGeoFilter extends Filter {
filter = (candidates: Array<Candidate>): Array<Candidate> => { filter = (candidates: Candidate[]): Candidate[] => {
return candidates; return candidates;
}; };
} }

View File

@ -2,7 +2,7 @@ import { Candidate } from '../../../candidate';
import { Filter } from '../filter.abstract'; import { Filter } from '../filter.abstract';
export class ClassicTimeFilter extends Filter { export class ClassicTimeFilter extends Filter {
filter = (candidates: Array<Candidate>): Array<Candidate> => { filter = (candidates: Candidate[]): Candidate[] => {
return candidates; return candidates;
}; };
} }

View File

@ -8,5 +8,5 @@ export abstract class Processor {
this.matchQuery = matchQuery; this.matchQuery = matchQuery;
} }
abstract execute(candidates: Array<Candidate>): Array<Candidate>; abstract execute(candidates: Candidate[]): Candidate[];
} }

View File

@ -2,7 +2,7 @@ import { Candidate } from '../candidate';
import { Selector } from './selector.abstract'; import { Selector } from './selector.abstract';
export class ClassicSelector extends Selector { export class ClassicSelector extends Selector {
select = async (): Promise<Array<Candidate>> => { select = async (): Promise<Candidate[]> => {
return []; return [];
}; };
} }

View File

@ -8,5 +8,5 @@ export abstract class Selector {
this.matchQuery = matchQuery; this.matchQuery = matchQuery;
} }
abstract select(): Promise<Array<Candidate>>; abstract select(): Promise<Candidate[]>;
} }

View File

@ -1,5 +1,5 @@
import { Point } from '../../../geography/domain/types/point.type'; import { Point } from '../../../geography/domain/types/point.type';
export interface IRequestGeography { export interface IRequestGeography {
waypoints: Array<Point>; waypoints: Point[];
} }

View File

@ -3,8 +3,5 @@ import { GeorouterSettings } from '../types/georouter-settings.type';
import { Path } from '../types/path.type'; import { Path } from '../types/path.type';
export interface IGeorouter { export interface IGeorouter {
route( route(paths: Path[], settings: GeorouterSettings): Promise<NamedRoute[]>;
paths: Array<Path>,
settings: GeorouterSettings,
): Promise<Array<NamedRoute>>;
} }

View File

@ -2,5 +2,5 @@ import { Point } from '../../../geography/domain/types/point.type';
export type Path = { export type Path = {
key: string; key: string;
points: Array<Point>; points: Point[];
}; };

View File

@ -3,5 +3,5 @@ import { Point } from '../../../geography/domain/types/point.type';
export type Waypoint = { export type Waypoint = {
point: Point; point: Point;
actors: Array<Actor>; actors: Actor[];
}; };

View File

@ -17,7 +17,7 @@ export class MatchUseCase {
execute = async (matchQuery: MatchQuery): Promise<ICollection<Match>> => { execute = async (matchQuery: MatchQuery): Promise<ICollection<Match>> => {
try { try {
const data: Array<Match> = await this._matcher.match(matchQuery); const data: Match[] = await this._matcher.match(matchQuery);
this._messager.publish('matcher.match', 'match !'); this._messager.publish('matcher.match', 'match !');
return { return {
data, data,

View File

@ -15,10 +15,10 @@ export class MatchQuery {
private readonly defaultParams: IDefaultParams; private readonly defaultParams: IDefaultParams;
private readonly georouterCreator: ICreateGeorouter; private readonly georouterCreator: ICreateGeorouter;
person: Person; person: Person;
roles: Array<Role>; roles: Role[];
time: Time; time: Time;
geography: Geography; geography: Geography;
exclusions: Array<number>; exclusions: number[];
requirement: Requirement; requirement: Requirement;
algorithmSettings: AlgorithmSettings; algorithmSettings: AlgorithmSettings;
georouter: IGeorouter; georouter: IGeorouter;