@wemap/routers 11.0.0-alpha.12 → 11.0.0-alpha.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +2015 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +2010 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +3 -3
- package/src/model/generateSteps.ts +14 -6
- package/src/wemap-osm/WemapOsmRouter.spec.ts +38 -0
- package/src/wemap-osm/WemapOsmRouter.ts +30 -3
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/Utils.ts","../src/model/LevelChange.ts","../src/model/StepInfo.ts","../src/model/generateSteps.ts","../src/model/RoutingMode.ts","../src/model/Leg.ts","../src/model/Itinerary.ts","../src/model/RouterResponse.ts","../src/wemap-osm/WemapOsmRouterOptions.ts","../src/wemap-osm/WemapOsmRouter.ts","../src/remote/RemoteRouter.ts","../src/remote/RemoteRouterServerUnreachable.ts","../src/remote/RoutingModeCorrespondanceNotFound.ts","../src/remote/RemoteRouterUtils.ts","../src/remote/cityway/CitywayRemoteRouter.ts","../src/remote/deutsche-bahn/DeutscheBahnRemoteRouter.ts","../src/remote/idfm/IdfmRemoteRouter.ts","../src/remote/osrm/OsrmRemoteRouter.ts","../src/remote/otp/OtpRemoteRouter.ts","../src/remote/wemap-multi/WemapMultiRemoteRouterPayload.ts","../src/remote/wemap-multi/WemapMultiRemoteRouter.ts","../src/remote/RemoteRouterManager.ts","../src/wemap-multi/WemapMultiRouter.ts","../src/wemap-multi/CustomNetworkMap.ts","../src/wemap-osm/WemapOsmRouterUtils.ts","../src/ItineraryInfoManager.ts"],"sourcesContent":["/**\n * Get route duration\n * @param {Number} speed in km/h\n * @returns {Number} duration in seconds\n */\nexport function getDurationFromLength(length: number, speed = 5) {\n return length / (speed * 1000 / 3600);\n}\n","export type LevelChangeType = 'elevator' | 'conveyor' | 'stairs';\n\nexport type LevelChange = {\n direction: 'up' | 'down';\n difference: number;\n type?: LevelChangeType;\n}\n\nexport function areLevelChangeEquals(l1: LevelChange, l2: LevelChange) {\n return l1 === l2\n || l1.difference === l2.difference\n && l1.direction === l2.direction\n && l1.type === l2.type;\n}","import { Coordinates, CoordinatesCompressedJson } from '@wemap/geo';\n\nimport { LevelChange, areLevelChangeEquals } from './LevelChange.js';\nimport { StepExtra } from './StepExtra.js';\n\ntype StepInfoCommon = {\n name?: string,\n levelChange?: LevelChange\n extras?: StepExtra,\n distance?: number,\n duration?: number\n}\n\ntype StepInfoConstructor = {\n coords: Coordinates,\n} & StepInfoCommon;\n\nexport type StepInfoJson = {\n coords: CoordinatesCompressedJson,\n} & StepInfoCommon;\n\n\nexport default class StepInfo {\n\n readonly coords: Coordinates;\n readonly name: string | null;\n distance: number | null;\n duration: number | null;\n readonly levelChange: LevelChange | null;\n readonly extras: StepExtra | null;\n\n constructor({\n coords, distance, name, levelChange, extras, duration\n }: StepInfoConstructor) {\n this.coords = coords;\n this.name = name || null;\n this.distance = typeof distance === 'number' ? distance : null;\n this.duration = typeof duration === 'number' ? duration : null;\n this.levelChange = levelChange || null;\n this.extras = extras || null;\n }\n\n static equals(obj1: StepInfo, obj2: StepInfo) {\n return obj1.coords.equals(obj2.coords)\n && obj1.distance === obj2.distance\n && obj1.duration === obj2.duration\n && obj1.name === obj2.name\n && (\n obj1.levelChange === obj2.levelChange\n || (\n obj1.levelChange\n && obj2.levelChange\n && areLevelChangeEquals(obj1.levelChange, obj2.levelChange)\n )\n );\n }\n\n equals(obj: StepInfo) {\n return StepInfo.equals(this, obj);\n }\n\n toJson(): StepInfoJson {\n return {\n coords: this.coords.toCompressedJson(),\n ...(this.distance !== null && { distance: this.distance }),\n ...(this.duration !== null && { duration: this.duration }),\n ...(this.name !== null && { name: this.name }),\n ...(this.levelChange !== null && { levelChange: this.levelChange }),\n ...(this.extras && Object.keys(this.extras).length !== 0 && { extras: this.extras }),\n };\n }\n\n static fromJson(json: StepInfoJson) {\n return new StepInfo(Object.assign({}, json, {\n coords: Coordinates.fromCompressedJson(json.coords)\n }));\n }\n}\n","import { Coordinates, Level } from '@wemap/geo';\nimport logger from '@wemap/logger';\nimport { diffAngle, deg2rad } from '@wemap/maths';\nimport Leg from './Leg.js';\n\nimport { LevelChange, LevelChangeType } from './LevelChange.js';\nimport { StepExtra } from './StepExtra.js';\nimport StepInfo from './StepInfo.js';\n\nconst SKIP_STEP_ANGLE_MAX = deg2rad(20);\n\nexport type StepsGenerationRules =\n (currentCoords: Coordinates, nextCoords: Coordinates, previousStep: StepInfo | null) => {\n createNewStep?: boolean;\n duration?: number;\n stepName?: string;\n stepExtras?: StepExtra;\n levelChangeType?: LevelChangeType;\n levelChangeDirection?: 'up' | 'down';\n };\n\nexport default function generateSteps(leg: Leg, rules?: StepsGenerationRules) {\n\n const steps: StepInfo[] = [];\n\n const { from, to, coords: coordsArray } = leg;\n\n let currentStep: StepInfo | null = null;\n let previousBearing = from.coords.bearingTo(coordsArray[0]);\n\n for (let i = 0; i < coordsArray.length - 1; i++) {\n\n const isFirstStep = i === 0;\n\n const currentCoords = coordsArray[i];\n const nextCoords = coordsArray[i + 1];\n const edgeLevel = Level.union(currentCoords.level, nextCoords.level);\n\n const nextBearing = currentCoords.bearingTo(nextCoords);\n const angle = diffAngle(previousBearing, nextBearing + Math.PI);\n\n let splitByAngle = Math.abs(diffAngle(Math.PI, angle)) >= SKIP_STEP_ANGLE_MAX;\n\n const splitByLevel = Level.isRange(edgeLevel) && !Level.isRange(currentCoords.level);\n splitByAngle = splitByAngle && !(currentCoords.level && Level.isRange(currentCoords.level));\n\n const previousStep = steps.length ? steps[steps.length - 1] : null;\n const customRules = rules?.(currentCoords, nextCoords, previousStep);\n\n const splitStepCondition = splitByAngle || splitByLevel || customRules?.createNewStep;\n\n // New step creation\n if (isFirstStep || splitStepCondition) {\n\n let levelChange: LevelChange | undefined;\n\n if (splitByLevel || customRules?.levelChangeType) {\n const difference = Level.diff(currentCoords.level, nextCoords.level) || 0;\n let direction: 'up' | 'down' = difference > 0 ? 'up' : 'down';\n // if (difference !== 0 && customRules?.levelChangeDirection && customRules?.levelChangeDirection !== direction) {\n // logger.warn(`direction from level and from customrules are different`);\n // }\n if (difference === 0 && customRules?.levelChangeDirection) {\n direction = customRules.levelChangeDirection;\n }\n levelChange = { difference, direction, type: customRules?.levelChangeType };\n }\n\n // Remove duration in the case of rules do not provide duration.\n if (currentStep && currentStep.duration === 0) {\n currentStep.duration = null;\n }\n\n currentStep = new StepInfo({\n coords: currentCoords,\n name: customRules?.stepName,\n extras: customRules?.stepExtras,\n levelChange,\n distance: 0,\n duration: 0\n });\n\n steps.push(currentStep);\n }\n\n currentStep!.distance! += currentCoords.distanceTo(nextCoords);\n if (customRules?.duration) {\n currentStep!.duration! += customRules?.duration;\n }\n previousBearing = nextBearing;\n }\n\n const lastCoords = coordsArray[coordsArray.length - 1];\n\n // Create a last step if end is not on the network\n if (!Coordinates.equals(lastCoords, to.coords)) {\n steps.push(new StepInfo({ coords: lastCoords }));\n }\n\n return steps;\n}\n","\nexport type RoutingMode = 'AIRPLANE' | 'BOAT' | 'BIKE' | 'BUS' | 'CAR' |\n 'FERRY' | 'FUNICULAR' | 'METRO' | 'MOTO' | 'TRAIN' | 'TAXI' |\n 'TRAM' | 'WALK' | 'MULTI' | 'UNKNOWN';\n\nexport type PublicTransport = 'AIRPLANE' | 'BOAT' | 'BUS' |\n 'FERRY' | 'FUNICULAR' | 'METRO' | 'TRAIN' | 'TRAM';\n\nexport function isRoutingModePublicTransport(routingMode: RoutingMode): routingMode is PublicTransport {\n return [\n 'AIRPLANE', 'BOAT', 'BUS', 'FERRY',\n 'FUNICULAR', 'METRO', 'TRAIN', 'TRAM'\n ].includes(routingMode);\n}\n","import {\n Coordinates, CoordinatesCompressedJson, GraphItinerary, Level,\n Network, Utils as GeoUtils\n} from '@wemap/geo';\nimport { getDurationFromLength } from '../Utils.js';\nimport generateSteps, { StepsGenerationRules } from './generateSteps.js';\nimport { RoutingMode, isRoutingModePublicTransport } from './RoutingMode.js';\n\nimport { Step } from './Step.js'\nimport StepInfo, { StepInfoJson } from './StepInfo.js';\n\nexport type Destination = {\n name: string | null,\n coords: Coordinates\n};\n\nexport type DestinationConstructor = {\n name?: string,\n coords: Coordinates\n};\n\nexport type DestinationJson = {\n name?: string,\n coords: CoordinatesCompressedJson\n};\n\nexport type TransportInfo = {\n name: string,\n routeColor?: string,\n routeTextColor?: string,\n directionName?: string\n}\n\ntype LegCommon = {\n mode: RoutingMode,\n startTime?: number,\n endTime?: number,\n transportInfo?: TransportInfo,\n}\n\ntype LegConstructor =\n {\n from: DestinationConstructor,\n to: DestinationConstructor,\n coords: Coordinates[],\n duration?: number\n }\n & (\n { stepsGenerationRules?: StepsGenerationRules }\n | { stepsInfo: StepInfo[] }\n )\n & LegCommon;\n\nexport type LegJson = {\n from: DestinationJson,\n to: DestinationJson,\n coords: CoordinatesCompressedJson[],\n steps: StepInfoJson[],\n duration: number\n} & LegCommon;\n\nexport default class Leg {\n\n from: Destination;\n to: Destination;\n coords: Coordinates[];\n distance: number;\n mode: RoutingMode;\n\n duration: number;\n startTime: number | null;\n endTime: number | null;\n\n stepsInfo: StepInfo[];\n transportInfo: TransportInfo | null;\n\n constructor({\n from, to, coords, mode, duration,\n startTime, endTime, transportInfo, ...otherParams\n }: LegConstructor) {\n this.from = {\n name: from.name || null,\n coords: from.coords\n };\n this.to = {\n name: to.name || null,\n coords: to.coords\n };\n this.coords = coords;\n this.mode = mode;\n this.distance = GeoUtils.calcDistance(coords)\n this.duration = typeof duration === 'number' ? duration : getDurationFromLength(this.distance);\n this.startTime = typeof startTime === 'number' ? startTime : null;\n this.endTime = typeof endTime === 'number' ? endTime : null;\n this.transportInfo = transportInfo || null;\n this.stepsInfo = 'stepsInfo' in otherParams\n ? otherParams.stepsInfo\n : generateSteps(this, otherParams.stepsGenerationRules);\n }\n\n isPublicTransport() {\n return isRoutingModePublicTransport(this.mode);\n }\n\n toNetwork<N, E>() {\n return Network.fromCoordinates<N, E>([this.coords]);\n }\n\n static equals(obj1: Leg, obj2: Leg) {\n const intermediate = obj1.mode === obj2.mode\n && obj1.duration === obj2.duration\n && obj1.startTime === obj2.startTime\n && obj1.endTime === obj2.endTime\n && obj1.from.name === obj2.from.name\n && obj1.from.coords.equals(obj2.from.coords)\n && obj1.to.name === obj2.to.name\n && obj1.to.coords.equals(obj2.to.coords)\n && obj1.coords.length === obj2.coords.length\n && (\n obj1.stepsInfo === obj2.stepsInfo\n || obj1.stepsInfo?.length === obj2.stepsInfo?.length\n );\n\n if (!intermediate) {\n return false;\n }\n\n let i;\n for (i = 0; i < obj1.coords.length; i++) {\n if (!obj1.coords[i].equals(obj2.coords[i])) {\n return false;\n }\n }\n if (obj1.stepsInfo && obj2.stepsInfo) {\n for (i = 0; i < obj1.stepsInfo.length; i++) {\n if (!obj1.stepsInfo[i].equals(obj2.stepsInfo[i])) {\n return false;\n }\n }\n }\n\n if (obj1.transportInfo !== obj2.transportInfo) {\n if (obj1.transportInfo === null || obj2.transportInfo === null) {\n return false;\n }\n if (\n obj1.transportInfo.name !== obj2.transportInfo.name\n || obj1.transportInfo.routeColor !== obj2.transportInfo.routeColor\n || obj1.transportInfo.routeTextColor !== obj2.transportInfo.routeTextColor\n || obj1.transportInfo.directionName !== obj2.transportInfo.directionName\n ) {\n return false;\n }\n }\n\n return true;\n }\n\n equals(obj: Leg) {\n return Leg.equals(this, obj);\n }\n\n toJson(): LegJson {\n return {\n mode: this.mode,\n from: {\n coords: this.from.coords.toCompressedJson(),\n ...(this.from.name && { name: this.from.name }),\n },\n to: {\n coords: this.to.coords.toCompressedJson(),\n ...(this.to.name && { name: this.to.name }),\n },\n duration: this.duration,\n coords: this.coords.map(coords => coords.toCompressedJson()),\n steps: this.stepsInfo.map(stepInfo => stepInfo.toJson()),\n ...(this.startTime !== null && { startTime: this.startTime }),\n ...(this.endTime !== null && { endTime: this.endTime }),\n ...(this.transportInfo !== null && { transportInfo: this.transportInfo }),\n };\n }\n\n static fromJson(json: LegJson) {\n const leg = new Leg(Object.assign({}, json, {\n from: {\n coords: Coordinates.fromCompressedJson(json.from.coords),\n name: json.from.name || null\n },\n to: {\n coords: Coordinates.fromCompressedJson(json.to.coords),\n name: json.to.name || null\n },\n coords: json.coords.map(Coordinates.fromCompressedJson),\n stepsInfo: json.steps?.map(StepInfo.fromJson) || null,\n stepsGenerationRules: undefined\n }));\n\n return leg;\n }\n\n static fromGraphItinerary<T>(\n graphItinerary: GraphItinerary<T>,\n mode: RoutingMode = 'WALK',\n stepsGenerationRules?: StepsGenerationRules\n ) {\n return new Leg({\n from: { coords: graphItinerary.start },\n to: { coords: graphItinerary.end },\n coords: graphItinerary.nodes.map(node => node.coords),\n duration: graphItinerary.edgesWeights.reduce((acc, weight) => acc + weight, 0),\n mode,\n stepsGenerationRules\n });\n }\n\n // TODO: Remove when possible...\n // Livemap specific\n multiplyLevel(levelFactor: number) {\n this.from.coords.level = Level.multiplyBy(this.from.coords.level, levelFactor);\n this.to.coords.level = Level.multiplyBy(this.to.coords.level, levelFactor);\n for (const coords of this.coords) {\n coords.level = Level.multiplyBy(coords.level, levelFactor);\n }\n this.stepsInfo.forEach(step => {\n step.coords.level = Level.multiplyBy(step.coords.level, levelFactor);\n });\n }\n\n /**\n * Get leg steps from itinerary steps\n * Steps cannot be retrieved directly from stepsInfo due to nextBearing/previousBearing \n */\n getSteps(itinerarySteps: Step[]) {\n return this.stepsInfo.map(stepInfo => itinerarySteps.find(_step => _step.coords.equals(stepInfo.coords)));\n }\n}\n","import { \n Coordinates, CoordinatesCompressedJson, GraphItinerary, \n Level, Network, Utils as GeoUtils \n} from '@wemap/geo';\nimport { diffAngle, Point2_t, Vector3_t } from '@wemap/maths';\nimport { Feature, MultiLineString } from 'geojson';\n\nimport Leg, { LegJson } from './Leg.js';\nimport { getDurationFromLength } from '../Utils.js';\nimport { RoutingMode, isRoutingModePublicTransport } from './RoutingMode.js';\nimport { Step } from './Step.js';\nimport { StepsGenerationRules } from './generateSteps.js';\n\n\nexport type ItineraryMode = 'PT' | 'CAR' | 'BIKE' | 'WALK';\n\nexport type ItineraryCommon = {\n startTime?: number,\n endTime?: number\n};\n\nexport type ItineraryJson = {\n mode: ItineraryMode,\n from: CoordinatesCompressedJson,\n to: CoordinatesCompressedJson,\n duration: number,\n legs: LegJson[]\n} & ItineraryCommon;\n\n\nexport type ItineraryConstructor = {\n from: Coordinates,\n to: Coordinates,\n duration?: number\n legs: Leg[],\n} & ItineraryCommon;\n\n/**\n * Main attributes are:\n * nodes: the ordered list of Node\n * edges: the ordered list of Edge\n * start: the start point (Coordinates)\n * end: the end point (Coordinates)\n * length: the route length\n */\nexport default class Itinerary {\n\n from: Coordinates;\n to: Coordinates;\n duration: number;\n legs: Leg[];\n\n private _mode: ItineraryMode | null = null;\n startTime: number | null;\n endTime: number | null;\n\n private _coords: Coordinates[] | null = null;\n private _steps: Step[] | null = null;\n private _distance: number | null = null;\n\n constructor({\n from, to, duration, legs, startTime, endTime\n }: ItineraryConstructor) {\n this.from = from;\n this.to = to;\n this.legs = legs;\n this.duration = typeof duration === 'number'\n ? duration\n : this.legs.reduce((dur, leg) => dur + leg.duration, 0);\n this.startTime = typeof startTime === 'number' ? startTime : null;\n this.endTime = typeof endTime === 'number' ? endTime : null;\n }\n\n set coords(_) {\n throw new Error('Itinerary.coords cannot be set. They are calculated from Itinerary.legs.');\n }\n\n public get coords() {\n if (!this._coords) {\n this._coords = this.legs.map(leg => leg.coords)\n .flat()\n // Remove duplicates\n .filter((coords, idx, arr) => idx === 0 || !arr[idx - 1].equals(coords));\n }\n return this._coords;\n }\n\n set steps(_) {\n throw new Error('Itinerary.step cannot be set. They are calculated from Itinerary.legs.');\n }\n\n get steps(): Step[] {\n\n if (this._steps) {\n return this._steps;\n }\n\n const itineraryCoords = this.coords\n // Remove duplicates\n .filter((coords, idx, arr) => idx === 0 || !arr[idx - 1].equals(coords));\n const stepsInfo = this.legs.map(leg => leg.stepsInfo).flat();\n\n const steps: Step[] = stepsInfo.map((stepInfo, stepId) => {\n\n const coordsId = itineraryCoords.findIndex(coords => coords.equals(stepInfo.coords));\n if (coordsId === -1) {\n throw new Error('Cannot find step coordinates in itinerary coordinates.');\n }\n\n const coordsBeforeStep = coordsId === 0 ? this.from : itineraryCoords[coordsId - 1];\n const coordsAfterStep = coordsId === itineraryCoords.length - 1\n ? this.to\n : itineraryCoords[coordsId + 1];\n\n const previousBearing = coordsBeforeStep.bearingTo(stepInfo.coords);\n const nextBearing = stepInfo.coords.bearingTo(coordsAfterStep);\n\n let distance = 0;\n const coordsToStopCalculation = stepId !== stepsInfo.length - 1\n ? stepsInfo[stepId + 1].coords\n : itineraryCoords[itineraryCoords.length - 1];\n let currentCoordsId = coordsId;\n while (!itineraryCoords[currentCoordsId].equals(coordsToStopCalculation)) {\n distance += itineraryCoords[currentCoordsId].distanceTo(itineraryCoords[currentCoordsId + 1]);\n currentCoordsId++;\n }\n if (currentCoordsId === itineraryCoords.length - 1) {\n distance += itineraryCoords[currentCoordsId].distanceTo(this.to);\n }\n\n return {\n ...stepInfo,\n number: stepId + 1,\n previousBearing,\n nextBearing,\n angle: diffAngle(previousBearing, nextBearing + Math.PI),\n firstStep: stepId === 0,\n lastStep: stepId === stepsInfo.length - 1,\n distance,\n duration: stepInfo.duration || getDurationFromLength(distance),\n previousStep: null,\n nextStep: null\n }\n });\n\n return steps;\n }\n\n set mode(_) {\n throw new Error('Itinerary.mode cannot be set. They are calculated from Itinerary.legs.');\n }\n\n get mode() {\n if (!this._mode) {\n let isPublicTransport = false;\n let isBicycle = false;\n let isDriving = false;\n\n this.legs.forEach((leg) => {\n isPublicTransport = isPublicTransport || isRoutingModePublicTransport(leg.mode);\n isBicycle = isBicycle || leg.mode === 'BIKE';\n isDriving = isDriving || leg.mode === 'CAR';\n });\n\n if (isPublicTransport) {\n this._mode = 'PT';\n } else if (isDriving) {\n this._mode = 'CAR';\n } else if (isBicycle) {\n this._mode = 'BIKE';\n } else {\n this._mode = 'WALK';\n }\n }\n\n return this._mode;\n\n }\n\n set distance(_) {\n throw new Error('Itinerary.distance cannot be set. They are calculated from Itinerary.legs.');\n }\n\n get distance() {\n if (this._distance === null) {\n this._distance = GeoUtils.calcDistance(this.coords);\n }\n return this._distance;\n\n // Does not work if legs does not intersect\n // return this.legs.reduce((dist, leg) => dist + leg.distance, 0);\n }\n\n toNetwork<N = unknown, E = unknown>() {\n return Network.fromCoordinates<N, E>([this.coords]);\n }\n\n static fromItineraries(...itineraries: Itinerary[]) {\n let duration = 0;\n const legs: Leg[] = [];\n\n itineraries.forEach(_itinerary => {\n duration += _itinerary.duration;\n legs.push(..._itinerary.legs);\n });\n\n return new Itinerary({\n from: itineraries[0].from,\n to: itineraries[itineraries.length - 1].to,\n duration,\n legs\n });\n }\n\n /**\n * Convert lat/lng/level? points to Itinerary\n */\n static fromOrderedPointsArray(\n points: (Point2_t | Vector3_t)[],\n start: (Point2_t | Vector3_t),\n end: (Point2_t | Vector3_t)) {\n\n const pointToCoordinates = (point: Point2_t | Vector3_t) =>\n new Coordinates(point[0], point[1], null, point[2]);\n\n return this.fromOrderedCoordinates(\n points.map(pointToCoordinates),\n pointToCoordinates(start),\n pointToCoordinates(end)\n );\n }\n\n /**\n * Convert ordered Coordinates to Itinerary\n */\n static fromOrderedCoordinates(\n coords: Coordinates[],\n from: Coordinates, to: Coordinates,\n mode: RoutingMode = 'WALK'\n ) {\n\n const leg = new Leg({\n from: { coords: from },\n to: { coords: to },\n coords,\n mode\n });\n\n return new Itinerary({ from, to, legs: [leg] });\n }\n\n\n static equals(obj1: Itinerary, obj2: Itinerary) {\n const intermediate = obj1.from.equals(obj2.from)\n && obj1.to.equals(obj2.to)\n && obj1.distance === obj2.distance\n && obj1.duration === obj2.duration\n && obj1.startTime === obj2.startTime\n && obj1.endTime === obj2.endTime\n && obj1.legs.length === obj2.legs.length;\n\n if (!intermediate) {\n return false;\n }\n\n for (let i = 0; i < obj1.legs.length; i++) {\n if (!obj1.legs[i].equals(obj2.legs[i])) {\n return false;\n }\n }\n\n return true;\n }\n\n equals(obj: Itinerary) {\n return Itinerary.equals(this, obj);\n }\n\n toJson(): ItineraryJson {\n return {\n from: this.from.toCompressedJson(),\n to: this.to.toCompressedJson(),\n duration: this.duration,\n mode: this.mode,\n legs: this.legs.map(leg => leg.toJson()),\n ...(this.startTime !== null && { startTime: this.startTime }),\n ...(this.endTime !== null && { endTime: this.endTime })\n };\n }\n\n static fromJson(json: ItineraryJson) {\n return new Itinerary({\n from: Coordinates.fromCompressedJson(json.from),\n to: Coordinates.fromCompressedJson(json.to),\n duration: json.duration,\n legs: json.legs.map(Leg.fromJson),\n startTime: json.startTime,\n endTime: json.endTime\n });\n }\n\n static fromGraphItinerary<T>(\n graphItinerary: GraphItinerary<T>,\n mode: RoutingMode = 'WALK',\n stepsGenerationRules?: StepsGenerationRules\n ) {\n const leg = Leg.fromGraphItinerary(graphItinerary, mode, stepsGenerationRules);\n return new Itinerary({\n from: graphItinerary.start,\n to: graphItinerary.end,\n duration: leg.duration,\n legs: [leg]\n });\n }\n\n // TODO: Remove when possible...\n // Livemap specific\n multiplyLevel(levelFactor: number) {\n\n this.from.level = Level.multiplyBy(this.from.level, levelFactor);\n this.to.level = Level.multiplyBy(this.to.level, levelFactor);\n\n this.legs.forEach(leg => leg.multiplyLevel(levelFactor));\n\n // It is not necessary to multiply this._coords because \n // coords are not cloned between legs and itinerary\n }\n\n // TODO: Remove when possible...\n // Livemap specific\n forceUnknownLevelTo0() {\n\n this.from.level = this.from.level || 0;\n this.to.level = this.to.level || 0;\n\n for (const leg of this.legs) {\n leg.from.coords.level = leg.from.coords.level || 0;\n leg.to.coords.level = leg.to.coords.level || 0;\n for (const coords of leg.coords) {\n coords.level = coords.level || 0;\n }\n if (leg.stepsInfo) {\n for (const step of leg.stepsInfo) {\n step.coords.level = step.coords.level || 0;\n }\n }\n }\n\n if (this._coords) {\n for (const coords of this._coords) {\n coords.level = coords.level || 0;\n }\n }\n }\n\n toGeoJson(): Feature<MultiLineString> {\n return {\n type: \"Feature\",\n properties: {},\n geometry: {\n type: 'MultiLineString',\n coordinates: this.legs.map(leg => leg.coords.map(({ lat, lng }) => [lng, lat]))\n }\n };\n }\n}\n","import { Coordinates, CoordinatesCompressedJson, Level } from '@wemap/geo';\n\nimport Itinerary, { ItineraryJson } from './Itinerary.js';\n\nexport type RouterResponseCommon = {\n routerName: string | string[];\n error?: string\n};\n\nexport type RouterResponseJson = {\n from: CoordinatesCompressedJson;\n to: CoordinatesCompressedJson;\n itineraries?: ItineraryJson[];\n} & RouterResponseCommon;\n\nexport type RouterResponseConstructor = {\n from: Coordinates;\n to: Coordinates;\n itineraries?: Itinerary[];\n} & RouterResponseCommon;\n\nexport default class RouterResponse {\n\n routerName: string | string[];\n\n from: Coordinates;\n to: Coordinates;\n itineraries: Itinerary[];\n\n error: string | null;\n\n constructor({\n routerName, from, to, itineraries, error\n }: RouterResponseConstructor) {\n this.routerName = routerName;\n this.from = from;\n this.to = to;\n this.itineraries = itineraries || [];\n this.error = error || null;\n }\n\n static equals(obj1: RouterResponse, obj2: RouterResponse) {\n const intermediate = obj1.routerName === obj2.routerName\n && obj1.from.equals(obj2.from)\n && obj1.to.equals(obj2.to)\n && obj1.itineraries.length === obj2.itineraries.length;\n\n if (!intermediate) {\n return false;\n }\n\n for (let i = 0; i < obj1.itineraries.length; i++) {\n if (!obj1.itineraries[i].equals(obj2.itineraries[i])) {\n return false;\n }\n }\n\n return true;\n }\n\n equals(obj: RouterResponse) {\n return RouterResponse.equals(this, obj);\n }\n\n\n toJson(): RouterResponseJson {\n return {\n routerName: this.routerName,\n from: this.from.toCompressedJson(),\n to: this.to.toCompressedJson(),\n ...(this.itineraries.length && { itineraries: this.itineraries.map(itinerary => itinerary.toJson()) }),\n ...(this.error && { error: this.error })\n };\n }\n\n\n static fromJson(json: RouterResponseJson) {\n return new RouterResponse({\n routerName: json.routerName,\n from: Coordinates.fromCompressedJson(json.from),\n to: Coordinates.fromCompressedJson(json.to),\n itineraries: json.itineraries?.map(Itinerary.fromJson),\n error: json.error\n });\n }\n\n // TODO: Remove when possible...\n // Livemap specific\n multiplyLevel(levelFactor: number) {\n\n this.from.level = Level.multiplyBy(this.from.level, levelFactor);\n this.to.level = Level.multiplyBy(this.to.level, levelFactor);\n \n for (const itinerary of this.itineraries) {\n itinerary.multiplyLevel(levelFactor);\n }\n }\n \n}\n","import { GraphEdge } from '@wemap/geo';\nimport { OsmNode, OsmGraphRouterOptions, OsmGraphEdge } from '@wemap/osm';\n\nimport { getDurationFromLength } from '../Utils.js';\n\nclass WemapOsmRouterOptions extends OsmGraphRouterOptions {\n\n static DEFAULT = new WemapOsmRouterOptions();\n\n static get WITHOUT_STAIRS() {\n const options = new WemapOsmRouterOptions();\n options.acceptEdgeFn = (edge: OsmGraphEdge) => edge.builtFrom?.tags.highway !== 'steps';\n return options;\n }\n\n weightEdgeFn = (edge: GraphEdge) =>\n edge.builtFrom instanceof OsmNode && edge.builtFrom.isElevator\n ? 30\n : getDurationFromLength(edge.length);\n\n}\n\nexport default WemapOsmRouterOptions;\n","import { Coordinates, GraphUtils } from '@wemap/geo';\nimport { OsmGraphItinerary, OsmGraphNode, OsmGraphRouter, OsmNetwork, OsmNode, OsmWay } from '@wemap/osm';\n\nimport { StepsGenerationRules } from '../model/generateSteps.js';\nimport Itinerary from '../model/Itinerary.js';\nimport { LevelChangeType } from '../model/LevelChange.js';\nimport StepInfo from '../model/StepInfo.js';\nimport WemapOsmRouterOptions from './WemapOsmRouterOptions.js';\n\n\nconst buildStepsRules = (graphItinerary: OsmGraphItinerary): StepsGenerationRules => (\n currentCoords: Coordinates,\n nextCoords: Coordinates,\n previousStep: StepInfo | null\n) => {\n const edges = graphItinerary.edges;\n const nodes = graphItinerary.nodes;\n const node = GraphUtils.getNodeByCoords(nodes, currentCoords);\n const nextNode = GraphUtils.getNodeByCoords(nodes, nextCoords);\n if (!node || !nextNode) return {};\n const edge = GraphUtils.getEdgeByNodes(edges, node, nextNode);\n if (!edge) return {};\n const edgeId = edges.findIndex(_edge => _edge === edge) as number;\n\n const isSubwayEntrance = node ? node.builtFrom?.tags.railway === 'subway_entrance' : false;\n const isGate = node ? (node.builtFrom?.tags.barrier === 'gate' || node.builtFrom?.tags.aeroway === 'gate') : false;\n\n let levelChangeType: LevelChangeType | null = null;\n if (edge.builtFrom?.isElevator) {\n levelChangeType = 'elevator';\n } else if (\n (edge.builtFrom instanceof OsmNode || edge.builtFrom instanceof OsmWay)\n && edge.builtFrom.isConveying\n ) {\n levelChangeType = 'conveyor';\n } else if (edge.builtFrom instanceof OsmWay && edge.builtFrom.areStairs) {\n levelChangeType = 'stairs';\n }\n\n const edgeTags = edge.builtFrom?.tags || {};\n let levelChangeDirection: 'up' | 'down' | null = null;\n if (\n edge.builtFrom instanceof OsmWay \n && edge.builtFrom.areStairs\n && ['up', 'down'].includes(edgeTags.incline)\n && !previousStep?.levelChange\n ) {\n levelChangeDirection = edgeTags.incline as 'up' | 'down';\n for (const n of edge.builtFrom.nodes) {\n if (n !== node.builtFrom) continue;\n }\n const isReversed = edge.builtFrom.nodes.reduce((acc: boolean | null, n, idx, arr) => {\n if (n !== node.builtFrom) return acc;\n acc = !(idx + 1 < arr.length && arr[idx+1] === nextNode.builtFrom);\n return acc;\n }, null);\n if (isReversed) {\n levelChangeDirection = levelChangeDirection === 'up' ? 'down' : 'up';\n }\n }\n\n const createNewStep = isSubwayEntrance || levelChangeDirection;\n\n return {\n createNewStep,\n stepName: edge.builtFrom?.tags.name,\n duration: graphItinerary.edgesWeights[edgeId],\n stepExtras: {\n ...(isSubwayEntrance && { isSubwayEntrance: true }),\n ...(isSubwayEntrance && node.builtFrom?.tags.ref && { subwayEntranceRef: node.builtFrom.tags.ref }),\n ...(isGate && { isGate: true })\n },\n ...(levelChangeType && { levelChangeType }),\n ...(levelChangeDirection && { levelChangeDirection })\n };\n};\n\nclass WemapOsmRouter extends OsmGraphRouter {\n\n constructor(network: OsmNetwork) {\n super(network);\n }\n\n static get rname() {\n return 'wemap';\n }\n\n getShortestPath(\n start: OsmGraphNode | Coordinates,\n end: OsmGraphNode | Coordinates,\n options = new WemapOsmRouterOptions()\n ) {\n return super.getShortestPath(start, end, options);\n }\n\n getItinerary(\n start: OsmGraphNode | Coordinates,\n end: OsmGraphNode | Coordinates,\n options = new WemapOsmRouterOptions()\n ) {\n const graphItinerary = this.getShortestPath(start, end, options);\n\n // Transform a network itinerary (nodes, edges...) to a router itinerary (legs, steps...)\n return Itinerary.fromGraphItinerary(graphItinerary, 'WALK', buildStepsRules(graphItinerary))\n }\n\n}\n\nexport default WemapOsmRouter;\n","import { Coordinates } from '@wemap/geo';\n\nimport RouterResponse from '../model/RouterResponse.js';\nimport { RoutingMode } from '../model/RoutingMode.js';\nimport { RemoteRouterOptions } from './RemoteRouterOptions.js';\n\nabstract class RemoteRouter {\n\n /**\n * Get the router name\n */\n abstract get rname(): string;\n\n abstract getItineraries(\n endpointUrl: string,\n mode: RoutingMode,\n waypoints: Coordinates[],\n options?: RemoteRouterOptions\n ): Promise<RouterResponse>;\n\n}\n\nexport default RemoteRouter;\n","export default class RemoteRouterServerUnreachable extends Error {\n\n constructor(name: string, endpointUrl: string) {\n super(`Remote router server ${name} is unreachable. URL: ${endpointUrl}`);\n }\n}\n","export default class RoutingModeCorrespondanceNotFound extends Error {\n\n constructor(public routerName: string, public routingMode: string) {\n super(`routing mode \"${routingMode}\" correspondance not found for router \"${routerName}\"`);\n }\n}\n","import { NoRouteFoundError } from '@wemap/geo';\n\nimport RemoteRouterServerUnreachable from './RemoteRouterServerUnreachable.js';\nimport RoutingModeCorrespondanceNotFound from './RoutingModeCorrespondanceNotFound.js';\n\n\n/**\n * Create and return a date with a given timezone\n * timeZone - timezone name (e.g. 'Europe/Paris')\n */\nexport function dateWithTimeZone(\n year: number, month: number, day: number,\n hour: number, minute: number, second: number,\n timeZone = 'Europe/Paris'\n) {\n const date = new Date(Date.UTC(year, month, day, hour, minute, second));\n\n const utcDate = new Date(date.toLocaleString('en-US', { timeZone: 'UTC' }));\n const tzDate = new Date(date.toLocaleString('en-US', { timeZone: timeZone }));\n const offset = utcDate.getTime() - tzDate.getTime();\n\n date.setTime(date.getTime() + offset);\n\n return date;\n}\n\nexport function isRoutingError(e: unknown): e is Error {\n return e instanceof RemoteRouterServerUnreachable\n || e instanceof RoutingModeCorrespondanceNotFound\n || e instanceof NoRouteFoundError;\n}\n","import { Coordinates } from '@wemap/geo';\nimport Logger from '@wemap/logger';\n\nimport RemoteRouter from '../RemoteRouter.js';\nimport Itinerary from '../../model/Itinerary.js';\nimport Leg, { TransportInfo } from '../../model/Leg.js';\nimport RouterResponse from '../../model/RouterResponse.js';\nimport { dateWithTimeZone } from '../RemoteRouterUtils.js';\nimport RemoteRouterServerUnreachable from '../RemoteRouterServerUnreachable.js';\nimport RoutingModeCorrespondanceNotFound from '../RoutingModeCorrespondanceNotFound.js';\nimport { RoutingMode, isRoutingModePublicTransport } from '../../model/RoutingMode.js';\nimport StepInfo from '../../model/StepInfo.js';\n\ntype CitywayCoordinates = { Lat: number, Long: number };\ntype CitywayLeg = {\n TransportMode: string,\n Duration: string,\n Departure: {\n Time: string,\n Site: {\n Name: string,\n Position: CitywayCoordinates\n },\n StopPlace: {\n Name: string,\n Position: CitywayCoordinates\n }\n },\n Arrival: {\n Time: string,\n Site: {\n Name: string,\n Position: CitywayCoordinates\n },\n StopPlace: {\n Name: string,\n Position: CitywayCoordinates\n }\n },\n Line: {\n Name: string,\n Number: string,\n Color: string,\n TextColor: string,\n },\n Destination: string,\n Distance: number,\n steps: {\n Step: {\n Geometry: string\n }[]\n },\n pathLinks: {\n PathLink: {\n Departure: {\n Site: {\n Name: string\n }\n },\n Distance: number,\n Geometry: string | 'Null'\n }[]\n }\n};\ntype CitywayJson = {\n StatusCode: number,\n Data: {\n response: {\n trips: {\n Trip: {\n Duration: string,\n Departure: {\n Time: string,\n Site: {\n Position: CitywayCoordinates\n }\n },\n Arrival: {\n Time: string,\n Site: {\n Position: CitywayCoordinates\n }\n },\n sections: {\n Section: {\n Leg?: CitywayLeg,\n PTRide: CitywayLeg\n }[]\n }\n }[]\n }\n },\n PlanTripType?: string\n }[],\n};\n\n\n\nfunction jsonToCoordinates(json: CitywayCoordinates) {\n return new Coordinates(json.Lat, json.Long);\n}\n\nfunction jsonDateToTimestamp(jsonDate: string) {\n const [dateStr, timeStr] = jsonDate.split(' ');\n const [dayStr, monthStr, yearStr] = dateStr.split('/');\n const [hoursStr, minutesStr, secondsStr] = timeStr.split(':');\n\n return dateWithTimeZone(\n Number(yearStr),\n Number(monthStr) - 1,\n Number(dayStr),\n Number(hoursStr),\n Number(minutesStr),\n Number(secondsStr)\n ).getTime();\n}\n\n/**\n * Input mode correspondance\n */\nconst inputModeCorrespondance = new Map<RoutingMode, string>();\ninputModeCorrespondance.set('CAR', 'Car');\ninputModeCorrespondance.set('WALK', 'Walk');\ninputModeCorrespondance.set('BIKE', 'Bike');\ninputModeCorrespondance.set('BUS', 'PT');\ninputModeCorrespondance.set('MULTI', 'PT');\n\n\n/**\n * List of all routing modes supported by the API\n */\nconst routingModeCorrespondance = new Map<string, RoutingMode>();\nroutingModeCorrespondance.set('WALK', 'WALK');\nroutingModeCorrespondance.set('BICYCLE', 'BIKE');\nroutingModeCorrespondance.set('TRAMWAY', 'TRAM');\nroutingModeCorrespondance.set('METRO', 'METRO');\nroutingModeCorrespondance.set('FUNICULAR', 'FUNICULAR');\nroutingModeCorrespondance.set('BUS', 'BUS');\nroutingModeCorrespondance.set('COACH', 'BUS');\nroutingModeCorrespondance.set('SCHOOL', 'BUS');\nroutingModeCorrespondance.set('BUS_PMR', 'BUS');\nroutingModeCorrespondance.set('MINIBUS', 'BUS');\nroutingModeCorrespondance.set('TROLLEY_BUS', 'BUS');\nroutingModeCorrespondance.set('TAXIBUS', 'BUS');\nroutingModeCorrespondance.set('SHUTTLE', 'BUS');\nroutingModeCorrespondance.set('TRAIN', 'TRAIN');\nroutingModeCorrespondance.set('HST', 'TRAIN');\nroutingModeCorrespondance.set('LOCAL_TRAIN', 'TRAIN');\nroutingModeCorrespondance.set('AIR', 'AIRPLANE');\nroutingModeCorrespondance.set('FERRY', 'BOAT');\nroutingModeCorrespondance.set('TAXI', 'UNKNOWN');\nroutingModeCorrespondance.set('CAR_POOL', 'UNKNOWN');\nroutingModeCorrespondance.set('PRIVATE_VEHICLE', 'CAR');\nroutingModeCorrespondance.set('SCOOTER', 'MOTO');\n\n/**\n * List of all plan trip supported by the API\n * Routing mode UNKNOWN means that the itinerary will not be parsed by the router\n */\nconst planTripType = new Map();\nplanTripType.set(0, 'BUS');\nplanTripType.set(1, 'WALK');\nplanTripType.set(2, 'BIKE');\nplanTripType.set(3, 'CAR');\nplanTripType.set(4, 'UNKNOWN');\nplanTripType.set(5, 'UNKNOWN');\nplanTripType.set(6, 'UNKNOWN');\nplanTripType.set(7, 'UNKNOWN');\nplanTripType.set(8, 'UNKNOWN');\nplanTripType.set(9, 'UNKNOWN');\nplanTripType.set(10, 'UNKNOWN');\nplanTripType.set(11, 'UNKNOWN');\nplanTripType.set(12, 'UNKNOWN');\nplanTripType.set(13, 'UNKNOWN');\nplanTripType.set(14, 'UNKNOWN');\n\nfunction parseWKTGeometry(wktGeometry: string) {\n const tmpCoordsStr = wktGeometry.match(/LINESTRING ?\\((.*)\\)/i);\n const tmpCoordsPt = wktGeometry.match(/POINT ?\\((.*)\\)/i);\n\n if (tmpCoordsPt) {\n const [lng, lat] = tmpCoordsPt[1].split(' ');\n return [new Coordinates(Number(lat), Number(lng))];\n }\n\n return (tmpCoordsStr as RegExpMatchArray)[1].split(',').map(str => {\n const sp = str.trim().split(' ');\n return new Coordinates(Number(sp[1]), Number(sp[0]));\n });\n}\n\n/**\n * Singleton.\n */\nclass CitywayRemoteRouter extends RemoteRouter {\n\n /**\n * @override\n */\n get rname() {\n return 'cityway';\n }\n\n\n /**\n * @override\n * @throws {RoutingModeCorrespondanceNotFound}\n * @throws {RemoteRouterServerUnreachable}\n */\n async getItineraries(endpointUrl: string, mode: RoutingMode, waypoints: Coordinates[]) {\n const url = this.getURL(endpointUrl, mode, waypoints);\n const res = await (fetch(url).catch(() => {\n throw new RemoteRouterServerUnreachable(this.rname, url);\n }));\n\n const jsonResponse = await res.json().catch(() => {\n throw new RemoteRouterServerUnreachable(this.rname, url);\n });\n return this.createRouterResponseFromJson(jsonResponse, waypoints[0], waypoints[1]);\n }\n\n\n /**\n * @throws {RoutingModeCorrespondanceNotFound}\n */\n getURL(endpointUrl: string, mode: RoutingMode, waypoints: Coordinates[]) {\n const citywayMode = inputModeCorrespondance.get(mode);\n if (!citywayMode) {\n throw new RoutingModeCorrespondanceNotFound(this.rname, mode);\n }\n if (waypoints.length > 2) {\n Logger.warn(`${this.rname} router uses only the first 2 waypoints (asked ${waypoints.length})`);\n }\n const fromPlace = `DepartureLatitude=${waypoints[0].latitude}&DepartureLongitude=${waypoints[0].longitude}`;\n const toPlace = `ArrivalLatitude=${waypoints[1].latitude}&ArrivalLongitude=${waypoints[1].longitude}`;\n const queryMode = `TripModes=${citywayMode}`;\n\n const url = new URL(endpointUrl);\n let { search } = url;\n search = (search ? `${search}&` : '?') + `${fromPlace}&${toPlace}&${queryMode}`;\n\n return `${url.origin}${url.pathname}${search}`;\n }\n\n /**\n * Generate multi itineraries from Cityway JSON\n * @returns {!RouterResponse}\n * @example https://preprod.api.lia2.cityway.fr/journeyplanner/api/opt/PlanTrips/json?DepartureLatitude=49.51509388236216&DepartureLongitude=0.09341749619366316&ArrivalLatitude=49.5067090188444&ArrivalLongitude=0.1694842115417831&DepartureType=COORDINATES&ArrivalType=COORDINATES\n */\n createRouterResponseFromJson(json: CitywayJson, from: Coordinates, to: Coordinates) {\n\n const routerResponse = new RouterResponse({ routerName: this.rname, from, to });\n\n if (json.StatusCode !== 200 || !json.Data || !json.Data.length) {\n return routerResponse;\n }\n\n const allJsonTrips = json.Data.map(dataObj =>\n dataObj.response.trips.Trip.map(trip => ({\n ...trip,\n ...(dataObj.hasOwnProperty('PlanTripType') && { PlanTripType: dataObj.PlanTripType })\n }))\n ).flat();\n\n // eslint-disable-next-line no-labels\n itineraryLoop:\n for (const trip of allJsonTrips) {\n\n if (trip.hasOwnProperty('PlanTripType') && planTripType.get(trip.PlanTripType) === 'UNKNOWN') {\n continue;\n }\n\n const legs = []\n for (const jsonSection of trip.sections.Section) {\n\n const jsonLeg = jsonSection.Leg ? jsonSection.Leg : jsonSection.PTRide;\n\n const legMode = routingModeCorrespondance.get(jsonLeg.TransportMode) as RoutingMode;\n const legCoords: Coordinates[] = [];\n let legFrom, legTo;\n let transportInfo: TransportInfo | undefined;\n let stepsInfo: StepInfo[];\n\n if (legMode === 'UNKNOWN') {\n // eslint-disable-next-line\n continue itineraryLoop;\n }\n\n if (legMode === 'WALK'\n || legMode === 'BIKE'\n || legMode === 'CAR') {\n\n legFrom = {\n name: jsonLeg.Departure.Site.Name,\n coords: jsonToCoordinates(jsonLeg.Departure.Site.Position)\n };\n legTo = {\n name: jsonLeg.Arrival.Site.Name,\n coords: jsonToCoordinates(jsonLeg.Arrival.Site.Position)\n };\n\n stepsInfo = [];\n for (const jsonPathLink of jsonLeg.pathLinks.PathLink) {\n let stepCoords;\n // jsonPathLink.Geometry is either a POINT or a LINESTRING\n // or it can also be 'Null' as string\n if (jsonPathLink.Geometry && jsonPathLink.Geometry !== 'Null') {\n stepCoords = parseWKTGeometry(jsonPathLink.Geometry);\n } else {\n stepCoords = [legFrom.coords, legTo.coords];\n }\n\n stepCoords.forEach((coords, idx) => {\n if (\n idx !== 0\n || legCoords.length === 0\n || !legCoords[legCoords.length - 1].equals(coords)\n ) {\n legCoords.push(coords);\n }\n });\n\n stepsInfo.push(new StepInfo({\n coords: stepCoords[0],\n distance: jsonPathLink.Distance,\n name: jsonPathLink.Departure.Site.Name\n }));\n }\n\n } else if (isRoutingModePublicTransport(legMode)) {\n\n legFrom = {\n name: jsonLeg.Departure.StopPlace.Name,\n coords: jsonToCoordinates(jsonLeg.Departure.StopPlace.Position)\n };\n legTo = {\n name: jsonLeg.Arrival.StopPlace.Name,\n coords: jsonToCoordinates(jsonLeg.Arrival.StopPlace.Position)\n };\n\n let transportName = jsonLeg.Line.Number;\n if (legMode === 'TRAM' && transportName.toLowerCase().includes('tram')) {\n // In order to remove the \"TRAM \" prefix.\n transportName = transportName.substr(5);\n }\n\n transportInfo = {\n name: transportName,\n routeColor: jsonLeg.Line.Color,\n routeTextColor: jsonLeg.Line.TextColor,\n directionName: jsonLeg.Destination\n };\n\n for (const jsonStep of jsonLeg.steps.Step) {\n const stepCoords = parseWKTGeometry(jsonStep.Geometry);\n stepCoords.forEach((coords, idx) => {\n if (\n idx !== 0\n || legCoords.length === 0\n || !legCoords[legCoords.length - 1].equals(coords)\n ) {\n legCoords.push(coords);\n }\n });\n }\n\n stepsInfo = [new StepInfo({\n coords: legCoords[0],\n name: jsonLeg.Line.Name,\n distance: jsonLeg.Distance,\n })];\n } else {\n Logger.warn(`[CitywayParser] Unknown leg mode: ${jsonLeg.TransportMode}`);\n continue;\n }\n\n const leg = new Leg({\n mode: legMode,\n duration: this.parseDuration(jsonLeg.Duration),\n startTime: jsonDateToTimestamp(jsonLeg.Departure.Time),\n endTime: jsonDateToTimestamp(jsonLeg.Arrival.Time),\n coords: legCoords,\n from: legFrom,\n to: legTo,\n transportInfo,\n stepsInfo\n });\n\n legs.push(leg);\n }\n\n const itinerary = new Itinerary({\n duration: this.parseDuration(trip.Duration),\n startTime: jsonDateToTimestamp(trip.Departure.Time),\n from: jsonToCoordinates(trip.Departure.Site.Position),\n endTime: jsonDateToTimestamp(trip.Arrival.Time),\n to: jsonToCoordinates(trip.Arrival.Site.Position),\n legs\n });\n\n routerResponse.itineraries.push(itinerary);\n }\n\n return routerResponse;\n }\n\n\n /**\n * @param {string} iso8601Duration\n * @see https://stackoverflow.com/a/29153059/2239938\n */\n parseDuration(iso8601Duration: string) {\n const iso8601DurationRegex = /(-)?P(?:([.,\\d]+)Y)?(?:([.,\\d]+)M)?(?:([.,\\d]+)W)?(?:([.,\\d]+)D)?T(?:([.,\\d]+)H)?(?:([.,\\d]+)M)?(?:([.,\\d]+)S)?/;\n\n const matches = iso8601Duration.match(iso8601DurationRegex)!;\n\n // const sign = typeof matches[1] === 'undefined' ? '+' : '-',\n const years = typeof matches[2] === 'undefined' ? 0 : Number(matches[2]);\n const months = typeof matches[3] === 'undefined' ? 0 : Number(matches[3]);\n const weeks = typeof matches[4] === 'undefined' ? 0 : Number(matches[4]);\n const days = typeof matches[5] === 'undefined' ? 0 : Number(matches[5]);\n const hours = typeof matches[6] === 'undefined' ? 0 : Number(matches[6]);\n const minutes = typeof matches[7] === 'undefined' ? 0 : Number(matches[7]);\n const seconds = typeof matches[8] === 'undefined' ? 0 : Number(matches[8]);\n\n return seconds\n + minutes * 60\n + hours * 3600\n + days * 86400\n + weeks * (86400 * 7)\n + months * (86400 * 30)\n + years * (86400 * 365.25);\n }\n}\n\nexport default new CitywayRemoteRouter();","import { Coordinates, Level } from '@wemap/geo';\n\nimport RemoteRouter from '../RemoteRouter.js';\nimport Itinerary from '../../model/Itinerary.js';\nimport RouterResponse from '../../model/RouterResponse.js';\nimport RemoteRouterServerUnreachable from '../RemoteRouterServerUnreachable.js';\nimport { RoutingMode } from '../../model/RoutingMode.js';\nimport Leg from '../../model/Leg.js';\n\ntype DBJson = {\n segments: {\n fromLevel: number,\n toLevel: number,\n polyline: {\n lat: number,\n lon: number\n }[]\n }[]\n};\n\n/**\n * Singleton.\n */\nclass DeutscheBahnRemoteRouter extends RemoteRouter {\n\n /**\n * @override\n */\n get rname() {\n return 'deutsche-bahn';\n }\n\n /**\n * @override\n * @throws {RemoteRouterServerUnreachable}\n */\n async getItineraries(endpointUrl: string, mode: RoutingMode, waypoints: Coordinates[]) {\n const url = this.getURL(endpointUrl, mode, waypoints);\n const res = await (fetch(url).catch(() => {\n throw new RemoteRouterServerUnreachable(this.rname, url);\n }));\n\n const jsonResponse = await res.json().catch(() => {\n throw new RemoteRouterServerUnreachable(this.rname, url);\n });\n return this.createRouterResponseFromJson(jsonResponse, waypoints[0], waypoints[1]);\n }\n\n getURL(endpointUrl: string, mode: RoutingMode, waypoints: Coordinates[]) {\n let url = endpointUrl + '/route/v1/walking/';\n\n url += waypoints.map(waypoint => {\n if (waypoint.level !== null) {\n const altitude = Level.isRange(waypoint.level) ? waypoint.level[0] : waypoint.level;\n return waypoint.longitude + ',' + waypoint.latitude + ',' + altitude;\n }\n return waypoint.longitude + ',' + waypoint.latitude;\n }).join(';');\n\n url += '?geometries=geojson&overview=full&steps=true';\n\n return url;\n }\n\n createRouterResponseFromJson(json: DBJson, from: Coordinates, to: Coordinates) {\n\n const routerResponse = new RouterResponse({ routerName: this.rname, from, to });\n\n if (!json.segments) {\n return routerResponse;\n }\n\n const legs = json.segments.map(segment => {\n const level = Level.union(segment.fromLevel, segment.toLevel);\n const coords = segment.polyline.map(({ lon, lat }) =>\n new Coordinates(lat, lon, null, level)\n );\n return new Leg({\n mode: 'WALK',\n coords,\n from: { coords: coords[0] },\n to: { coords: coords[coords.length - 1] },\n })\n });\n\n routerResponse.itineraries = [new Itinerary({ from, to, legs })];\n return routerResponse;\n }\n}\n\nexport default new DeutscheBahnRemoteRouter();\n","/* eslint-disable max-statements */\nimport { Coordinates, Utils as GeoUtils } from '@wemap/geo';\nimport Logger from '@wemap/logger';\n\nimport Itinerary from '../../model/Itinerary.js';\nimport Leg from '../../model/Leg.js';\nimport RouterResponse from '../../model/RouterResponse.js';\nimport { dateWithTimeZone } from '../RemoteRouterUtils.js';\nimport RemoteRouter from '../RemoteRouter.js';\nimport RemoteRouterServerUnreachable from '../RemoteRouterServerUnreachable.js';\nimport { RoutingMode } from '../../model/RoutingMode.js';\nimport StepInfo from '../../model/StepInfo.js';\n\ntype IdfmCoordinates = { lat: number, lon: number };\ntype IdfmSection = {\n type: 'waiting' | 'transfer' | string,\n mode: string,\n departure_date_time: string,\n arrival_date_time: string,\n duration: number,\n geojson: {\n coordinates: [number, number][],\n properties: { length: number }[]\n },\n path: {\n name: string,\n length: number\n }[],\n display_informations: {\n code: string,\n color: string,\n text_color: string,\n direction: string,\n physical_mode: string\n },\n from: {\n name: string,\n stop_point: { coord: IdfmCoordinates },\n address: { coord: IdfmCoordinates }\n },\n to: {\n name: string,\n stop_point: { coord: IdfmCoordinates },\n address: { coord: IdfmCoordinates }\n }\n}\ntype IdfmJson = {\n journeys: {\n duration: number,\n departure_date_time: string,\n arrival_date_time: string,\n sections: IdfmSection[]\n }[],\n context: {\n timezone: string\n }\n};\n\ntype IdfmIntermediateStep = {\n name: string,\n distance: number\n};\n\n/**\n * List of all modes supported by the API\n * http://doc.navitia.io/#physical-mode\n */\n\nconst routingModeCorrespondance = new Map<string, RoutingMode>();\nroutingModeCorrespondance.set('Air', 'AIRPLANE');\nroutingModeCorrespondance.set('Boat', 'BOAT');\nroutingModeCorrespondance.set('Bus', 'BUS');\nroutingModeCorrespondance.set('BusRapidTransit', 'BUS');\nroutingModeCorrespondance.set('Coach', 'BUS');\nroutingModeCorrespondance.set('Ferry', 'FERRY');\nroutingModeCorrespondance.set('Funicular', 'FUNICULAR');\nroutingModeCorrespondance.set('LocalTrain', 'TRAIN');\nroutingModeCorrespondance.set('LongDistanceTrain', 'TRAIN');\nroutingModeCorrespondance.set('Metro', 'METRO');\nroutingModeCorrespondance.set('Métro', 'METRO');\nroutingModeCorrespondance.set('RailShuttle', 'TRAIN');\nroutingModeCorrespondance.set('RapidTransit', 'BUS');\nroutingModeCorrespondance.set('Shuttle', 'BUS');\nroutingModeCorrespondance.set('SuspendedCableCar', 'FUNICULAR');\nroutingModeCorrespondance.set('Taxi', 'TAXI');\nroutingModeCorrespondance.set('Train', 'TRAIN');\nroutingModeCorrespondance.set('RER', 'TRAIN');\nroutingModeCorrespondance.set('Tramway', 'TRAM');\nroutingModeCorrespondance.set('walking', 'WALK');\nroutingModeCorrespondance.set('bike', 'BIKE');\n\n/**\n * List of transports modes\n */\nconst TRANSPORT_IDS = [\n 'physical_mode:Air',\n 'physical_mode:Boat',\n 'physical_mode:Bus',\n 'physical_mode:BusRapidTransit',\n 'physical_mode:Coach',\n 'physical_mode:Ferry',\n 'physical_mode:Funicular',\n 'physical_mode:LocalTrain',\n 'physical_mode:LongDistanceTrain',\n 'physical_mode:Metro',\n 'physical_mode:RailShuttle',\n 'physical_mode:RapidTransit',\n 'physical_mode:Shuttle',\n 'physical_mode:SuspendedCableCar',\n 'physical_mode:Taxi',\n 'physical_mode:Train',\n 'physical_mode:Tramway'\n];\n\nconst apiKey = 'qWHj6ax6DMttG8DX6tH9CQARaiTgQ1Di';\n\n\nfunction jsonToCoordinates(json: IdfmCoordinates) {\n return new Coordinates(Number(json.lat), Number(json.lon));\n}\n\nfunction last(array: any[]) {\n return array[array.length - 1];\n}\n\n/**\n * stringDate (e.g. 20211117T104516)\n */\nfunction dateStringToTimestamp(stringDate: string, timeZone: string) {\n const yearStr = stringDate.substr(0, 4);\n const monthStr = stringDate.substr(4, 2);\n const dayStr = stringDate.substr(6, 2);\n const hoursStr = stringDate.substr(9, 2);\n const minutesStr = stringDate.substr(11, 2);\n const secondsStr = stringDate.substr(13, 2);\n\n return dateWithTimeZone(\n Number(yearStr),\n Number(monthStr) - 1,\n Number(dayStr),\n Number(hoursStr),\n Number(minutesStr),\n Number(secondsStr),\n timeZone\n ).getTime();\n}\n\n\n/**\n * Singleton.\n */\nclass IdfmRemoteRouter extends RemoteRouter {\n\n /**\n * @override\n */\n get rname() {\n return 'idfm';\n }\n\n /**\n * @throws {IdfmRemoteRouterTokenError}\n * @throws {RemoteRouterServerUnreachable}\n */\n async getItineraries(endpointUrl: string, mode: RoutingMode, waypoints: Coordinates[]) {\n const url = this.getURL(endpointUrl, mode, waypoints);\n\n const res = await (fetch(url, {\n method: 'GET',\n headers: { apiKey }\n }).catch(() => {\n throw new RemoteRouterServerUnreachable(this.rname, url);\n }));\n\n\n const jsonResponse = await res.json().catch(() => {\n throw new RemoteRouterServerUnreachable(this.rname, url);\n });\n\n // When IDFM failed to calculate an itinerary (ie. start or end\n // point is far from network), it respond a 404 with an error message\n // or a 200 with an error message\n if (jsonResponse && jsonResponse.error) {\n return new RouterResponse({\n routerName: this.rname,\n from: waypoints[0],\n to: waypoints[1],\n error: jsonResponse.error.message || 'no details.'\n });\n }\n\n return this.createRouterResponseFromJson(jsonResponse, waypoints[0], waypoints[1]);\n }\n\n getURL(endpointUrl: string, mode: RoutingMode, waypoints: Coordinates[]) {\n\n if (waypoints.length > 2) {\n Logger.warn(`${this.rname} router uses only the first 2 waypoints (asked ${waypoints.length})`);\n }\n\n const fromPlace = `from=${waypoints[0].longitude};${waypoints[0].latitude}`;\n const toPlace = `to=${waypoints[1].longitude};${waypoints[1].latitude}`;\n\n const url = new URL(endpointUrl);\n let { search } = url;\n search = (search ? `${search}&` : '?') + `${fromPlace}&${toPlace}`;\n\n let query = '';\n switch (mode) {\n case 'WALK':\n query = this.getWalkingQuery();\n break;\n case 'BIKE':\n query = this.getBikeQuery();\n break;\n case 'CAR':\n query = this.getCarQuery();\n break;\n default:\n break;\n }\n\n return `${url.origin}${url.pathname}${search}${query}`;\n }\n\n getCarQuery() {\n const forbiddenTransport = TRANSPORT_IDS.map((id) => `forbidden_uris[]=${id}`).join('&');\n const allowCar = 'first_section_mode[]=walking&first_section_mode[]=car&last_section_mode[]=walking&last_section_mode[]=car';\n\n return `&${forbiddenTransport}&${allowCar}`;\n }\n\n getWalkingQuery() {\n const forbiddenTransport = TRANSPORT_IDS.map((id) => `forbidden_uris[]=${id}`).join('&');\n const allowWalking = 'first_section_mode[]=walking&last_section_mode[]=walking';\n\n return `&${forbiddenTransport}&${allowWalking}`;\n }\n\n getBikeQuery() {\n const forbiddenTransport = TRANSPORT_IDS.map((id) => `forbidden_uris[]=${id}`).join('&');\n const allowBike = 'first_section_mode[]=bike&last_section_mode[]=bike';\n\n return `&${forbiddenTransport}&${allowBike}`;\n }\n\n\n getSectionCoords(section: IdfmSection) {\n const from = section.from.stop_point ? jsonToCoordinates(section.from.stop_point.coord) : jsonToCoordinates(section.from.address.coord);\n const to = section.to.stop_point ? jsonToCoordinates(section.to.stop_point.coord) : jsonToCoordinates(section.to.address.coord);\n\n return {\n from,\n to\n };\n }\n\n /**\n * Since the IDFM API does not provide coords for each step, we need to compute them\n * We trim the coordinates of the leg with the distance of each step and keep the last result as the coords of the step\n * @param {Leg} leg\n */\n findStepsCoord(legCoords: Coordinates[], steps: IdfmIntermediateStep[]) {\n const coords = legCoords;\n\n const duplicatedCoords = [...coords];\n let previousStep = steps[0];\n let accumulatedIndex = 0;\n const outputSteps = [];\n\n for (const [idx, step] of steps.entries()) {\n let newCoords: Coordinates;\n\n let _idCoordsInLeg;\n\n if (idx === 0) {\n _idCoordsInLeg = 0;\n newCoords = coords[0];\n } else if (idx === steps.length - 1) {\n _idCoordsInLeg = coords.length - 1;\n newCoords = last(coords);\n } else if (duplicatedCoords.length === 1) {\n accumulatedIndex++;\n\n _idCoordsInLeg = accumulatedIndex;\n\n newCoords = duplicatedCoords[0];\n\n coords[_idCoordsInLeg] = newCoords;\n } else {\n const result = GeoUtils.trimRoute(duplicatedCoords, duplicatedCoords[0], previousStep.distance);\n accumulatedIndex += result.length - 1;\n\n duplicatedCoords.splice(0, result.length - 1);\n\n _idCoordsInLeg = accumulatedIndex;\n\n newCoords = last(result);\n\n coords[_idCoordsInLeg] = newCoords;\n }\n\n outputSteps.push(new StepInfo({\n ...step,\n coords: newCoords\n }));\n\n previousStep = step;\n }\n\n return outputSteps;\n }\n\n createRouterResponseFromJson(json: IdfmJson, from: Coordinates, to: Coordinates) {\n\n const routerResponse = new RouterResponse({ routerName: this.rname, from, to });\n\n if (!json || !json.journeys) {\n return routerResponse;\n }\n\n const timeZone = json.context.timezone;\n\n for (const jsonItinerary of json.journeys) {\n\n const legs = [];\n\n for (const jsonSection of jsonItinerary.sections) {\n\n if (jsonSection.type === 'waiting' || jsonSection.type === 'transfer') {\n continue;\n }\n\n const { from: fromSection, to: toSection } = this.getSectionCoords(jsonSection);\n\n // A section can have multiple same coordinates, we need to remove them\n let existingCoords: string[] = [];\n const legCoords = jsonSection.geojson.coordinates.reduce((acc, [lon, lat]) => {\n if (!existingCoords.includes(`${lon}-${lat}`)) {\n existingCoords = existingCoords.concat(`${lon}-${lat}`);\n acc.push(new Coordinates(lat, lon));\n }\n return acc;\n }, [] as Coordinates[]);\n\n let stepsInfo: StepInfo[] | undefined;\n if (jsonSection.path) {\n const idfmIntermediateSteps = [];\n for (const jsonPathLink of jsonSection.path) {\n idfmIntermediateSteps.push({\n name: jsonPathLink.name,\n distance: jsonPathLink.length,\n });\n }\n stepsInfo = this.findStepsCoord(legCoords, idfmIntermediateSteps);\n }\n\n const leg = new Leg({\n mode: routingModeCorrespondance.get(jsonSection.mode) as RoutingMode,\n duration: jsonSection.duration,\n startTime: dateStringToTimestamp(jsonSection.departure_date_time, timeZone),\n endTime: dateStringToTimestamp(jsonSection.arrival_date_time, timeZone),\n from: {\n name: jsonSection.from.name,\n coords: fromSection\n },\n to: {\n name: jsonSection.to.name,\n coords: toSection\n },\n coords: legCoords,\n stepsInfo\n });\n\n\n if (jsonSection.type === 'public_transport') {\n leg.transportInfo = {\n name: jsonSection.display_informations.code,\n routeColor: jsonSection.display_informations.color,\n routeTextColor: jsonSection.display_informations.text_color,\n directionName: jsonSection.display_informations.direction\n };\n\n leg.mode = routingModeCorrespondance.get(jsonSection.display_informations.physical_mode) as RoutingMode;\n\n const legStep = new StepInfo({\n coords: leg.coords[0],\n name: leg.transportInfo?.directionName,\n distance: jsonSection.geojson.properties[0].length\n });\n leg.stepsInfo = [legStep];\n }\n\n legs.push(leg);\n }\n\n const itinerary = new Itinerary({\n duration: jsonItinerary.duration,\n startTime: dateStringToTimestamp(jsonItinerary.departure_date_time, timeZone),\n endTime: dateStringToTimestamp(jsonItinerary.arrival_date_time, timeZone),\n from: this.getSectionCoords(jsonItinerary.sections[0]).from,\n to: this.getSectionCoords(last(jsonItinerary.sections)).to,\n legs\n });\n\n routerResponse.itineraries.push(itinerary);\n }\n\n return routerResponse;\n }\n}\n\nexport default new IdfmRemoteRouter();","/* eslint-disable max-statements */\n\nimport { Coordinates, Level } from '@wemap/geo';\nimport { rad2deg, positiveMod } from '@wemap/maths';\nimport { LineString, Position } from 'geojson';\n\nimport Itinerary from '../../model/Itinerary.js';\nimport RouterResponse from '../../model/RouterResponse.js';\nimport Leg from '../../model/Leg.js';\nimport RemoteRouter from '../RemoteRouter.js';\nimport RoutingModeCorrespondanceNotFound from '../RoutingModeCorrespondanceNotFound.js';\nimport RemoteRouterServerUnreachable from '../RemoteRouterServerUnreachable.js';\nimport { RoutingMode } from '../../model/RoutingMode.js';\nimport StepInfo from '../../model/StepInfo.js';\n\n/**\n * Input mode correspondance\n */\nconst inputModeCorrespondance = new Map();\ninputModeCorrespondance.set('CAR', 'driving');\ninputModeCorrespondance.set('WALK', 'walking');\ninputModeCorrespondance.set('BIKE', 'bike');\ninputModeCorrespondance.set('BUS', 'bus');\ninputModeCorrespondance.set('MULTI', 'walking');\n\n\ntype OsrmCoordinates = Position;\ntype OsrmModifier = 'sharp right' | 'sharp left' | 'slight right'\n | 'slight left' | 'right' | 'left' | 'u turn' | 'straight';\ntype OsrmManeuverType = 'depart' | 'turn' | 'arrive';\ntype OsrmStep = {\n geometry: LineString,\n distance: number,\n duration: number,\n name?: string,\n maneuver: {\n bearing_before: number,\n bearing_after: number,\n location: OsrmCoordinates,\n modifier: OsrmModifier,\n type: OsrmManeuverType\n }\n};\ntype OsrmJson = {\n code?: string,\n routes?: {\n geometry: LineString,\n legs: {\n distance: number,\n duration: number,\n steps: OsrmStep[]\n }[],\n distance: number,\n duration: number,\n weight_name: string,\n weight: number\n }[],\n waypoints?: []\n};\n\n/**\n * Singleton.\n */\nclass OsrmRemoteRouter extends RemoteRouter {\n\n /**\n * @override\n */\n get rname() {\n return 'osrm';\n }\n\n /**\n * @throws {RemoteRouterServerUnreachable}\n * @throws {RoutingModeCorrespondanceNotFound}\n */\n async getItineraries(\n endpointUrl: string,\n mode: RoutingMode,\n waypoints: Coordinates[]\n ) {\n const url = this.getURL(endpointUrl, mode, waypoints);\n\n const res = await (fetch(url).catch(() => {\n throw new RemoteRouterServerUnreachable(this.rname, url);\n }));\n\n const jsonResponse = await res.json().catch(() => {\n throw new RemoteRouterServerUnreachable(this.rname, url);\n });\n\n const from = waypoints[0];\n const to = waypoints[waypoints.length - 1];\n return this.createRouterResponseFromJson(jsonResponse, from, to);\n }\n\n /**\n * @throws {RoutingModeCorrespondanceNotFound}\n */\n getURL(\n endpointUrl: string,\n mode: RoutingMode,\n waypoints: Coordinates[]\n ) {\n\n const osrmMode = inputModeCorrespondance.get(mode);\n if (!osrmMode) {\n throw new RoutingModeCorrespondanceNotFound(this.rname, mode);\n }\n\n let url = endpointUrl + '/route/v1/' + osrmMode + '/';\n url += waypoints.map(waypoint => [waypoint.longitude + ',' + waypoint.latitude]).join(';');\n url += '?geometries=geojson&overview=full&steps=true';\n\n return url;\n }\n\n\n coordinatesToJson({ lat, lng, level }: Coordinates): OsrmCoordinates {\n if (level === null) {\n return [lng, lat];\n }\n if (Level.isRange(level)) {\n return [lng, lat, level[0]];\n }\n return [lng, lat, level];\n }\n\n /**\n * @param {object} json\n * @returns {Coordinates}\n */\n jsonToCoordinates(json: OsrmCoordinates): Coordinates {\n const coords = new Coordinates(json[1], json[0]);\n if (json.length > 2) {\n coords.level = json[2] as number;\n }\n return coords;\n }\n\n getModifierFromAngle(_angle: number): OsrmModifier {\n\n const angle = positiveMod(rad2deg(_angle), 360);\n\n if (angle > 0 && angle < 60) {\n return 'sharp right';\n }\n if (angle >= 60 && angle < 140) {\n return 'right';\n }\n if (angle >= 140 && angle < 160) {\n return 'slight right';\n }\n if (angle >= 160 && angle <= 200) {\n return 'straight';\n }\n if (angle > 200 && angle <= 220) {\n return 'slight left';\n }\n if (angle > 220 && angle <= 300) {\n return 'left';\n }\n if (angle > 300 && angle < 360) {\n return 'sharp left';\n }\n return 'u turn';\n }\n\n\n noRouteFoundJson(message: object) {\n return {\n 'code': 'NoRoute',\n message\n };\n }\n\n /**\n * @deprecated\n */\n itineraryToOsrmJson(itinerary: Itinerary): OsrmJson {\n\n const lastLegId = itinerary.legs.length - 1;\n const itinerarySteps = itinerary.steps;\n\n const jsonLegs = itinerary.legs.map(({ distance, duration, coords }, idLeg) => {\n\n // Filter steps which are in leg\n const legSteps = itinerarySteps.filter(step =>\n coords.find(_coords => _coords.equals(step.coords))\n );\n\n const lastStepId = legSteps.length - 1;\n\n return {\n distance,\n duration: duration || 0,\n steps: legSteps.map((step, idStep, arr) => {\n\n let type: OsrmManeuverType = idStep === 0 && idLeg === 0 ? 'depart' : 'turn';\n type = idStep === lastStepId && idLeg === lastLegId ? 'arrive' : type;\n\n const stepCoordsIdx = coords.findIndex(p => p.equals(step.coords));\n const nextStepCoordsIdx = idStep === lastStepId\n ? stepCoordsIdx\n : coords.findIndex(p => p.equals(arr[idStep + 1].coords));\n\n const osrmStep: OsrmStep = {\n geometry: {\n type: 'LineString',\n coordinates: coords.slice(stepCoordsIdx, nextStepCoordsIdx + 1).map(this.coordinatesToJson)\n },\n distance: step.distance,\n duration: step.duration || 0,\n ...(step.name && { name: step.name }),\n maneuver: {\n bearing_before: rad2deg(step.previousBearing),\n bearing_after: rad2deg(step.nextBearing),\n location: this.coordinatesToJson(step.coords),\n modifier: this.getModifierFromAngle(step.angle),\n type\n },\n };\n return osrmStep;\n })\n };\n });\n\n return {\n 'code': 'Ok',\n 'routes': [\n {\n 'geometry': {\n 'type': 'LineString',\n 'coordinates': itinerary.coords.map(this.coordinatesToJson)\n },\n 'legs': jsonLegs,\n 'distance': itinerary.distance,\n 'duration': itinerary.duration,\n 'weight_name': 'routability',\n 'weight': 0\n }\n ],\n 'waypoints': []\n };\n }\n\n createRouterResponseFromJson(\n json: OsrmJson,\n from: Coordinates,\n to: Coordinates,\n routingMode = 'walking') {\n\n const routerResponse = new RouterResponse({ routerName: this.rname, from, to });\n\n const { routes: jsonRoutes } = json;\n if (!jsonRoutes) {\n return routerResponse;\n }\n\n const routingModeCorrespondance = new Map<string, RoutingMode>();\n routingModeCorrespondance.set('walking', 'WALK');\n routingModeCorrespondance.set('driving', 'CAR');\n routingModeCorrespondance.set('bicycle', 'BIKE');\n const mode = routingModeCorrespondance.get(routingMode) || 'WALK';\n\n routerResponse.itineraries = jsonRoutes.map(jsonItinerary => {\n\n const legs = jsonItinerary.legs.map(jsonLeg => {\n\n const legCoords = jsonLeg.steps\n .map(step => step.geometry.coordinates.map(this.jsonToCoordinates))\n .flat()\n // Remove duplicates\n .filter((coords, idx, arr) => idx === 0 || !arr[idx - 1].equals(coords));\n\n const stepsInfo = jsonLeg.steps?.map(({ maneuver, name, distance, duration }) => {\n\n const stepCoords = this.jsonToCoordinates(maneuver.location);\n\n // Sometimes, OSRM step does not have the same coordinates than a point in legCoords.\n // ex: first step of https://routing.getwemap.com/route/v1/walking/2.33222164147,48.87084765712;2.3320734,48.8730212?geometries=geojson&overview=full&steps=true\n // That is why we look for the closest point.\n const distances = legCoords.map(coords => coords.distanceTo(stepCoords));\n const idStepCoordsInLeg = distances.indexOf(Math.min(...distances));\n if (idStepCoordsInLeg < 0) {\n throw new Error('Osrm Parser: Cannot find step coords in leg coordinates');\n }\n\n return new StepInfo({\n coords: stepCoords,\n name,\n distance,\n duration\n });\n })\n\n return new Leg({\n mode,\n duration: jsonLeg.duration,\n coords: legCoords,\n from: {\n coords: legCoords[0]\n },\n to: {\n coords: legCoords[legCoords.length - 1]\n },\n stepsInfo\n });\n });\n\n return new Itinerary({\n duration: jsonItinerary.duration,\n from,\n to,\n legs\n });\n });\n\n return routerResponse;\n }\n}\n\nexport default new OsrmRemoteRouter();","import Polyline from '@mapbox/polyline';\n\nimport { Coordinates } from '@wemap/geo';\nimport Logger from '@wemap/logger';\n\nimport Itinerary from '../../model/Itinerary.js';\nimport Leg, { TransportInfo } from '../../model/Leg.js';\nimport RouterResponse from '../../model/RouterResponse.js';\nimport RemoteRouter from '../RemoteRouter.js';\nimport RoutingModeCorrespondanceNotFound from '../RoutingModeCorrespondanceNotFound.js';\nimport RemoteRouterServerUnreachable from '../RemoteRouterServerUnreachable.js';\nimport { RoutingMode } from '../../model/RoutingMode.js';\nimport StepInfo from '../../model/StepInfo.js';\n\ntype OtpCoordinates = { lat: number, lon: number };\ntype FromTo = OtpCoordinates & { name: string };\ntype FromToPT = FromTo & { stopId: string, stopCode: string };\n\ntype CommonLeg = {\n startTime: number,\n endTime: number,\n legGeometry: {\n points: string,\n length: number\n },\n duration: number,\n};\n\ntype LegWalk = CommonLeg & {\n mode: 'WALK',\n from: FromTo,\n to: FromTo,\n steps: (OtpCoordinates & {\n distance: number,\n streetName: string\n })[]\n}\n\ntype LegPT = CommonLeg & {\n mode: 'BUS' | 'TRAM',\n from: FromToPT,\n to: FromToPT,\n intermediateStops: FromToPT,\n routeShortName: 'string',\n routeColor?: 'string',\n routeTextColor?: 'string',\n headsign: 'string'\n}\n\ntype OtpJson = {\n plan: {\n from: FromTo,\n to: FromTo,\n itineraries: {\n duration: number,\n startTime: number,\n endTime: number,\n walkDistance: number,\n legs: (LegWalk | LegPT)[]\n }[]\n }\n}\n\nfunction isLegPT(leg: LegPT | LegWalk): leg is LegPT {\n return leg.mode === 'BUS' || leg.mode === 'TRAM';\n}\n\nfunction jsonToCoordinates(json: OtpCoordinates) {\n return new Coordinates(json.lat, json.lon);\n}\n\n\n/**\n * Input mode correspondance\n */\nconst inputModeCorrespondance = new Map<RoutingMode, string>();\ninputModeCorrespondance.set('CAR', 'CAR');\ninputModeCorrespondance.set('WALK', 'WALK');\ninputModeCorrespondance.set('BIKE', 'BICYCLE');\ninputModeCorrespondance.set('BUS', 'WALK,TRANSIT');\ninputModeCorrespondance.set('MULTI', 'WALK,TRANSIT');\n\n/**\n * Singleton.\n */\nclass OtpRemoteRouter extends RemoteRouter {\n\n get rname() {\n return 'otp';\n }\n\n /**\n * @throws {RemoteRouterServerUnreachable}\n * @throws {RoutingModeCorrespondanceNotFound}\n */\n async getItineraries(endpointUrl: string, mode: RoutingMode, waypoints: Coordinates[]) {\n const url = this.getURL(endpointUrl, mode, waypoints);\n const res = await (fetch(url).catch(() => {\n throw new RemoteRouterServerUnreachable(this.rname, url);\n }));\n\n const jsonResponse = await res.json().catch(() => {\n throw new RemoteRouterServerUnreachable(this.rname, url);\n });\n return this.createRouterResponseFromJson(jsonResponse, waypoints[0], waypoints[1]);\n }\n\n /**\n * @throws {RoutingModeCorrespondanceNotFound}\n */\n getURL(endpointUrl: string, mode: RoutingMode, waypoints: Coordinates[]) {\n\n const otpMode = inputModeCorrespondance.get(mode);\n if (!otpMode) {\n throw new RoutingModeCorrespondanceNotFound(this.rname, mode);\n }\n\n if (waypoints.length > 2) {\n Logger.warn(`${this.rname} router uses only the first 2 waypoints (asked ${waypoints.length})`);\n }\n\n const fromPlace = `fromPlace=${waypoints[0].latitude},${waypoints[0].longitude}`;\n const toPlace = `toPlace=${waypoints[1].latitude},${waypoints[1].longitude}`;\n const queryMode = `mode=${otpMode}`;\n\n const url = new URL(endpointUrl);\n let { search } = url;\n search = (search ? `${search}&` : '?') + `${fromPlace}&${toPlace}&${queryMode}`;\n\n return `${url.origin}${url.pathname}${search}`;\n }\n\n\n /**\n * Generate multi itineraries from OTP JSON\n */\n createRouterResponseFromJson(json: OtpJson, from: Coordinates, to: Coordinates) {\n\n const routerResponse = new RouterResponse({ routerName: this.rname, from, to });\n\n const { plan: jsonPlan } = json;\n if (!jsonPlan) {\n return routerResponse;\n }\n\n const itinerariesFrom = jsonToCoordinates(jsonPlan.from);\n const itinerariesTo = jsonToCoordinates(jsonPlan.to);\n\n for (const jsonItinerary of jsonPlan.itineraries) {\n\n const legs: Leg[] = [];\n\n for (const jsonLeg of jsonItinerary.legs) {\n\n const legCoords = Polyline.decode(jsonLeg.legGeometry.points)\n .map(([lat, lon]) => new Coordinates(lat, lon));\n\n let transportInfo: TransportInfo | undefined;\n let stepsInfo;\n\n if (isLegPT(jsonLeg)) {\n\n transportInfo = {\n name: jsonLeg.routeShortName,\n routeColor: jsonLeg.routeColor,\n routeTextColor: jsonLeg.routeTextColor,\n directionName: jsonLeg.headsign\n };\n\n stepsInfo = [new StepInfo({\n coords: legCoords[0],\n name: jsonLeg.headsign\n })];\n\n } else {\n\n stepsInfo = jsonLeg.steps.map(jsonStep => {\n // OTP step does not have the same coordinates than a point in legCoords.\n // That is why we look for the closest point.\n const distances = legCoords.map(coords => coords.distanceTo(jsonToCoordinates(jsonStep)));\n const idStepCoordsInLeg = distances.indexOf(Math.min(...distances));\n if (idStepCoordsInLeg < 0) {\n throw new Error('OTP Parser: Cannot find closest step');\n }\n\n return new StepInfo({\n coords: legCoords[idStepCoordsInLeg],\n name: jsonStep.streetName \n });\n })\n }\n\n\n const leg = new Leg({\n mode: jsonLeg.mode,\n duration: jsonLeg.duration,\n startTime: jsonLeg.startTime,\n endTime: jsonLeg.endTime,\n from: {\n name: jsonLeg.from.name,\n coords: jsonToCoordinates(jsonLeg.from)\n },\n to: {\n name: jsonLeg.to.name,\n coords: jsonToCoordinates(jsonLeg.to)\n },\n coords: legCoords,\n transportInfo,\n stepsInfo\n });\n\n legs.push(leg);\n\n }\n const itinerary = new Itinerary({\n duration: jsonItinerary.duration,\n startTime: jsonItinerary.startTime,\n endTime: jsonItinerary.endTime,\n from: itinerariesFrom,\n to: itinerariesTo,\n legs\n });\n routerResponse.itineraries.push(itinerary);\n }\n\n return routerResponse;\n }\n}\n\nexport default new OtpRemoteRouter();\n","import { Coordinates, CoordinatesCompressedJson } from '@wemap/geo';\nimport { RoutingMode } from '../../model/RoutingMode.js';\nimport { WemapMultiRemoteRouterOptions } from './WemapMultiRemoteRouterOptions.js';\n\ntype WemapMetaRemoteRouterPayloadJson = {\n waypoints: CoordinatesCompressedJson[];\n mode: RoutingMode,\n options?: WemapMultiRemoteRouterOptions\n}\n\nclass WemapMultiRemoteRouterPayload {\n\n constructor(\n public waypoints: Coordinates[],\n public mode: RoutingMode,\n public options: WemapMultiRemoteRouterOptions | null = null\n ) { }\n\n toJson(): WemapMetaRemoteRouterPayloadJson {\n return {\n waypoints: this.waypoints.map(coords => coords.toCompressedJson()),\n mode: this.mode,\n ...(this.options && { options: this.options })\n };\n }\n\n \n static fromJson(json: WemapMetaRemoteRouterPayloadJson) {\n return new WemapMultiRemoteRouterPayload(\n json.waypoints.map(Coordinates.fromCompressedJson),\n json.mode,\n json.options\n );\n }\n}\n\nexport default WemapMultiRemoteRouterPayload;\n","import { Coordinates } from '@wemap/geo';\n\nimport RouterResponse from '../../model/RouterResponse.js';\nimport { RoutingMode } from '../../model/RoutingMode.js';\nimport RemoteRouter from '../RemoteRouter.js';\nimport RemoteRouterServerUnreachable from '../RemoteRouterServerUnreachable.js';\nimport { WemapMultiRemoteRouterOptions } from './WemapMultiRemoteRouterOptions.js';\nimport WemapMultiRemoteRouterPayload from './WemapMultiRemoteRouterPayload.js';\n\n\n/**\n * Singleton.\n */\nclass WemapMultiRemoteRouter extends RemoteRouter {\n\n get rname() {\n return 'wemap-meta';\n }\n\n async getItineraries(\n endpointUrl: string, mode: RoutingMode, waypoints: Coordinates[],\n options?: WemapMultiRemoteRouterOptions\n ) {\n\n const payload = new WemapMultiRemoteRouterPayload(\n waypoints, mode, options\n );\n\n const res = await (fetch(endpointUrl, {\n method: 'POST',\n headers: {\n 'Accept': 'application/json',\n 'Content-Type': 'application/json'\n },\n body: JSON.stringify(payload.toJson())\n }).catch(() => {\n throw new RemoteRouterServerUnreachable(this.rname, endpointUrl);\n }));\n\n const jsonResponse = await res.json().catch(() => {\n throw new RemoteRouterServerUnreachable(this.rname, endpointUrl);\n });\n\n return RouterResponse.fromJson(jsonResponse);\n }\n\n}\n\nexport default new WemapMultiRemoteRouter();\n","import { Coordinates } from '@wemap/geo';\n\nimport RouterResponse from '../model/RouterResponse.js';\nimport RemoteRouter from './RemoteRouter.js';\nimport CitywayRemoteRouter from './cityway/CitywayRemoteRouter.js';\nimport DeutscheBahnRemoteRouter from './deutsche-bahn/DeutscheBahnRemoteRouter.js';\nimport IdfmRemoteRouter from './idfm/IdfmRemoteRouter.js';\nimport OsrmRemoteRouter from './osrm/OsrmRemoteRouter.js';\nimport OtpRemoteRouter from './otp/OtpRemoteRouter.js';\nimport WemapMultiRemoteRouter from './wemap-multi/WemapMultiRemoteRouter.js';\nimport { RemoteRouterOptions } from './RemoteRouterOptions.js';\nimport { RoutingMode } from '../model/RoutingMode.js';\n\n/**\n * Singleton\n */\nclass RemoteRouterManager {\n\n remoteRouters: RemoteRouter[] = [\n CitywayRemoteRouter,\n DeutscheBahnRemoteRouter,\n IdfmRemoteRouter,\n OsrmRemoteRouter,\n OtpRemoteRouter,\n WemapMultiRemoteRouter\n ];\n\n getRouterByName(name: string) {\n return this.remoteRouters.find(remoteRouter => remoteRouter.rname === name);\n }\n\n /**\n * @throws {RemoteRouterServerUnreachable}\n * @throws {RoutingModeCorrespondanceNotFound}\n * @throws {IdfmRemoteRouterTokenError}\n */\n async getItineraries(\n name: string,\n endpointUrl: string,\n mode: RoutingMode,\n waypoints: Coordinates[],\n options?: RemoteRouterOptions\n ) {\n const router = this.getRouterByName(name);\n if (!router) {\n throw new Error(`Unknown \"${name}\" remote router`);\n }\n return router.getItineraries(endpointUrl, mode, waypoints, options);\n }\n\n\n /**\n * @throws {RemoteRouterServerUnreachable}\n * @throws {RoutingModeCorrespondanceNotFound}\n * @throws {IdfmRemoteRouterTokenError}\n */\n async getItinerariesWithFallback(\n remoteRouters: {name: string, endpointUrl: string}[], \n mode: RoutingMode, \n waypoints: Coordinates[], \n options?: RemoteRouterOptions\n ) {\n let routerResponse;\n for (const { name, endpointUrl } of remoteRouters) {\n routerResponse = await this.getItineraries(name, endpointUrl, mode, waypoints, options);\n if (routerResponse.itineraries.length) {\n return routerResponse;\n }\n }\n if (!routerResponse) {\n routerResponse = new RouterResponse({\n routerName: remoteRouters.map(rr => rr.name),\n from: waypoints[0],\n to: waypoints[waypoints.length],\n });\n }\n return routerResponse;\n }\n}\n\nexport default new RemoteRouterManager();\n","/* eslint-disable complexity */\n/* eslint-disable max-statements */\n\nimport { Coordinates, NoRouteFoundError } from '@wemap/geo';\nimport Logger from '@wemap/logger';\n\nimport CustomNetworkMap from './CustomNetworkMap.js';\nimport { WemapMultiRouterOptions } from './WemapMultiRouterOptions.js';\nimport RemoteRouterManager from '../remote/RemoteRouterManager.js';\nimport { isRoutingError } from '../remote/RemoteRouterUtils.js';\nimport WemapOsmRouterOptions from '../wemap-osm/WemapOsmRouterOptions.js';\nimport RouterResponse from '../model/RouterResponse.js';\nimport WemapOsmRouter from '../wemap-osm/WemapOsmRouter.js';\nimport Itinerary from '../model/Itinerary.js';\nimport { RoutingMode } from '../model/RoutingMode.js';\nimport WemapMultiRemoteRouter from '../remote/wemap-multi/WemapMultiRemoteRouter.js';\n\n\nconst getRouterNameArray = (routerResponse: RouterResponse) =>\n Array.isArray(routerResponse.routerName)\n ? routerResponse.routerName\n : [routerResponse.routerName];\n\nclass WemapMultiRouter {\n\n maps: CustomNetworkMap[] = [];\n\n get rname() {\n return 'wemap-meta';\n }\n\n addIOMap(customNetworkMap: CustomNetworkMap) {\n this.maps.push(customNetworkMap);\n }\n\n removeIOMap(customNetworkMap: CustomNetworkMap) {\n this.maps = this.maps.filter(map => map !== customNetworkMap);\n }\n\n async getItineraries(mode: RoutingMode, waypoints: Coordinates[], options: WemapMultiRouterOptions) {\n\n /*\n * Here, we try to get the shortest path using io maps networks and a remote router server.\n */\n\n /**\n * ----- 1 -----\n * Parse function params\n * -------------\n */\n\n if (waypoints.length > 2) {\n Logger.warn(`WemapMultiRouter uses only the first 2 waypoints (asked ${waypoints.length})`);\n }\n const start = waypoints[0];\n const end = waypoints[1];\n\n const routerResponse = new RouterResponse({\n routerName: this.rname,\n from: start,\n to: end\n });\n\n // Avoid cycles on remoteRouters\n const remoteRouters = options.remoteRouters?.filter(({ name }) => name !== WemapMultiRemoteRouter.rname) || [];\n\n /*\n * ----- 2 -----\n * Retrieve the IO maps to consider for this itinerary\n * -------------\n *\n * By default, all maps in this.maps are considered\n * If options.targetMaps is defined, only use this subset\n */\n let ioMapsToTest = this.maps;\n\n const { targetMaps } = options;\n if (targetMaps) {\n\n ioMapsToTest = this.maps.filter(map => map.name && targetMaps.includes(map.name));\n\n // Send a warning if one of the request customNetworkMap (from targetMaps) is not present in this.maps\n if (ioMapsToTest.length !== targetMaps.length) {\n ioMapsToTest.forEach(map => {\n if (map.name && !targetMaps.includes(map.name)) {\n Logger.warn(`CustomNetworkMap \"${map.name}\" not found in WemapMultiRouter`);\n }\n });\n }\n }\n\n /*\n * If there is no local map to test, use remote router directly.\n * This should happen:\n * 1 - this.maps is empty\n * 2 - options.targetMaps is defined but empty\n * 3 - intersection of this.maps and options.targetMaps is empty\n */\n if (!ioMapsToTest.length) {\n try {\n return await RemoteRouterManager.getItinerariesWithFallback(remoteRouters, mode, waypoints);\n } catch (e) {\n if (!isRoutingError(e)) {\n throw e;\n }\n routerResponse.error = e.message;\n return routerResponse;\n }\n }\n\n\n /**\n * ----- 3 -----\n * Run the IO Maps - Remote Routers logic\n * -------------\n *\n * For this purpose we have to consider 5 use cases\n *\n */\n\n let ioMapItinerary: Itinerary;\n\n // Find the first map where the \"start\" is inside.\n const mapWithStart = ioMapsToTest.find(map => map.isPointInside(start));\n\n // Create WemapOsmRouterOptions from WemapMultiRouterOptions\n const wemapOsmRouterOptions = !('useStairs' in options) && options.useStairs\n ? WemapOsmRouterOptions.DEFAULT\n : WemapOsmRouterOptions.WITHOUT_STAIRS;\n\n /*\n * Case 1\n *\n * If \"start\" and \"end\" are in the same map, use the local router.\n */\n if (mapWithStart && mapWithStart.isPointInside(end)) {\n\n try {\n ioMapItinerary = mapWithStart.getItineraryInsideMap(start, end, wemapOsmRouterOptions);\n } catch (e) {\n if (!isRoutingError(e)) {\n throw e;\n }\n routerResponse.error = `${e.message} - on map ${mapWithStart.name}.`;\n return routerResponse;\n }\n\n routerResponse.itineraries.push(ioMapItinerary);\n routerResponse.routerName = [this.rname, WemapOsmRouter.rname];\n\n return routerResponse;\n }\n\n // Find the first map where the \"end\" is inside.\n // Note: At this step, mapWithEnd is necessarily different from mapWithStart\n const mapWithEnd = ioMapsToTest.find(map => map.isPointInside(end));\n\n\n let remoteRouterResponse: RouterResponse;\n\n /*\n * Case 2\n *\n * If no io map have been found for \"start\" and \"end\", therefore use remote router.\n */\n if (!mapWithStart && !mapWithEnd) {\n try {\n return await RemoteRouterManager.getItinerariesWithFallback(remoteRouters, mode, waypoints);\n } catch (e) {\n if (!isRoutingError(e)) {\n throw e;\n }\n routerResponse.error = e.message;\n return routerResponse;\n }\n }\n\n /**\n * Case 3\n *\n * If a map has been found for the \"start\" but not for the \"end\", so:\n * - A first itinerary (firstRoute) is calculated from \"start\" to an \"entrypoint\"\n * of the IO map network using the wemap router.\n * - A second itinerary (secondRoute) is calculated from an \"entrypoint\" to the\n * \"end\" using remote routers.\n * Itinerary returned is the concatenation of the both itineraries.\n *\n * Note: Check the mapWithEnd.getBestItineraryFromEntryPointsToEnd to understand\n * which \"entrypoint\" is chosen by the algorithm\n */\n if (mapWithStart && !mapWithEnd) {\n\n if (!mapWithStart.entryPoints.length) {\n routerResponse.error = `A map including the \"start\" but the \"end\" has been \n found (${mapWithStart.name}), however, no \"entrypoints\" have been found to go out`;\n return routerResponse;\n }\n\n try {\n ioMapItinerary = mapWithStart.getBestItineraryFromStartToEntryPoints(start, end, wemapOsmRouterOptions);\n remoteRouterResponse = await RemoteRouterManager.getItinerariesWithFallback(\n remoteRouters, mode, [ioMapItinerary.to, end]\n );\n if (!remoteRouterResponse.itineraries.length) {\n throw new NoRouteFoundError(ioMapItinerary.to, end, remoteRouterResponse.error);\n }\n } catch (e) {\n if (!isRoutingError(e)) {\n throw e;\n }\n routerResponse.error = 'Tried to calculate an itinerary from \"start\" '\n + `to \"entrypoints\" using wemap router on local map \"${mapWithStart.name}\" and `\n + 'an itinerary from \"entrypoints\" to \"end\" using remote routers '\n + `(${remoteRouters.map(r => r.name).join(', ')}), but failed. `\n + `Details: ${e.message}.`;\n return routerResponse;\n }\n\n // Concat the the IO map itinerary with the remote router response (for each itinerary)\n routerResponse.itineraries = remoteRouterResponse.itineraries.map(\n remoteRouterItinerary => Itinerary.fromItineraries(ioMapItinerary, remoteRouterItinerary)\n );\n routerResponse.routerName = [this.rname, ...getRouterNameArray(remoteRouterResponse), WemapOsmRouter.rname];\n return routerResponse;\n }\n\n /*\n * Case 4\n *\n * If a map has been found for the \"end\" but not for the \"start\", so:\n * - A first itinerary (remoteRouterResponse) is calculated from \"start\" to an \"entrypoint\"\n * of the IO map network using remote routers.\n * - A second itinerary (ioMapItinerary) is calculated from an \"entrypoint\" to the\n * \"end\" using the wemap router.\n * Itinerary returned is the concatenation of the both itineraries.\n *\n * Note: Check the mapWithEnd.getBestItineraryFromEntryPointsToEnd to understand\n * which \"entrypoint\" is chosen by the algorithm\n */\n if (!mapWithStart && mapWithEnd) {\n\n if (!mapWithEnd.entryPoints.length) {\n routerResponse.error = `A map including the \"end\" but the \"start\" has been \n found (${mapWithEnd.name}), however, no \"entrypoints\" have been found to go in`;\n return routerResponse;\n }\n\n /*\n * ioMapItinerary is computed before the remoteRouterResponse because it is less expensive to\n * calculate all the routes to entrypoints using local router than all the routes with the\n * remote router.\n */\n try {\n ioMapItinerary = mapWithEnd.getBestItineraryFromEntryPointsToEnd(start, end, wemapOsmRouterOptions);\n remoteRouterResponse = await RemoteRouterManager.getItinerariesWithFallback(\n remoteRouters, mode, [start, ioMapItinerary.from]\n );\n if (!remoteRouterResponse.itineraries.length) {\n throw new NoRouteFoundError(start, ioMapItinerary.from, remoteRouterResponse.error);\n }\n } catch (e) {\n if (!isRoutingError(e)) {\n throw e;\n }\n routerResponse.error = 'Tried to calculate an itinerary from \"start\" to \"entrypoints\" '\n + `using remote routers (${remoteRouters.map(r => r.name).join(', ')}) and an `\n + 'itinerary from \"entrypoints\" to \"end\" using wemap router on local map '\n + `\"${mapWithEnd.name}\", but failed. `\n + `Details: ${e.message}.`;\n return routerResponse;\n }\n\n // Concat the remote router response (for each itinerary) with the IO map itinerary\n routerResponse.itineraries = remoteRouterResponse.itineraries.map(\n remoteRouterItinerary => Itinerary.fromItineraries(remoteRouterItinerary, ioMapItinerary)\n );\n routerResponse.routerName = [this.rname, ...getRouterNameArray(remoteRouterResponse), WemapOsmRouter.rname];\n return routerResponse;\n }\n\n /**\n * Case 5\n *\n * If maps have been found for the \"start\" and the \"end\" but they are different, so:\n * - A first itinerary (ioMapItinerary1) is calculated from \"start\" to an \"entrypoint\" of\n * the mapWithStart using the wemap router.\n * - A second itinerary (remoteRouterResponse) is calculated from an \"entrypoint\" of the\n * mapWithStart to an \"entrypoint\" of the endWithMap using remote routers.\n * - A third itinerary (ioMapItinerary2) is calculated from an \"entrypoint\" of the mapWithEnd\n * to the \"end\" using the wemap router.\n * Itinerary returned is the concatenation of the three itineraries.\n */\n if (mapWithStart && mapWithEnd) {\n\n if (!mapWithStart.entryPoints.length) {\n routerResponse.error = `One map including the \"start\" (${mapWithStart.name}) and another \n including the \"end\" (${mapWithEnd.name}) has been found, however, no \"entrypoints\" have \n been found to go out of the start map`;\n return routerResponse;\n }\n\n if (!mapWithEnd.entryPoints.length) {\n routerResponse.error = `One map including the \"start\" (${mapWithStart.name}) and another \n including the \"end\" (${mapWithEnd.name}) has been found, however, no \"entrypoints\" have \n been found to go in the second map`;\n return routerResponse;\n }\n\n let ioMapItinerary1: Itinerary, ioMapItinerary2: Itinerary;\n try {\n ioMapItinerary1 = mapWithStart.getBestItineraryFromStartToEntryPoints(start, end, wemapOsmRouterOptions);\n ioMapItinerary2 = mapWithEnd.getBestItineraryFromEntryPointsToEnd(start, end, wemapOsmRouterOptions);\n remoteRouterResponse = await RemoteRouterManager.getItinerariesWithFallback(\n remoteRouters, mode, [ioMapItinerary1.to, ioMapItinerary2.from]\n );\n if (!remoteRouterResponse.itineraries.length) {\n throw new NoRouteFoundError(ioMapItinerary1.to, ioMapItinerary2.from, remoteRouterResponse.error);\n }\n } catch (e) {\n if (!isRoutingError(e)) {\n throw e;\n }\n routerResponse.error = 'Tried to calculate an itinerary from \"start\" to \"entrypoints1\" '\n + `using wemap router on local map \"${mapWithStart.name}\", an itinerary from `\n + '\"entrypoints1\" to \"entrypoints2\" using remote routers '\n + `(${remoteRouters.map(r => r.name).join(', ')}) and an itinerary from \"entrypoints2\" `\n + `to \"end\" using wemap router on local map \"${mapWithEnd.name}\", but failed. `\n + `Details: ${e.message}.`;\n return routerResponse;\n }\n\n // Concat the IO map itinerary 2 with the remote router response (for each itinerary)\n // and the IO map itinerary 2\n routerResponse.itineraries = remoteRouterResponse.itineraries.map(\n remoteRouterItinerary => Itinerary.fromItineraries(\n ioMapItinerary1,\n remoteRouterItinerary,\n ioMapItinerary2\n )\n );\n routerResponse.routerName = [this.rname, ...getRouterNameArray(remoteRouterResponse), WemapOsmRouter.rname];\n return routerResponse;\n\n }\n\n throw new Error('Should never happen');\n }\n\n}\n\nexport default WemapMultiRouter;\n","import pointInPolygon from '@turf/boolean-point-in-polygon';\nimport convexHullFn from '@turf/convex';\nimport { Feature, Polygon, polygon as turfPolygon, Position } from '@turf/helpers';\n\nimport { Coordinates, NoRouteFoundError } from '@wemap/geo';\nimport { OsmParser, OsmNetworkUtils, OsmNetwork, OsmGraphNode } from '@wemap/osm';\n\nimport WemapOsmRouter from '../wemap-osm/WemapOsmRouter.js';\nimport WemapOsmRouterOptions from '../wemap-osm/WemapOsmRouterOptions.js';\n\nclass CustomNetworkMap {\n\n name: string | null;\n network: OsmNetwork;\n router: WemapOsmRouter;\n bounds: Feature<Polygon>;\n entryPoints: OsmGraphNode[];\n disabledWays = new Set<number>();\n\n constructor(\n network: OsmNetwork,\n entryPoints: OsmGraphNode[],\n bounds: Coordinates[] | null = null,\n name: string | null = null) {\n\n this.name = name;\n this.network = network;\n this.router = new WemapOsmRouter(network);\n\n // Entry points\n entryPoints.forEach(entryPoint => {\n if (!network.nodes.includes(entryPoint)) {\n throw new Error(`Cannot find entry point ${entryPoint.coords.toString()} in network \"${name}\"`);\n }\n });\n this.entryPoints = entryPoints;\n\n // Bounds\n if (bounds) {\n this.bounds = turfPolygon([bounds.map(coords => [coords.lng, coords.lat])]);\n } else {\n const polygon = [network.nodes.map(node => [node.coords.lng, node.coords.lat] as Position)];\n const convexHull = convexHullFn({ type: 'polygon', coordinates: polygon });\n if (!convexHull) {\n throw new Error(`Cannot calculate convexHull of network \"${name}\"`);\n }\n this.bounds = convexHull;\n }\n }\n\n\n static fromOsmXml(osmXmlString: string, name: string | null = null) {\n\n const osmModel = OsmParser.parseOsmXmlString(osmXmlString);\n const network = OsmNetworkUtils.createNetworkFromOsmModel(osmModel);\n\n const entryPoints = osmModel.nodes\n .filter(({ tags }) => tags && tags['wemap:routing-io'])\n .map(osmNode => network.getNodeByCoords(osmNode.coords) as OsmGraphNode);\n if (entryPoints.some(el => el === null)\n || new Set(entryPoints).size !== entryPoints.length\n ) {\n throw new Error('Cannot parse wemap:routing-io correctly');\n }\n\n const wayBounds = osmModel.ways.find(({ tags }) => tags['wemap:routing-bounds']);\n if (!wayBounds) {\n throw new Error('Search bounds is undefined. Please use OSM tag : \"wemap:routing-bounds=yes\"');\n }\n const bounds = wayBounds.nodes.map(node => node.coords);\n return new CustomNetworkMap(network, entryPoints, bounds, name);\n }\n\n isPointInside(coordinates: Coordinates) {\n return pointInPolygon([coordinates.lng, coordinates.lat], this.bounds);\n }\n\n /**\n * Get the list of entry points sorted by the lowest distance between:\n * start -> entry point -> end\n * (as the crow flies)\n *\n */\n getOrderedEntryPointsSortedByDistance(start: Coordinates, end: Coordinates) {\n const entryPointsCopy = [...this.entryPoints];\n return entryPointsCopy.sort((ep1, ep2) =>\n Number(ep1.coords.distanceTo(start)) + ep1.coords.distanceTo(end)\n - ep2.coords.distanceTo(start) - ep2.coords.distanceTo(end)\n );\n }\n\n /**\n * Get the best itinerary from any entry point to an end coordinates.\n *\n * The algorithm works as following:\n * 1 - Entry points are sorted using distance (as the crow flies) between start - entry point - end\n * 2 - Try to calculate an itinerary from the first entry point to the end coordinates.\n * 3 - If an itinerary is found, it is returned. Otherwise it tries from the next entry point.\n *\n * /!\\ start is only used to sort the entry points (step 1).\n *\n */\n getBestItineraryFromEntryPointsToEnd(start: Coordinates, end: Coordinates, options: WemapOsmRouterOptions) {\n\n const sortedEntryPoints = this.getOrderedEntryPointsSortedByDistance(start, end);\n for (const entryPoint of sortedEntryPoints) {\n const itinerary = this.router.getItinerary(entryPoint, end, options);\n if (itinerary) {\n return itinerary;\n }\n // no route found\n }\n throw new NoRouteFoundError(start, end,\n `No route found from entry points to ${end.toString()} in map: ${this.name}`\n );\n }\n\n\n /**\n * Get the best itinerary from start coordinates to any entry point.\n *\n * The algorithm works as following:\n * 1 - Entry points are sorted using distance (as the crow flies) between start - entry point - end\n * 2 - Try to calculate an itinerary from the start coordinates to the first entry point.\n * 3 - If an itinerary is found, it is returned. Otherwise it tries to the next entry point.\n *\n * /!\\ end is only used to sort the entry points (step 1).\n *\n */\n getBestItineraryFromStartToEntryPoints(start: Coordinates, end: Coordinates, options: WemapOsmRouterOptions) {\n\n const sortedEntryPoints = this.getOrderedEntryPointsSortedByDistance(start, end);\n for (const entryPoint of sortedEntryPoints) {\n const itinerary = this.router.getItinerary(start, entryPoint, options);\n if (itinerary) {\n return itinerary;\n }\n // no route found\n }\n throw new NoRouteFoundError(start, end,\n `No route found from ${start.toString()} to entry points in map: ${this.name}`\n );\n }\n\n getItineraryInsideMap(start: Coordinates, end: Coordinates, options: WemapOsmRouterOptions) {\n // Call the Wemap router to get the shortest path\n return this.router.getItinerary(start, end, options);\n }\n\n enableWay(osmId: number) {\n this.network.edges\n .filter(edge => edge.builtFrom?.id === osmId)\n .forEach(e => this.router.disabledEdges.delete(e));\n this.disabledWays.delete(osmId);\n }\n\n disableWay(osmId: number) {\n this.network.edges\n .filter(edge => edge.builtFrom?.id === osmId)\n .forEach(e => this.router.disabledEdges.add(e));\n this.disabledWays.add(osmId);\n }\n}\n\nexport default CustomNetworkMap;\n","import { diffAngle, rad2deg } from '@wemap/maths';\n\nexport function getTurnInfoFromAngle(_angle: number) {\n\n let direction, directionExtra;\n\n const directionAngle = rad2deg(diffAngle(_angle, Math.PI));\n const directionAngleAbs = Math.abs(directionAngle);\n if (directionAngleAbs <= 20) {\n direction = 'straight';\n } else {\n direction = directionAngle > 0 ? 'left' : 'right';\n if (directionAngleAbs < 55) {\n directionExtra = 'slight';\n } else if (directionAngleAbs > 120) {\n directionExtra = 'sharp';\n }\n }\n\n return { direction, directionExtra };\n}","import { Coordinates, GraphEdge, GraphNode, GraphProjection, MapMatching } from '@wemap/geo';\n\nimport Itinerary from './model/Itinerary.js';\nimport Leg from './model/Leg.js';\nimport { Step } from './model/Step.js';\n\nexport type ItineraryInfo<U extends Coordinates = Coordinates> = {\n nextStep: Step | null;\n previousStep: Step | null;\n projection: GraphProjection<unknown, unknown, U>;\n leg: Leg;\n traveledDistance: number;\n remainingDistance: number;\n traveledPercentage: number;\n remainingPercentage: number;\n};\n\nclass ItineraryInfoManager {\n\n _itinerary: Itinerary | null = null;\n _mapMatching: MapMatching | null = null;\n\n _steps: Step[] = [];\n _coordsNextStep: (Step | null)[] = [];\n _coordsPreviousStep: (Step | null)[] = [];\n _coordsDistanceTraveled: number[] = [];\n _coordsLeg: Leg[] = [];\n\n constructor(itinerary: Itinerary | null = null) {\n this.itinerary = itinerary;\n }\n\n get itinerary() {\n return this._itinerary;\n }\n\n set itinerary(itinerary) {\n\n if (itinerary === null) {\n this._itinerary = null;\n return;\n }\n\n this._itinerary = itinerary;\n this._steps = itinerary.steps;\n const network = itinerary.toNetwork();\n this._mapMatching = new MapMatching(network);\n\n this._coordsNextStep = new Array(itinerary.coords.length);\n this._coordsPreviousStep = new Array(itinerary.coords.length);\n this._coordsDistanceTraveled = new Array(itinerary.coords.length);\n this._coordsLeg = new Array(itinerary.coords.length);\n\n let stepId = 0;\n let previousStep: Step | null = null;\n let nextStep: Step | null = this._steps[0];\n let distanceTraveled = 0;\n\n itinerary.coords.forEach((coords, idx, arr) => {\n if (idx !== 0) {\n distanceTraveled += arr[idx - 1].distanceTo(coords);\n }\n\n this._coordsNextStep[idx] = nextStep;\n this._coordsPreviousStep[idx] = previousStep;\n this._coordsDistanceTraveled[idx] = distanceTraveled;\n this._coordsLeg[idx] = itinerary.legs.find(leg => leg.coords.includes(coords)) as Leg;\n\n if (stepId < this._steps.length && this._steps[stepId].coords.equals(coords)) {\n previousStep = this._steps[stepId];\n nextStep = stepId === this._steps.length - 1 ? null : this._steps[stepId + 1];\n stepId++;\n }\n });\n }\n\n getInfo<U extends Coordinates = Coordinates>(position: U) {\n\n if (!this._itinerary || !this._mapMatching) {\n return null;\n }\n\n const projection = this._mapMatching.getProjection(position);\n if (!projection) {\n return null;\n }\n\n let itineraryInfo: ItineraryInfo<U> | null = null;\n\n if (projection.nearestElement instanceof GraphNode) {\n const idx = this._itinerary.coords.findIndex(\n coords => (projection.nearestElement as GraphNode).coords === coords\n );\n if (idx === -1) {\n throw new Error('ItineraryInfoManager: could not find projection in itinerary (Node)');\n }\n\n const traveledDistance = this._coordsDistanceTraveled[idx];\n const remainingDistance = this._itinerary.distance - traveledDistance;\n itineraryInfo = {\n nextStep: this._coordsNextStep[idx],\n previousStep: this._coordsPreviousStep[idx],\n projection: projection,\n leg: this._coordsLeg[idx],\n traveledDistance,\n remainingDistance,\n traveledPercentage: traveledDistance / this._itinerary.distance,\n remainingPercentage: remainingDistance / this._itinerary.distance\n };\n\n } else if (projection.nearestElement instanceof GraphEdge) {\n\n let firstNode = projection.nearestElement.node1.coords;\n let idx = this._itinerary.coords.findIndex(coords => firstNode === coords);\n if (idx === -1) {\n throw new Error('ItineraryInfoManager: could not find projection in itinerary (Edge)');\n }\n\n // graphEdge is not necessarly ordered. We have to look for the first point\n if (idx === this._itinerary.coords.length - 1\n || this._itinerary.coords[idx + 1] !== projection.nearestElement.node2.coords\n ) {\n firstNode = projection.nearestElement.node2.coords;\n idx--;\n }\n\n const traveledDistance = this._coordsDistanceTraveled[idx]\n + projection.coords.distanceTo(firstNode);\n const remainingDistance = this._itinerary.distance - traveledDistance;\n itineraryInfo = {\n nextStep: this._coordsNextStep[idx + 1],\n previousStep: this._coordsPreviousStep[idx + 1],\n projection: projection,\n leg: this._coordsLeg[idx + 1],\n traveledDistance,\n remainingDistance,\n traveledPercentage: traveledDistance / this._itinerary.distance,\n remainingPercentage: remainingDistance / this._itinerary.distance\n };\n\n }\n\n return itineraryInfo;\n }\n\n}\n\nexport default ItineraryInfoManager;\n"],"names":["Coordinates","deg2rad","Level","diffAngle","GeoUtils","Network","OsmGraphRouterOptions","OsmNode","GraphUtils","OsmWay","OsmGraphRouter","NoRouteFoundError","jsonToCoordinates","inputModeCorrespondance","routingModeCorrespondance","Logger","positiveMod","rad2deg","Polyline","CitywayRemoteRouter","DeutscheBahnRemoteRouter","IdfmRemoteRouter","OsrmRemoteRouter","OtpRemoteRouter","WemapMultiRemoteRouter","RemoteRouterManager","turfPolygon","convexHullFn","OsmParser","OsmNetworkUtils","pointInPolygon","MapMatching","GraphNode","GraphEdge"],"mappings":"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"}
|