@wemap/routers 11.2.2 → 11.2.3
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 +10 -3
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +10 -3
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
- package/src/wemap-multi/CustomNetworkMap.ts +15 -5
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../src/Utils.ts","../src/model/generateSteps.ts","../src/model/RoutingMode.ts","../src/model/Step.ts","../src/model/Leg.ts","../src/model/Itinerary.ts","../src/model/RouterResponse.ts","../src/wemap-osm/OsmGraph.ts","../src/wemap-osm/OsmRouter.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/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","import { Coordinates, Level } from '@wemap/geo';\nimport { diffAngle, deg2rad } from '@wemap/maths';\nimport Leg from './Leg.js';\n\nimport { LevelChange, LevelChangeType } from './LevelChange.js';\nimport { MinStepInfo } from './Step.js';\nimport { StepExtra } from './StepExtra.js';\n\nconst SKIP_STEP_ANGLE_MAX = deg2rad(20);\n\nexport type StepsGenerationRules =\n (currentCoords: Coordinates, nextCoords: Coordinates, previousStep: MinStepInfo | null) => {\n createNewStep?: boolean;\n duration?: number;\n stepName?: string;\n stepExtras?: StepExtra;\n levelChangeType?: LevelChangeType;\n forceLevelChange?: 'up' | 'down';\n forceEndOfLevelChange?: boolean;\n };\n\nexport default function generateSteps(leg: Leg, rules?: StepsGenerationRules) {\n\n const steps: MinStepInfo[] = [];\n\n const { from, to, coords: coordsArray } = leg;\n\n let currentStep: MinStepInfo | 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 const previousStep = steps.length ? steps[steps.length - 1] : null;\n const customRules = rules?.(currentCoords, nextCoords, previousStep);\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) || customRules?.forceLevelChange;\n splitByAngle = splitByAngle && !(currentCoords.level && Level.isRange(currentCoords.level));\n\n\n const splitByEndOfLevelChange = previousStep?.levelChange && !Level.isRange(currentCoords.level)\n || customRules?.forceEndOfLevelChange;\n\n const splitStepCondition = splitByAngle || splitByLevel || splitByEndOfLevelChange || customRules?.createNewStep;\n\n // New step creation\n if (isFirstStep || splitStepCondition) {\n\n let levelChange: LevelChange | undefined;\n\n if (splitByLevel) {\n const difference = Level.diff(currentCoords.level, nextCoords.level) || 0;\n let direction: 'up' | 'down' = difference > 0 ? 'up' : 'down';\n if (customRules?.forceLevelChange) {\n direction = customRules?.forceLevelChange;\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 delete currentStep.duration;\n }\n\n currentStep = {\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({ 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 { Coordinates, CoordinatesCompressedJson } from '@wemap/geo';\n\nimport { LevelChange } from './LevelChange.js';\nimport { StepExtra } from './StepExtra.js';\n\nexport type Step = {\n\n firstStep: boolean;\n lastStep: boolean;\n number: number;\n\n angle: number;\n previousBearing: number;\n nextBearing: number;\n distance: number;\n duration: number;\n\n readonly coords: Coordinates;\n readonly name: string | null;\n readonly levelChange: LevelChange | null;\n readonly extras: StepExtra | null;\n}\n\nexport type StepJson = {\n firstStep?: boolean,\n lastStep?: boolean\n number: number,\n coords: CoordinatesCompressedJson,\n name?: string,\n angle: number,\n previousBearing: number,\n nextBearing: number,\n distance: number,\n duration: number\n levelChange?: LevelChange\n extras?: StepExtra,\n};\n\nexport type MinStepInfo = {\n coords: Coordinates,\n name?: string,\n levelChange?: LevelChange\n extras?: StepExtra,\n distance?: number,\n duration?: number\n};\n\nexport function stepToJson(step: Step): StepJson {\n return {\n ...(step.firstStep && { firstStep: true }),\n ...(step.lastStep && { lastStep: true }),\n number: step.number,\n coords: step.coords.toCompressedJson(),\n ...(step.name !== null && { name: step.name }),\n angle: Number(step.angle.toFixed(2)),\n previousBearing: Number(step.previousBearing.toFixed(2)),\n nextBearing: Number(step.nextBearing.toFixed(2)),\n distance: Number(step.distance.toFixed(1)),\n duration: Number(step.duration.toFixed(1)),\n ...(step.levelChange !== null && { levelChange: step.levelChange }),\n ...(step.extras && Object.keys(step.extras).length !== 0 && { extras: step.extras }),\n };\n}\n\nexport function jsonToStep(json: StepJson): Step {\n return Object.assign({}, json, {\n coords: Coordinates.fromCompressedJson(json.coords),\n firstStep: Boolean(json.firstStep),\n lastStep: Boolean(json.lastStep),\n name: json.name || null,\n levelChange: json.levelChange || null,\n extras: json.extras || null\n });\n}\n\nexport function stepEquals(step1: Step, step2: Step) {\n return step1.coords.equals(step2.coords)\n && Math.abs(step1.angle - step2.angle) <= 0.005\n && Math.abs(step1.distance - step2.distance) <= 0.05\n && Math.abs(step1.duration - step2.duration) <= 0.05\n && step1.firstStep === step2.firstStep\n && step1.lastStep === step2.lastStep\n && step1.levelChange?.difference === step2.levelChange?.difference\n && step1.levelChange?.direction === step2.levelChange?.direction\n && step1.levelChange?.type === step2.levelChange?.type\n && step1.name === step2.name\n && Math.abs(step1.nextBearing - step2.nextBearing) <= 0.005\n && step1.number === step2.number\n && Math.abs(step1.previousBearing - step2.previousBearing) <= 0.005\n}\n","import {\n Coordinates, CoordinatesCompressedJson, GeoGraphItinerary,\n Level, Utils as GeoUtils, GeoGraph\n} from '@wemap/geo';\nimport { diffAngle } from '@wemap/maths';\nimport { getDurationFromLength } from '../Utils.js';\nimport generateSteps, { StepsGenerationRules } from './generateSteps.js';\nimport { RoutingMode, isRoutingModePublicTransport } from './RoutingMode.js';\n\nimport { jsonToStep, MinStepInfo, Step, stepEquals, StepJson, stepToJson } from './Step.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 | { minStepsInfo: MinStepInfo[] }\n | { steps: Step[] }\n )\n & LegCommon;\n\nexport type LegJson = {\n from: DestinationJson,\n to: DestinationJson,\n coords: CoordinatesCompressedJson[],\n steps: StepJson[],\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 steps: Step[];\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\n // Steps management\n\n if ('steps' in otherParams) {\n this.steps = otherParams.steps;\n return;\n }\n const minStepsInfo = 'minStepsInfo' in otherParams ? otherParams.minStepsInfo\n : generateSteps(this, otherParams.stepsGenerationRules);\n\n this.steps = Leg.generateStepsFromMinStepInfo(from.coords, to.coords, coords, minStepsInfo);\n }\n\n isPublicTransport() {\n return isRoutingModePublicTransport(this.mode);\n }\n\n toGraph() {\n return GeoGraph.fromCoordinates([this.coords]);\n }\n\n static equals(obj1: Leg, obj2: Leg) {\n const intermediate = obj1.mode === obj2.mode\n && Math.abs(obj1.duration - obj2.duration) <= 0.05\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.steps === obj2.steps\n || obj1.steps?.length === obj2.steps?.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 for (i = 0; i < obj1.steps.length; i++) {\n if (!stepEquals(obj1.steps[i], obj2.steps[i])) {\n return false;\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: Number(this.duration.toFixed(1)),\n coords: this.coords.map(coords => coords.toCompressedJson()),\n steps: this.steps.map(stepToJson),\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 steps: json.steps?.map(jsonToStep) || null,\n }));\n\n return leg;\n }\n\n\n\n static fromGraphItinerary(\n graphItinerary: GeoGraphItinerary,\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.vertices.map(vertex => vertex.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.steps.forEach(step => {\n step.coords.level = Level.multiplyBy(step.coords.level, levelFactor);\n });\n }\n\n static generateStepsFromMinStepInfo(from: Coordinates, to: Coordinates, legCoords: Coordinates[], stepsInfo: MinStepInfo[]): Step[] {\n return stepsInfo.map((stepInfo, stepId) => {\n const coordsId = legCoords.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 ? from : legCoords[coordsId - 1];\n const coordsAfterStep = coordsId === legCoords.length - 1\n ? to\n : legCoords[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 : legCoords[legCoords.length - 1];\n let currentCoordsId = coordsId;\n while (!legCoords[currentCoordsId].equals(coordsToStopCalculation)) {\n distance += legCoords[currentCoordsId].distanceTo(legCoords[currentCoordsId + 1]);\n currentCoordsId++;\n }\n if (currentCoordsId === legCoords.length - 1) {\n distance += legCoords[currentCoordsId].distanceTo(to);\n }\n\n return {\n coords: stepInfo.coords,\n name: stepInfo.name || null,\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, // stepInfo.distance is overwritten\n duration: stepInfo.duration || getDurationFromLength(distance),\n levelChange: stepInfo.levelChange || null,\n extras: stepInfo.extras || null\n }\n });\n }\n}\n","import {\n Coordinates, CoordinatesCompressedJson, GeoGraph, GeoGraphItinerary,\n Level, 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 { RoutingMode, isRoutingModePublicTransport } from './RoutingMode.js';\nimport { Step } from './Step.js';\nimport { StepsGenerationRules } from './generateSteps.js';\nimport { getDurationFromLength } from '../Utils.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 readonly 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 _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 this.updateStepsFromLegs();\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 return this.legs.map(leg => leg.steps).flat();\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 toGraph() {\n return GeoGraph.fromCoordinates([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 && Math.abs(obj1.distance - obj2.distance) <= 0.05\n && Math.abs(obj1.duration - obj2.duration) <= 0.05\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: Number(this.duration.toFixed(1)),\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(\n graphItinerary: GeoGraphItinerary,\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.steps) {\n for (const step of leg.steps) {\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 /**\n * Update steps info thanks to the coordinates of the whole itinerary.\n * This method will update:\n * - all steps number\n * - first/last steps\n * - previousBearing/nextBearing/angle of first and last step of each leg\n * - distance/duration of first and last step of each leg\n */\n updateStepsFromLegs() {\n\n const itineraryCoords = this.coords\n // Remove duplicates\n .filter((coords, idx, arr) => idx === 0 || !arr[idx - 1].equals(coords));\n const steps = this.legs.map(leg => leg.steps).flat();\n\n\n steps.map((step, stepId) => {\n const coordsId = itineraryCoords.findIndex(coords => coords.equals(step.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 step.previousBearing = coordsBeforeStep.bearingTo(step.coords);\n step.nextBearing = step.coords.bearingTo(coordsAfterStep);\n step.angle = diffAngle(step.previousBearing, step.nextBearing + Math.PI);\n\n const stepDistanceBefore = step.distance;\n step.distance = 0;\n const coordsToStopCalculation = stepId !== steps.length - 1\n ? steps[stepId + 1].coords\n : itineraryCoords[itineraryCoords.length - 1];\n let currentCoordsId = coordsId;\n while (!itineraryCoords[currentCoordsId].equals(coordsToStopCalculation)) {\n step.distance += itineraryCoords[currentCoordsId].distanceTo(itineraryCoords[currentCoordsId + 1]);\n currentCoordsId++;\n }\n if (currentCoordsId === itineraryCoords.length - 1) {\n step.distance += itineraryCoords[currentCoordsId].distanceTo(this.to);\n }\n\n step.number = stepId + 1;\n step.firstStep = stepId === 0;\n step.lastStep = stepId === steps.length - 1;\n\n step.duration += getDurationFromLength(step.distance - stepDistanceBefore)\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 { Coordinates, GeoGraph, GeoGraphEdge, GeoGraphVertex, Level } from '@wemap/geo';\nimport { OsmModel, OsmNode, OsmWay } from '@wemap/osm';\n\nconst HIGHWAYS_PEDESTRIANS = ['footway', 'steps', 'pedestrian', 'living_street', 'path', 'track', 'sidewalk', 'elevator'];\n\nconst DEFAULT_WAY_SELECTOR = (way: OsmWay) => {\n const isElevatorArea = way.tags.highway === 'elevator' && way.isArea\n return HIGHWAYS_PEDESTRIANS.includes(way.tags.highway) \n && !isElevatorArea \n && !['no', 'private'].includes(way.tags.access)\n || way.tags.footway === 'sidewalk'\n || way.tags.public_transport === 'platform'\n || way.tags.railway === 'platform';\n};\n\nexport type OsmVertexData = OsmNode;\nexport type OsmEdgeData = OsmWay | OsmNode;\n\nexport type OsmVertex = GeoGraphVertex<OsmVertexData, OsmEdgeData> & { data: OsmVertexData };\nexport type OsmEdge = GeoGraphEdge<OsmVertexData, OsmEdgeData> & { data: OsmEdgeData };\n\nexport default class OsmGraph extends GeoGraph<OsmVertexData, OsmEdgeData> {\n\n declare vertices: OsmVertex[];\n declare edges: OsmEdge[];\n\n static HIGHWAYS_PEDESTRIANS = HIGHWAYS_PEDESTRIANS;\n static DEFAULT_WAY_SELECTOR = DEFAULT_WAY_SELECTOR;\n\n getVertexByCoords(coords: Coordinates) {\n return GeoGraph.getVertexByCoords(this.vertices, coords) as OsmVertex | undefined;\n }\n\n getVertexByName(name: string) {\n return super.getVertexByName(name) as OsmVertex | undefined;\n }\n\n getEdgeByName(name: string) {\n return super.getEdgeByName(name) as OsmEdge | undefined;\n }\n\n static fromOsmModel(osmModel: OsmModel, waySelectionFilter = DEFAULT_WAY_SELECTOR) {\n\n const nodes: OsmVertex[] = [];\n const edges: OsmEdge[] = [];\n\n const nodesCreated: { [key: number]: OsmVertex } = {};\n const elevatorNodes: OsmVertex[] = [];\n\n const getOrCreateNode = (osmNode: OsmNode) => {\n let node = nodesCreated[osmNode.id];\n if (!node) {\n node = new GeoGraphVertex(osmNode.coords, { data: osmNode, name: osmNode.tags.name }) as OsmVertex;\n nodesCreated[osmNode.id] = node;\n nodes.push(node);\n\n if (osmNode.tags.highway === 'elevator') {\n elevatorNodes.push(node);\n }\n }\n return node;\n };\n\n osmModel.ways.forEach(way => {\n if (!waySelectionFilter(way)) {\n return;\n }\n\n let firstNode = getOrCreateNode(way.nodes[0]);\n for (let i = 1; i < way.nodes.length; i++) {\n const secondNode = getOrCreateNode(way.nodes[i]);\n\n const edge = new GeoGraphEdge(firstNode, secondNode,\n { data: way, name: way.tags.name, level: way.level }\n ) as OsmEdge;\n OsmGraph.manageOneWay(edge, way);\n edges.push(edge);\n firstNode = secondNode;\n }\n\n });\n\n osmModel.ways\n .filter(way => way.isElevator)\n .forEach(way => {\n way.nodes.forEach(node => {\n const connectedWays = node.ways.filter(otherWay => otherWay != way);\n if (connectedWays.length) {\n const graphVertex = getOrCreateNode(node);\n graphVertex.data.tags.highway = 'elevator';\n elevatorNodes.push(graphVertex);\n }\n })\n });\n\n elevatorNodes.forEach(node => {\n // We have to clone this node for each connected edge\n OsmGraph.createNodesAndEdgesFromElevator(nodes, edges, node);\n });\n\n return new OsmGraph(nodes, edges, true);\n }\n\n\n\n private static manageOneWay(edge: OsmEdge, way: OsmWay) {\n\n const { highway, oneway, conveying } = way.tags;\n\n edge.isOneway = Boolean((oneway === 'yes' || oneway === 'true' || oneway === '1')\n || (conveying && highway && ['forward', 'backward'].includes(conveying)));\n\n if (edge.isOneway && conveying === 'backward') {\n const tmpNode = edge.vertex1;\n edge.vertex1 = edge.vertex2;\n edge.vertex2 = tmpNode;\n }\n }\n\n\n private static createNodesAndEdgesFromElevator(\n nodes: OsmVertex[],\n edges: OsmEdge[],\n elevatorNode: OsmVertex\n ) {\n\n const createdNodes: OsmVertex[] = [];\n const getOrCreateLevelVertex = (level: number | null) => {\n let levelVertex = createdNodes.find(({ coords }) => Level.equals(level, coords.level));\n if (!levelVertex) {\n levelVertex = new GeoGraphVertex(elevatorNode.coords.clone(), {\n data: elevatorNode.data,\n name: `${elevatorNode.name} (elevator lvl: ${level})`\n }) as OsmVertex;\n levelVertex.coords.level = level;\n createdNodes.push(levelVertex);\n nodes.push(levelVertex);\n }\n return levelVertex;\n };\n\n // Create nodes from node.edges\n elevatorNode.edges.forEach(edge => {\n if (Level.isRange(edge.level)) {\n throw new Error('Cannot handle this elevator edge due to ambiguity');\n }\n\n const levelVertex = getOrCreateLevelVertex(edge.level);\n if (edge.vertex1 === elevatorNode) {\n edge.vertex1 = levelVertex;\n } else {\n edge.vertex2 = levelVertex;\n }\n levelVertex.edges.push(edge);\n });\n\n // Create edges from createdNodes\n for (let i = 0; i < createdNodes.length; i++) {\n for (let j = i + 1; j < createdNodes.length; j++) {\n\n const createdNode1 = createdNodes[i];\n const createdNode2 = createdNodes[j];\n\n if (createdNode1.coords.level === null || createdNode2.coords.level === null) {\n // TODO: not the best approach... but cannot do better with [number, number] range for levels\n continue;\n }\n\n const minLevel = Math.min(createdNode1.coords.level as number, createdNode2.coords.level as number);\n const maxLevel = Math.max(createdNode1.coords.level as number, createdNode2.coords.level as number);\n\n const newEdge = new GeoGraphEdge<OsmVertexData, OsmEdgeData>(\n createdNode1,\n createdNode2,\n { data: elevatorNode.data, name: elevatorNode.name, level: [minLevel, maxLevel] }\n ) as OsmEdge;\n edges.push(newEdge);\n }\n }\n\n // Remove the historical elevator node from the network\n const elevatorNodeIndex = nodes.indexOf(elevatorNode);\n if (elevatorNodeIndex > -1) {\n nodes.splice(elevatorNodeIndex, 1);\n }\n }\n\n}","import salesman from '@wemap/salesman.js';\n\nimport { Coordinates, GeoGraph, GeoGraphEdge, GeoGraphItinerary, GeoGraphRouter, GeoGraphRouterOptions } from '@wemap/geo';\nimport { diffAngle, rad2deg } from '@wemap/maths';\nimport { OsmWay } from '@wemap/osm';\n\nimport { StepsGenerationRules } from '../model/generateSteps.js';\nimport Itinerary from '../model/Itinerary.js';\nimport { LevelChangeType } from '../model/LevelChange.js';\nimport { getDurationFromLength } from '../Utils.js';\nimport OsmGraph, { OsmEdge, OsmEdgeData, OsmVertex, OsmVertexData } from './OsmGraph.js';\nimport Leg from '../model/Leg.js';\nimport { MinStepInfo } from '../model/Step.js';\n\n\nconst DEFAULT_OPTIONS = Object.assign({}, GeoGraphRouter.DEFAULT_OPTIONS, {\n weightEdgeFn: (edge: OsmEdge) => {\n if (edge.data.isElevator) {\n return 90;\n }\n let duration = getDurationFromLength(edge.length, 4);\n if (edge.data instanceof OsmWay && edge.data.areStairs) {\n duration *= 3;\n }\n return duration;\n },\n acceptEdgeFn: (edge: GeoGraphEdge) => {\n const accessTag = (edge as OsmEdge).data.tags.access;\n return typeof accessTag === 'undefined' || accessTag === 'yes';\n }\n});\n\nconst WITHOUT_STAIRS_OPTIONS = Object.assign({}, DEFAULT_OPTIONS, {\n acceptEdgeFn: (edge: GeoGraphEdge) => (edge as OsmEdge).data.tags.highway !== 'steps'\n});\n\nexport type GeoGraphTripRouterOptions<VertexData = unknown, EdgeData = unknown> =\n GeoGraphRouterOptions<VertexData, EdgeData> & {\n tspTempCoeff?: number; // https://github.com/wemap/salesman.js/blob/master/salesman.js#L164\n };\n\nconst DEFAULT_TRIP_OPTIONS = Object.assign({}, {\n tspTempCoeff: 0.99\n}, GeoGraphRouter.DEFAULT_OPTIONS);\n\n\nconst buildStepsRules = (graphItinerary: OsmItinerary): StepsGenerationRules => (\n currentCoords: Coordinates,\n nextCoords: Coordinates,\n previousStep: MinStepInfo | null\n) => {\n const edges = graphItinerary.edges;\n const vertices = graphItinerary.vertices;\n const vertex = GeoGraph.getVertexByCoords(vertices, currentCoords);\n const nextVertex = GeoGraph.getVertexByCoords(vertices, nextCoords);\n if (!vertex || !nextVertex) return {};\n const edge = GeoGraphEdge.getEdgeByVertices(edges, vertex, nextVertex) as OsmEdge | undefined;\n if (!edge) return {};\n const edgeId = edges.findIndex(_edge => _edge === edge) as number;\n\n const isSubwayEntrance = vertex ? vertex.data?.tags.railway === 'subway_entrance' : false;\n const isGate = vertex ? (vertex.data?.tags.barrier === 'gate' || vertex.data?.tags.aeroway === 'gate') : false;\n\n let levelChangeType: LevelChangeType | null = null;\n if (edge.data.isElevator) {\n levelChangeType = 'elevator';\n } else if (edge.data.isConveying) {\n levelChangeType = 'conveyor';\n } else if (edge.data instanceof OsmWay && edge.data.areStairs) {\n levelChangeType = 'stairs';\n }\n\n // Handle stairs/elevator/conveyors without change in level coordinates\n let forceLevelChange: 'up' | 'down' | undefined;\n const edgeTags = edge.data.tags || {};\n if (\n edge.data instanceof OsmWay\n && edge.data.areStairs\n && ['up', 'down'].includes(edgeTags.incline)\n && !previousStep?.levelChange\n ) {\n forceLevelChange = edgeTags.incline as 'up' | 'down';\n for (const n of edge.data.nodes) {\n if (n !== vertex.data) continue;\n }\n const isReversed = edge.data.nodes.reduce((acc: boolean | null, n, idx, arr) => {\n if (n !== vertex.data) return acc;\n acc = !(idx + 1 < arr.length && arr[idx + 1] === nextVertex.data);\n return acc;\n }, null);\n if (isReversed) {\n forceLevelChange = forceLevelChange === 'up' ? 'down' : 'up';\n }\n }\n\n const previousEdge = edgeId > 0 && edges.length ? edges[edgeId - 1] : null;\n const previousEdgeTags = previousEdge?.data.tags || {};\n const forceEndOfLevelChange = Boolean(\n previousEdge && previousEdge.data instanceof OsmWay && ['up', 'down'].includes(previousEdgeTags.incline) && previousEdge.data.areStairs\n && edge.data instanceof OsmWay && (!['up', 'down'].includes(edgeTags.incline) || !edge.data.areStairs));\n const createNewStep = isSubwayEntrance;\n\n return {\n createNewStep,\n stepName: edge.data?.tags.name,\n duration: graphItinerary.edgesWeights[edgeId],\n stepExtras: {\n ...(isSubwayEntrance && { isSubwayEntrance: true }),\n ...(isSubwayEntrance && vertex.data?.tags.ref && { subwayEntranceRef: vertex.data.tags.ref }),\n ...(isGate && { isGate: true })\n },\n ...(levelChangeType && { levelChangeType }),\n ...(forceLevelChange && { forceLevelChange }),\n ...(forceEndOfLevelChange && { forceEndOfLevelChange })\n };\n};\n\n// export type OsmItinerary = GeoGraphItinerary<OsmVertexData, OsmEdgeData>;\n\nexport class OsmItinerary extends GeoGraphItinerary<OsmVertexData, OsmEdgeData> {\n // declare vertices: OsmVertex[]; // Cannot use OsmVertex due to null data of projection\n declare edges: OsmEdge[];\n}\n\nclass WemapOsmRouter extends GeoGraphRouter<OsmVertexData, OsmEdgeData> {\n\n static DEFAULT_OPTIONS = DEFAULT_OPTIONS;\n static WITHOUT_STAIRS_OPTIONS = WITHOUT_STAIRS_OPTIONS;\n\n constructor(graph: OsmGraph) {\n super(graph);\n }\n\n static get rname() {\n return 'wemap-osm';\n }\n\n getShortestPath(\n start: OsmVertex | Coordinates,\n end: OsmVertex | Coordinates,\n options: GeoGraphRouterOptions<OsmVertexData, OsmEdgeData> = DEFAULT_OPTIONS\n ) {\n return super.getShortestPath(start, end, options) as OsmItinerary;\n }\n\n getItinerary(\n start: OsmVertex | Coordinates,\n end: OsmVertex | Coordinates,\n options: GeoGraphRouterOptions<OsmVertexData, OsmEdgeData> = DEFAULT_OPTIONS\n ) {\n const graphItinerary = this.getShortestPath(start, end, options);\n\n // Transform a network itinerary (vertices, edges...) to a router itinerary (legs, steps...)\n return Itinerary.fromGraphItinerary(graphItinerary, 'WALK', buildStepsRules(graphItinerary))\n }\n\n\n static 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 }\n\n getShortestTrip(\n waypoints: Coordinates[],\n options: GeoGraphTripRouterOptions<OsmVertexData, OsmEdgeData> = DEFAULT_TRIP_OPTIONS\n ) {\n type CustomPoint = salesman.Point & { coords: Coordinates };\n\n const points = waypoints.map(waypoint => {\n const point = new salesman.Point(0, 0) as CustomPoint;\n point.coords = waypoint;\n return point;\n });\n const cache: OsmItinerary[] = [];\n const solution = salesman.solve(points, options.tspTempCoeff, undefined, (p: salesman.Point, q: salesman.Point) => {\n // Throw an error if no path found\n const osmItinerary = this.getShortestPath(\n (p as CustomPoint).coords,\n (q as CustomPoint).coords,\n options\n );\n cache.push(osmItinerary);\n return osmItinerary.edgesWeights.reduce((acc, weight) => acc + weight, 0);\n });\n\n const orderedPoints = solution.map(i => points[i]);\n const orderedItineraries = [];\n for (let i = 0; i < orderedPoints.length; i++) {\n const p = orderedPoints[i] as CustomPoint;\n const q = orderedPoints[(i + 1) % orderedPoints.length] as CustomPoint;\n let cachedItinerary = cache.find(itinerary => itinerary.start === p.coords && itinerary.end === q.coords || itinerary.end === p.coords && itinerary.start === q.coords) as OsmItinerary;\n if (cachedItinerary.end === p.coords) {\n // Need to revert itinerary due to salesman bijectivity\n cachedItinerary = GeoGraphItinerary.fromGraphVertices(\n cachedItinerary.end,\n cachedItinerary.start,\n cachedItinerary.vertices.reverse(),\n cachedItinerary.edgesWeights\n ) as OsmItinerary;\n }\n\n orderedItineraries.push(cachedItinerary);\n }\n return orderedItineraries;\n }\n\n getTripItinerary(\n waypoints: Coordinates[],\n options: GeoGraphTripRouterOptions<OsmVertexData, OsmEdgeData> = DEFAULT_TRIP_OPTIONS\n ) {\n const shortestTrip = this.getShortestTrip(waypoints, options);\n return new Itinerary({\n from: shortestTrip[0].start,\n to: shortestTrip[shortestTrip.length - 1].end,\n legs: shortestTrip.map(graphItinerary => Leg.fromGraphItinerary(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 { MinStepInfo } from '../../model/Step.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() { return 'cityway' as const; }\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 minStepsInfo: MinStepInfo[];\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 minStepsInfo = [];\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 minStepsInfo.push({\n coords: stepCoords[0],\n distance: jsonPathLink.Distance,\n name: jsonPathLink.Departure.Site.Name\n });\n }\n\n // If it's last leg, create a last step because cityway doesn't use the end of itinerary as step\n if (jsonSection === trip.sections.Section[trip.sections.Section.length - 1]) {\n minStepsInfo.push({\n coords: legCoords[legCoords.length - 1]\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 minStepsInfo = [{\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 minStepsInfo\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() { return 'deutsche-bahn' as const; }\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, { TransportInfo } 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 { MinStepInfo } from '../../model/Step.js';\nimport { RemoteRouterOptions } from '../RemoteRouterOptions.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() { return 'idfm' as const; }\n\n /**\n * @throws {IdfmRemoteRouterTokenError}\n * @throws {RemoteRouterServerUnreachable}\n */\n async getItineraries(endpointUrl: string, mode: RoutingMode, waypoints: Coordinates[], options: RemoteRouterOptions = {}) {\n const url = this.getURL(endpointUrl, mode, waypoints, options);\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[], options: RemoteRouterOptions) {\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 url = new URL(endpointUrl);\n\n const coreParams = new URLSearchParams();\n coreParams.set('from', `${waypoints[0].longitude};${waypoints[0].latitude}`);\n coreParams.set('to', `${waypoints[1].longitude};${waypoints[1].latitude}`);\n\n if ('useStairs' in options && !options.useStairs) {\n coreParams.set('wheelchair', 'true')\n }\n\n let queryParams: URLSearchParams = new URLSearchParams();\n switch (mode) {\n case 'WALK':\n queryParams = this.getWalkingQuery();\n break;\n case 'BIKE':\n queryParams = this.getBikeQuery();\n break;\n case 'CAR':\n queryParams = this.getCarQuery();\n break;\n default:\n break;\n }\n\n [coreParams, queryParams].map(params => {\n for (const pair of params.entries()) {\n url.searchParams.append(pair[0], pair[1]);\n }\n });\n\n return url.toString();\n }\n\n getCarQuery() {\n const urlSearchParams = new URLSearchParams();\n\n TRANSPORT_IDS.forEach((id) => {\n urlSearchParams.append('forbidden_uris[]', id);\n });\n\n urlSearchParams.append('first_section_mode[]', 'walking');\n urlSearchParams.append('first_section_mode[]', 'car');\n urlSearchParams.append('last_section_mode[]', 'walking');\n urlSearchParams.append('last_section_mode[]', 'car');\n\n return urlSearchParams;\n }\n\n getWalkingQuery() {\n const urlSearchParams = new URLSearchParams();\n\n TRANSPORT_IDS.forEach((id) => {\n urlSearchParams.append('forbidden_uris[]', id);\n });\n\n urlSearchParams.append('first_section_mode[]', 'walking');\n urlSearchParams.append('last_section_mode[]', 'walking');\n\n return urlSearchParams;\n }\n\n getBikeQuery() {\n const urlSearchParams = new URLSearchParams();\n\n TRANSPORT_IDS.forEach((id) => {\n urlSearchParams.append('forbidden_uris[]', id);\n });\n\n urlSearchParams.append('first_section_mode[]', 'bike');\n urlSearchParams.append('last_section_mode[]', 'bike');\n\n return urlSearchParams;\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({\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 minStepsInfo: MinStepInfo[] | undefined;\n let transportInfo: TransportInfo | undefined;\n let mode = routingModeCorrespondance.get(jsonSection.mode) as RoutingMode;\n\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 minStepsInfo = this.findStepsCoord(legCoords, idfmIntermediateSteps);\n }\n\n if (jsonSection.type === 'public_transport') {\n 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 mode = routingModeCorrespondance.get(jsonSection.display_informations.physical_mode) as RoutingMode;\n\n const legStep: MinStepInfo = {\n coords: legCoords[0],\n name: transportInfo.directionName,\n distance: jsonSection.geojson.properties[0].length\n };\n minStepsInfo = [legStep];\n }\n\n const leg = new Leg({\n mode,\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 transportInfo,\n minStepsInfo\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';\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\ntype OsrmMode = 'driving' | 'walking' | 'bike' | 'bus' | 'walking';\n\n/**\n * Input mode correspondance\n */\nconst inputModeCorrespondance = new Map<RoutingMode, OsrmMode>();\ninputModeCorrespondance.set('CAR', 'driving');\ninputModeCorrespondance.set('WALK', 'walking');\ninputModeCorrespondance.set('BIKE', 'bike');\ninputModeCorrespondance.set('BUS', 'bus');\ninputModeCorrespondance.set('MULTI', 'walking');\n\n/**\n * Singleton.\n */\nclass OsrmRemoteRouter extends RemoteRouter {\n\n /**\n * @override\n */\n get rname() { return 'osrm' as const; }\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\n const osrmMode = inputModeCorrespondance.get(mode);\n\n return this.createRouterResponseFromJson(jsonResponse, from, to, osrmMode);\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: OsrmMode = '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 minStepsInfo = 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 {\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 minStepsInfo\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';\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() { return 'otp' as const; }\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 minStepsInfo;\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 minStepsInfo = [{\n coords: legCoords[0],\n name: jsonLeg.headsign\n }];\n\n } else {\n\n minStepsInfo = 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 {\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 minStepsInfo\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 WemapMultiRemoteRouterPayloadJson = {\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(): WemapMultiRemoteRouterPayloadJson {\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: WemapMultiRemoteRouterPayloadJson) {\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() { return 'wemap-multi' as const; }\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\nconst remoteRouters = [\n CitywayRemoteRouter,\n DeutscheBahnRemoteRouter,\n IdfmRemoteRouter,\n OsrmRemoteRouter,\n OtpRemoteRouter,\n WemapMultiRemoteRouter\n] as const;\n\nexport type RemoteRouterName = typeof remoteRouters[number]['rname'];\n\n/**\n * Singleton\n */\nclass RemoteRouterManager {\n\n getRouterByName(name: RemoteRouterName): RemoteRouter {\n return remoteRouters.find(remoteRouter => remoteRouter.rname === name) as RemoteRouter;\n }\n\n /**\n * @throws {RemoteRouterServerUnreachable}\n * @throws {RoutingModeCorrespondanceNotFound}\n * @throws {IdfmRemoteRouterTokenError}\n */\n async getItineraries(\n name: RemoteRouterName,\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: RemoteRouterName, 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, GeoGraphRouterOptions } 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 RouterResponse from '../model/RouterResponse.js';\nimport WemapOsmRouter, { GeoGraphTripRouterOptions } from '../wemap-osm/OsmRouter.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-multi';\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 private getIoMapsFromOptions(options: WemapMultiRouterOptions | null) {\n\n let ioMapsToTest = this.maps;\n const targetMaps = options?.targetMaps;\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 return ioMapsToTest;\n }\n\n private convertOptionsToWemapOsmOptions(options: WemapMultiRouterOptions | null) {\n // Create WemapOsmRouterOptions from WemapMultiRouterOptions\n const outputOptions : GeoGraphRouterOptions | GeoGraphTripRouterOptions\n = !options || !('useStairs' in options) || options.useStairs\n ? WemapOsmRouter.DEFAULT_OPTIONS\n : WemapOsmRouter.WITHOUT_STAIRS_OPTIONS;\n\n if(typeof options?.tspTempCoeff !== 'undefined') {\n (outputOptions as any).tspTempCoeff = options.tspTempCoeff;\n }\n return outputOptions;\n\n }\n\n async getTrip(mode: RoutingMode, waypoints: Coordinates[], options: WemapMultiRouterOptions | null = null) {\n const ioMapsToTest = this.getIoMapsFromOptions(options);\n if (waypoints.length < 2) {\n throw Error(`Cannot retrieve a trip itinerary. Two points or more are necessary`);\n }\n\n if (mode !== 'WALK') {\n throw Error(`Cannot calculate trip itinerary for mode \"${mode}\". Only \"WALK\" is implemented.`);\n }\n\n // Retrieve the map which embed all the waypoints\n const mapOfWaypoints = waypoints.reduce((map, waypoint) => {\n const mapOfThisWaypoint = ioMapsToTest.find(map => map.isPointInside(waypoint));\n if (!mapOfThisWaypoint) {\n throw Error(`Cannot find a network for this trip waypoint (${waypoint.toString()}). Outdoor trips are not implemented.`)\n }\n if (map && mapOfThisWaypoint !== map) {\n throw Error(`Cannot handle this trip, because two waypoints are on different maps (${mapOfThisWaypoint} and ${mapOfWaypoints}). ` +\n `Multi-map trips are not implemented.`)\n }\n return mapOfThisWaypoint\n }, null as CustomNetworkMap | null);\n\n // Create WemapOsmRouterOptions from WemapMultiRouterOptions\n const wemapOsmRouterOptions = this.convertOptionsToWemapOsmOptions(options);\n\n const tripItinerary = mapOfWaypoints!.getTripInsideMap(waypoints, wemapOsmRouterOptions);\n\n return new RouterResponse({\n routerName: this.rname,\n from: tripItinerary.from,\n to: tripItinerary.to,\n itineraries: [tripItinerary]\n });\n }\n\n async getItineraries(mode: RoutingMode, waypoints: Coordinates[], options: WemapMultiRouterOptions | null = null) {\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 const ioMapsToTest = this.getIoMapsFromOptions(options);\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 = this.convertOptionsToWemapOsmOptions(options);\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 { Position, MultiPolygon } from '@turf/helpers';\n\nimport { Coordinates, GeoGraphRouterOptions, NoRouteFoundError } from '@wemap/geo';\nimport { OsmParser } from '@wemap/osm';\n\nimport OsmGraph, { OsmVertex } from '../wemap-osm/OsmGraph.js';\nimport WemapOsmRouter from '../wemap-osm/OsmRouter.js';\n\nclass CustomNetworkMap {\n\n name: string | null;\n graph: OsmGraph;\n router: WemapOsmRouter;\n bounds: MultiPolygon;\n entryPoints: OsmVertex[];\n disabledWays = new Set<number>();\n\n constructor(\n graph: OsmGraph,\n entryPoints: OsmVertex[],\n bounds: MultiPolygon | null = null,\n name: string | null = null) {\n\n this.name = name;\n this.graph = graph;\n this.router = new WemapOsmRouter(graph);\n\n // Entry points\n entryPoints.forEach(entryPoint => {\n if (!graph.vertices.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 = bounds;\n } else {\n const polygon = [graph.vertices.map(vertex => [vertex.coords.lng, vertex.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 = {\n type: 'MultiPolygon',\n coordinates: [convexHull.geometry.coordinates]\n };\n }\n }\n\n\n static fromOsmXml(osmXmlString: string, name: string | null = null) {\n\n const osmModel = OsmParser.parseOsmXmlString(osmXmlString);\n const graph = OsmGraph.fromOsmModel(osmModel);\n\n const entryPoints = graph.vertices.filter(({ data: { tags } }) => tags && tags['wemap:routing-io']);\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 bounds: MultiPolygon = {\n type: 'MultiPolygon',\n coordinates: []\n };\n osmModel.ways\n .filter(({ tags }) => tags['wemap:routing-bounds'])\n .forEach(way => {\n bounds.coordinates.push([way.nodes.reduce((acc, node) => {\n acc.push([node.coords.lng, node.coords.lat]);\n return acc;\n }, [] as Position[])\n ]);\n });\n osmModel.relations\n .filter(rel => rel.tags['wemap:routing-bounds'] && rel.isMultipolygon())\n .forEach(rel => {\n const polygon = rel.getGeoJsonPolygon();\n polygon && bounds.coordinates.push(polygon.coordinates);\n });\n\n if (!bounds.coordinates.length) {\n throw new Error('Search bounds is undefined. Please use OSM tag : \"wemap:routing-bounds=yes\"');\n }\n return new CustomNetworkMap(graph, 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: GeoGraphRouterOptions) {\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: GeoGraphRouterOptions) {\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: GeoGraphRouterOptions) {\n // Call the Wemap router to get the shortest path\n return this.router.getItinerary(start, end, options);\n }\n\n getTripInsideMap(waypoints: Coordinates[], options: GeoGraphRouterOptions) {\n // Call the Wemap router to get the shortest trip itinerary\n return this.router.getTripItinerary(waypoints, options);\n }\n\n enableWay(osmId: number) {\n this.graph.edges\n .filter(edge => edge.data.id === osmId)\n .forEach(e => this.router.disabledEdges.delete(e));\n this.disabledWays.delete(osmId);\n }\n\n disableWay(osmId: number) {\n this.graph.edges\n .filter(edge => edge.data.id === osmId)\n .forEach(e => this.router.disabledEdges.add(e));\n this.disabledWays.add(osmId);\n }\n}\n\nexport default CustomNetworkMap;\n","import { Coordinates, GeoGraphEdge, GeoGraphProjection, GeoGraphProjectionHandler, GeoGraphVertex } 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: GeoGraphProjection<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 _geoGraphProjectionHandler: GeoGraphProjectionHandler | 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 graph = itinerary.toGraph();\n this._geoGraphProjectionHandler = new GeoGraphProjectionHandler(graph);\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._geoGraphProjectionHandler) {\n return null;\n }\n\n const projection = this._geoGraphProjectionHandler.getProjection(position);\n if (!projection) {\n return null;\n }\n\n let itineraryInfo: ItineraryInfo<U> | null = null;\n\n if (projection.nearestElement instanceof GeoGraphVertex) {\n const idx = this._itinerary.coords.findIndex(\n coords => (projection.nearestElement as GeoGraphVertex).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 GeoGraphEdge) {\n\n let firstNode = projection.nearestElement.vertex1.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.vertex2.coords\n ) {\n firstNode = projection.nearestElement.vertex2.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":["deg2rad","Level","diffAngle","Coordinates","GeoUtils","GeoGraph","GeoGraphVertex","GeoGraphEdge","GeoGraphRouter","OsmWay","rad2deg","salesman","GeoGraphItinerary","NoRouteFoundError","jsonToCoordinates","inputModeCorrespondance","routingModeCorrespondance","Logger","positiveMod","Polyline","CitywayRemoteRouter","DeutscheBahnRemoteRouter","IdfmRemoteRouter","OsrmRemoteRouter","OtpRemoteRouter","WemapMultiRemoteRouter","remoteRouters","map","RemoteRouterManager","convexHullFn","OsmParser","pointInPolygon","GeoGraphProjectionHandler"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/Utils.ts","../src/model/generateSteps.ts","../src/model/RoutingMode.ts","../src/model/Step.ts","../src/model/Leg.ts","../src/model/Itinerary.ts","../src/model/RouterResponse.ts","../src/wemap-osm/OsmGraph.ts","../src/wemap-osm/OsmRouter.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/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","import { Coordinates, Level } from '@wemap/geo';\nimport { diffAngle, deg2rad } from '@wemap/maths';\nimport Leg from './Leg.js';\n\nimport { LevelChange, LevelChangeType } from './LevelChange.js';\nimport { MinStepInfo } from './Step.js';\nimport { StepExtra } from './StepExtra.js';\n\nconst SKIP_STEP_ANGLE_MAX = deg2rad(20);\n\nexport type StepsGenerationRules =\n (currentCoords: Coordinates, nextCoords: Coordinates, previousStep: MinStepInfo | null) => {\n createNewStep?: boolean;\n duration?: number;\n stepName?: string;\n stepExtras?: StepExtra;\n levelChangeType?: LevelChangeType;\n forceLevelChange?: 'up' | 'down';\n forceEndOfLevelChange?: boolean;\n };\n\nexport default function generateSteps(leg: Leg, rules?: StepsGenerationRules) {\n\n const steps: MinStepInfo[] = [];\n\n const { from, to, coords: coordsArray } = leg;\n\n let currentStep: MinStepInfo | 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 const previousStep = steps.length ? steps[steps.length - 1] : null;\n const customRules = rules?.(currentCoords, nextCoords, previousStep);\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) || customRules?.forceLevelChange;\n splitByAngle = splitByAngle && !(currentCoords.level && Level.isRange(currentCoords.level));\n\n\n const splitByEndOfLevelChange = previousStep?.levelChange && !Level.isRange(currentCoords.level)\n || customRules?.forceEndOfLevelChange;\n\n const splitStepCondition = splitByAngle || splitByLevel || splitByEndOfLevelChange || customRules?.createNewStep;\n\n // New step creation\n if (isFirstStep || splitStepCondition) {\n\n let levelChange: LevelChange | undefined;\n\n if (splitByLevel) {\n const difference = Level.diff(currentCoords.level, nextCoords.level) || 0;\n let direction: 'up' | 'down' = difference > 0 ? 'up' : 'down';\n if (customRules?.forceLevelChange) {\n direction = customRules?.forceLevelChange;\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 delete currentStep.duration;\n }\n\n currentStep = {\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({ 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 { Coordinates, CoordinatesCompressedJson } from '@wemap/geo';\n\nimport { LevelChange } from './LevelChange.js';\nimport { StepExtra } from './StepExtra.js';\n\nexport type Step = {\n\n firstStep: boolean;\n lastStep: boolean;\n number: number;\n\n angle: number;\n previousBearing: number;\n nextBearing: number;\n distance: number;\n duration: number;\n\n readonly coords: Coordinates;\n readonly name: string | null;\n readonly levelChange: LevelChange | null;\n readonly extras: StepExtra | null;\n}\n\nexport type StepJson = {\n firstStep?: boolean,\n lastStep?: boolean\n number: number,\n coords: CoordinatesCompressedJson,\n name?: string,\n angle: number,\n previousBearing: number,\n nextBearing: number,\n distance: number,\n duration: number\n levelChange?: LevelChange\n extras?: StepExtra,\n};\n\nexport type MinStepInfo = {\n coords: Coordinates,\n name?: string,\n levelChange?: LevelChange\n extras?: StepExtra,\n distance?: number,\n duration?: number\n};\n\nexport function stepToJson(step: Step): StepJson {\n return {\n ...(step.firstStep && { firstStep: true }),\n ...(step.lastStep && { lastStep: true }),\n number: step.number,\n coords: step.coords.toCompressedJson(),\n ...(step.name !== null && { name: step.name }),\n angle: Number(step.angle.toFixed(2)),\n previousBearing: Number(step.previousBearing.toFixed(2)),\n nextBearing: Number(step.nextBearing.toFixed(2)),\n distance: Number(step.distance.toFixed(1)),\n duration: Number(step.duration.toFixed(1)),\n ...(step.levelChange !== null && { levelChange: step.levelChange }),\n ...(step.extras && Object.keys(step.extras).length !== 0 && { extras: step.extras }),\n };\n}\n\nexport function jsonToStep(json: StepJson): Step {\n return Object.assign({}, json, {\n coords: Coordinates.fromCompressedJson(json.coords),\n firstStep: Boolean(json.firstStep),\n lastStep: Boolean(json.lastStep),\n name: json.name || null,\n levelChange: json.levelChange || null,\n extras: json.extras || null\n });\n}\n\nexport function stepEquals(step1: Step, step2: Step) {\n return step1.coords.equals(step2.coords)\n && Math.abs(step1.angle - step2.angle) <= 0.005\n && Math.abs(step1.distance - step2.distance) <= 0.05\n && Math.abs(step1.duration - step2.duration) <= 0.05\n && step1.firstStep === step2.firstStep\n && step1.lastStep === step2.lastStep\n && step1.levelChange?.difference === step2.levelChange?.difference\n && step1.levelChange?.direction === step2.levelChange?.direction\n && step1.levelChange?.type === step2.levelChange?.type\n && step1.name === step2.name\n && Math.abs(step1.nextBearing - step2.nextBearing) <= 0.005\n && step1.number === step2.number\n && Math.abs(step1.previousBearing - step2.previousBearing) <= 0.005\n}\n","import {\n Coordinates, CoordinatesCompressedJson, GeoGraphItinerary,\n Level, Utils as GeoUtils, GeoGraph\n} from '@wemap/geo';\nimport { diffAngle } from '@wemap/maths';\nimport { getDurationFromLength } from '../Utils.js';\nimport generateSteps, { StepsGenerationRules } from './generateSteps.js';\nimport { RoutingMode, isRoutingModePublicTransport } from './RoutingMode.js';\n\nimport { jsonToStep, MinStepInfo, Step, stepEquals, StepJson, stepToJson } from './Step.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 | { minStepsInfo: MinStepInfo[] }\n | { steps: Step[] }\n )\n & LegCommon;\n\nexport type LegJson = {\n from: DestinationJson,\n to: DestinationJson,\n coords: CoordinatesCompressedJson[],\n steps: StepJson[],\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 steps: Step[];\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\n // Steps management\n\n if ('steps' in otherParams) {\n this.steps = otherParams.steps;\n return;\n }\n const minStepsInfo = 'minStepsInfo' in otherParams ? otherParams.minStepsInfo\n : generateSteps(this, otherParams.stepsGenerationRules);\n\n this.steps = Leg.generateStepsFromMinStepInfo(from.coords, to.coords, coords, minStepsInfo);\n }\n\n isPublicTransport() {\n return isRoutingModePublicTransport(this.mode);\n }\n\n toGraph() {\n return GeoGraph.fromCoordinates([this.coords]);\n }\n\n static equals(obj1: Leg, obj2: Leg) {\n const intermediate = obj1.mode === obj2.mode\n && Math.abs(obj1.duration - obj2.duration) <= 0.05\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.steps === obj2.steps\n || obj1.steps?.length === obj2.steps?.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 for (i = 0; i < obj1.steps.length; i++) {\n if (!stepEquals(obj1.steps[i], obj2.steps[i])) {\n return false;\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: Number(this.duration.toFixed(1)),\n coords: this.coords.map(coords => coords.toCompressedJson()),\n steps: this.steps.map(stepToJson),\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 steps: json.steps?.map(jsonToStep) || null,\n }));\n\n return leg;\n }\n\n\n\n static fromGraphItinerary(\n graphItinerary: GeoGraphItinerary,\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.vertices.map(vertex => vertex.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.steps.forEach(step => {\n step.coords.level = Level.multiplyBy(step.coords.level, levelFactor);\n });\n }\n\n static generateStepsFromMinStepInfo(from: Coordinates, to: Coordinates, legCoords: Coordinates[], stepsInfo: MinStepInfo[]): Step[] {\n return stepsInfo.map((stepInfo, stepId) => {\n const coordsId = legCoords.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 ? from : legCoords[coordsId - 1];\n const coordsAfterStep = coordsId === legCoords.length - 1\n ? to\n : legCoords[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 : legCoords[legCoords.length - 1];\n let currentCoordsId = coordsId;\n while (!legCoords[currentCoordsId].equals(coordsToStopCalculation)) {\n distance += legCoords[currentCoordsId].distanceTo(legCoords[currentCoordsId + 1]);\n currentCoordsId++;\n }\n if (currentCoordsId === legCoords.length - 1) {\n distance += legCoords[currentCoordsId].distanceTo(to);\n }\n\n return {\n coords: stepInfo.coords,\n name: stepInfo.name || null,\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, // stepInfo.distance is overwritten\n duration: stepInfo.duration || getDurationFromLength(distance),\n levelChange: stepInfo.levelChange || null,\n extras: stepInfo.extras || null\n }\n });\n }\n}\n","import {\n Coordinates, CoordinatesCompressedJson, GeoGraph, GeoGraphItinerary,\n Level, 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 { RoutingMode, isRoutingModePublicTransport } from './RoutingMode.js';\nimport { Step } from './Step.js';\nimport { StepsGenerationRules } from './generateSteps.js';\nimport { getDurationFromLength } from '../Utils.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 readonly 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 _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 this.updateStepsFromLegs();\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 return this.legs.map(leg => leg.steps).flat();\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 toGraph() {\n return GeoGraph.fromCoordinates([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 && Math.abs(obj1.distance - obj2.distance) <= 0.05\n && Math.abs(obj1.duration - obj2.duration) <= 0.05\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: Number(this.duration.toFixed(1)),\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(\n graphItinerary: GeoGraphItinerary,\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.steps) {\n for (const step of leg.steps) {\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 /**\n * Update steps info thanks to the coordinates of the whole itinerary.\n * This method will update:\n * - all steps number\n * - first/last steps\n * - previousBearing/nextBearing/angle of first and last step of each leg\n * - distance/duration of first and last step of each leg\n */\n updateStepsFromLegs() {\n\n const itineraryCoords = this.coords\n // Remove duplicates\n .filter((coords, idx, arr) => idx === 0 || !arr[idx - 1].equals(coords));\n const steps = this.legs.map(leg => leg.steps).flat();\n\n\n steps.map((step, stepId) => {\n const coordsId = itineraryCoords.findIndex(coords => coords.equals(step.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 step.previousBearing = coordsBeforeStep.bearingTo(step.coords);\n step.nextBearing = step.coords.bearingTo(coordsAfterStep);\n step.angle = diffAngle(step.previousBearing, step.nextBearing + Math.PI);\n\n const stepDistanceBefore = step.distance;\n step.distance = 0;\n const coordsToStopCalculation = stepId !== steps.length - 1\n ? steps[stepId + 1].coords\n : itineraryCoords[itineraryCoords.length - 1];\n let currentCoordsId = coordsId;\n while (!itineraryCoords[currentCoordsId].equals(coordsToStopCalculation)) {\n step.distance += itineraryCoords[currentCoordsId].distanceTo(itineraryCoords[currentCoordsId + 1]);\n currentCoordsId++;\n }\n if (currentCoordsId === itineraryCoords.length - 1) {\n step.distance += itineraryCoords[currentCoordsId].distanceTo(this.to);\n }\n\n step.number = stepId + 1;\n step.firstStep = stepId === 0;\n step.lastStep = stepId === steps.length - 1;\n\n step.duration += getDurationFromLength(step.distance - stepDistanceBefore)\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 { Coordinates, GeoGraph, GeoGraphEdge, GeoGraphVertex, Level } from '@wemap/geo';\nimport { OsmModel, OsmNode, OsmWay } from '@wemap/osm';\n\nconst HIGHWAYS_PEDESTRIANS = ['footway', 'steps', 'pedestrian', 'living_street', 'path', 'track', 'sidewalk', 'elevator'];\n\nconst DEFAULT_WAY_SELECTOR = (way: OsmWay) => {\n const isElevatorArea = way.tags.highway === 'elevator' && way.isArea\n return HIGHWAYS_PEDESTRIANS.includes(way.tags.highway) \n && !isElevatorArea \n && !['no', 'private'].includes(way.tags.access)\n || way.tags.footway === 'sidewalk'\n || way.tags.public_transport === 'platform'\n || way.tags.railway === 'platform';\n};\n\nexport type OsmVertexData = OsmNode;\nexport type OsmEdgeData = OsmWay | OsmNode;\n\nexport type OsmVertex = GeoGraphVertex<OsmVertexData, OsmEdgeData> & { data: OsmVertexData };\nexport type OsmEdge = GeoGraphEdge<OsmVertexData, OsmEdgeData> & { data: OsmEdgeData };\n\nexport default class OsmGraph extends GeoGraph<OsmVertexData, OsmEdgeData> {\n\n declare vertices: OsmVertex[];\n declare edges: OsmEdge[];\n\n static HIGHWAYS_PEDESTRIANS = HIGHWAYS_PEDESTRIANS;\n static DEFAULT_WAY_SELECTOR = DEFAULT_WAY_SELECTOR;\n\n getVertexByCoords(coords: Coordinates) {\n return GeoGraph.getVertexByCoords(this.vertices, coords) as OsmVertex | undefined;\n }\n\n getVertexByName(name: string) {\n return super.getVertexByName(name) as OsmVertex | undefined;\n }\n\n getEdgeByName(name: string) {\n return super.getEdgeByName(name) as OsmEdge | undefined;\n }\n\n static fromOsmModel(osmModel: OsmModel, waySelectionFilter = DEFAULT_WAY_SELECTOR) {\n\n const nodes: OsmVertex[] = [];\n const edges: OsmEdge[] = [];\n\n const nodesCreated: { [key: number]: OsmVertex } = {};\n const elevatorNodes: OsmVertex[] = [];\n\n const getOrCreateNode = (osmNode: OsmNode) => {\n let node = nodesCreated[osmNode.id];\n if (!node) {\n node = new GeoGraphVertex(osmNode.coords, { data: osmNode, name: osmNode.tags.name }) as OsmVertex;\n nodesCreated[osmNode.id] = node;\n nodes.push(node);\n\n if (osmNode.tags.highway === 'elevator') {\n elevatorNodes.push(node);\n }\n }\n return node;\n };\n\n osmModel.ways.forEach(way => {\n if (!waySelectionFilter(way)) {\n return;\n }\n\n let firstNode = getOrCreateNode(way.nodes[0]);\n for (let i = 1; i < way.nodes.length; i++) {\n const secondNode = getOrCreateNode(way.nodes[i]);\n\n const edge = new GeoGraphEdge(firstNode, secondNode,\n { data: way, name: way.tags.name, level: way.level }\n ) as OsmEdge;\n OsmGraph.manageOneWay(edge, way);\n edges.push(edge);\n firstNode = secondNode;\n }\n\n });\n\n osmModel.ways\n .filter(way => way.isElevator)\n .forEach(way => {\n way.nodes.forEach(node => {\n const connectedWays = node.ways.filter(otherWay => otherWay != way);\n if (connectedWays.length) {\n const graphVertex = getOrCreateNode(node);\n graphVertex.data.tags.highway = 'elevator';\n elevatorNodes.push(graphVertex);\n }\n })\n });\n\n elevatorNodes.forEach(node => {\n // We have to clone this node for each connected edge\n OsmGraph.createNodesAndEdgesFromElevator(nodes, edges, node);\n });\n\n return new OsmGraph(nodes, edges, true);\n }\n\n\n\n private static manageOneWay(edge: OsmEdge, way: OsmWay) {\n\n const { highway, oneway, conveying } = way.tags;\n\n edge.isOneway = Boolean((oneway === 'yes' || oneway === 'true' || oneway === '1')\n || (conveying && highway && ['forward', 'backward'].includes(conveying)));\n\n if (edge.isOneway && conveying === 'backward') {\n const tmpNode = edge.vertex1;\n edge.vertex1 = edge.vertex2;\n edge.vertex2 = tmpNode;\n }\n }\n\n\n private static createNodesAndEdgesFromElevator(\n nodes: OsmVertex[],\n edges: OsmEdge[],\n elevatorNode: OsmVertex\n ) {\n\n const createdNodes: OsmVertex[] = [];\n const getOrCreateLevelVertex = (level: number | null) => {\n let levelVertex = createdNodes.find(({ coords }) => Level.equals(level, coords.level));\n if (!levelVertex) {\n levelVertex = new GeoGraphVertex(elevatorNode.coords.clone(), {\n data: elevatorNode.data,\n name: `${elevatorNode.name} (elevator lvl: ${level})`\n }) as OsmVertex;\n levelVertex.coords.level = level;\n createdNodes.push(levelVertex);\n nodes.push(levelVertex);\n }\n return levelVertex;\n };\n\n // Create nodes from node.edges\n elevatorNode.edges.forEach(edge => {\n if (Level.isRange(edge.level)) {\n throw new Error('Cannot handle this elevator edge due to ambiguity');\n }\n\n const levelVertex = getOrCreateLevelVertex(edge.level);\n if (edge.vertex1 === elevatorNode) {\n edge.vertex1 = levelVertex;\n } else {\n edge.vertex2 = levelVertex;\n }\n levelVertex.edges.push(edge);\n });\n\n // Create edges from createdNodes\n for (let i = 0; i < createdNodes.length; i++) {\n for (let j = i + 1; j < createdNodes.length; j++) {\n\n const createdNode1 = createdNodes[i];\n const createdNode2 = createdNodes[j];\n\n if (createdNode1.coords.level === null || createdNode2.coords.level === null) {\n // TODO: not the best approach... but cannot do better with [number, number] range for levels\n continue;\n }\n\n const minLevel = Math.min(createdNode1.coords.level as number, createdNode2.coords.level as number);\n const maxLevel = Math.max(createdNode1.coords.level as number, createdNode2.coords.level as number);\n\n const newEdge = new GeoGraphEdge<OsmVertexData, OsmEdgeData>(\n createdNode1,\n createdNode2,\n { data: elevatorNode.data, name: elevatorNode.name, level: [minLevel, maxLevel] }\n ) as OsmEdge;\n edges.push(newEdge);\n }\n }\n\n // Remove the historical elevator node from the network\n const elevatorNodeIndex = nodes.indexOf(elevatorNode);\n if (elevatorNodeIndex > -1) {\n nodes.splice(elevatorNodeIndex, 1);\n }\n }\n\n}","import salesman from '@wemap/salesman.js';\n\nimport { Coordinates, GeoGraph, GeoGraphEdge, GeoGraphItinerary, GeoGraphRouter, GeoGraphRouterOptions } from '@wemap/geo';\nimport { diffAngle, rad2deg } from '@wemap/maths';\nimport { OsmWay } from '@wemap/osm';\n\nimport { StepsGenerationRules } from '../model/generateSteps.js';\nimport Itinerary from '../model/Itinerary.js';\nimport { LevelChangeType } from '../model/LevelChange.js';\nimport { getDurationFromLength } from '../Utils.js';\nimport OsmGraph, { OsmEdge, OsmEdgeData, OsmVertex, OsmVertexData } from './OsmGraph.js';\nimport Leg from '../model/Leg.js';\nimport { MinStepInfo } from '../model/Step.js';\n\n\nconst DEFAULT_OPTIONS = Object.assign({}, GeoGraphRouter.DEFAULT_OPTIONS, {\n weightEdgeFn: (edge: OsmEdge) => {\n if (edge.data.isElevator) {\n return 90;\n }\n let duration = getDurationFromLength(edge.length, 4);\n if (edge.data instanceof OsmWay && edge.data.areStairs) {\n duration *= 3;\n }\n return duration;\n },\n acceptEdgeFn: (edge: GeoGraphEdge) => {\n const accessTag = (edge as OsmEdge).data.tags.access;\n return typeof accessTag === 'undefined' || accessTag === 'yes';\n }\n});\n\nconst WITHOUT_STAIRS_OPTIONS = Object.assign({}, DEFAULT_OPTIONS, {\n acceptEdgeFn: (edge: GeoGraphEdge) => (edge as OsmEdge).data.tags.highway !== 'steps'\n});\n\nexport type GeoGraphTripRouterOptions<VertexData = unknown, EdgeData = unknown> =\n GeoGraphRouterOptions<VertexData, EdgeData> & {\n tspTempCoeff?: number; // https://github.com/wemap/salesman.js/blob/master/salesman.js#L164\n };\n\nconst DEFAULT_TRIP_OPTIONS = Object.assign({}, {\n tspTempCoeff: 0.99\n}, GeoGraphRouter.DEFAULT_OPTIONS);\n\n\nconst buildStepsRules = (graphItinerary: OsmItinerary): StepsGenerationRules => (\n currentCoords: Coordinates,\n nextCoords: Coordinates,\n previousStep: MinStepInfo | null\n) => {\n const edges = graphItinerary.edges;\n const vertices = graphItinerary.vertices;\n const vertex = GeoGraph.getVertexByCoords(vertices, currentCoords);\n const nextVertex = GeoGraph.getVertexByCoords(vertices, nextCoords);\n if (!vertex || !nextVertex) return {};\n const edge = GeoGraphEdge.getEdgeByVertices(edges, vertex, nextVertex) as OsmEdge | undefined;\n if (!edge) return {};\n const edgeId = edges.findIndex(_edge => _edge === edge) as number;\n\n const isSubwayEntrance = vertex ? vertex.data?.tags.railway === 'subway_entrance' : false;\n const isGate = vertex ? (vertex.data?.tags.barrier === 'gate' || vertex.data?.tags.aeroway === 'gate') : false;\n\n let levelChangeType: LevelChangeType | null = null;\n if (edge.data.isElevator) {\n levelChangeType = 'elevator';\n } else if (edge.data.isConveying) {\n levelChangeType = 'conveyor';\n } else if (edge.data instanceof OsmWay && edge.data.areStairs) {\n levelChangeType = 'stairs';\n }\n\n // Handle stairs/elevator/conveyors without change in level coordinates\n let forceLevelChange: 'up' | 'down' | undefined;\n const edgeTags = edge.data.tags || {};\n if (\n edge.data instanceof OsmWay\n && edge.data.areStairs\n && ['up', 'down'].includes(edgeTags.incline)\n && !previousStep?.levelChange\n ) {\n forceLevelChange = edgeTags.incline as 'up' | 'down';\n for (const n of edge.data.nodes) {\n if (n !== vertex.data) continue;\n }\n const isReversed = edge.data.nodes.reduce((acc: boolean | null, n, idx, arr) => {\n if (n !== vertex.data) return acc;\n acc = !(idx + 1 < arr.length && arr[idx + 1] === nextVertex.data);\n return acc;\n }, null);\n if (isReversed) {\n forceLevelChange = forceLevelChange === 'up' ? 'down' : 'up';\n }\n }\n\n const previousEdge = edgeId > 0 && edges.length ? edges[edgeId - 1] : null;\n const previousEdgeTags = previousEdge?.data.tags || {};\n const forceEndOfLevelChange = Boolean(\n previousEdge && previousEdge.data instanceof OsmWay && ['up', 'down'].includes(previousEdgeTags.incline) && previousEdge.data.areStairs\n && edge.data instanceof OsmWay && (!['up', 'down'].includes(edgeTags.incline) || !edge.data.areStairs));\n const createNewStep = isSubwayEntrance;\n\n return {\n createNewStep,\n stepName: edge.data?.tags.name,\n duration: graphItinerary.edgesWeights[edgeId],\n stepExtras: {\n ...(isSubwayEntrance && { isSubwayEntrance: true }),\n ...(isSubwayEntrance && vertex.data?.tags.ref && { subwayEntranceRef: vertex.data.tags.ref }),\n ...(isGate && { isGate: true })\n },\n ...(levelChangeType && { levelChangeType }),\n ...(forceLevelChange && { forceLevelChange }),\n ...(forceEndOfLevelChange && { forceEndOfLevelChange })\n };\n};\n\n// export type OsmItinerary = GeoGraphItinerary<OsmVertexData, OsmEdgeData>;\n\nexport class OsmItinerary extends GeoGraphItinerary<OsmVertexData, OsmEdgeData> {\n // declare vertices: OsmVertex[]; // Cannot use OsmVertex due to null data of projection\n declare edges: OsmEdge[];\n}\n\nclass WemapOsmRouter extends GeoGraphRouter<OsmVertexData, OsmEdgeData> {\n\n static DEFAULT_OPTIONS = DEFAULT_OPTIONS;\n static WITHOUT_STAIRS_OPTIONS = WITHOUT_STAIRS_OPTIONS;\n\n constructor(graph: OsmGraph) {\n super(graph);\n }\n\n static get rname() {\n return 'wemap-osm';\n }\n\n getShortestPath(\n start: OsmVertex | Coordinates,\n end: OsmVertex | Coordinates,\n options: GeoGraphRouterOptions<OsmVertexData, OsmEdgeData> = DEFAULT_OPTIONS\n ) {\n return super.getShortestPath(start, end, options) as OsmItinerary;\n }\n\n getItinerary(\n start: OsmVertex | Coordinates,\n end: OsmVertex | Coordinates,\n options: GeoGraphRouterOptions<OsmVertexData, OsmEdgeData> = DEFAULT_OPTIONS\n ) {\n const graphItinerary = this.getShortestPath(start, end, options);\n\n // Transform a network itinerary (vertices, edges...) to a router itinerary (legs, steps...)\n return Itinerary.fromGraphItinerary(graphItinerary, 'WALK', buildStepsRules(graphItinerary))\n }\n\n\n static 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 }\n\n getShortestTrip(\n waypoints: Coordinates[],\n options: GeoGraphTripRouterOptions<OsmVertexData, OsmEdgeData> = DEFAULT_TRIP_OPTIONS\n ) {\n type CustomPoint = salesman.Point & { coords: Coordinates };\n\n const points = waypoints.map(waypoint => {\n const point = new salesman.Point(0, 0) as CustomPoint;\n point.coords = waypoint;\n return point;\n });\n const cache: OsmItinerary[] = [];\n const solution = salesman.solve(points, options.tspTempCoeff, undefined, (p: salesman.Point, q: salesman.Point) => {\n // Throw an error if no path found\n const osmItinerary = this.getShortestPath(\n (p as CustomPoint).coords,\n (q as CustomPoint).coords,\n options\n );\n cache.push(osmItinerary);\n return osmItinerary.edgesWeights.reduce((acc, weight) => acc + weight, 0);\n });\n\n const orderedPoints = solution.map(i => points[i]);\n const orderedItineraries = [];\n for (let i = 0; i < orderedPoints.length; i++) {\n const p = orderedPoints[i] as CustomPoint;\n const q = orderedPoints[(i + 1) % orderedPoints.length] as CustomPoint;\n let cachedItinerary = cache.find(itinerary => itinerary.start === p.coords && itinerary.end === q.coords || itinerary.end === p.coords && itinerary.start === q.coords) as OsmItinerary;\n if (cachedItinerary.end === p.coords) {\n // Need to revert itinerary due to salesman bijectivity\n cachedItinerary = GeoGraphItinerary.fromGraphVertices(\n cachedItinerary.end,\n cachedItinerary.start,\n cachedItinerary.vertices.reverse(),\n cachedItinerary.edgesWeights\n ) as OsmItinerary;\n }\n\n orderedItineraries.push(cachedItinerary);\n }\n return orderedItineraries;\n }\n\n getTripItinerary(\n waypoints: Coordinates[],\n options: GeoGraphTripRouterOptions<OsmVertexData, OsmEdgeData> = DEFAULT_TRIP_OPTIONS\n ) {\n const shortestTrip = this.getShortestTrip(waypoints, options);\n return new Itinerary({\n from: shortestTrip[0].start,\n to: shortestTrip[shortestTrip.length - 1].end,\n legs: shortestTrip.map(graphItinerary => Leg.fromGraphItinerary(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 { MinStepInfo } from '../../model/Step.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() { return 'cityway' as const; }\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 minStepsInfo: MinStepInfo[];\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 minStepsInfo = [];\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 minStepsInfo.push({\n coords: stepCoords[0],\n distance: jsonPathLink.Distance,\n name: jsonPathLink.Departure.Site.Name\n });\n }\n\n // If it's last leg, create a last step because cityway doesn't use the end of itinerary as step\n if (jsonSection === trip.sections.Section[trip.sections.Section.length - 1]) {\n minStepsInfo.push({\n coords: legCoords[legCoords.length - 1]\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 minStepsInfo = [{\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 minStepsInfo\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() { return 'deutsche-bahn' as const; }\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, { TransportInfo } 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 { MinStepInfo } from '../../model/Step.js';\nimport { RemoteRouterOptions } from '../RemoteRouterOptions.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() { return 'idfm' as const; }\n\n /**\n * @throws {IdfmRemoteRouterTokenError}\n * @throws {RemoteRouterServerUnreachable}\n */\n async getItineraries(endpointUrl: string, mode: RoutingMode, waypoints: Coordinates[], options: RemoteRouterOptions = {}) {\n const url = this.getURL(endpointUrl, mode, waypoints, options);\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[], options: RemoteRouterOptions) {\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 url = new URL(endpointUrl);\n\n const coreParams = new URLSearchParams();\n coreParams.set('from', `${waypoints[0].longitude};${waypoints[0].latitude}`);\n coreParams.set('to', `${waypoints[1].longitude};${waypoints[1].latitude}`);\n\n if ('useStairs' in options && !options.useStairs) {\n coreParams.set('wheelchair', 'true')\n }\n\n let queryParams: URLSearchParams = new URLSearchParams();\n switch (mode) {\n case 'WALK':\n queryParams = this.getWalkingQuery();\n break;\n case 'BIKE':\n queryParams = this.getBikeQuery();\n break;\n case 'CAR':\n queryParams = this.getCarQuery();\n break;\n default:\n break;\n }\n\n [coreParams, queryParams].map(params => {\n for (const pair of params.entries()) {\n url.searchParams.append(pair[0], pair[1]);\n }\n });\n\n return url.toString();\n }\n\n getCarQuery() {\n const urlSearchParams = new URLSearchParams();\n\n TRANSPORT_IDS.forEach((id) => {\n urlSearchParams.append('forbidden_uris[]', id);\n });\n\n urlSearchParams.append('first_section_mode[]', 'walking');\n urlSearchParams.append('first_section_mode[]', 'car');\n urlSearchParams.append('last_section_mode[]', 'walking');\n urlSearchParams.append('last_section_mode[]', 'car');\n\n return urlSearchParams;\n }\n\n getWalkingQuery() {\n const urlSearchParams = new URLSearchParams();\n\n TRANSPORT_IDS.forEach((id) => {\n urlSearchParams.append('forbidden_uris[]', id);\n });\n\n urlSearchParams.append('first_section_mode[]', 'walking');\n urlSearchParams.append('last_section_mode[]', 'walking');\n\n return urlSearchParams;\n }\n\n getBikeQuery() {\n const urlSearchParams = new URLSearchParams();\n\n TRANSPORT_IDS.forEach((id) => {\n urlSearchParams.append('forbidden_uris[]', id);\n });\n\n urlSearchParams.append('first_section_mode[]', 'bike');\n urlSearchParams.append('last_section_mode[]', 'bike');\n\n return urlSearchParams;\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({\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 minStepsInfo: MinStepInfo[] | undefined;\n let transportInfo: TransportInfo | undefined;\n let mode = routingModeCorrespondance.get(jsonSection.mode) as RoutingMode;\n\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 minStepsInfo = this.findStepsCoord(legCoords, idfmIntermediateSteps);\n }\n\n if (jsonSection.type === 'public_transport') {\n 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 mode = routingModeCorrespondance.get(jsonSection.display_informations.physical_mode) as RoutingMode;\n\n const legStep: MinStepInfo = {\n coords: legCoords[0],\n name: transportInfo.directionName,\n distance: jsonSection.geojson.properties[0].length\n };\n minStepsInfo = [legStep];\n }\n\n const leg = new Leg({\n mode,\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 transportInfo,\n minStepsInfo\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';\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\ntype OsrmMode = 'driving' | 'walking' | 'bike' | 'bus' | 'walking';\n\n/**\n * Input mode correspondance\n */\nconst inputModeCorrespondance = new Map<RoutingMode, OsrmMode>();\ninputModeCorrespondance.set('CAR', 'driving');\ninputModeCorrespondance.set('WALK', 'walking');\ninputModeCorrespondance.set('BIKE', 'bike');\ninputModeCorrespondance.set('BUS', 'bus');\ninputModeCorrespondance.set('MULTI', 'walking');\n\n/**\n * Singleton.\n */\nclass OsrmRemoteRouter extends RemoteRouter {\n\n /**\n * @override\n */\n get rname() { return 'osrm' as const; }\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\n const osrmMode = inputModeCorrespondance.get(mode);\n\n return this.createRouterResponseFromJson(jsonResponse, from, to, osrmMode);\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: OsrmMode = '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 minStepsInfo = 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 {\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 minStepsInfo\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';\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() { return 'otp' as const; }\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 minStepsInfo;\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 minStepsInfo = [{\n coords: legCoords[0],\n name: jsonLeg.headsign\n }];\n\n } else {\n\n minStepsInfo = 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 {\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 minStepsInfo\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 WemapMultiRemoteRouterPayloadJson = {\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(): WemapMultiRemoteRouterPayloadJson {\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: WemapMultiRemoteRouterPayloadJson) {\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() { return 'wemap-multi' as const; }\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\nconst remoteRouters = [\n CitywayRemoteRouter,\n DeutscheBahnRemoteRouter,\n IdfmRemoteRouter,\n OsrmRemoteRouter,\n OtpRemoteRouter,\n WemapMultiRemoteRouter\n] as const;\n\nexport type RemoteRouterName = typeof remoteRouters[number]['rname'];\n\n/**\n * Singleton\n */\nclass RemoteRouterManager {\n\n getRouterByName(name: RemoteRouterName): RemoteRouter {\n return remoteRouters.find(remoteRouter => remoteRouter.rname === name) as RemoteRouter;\n }\n\n /**\n * @throws {RemoteRouterServerUnreachable}\n * @throws {RoutingModeCorrespondanceNotFound}\n * @throws {IdfmRemoteRouterTokenError}\n */\n async getItineraries(\n name: RemoteRouterName,\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: RemoteRouterName, 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, GeoGraphRouterOptions } 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 RouterResponse from '../model/RouterResponse.js';\nimport WemapOsmRouter, { GeoGraphTripRouterOptions } from '../wemap-osm/OsmRouter.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-multi';\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 private getIoMapsFromOptions(options: WemapMultiRouterOptions | null) {\n\n let ioMapsToTest = this.maps;\n const targetMaps = options?.targetMaps;\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 return ioMapsToTest;\n }\n\n private convertOptionsToWemapOsmOptions(options: WemapMultiRouterOptions | null) {\n // Create WemapOsmRouterOptions from WemapMultiRouterOptions\n const outputOptions : GeoGraphRouterOptions | GeoGraphTripRouterOptions\n = !options || !('useStairs' in options) || options.useStairs\n ? WemapOsmRouter.DEFAULT_OPTIONS\n : WemapOsmRouter.WITHOUT_STAIRS_OPTIONS;\n\n if(typeof options?.tspTempCoeff !== 'undefined') {\n (outputOptions as any).tspTempCoeff = options.tspTempCoeff;\n }\n return outputOptions;\n\n }\n\n async getTrip(mode: RoutingMode, waypoints: Coordinates[], options: WemapMultiRouterOptions | null = null) {\n const ioMapsToTest = this.getIoMapsFromOptions(options);\n if (waypoints.length < 2) {\n throw Error(`Cannot retrieve a trip itinerary. Two points or more are necessary`);\n }\n\n if (mode !== 'WALK') {\n throw Error(`Cannot calculate trip itinerary for mode \"${mode}\". Only \"WALK\" is implemented.`);\n }\n\n // Retrieve the map which embed all the waypoints\n const mapOfWaypoints = waypoints.reduce((map, waypoint) => {\n const mapOfThisWaypoint = ioMapsToTest.find(map => map.isPointInside(waypoint));\n if (!mapOfThisWaypoint) {\n throw Error(`Cannot find a network for this trip waypoint (${waypoint.toString()}). Outdoor trips are not implemented.`)\n }\n if (map && mapOfThisWaypoint !== map) {\n throw Error(`Cannot handle this trip, because two waypoints are on different maps (${mapOfThisWaypoint} and ${mapOfWaypoints}). ` +\n `Multi-map trips are not implemented.`)\n }\n return mapOfThisWaypoint\n }, null as CustomNetworkMap | null);\n\n // Create WemapOsmRouterOptions from WemapMultiRouterOptions\n const wemapOsmRouterOptions = this.convertOptionsToWemapOsmOptions(options);\n\n const tripItinerary = mapOfWaypoints!.getTripInsideMap(waypoints, wemapOsmRouterOptions);\n\n return new RouterResponse({\n routerName: this.rname,\n from: tripItinerary.from,\n to: tripItinerary.to,\n itineraries: [tripItinerary]\n });\n }\n\n async getItineraries(mode: RoutingMode, waypoints: Coordinates[], options: WemapMultiRouterOptions | null = null) {\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 const ioMapsToTest = this.getIoMapsFromOptions(options);\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 = this.convertOptionsToWemapOsmOptions(options);\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 { Position, MultiPolygon } from '@turf/helpers';\n\nimport { Coordinates, GeoGraphRouterOptions, Level, NoRouteFoundError } from '@wemap/geo';\nimport { OsmParser } from '@wemap/osm';\n\nimport OsmGraph, { OsmVertex } from '../wemap-osm/OsmGraph.js';\nimport WemapOsmRouter from '../wemap-osm/OsmRouter.js';\n\nclass CustomNetworkMap {\n\n name: string | null;\n graph: OsmGraph;\n router: WemapOsmRouter;\n bounds: MultiPolygon;\n entryPoints: OsmVertex[];\n disabledWays = new Set<number>();\n\n constructor(\n graph: OsmGraph,\n entryPoints: OsmVertex[],\n bounds: MultiPolygon | null = null,\n name: string | null = null) {\n\n this.name = name;\n this.graph = graph;\n this.router = new WemapOsmRouter(graph);\n\n // Entry points\n entryPoints.forEach(entryPoint => {\n if (!graph.vertices.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 = bounds;\n } else {\n const polygon = [graph.vertices.map(vertex => [vertex.coords.lng, vertex.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 = {\n type: 'MultiPolygon',\n coordinates: [convexHull.geometry.coordinates]\n };\n }\n }\n\n\n static fromOsmXml(osmXmlString: string, name: string | null = null) {\n\n const osmModel = OsmParser.parseOsmXmlString(osmXmlString);\n const graph = OsmGraph.fromOsmModel(osmModel);\n\n const entryPoints = graph.vertices.filter(({ data: { tags } }) => tags && tags['wemap:routing-io']);\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 bounds: MultiPolygon = {\n type: 'MultiPolygon',\n coordinates: []\n };\n osmModel.ways\n .filter(({ tags }) => tags['wemap:routing-bounds'])\n .forEach(way => {\n bounds.coordinates.push([way.nodes.reduce((acc, node) => {\n acc.push([node.coords.lng, node.coords.lat]);\n return acc;\n }, [] as Position[])\n ]);\n });\n osmModel.relations\n .filter(rel => rel.tags['wemap:routing-bounds'] && rel.isMultipolygon())\n .forEach(rel => {\n const polygon = rel.getGeoJsonPolygon();\n polygon && bounds.coordinates.push(polygon.coordinates);\n });\n\n if (!bounds.coordinates.length) {\n throw new Error('Search bounds is undefined. Please use OSM tag : \"wemap:routing-bounds=yes\"');\n }\n return new CustomNetworkMap(graph, 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 const levelDiffFactor = 50; // in meters\n return entryPointsCopy.sort((ep1, ep2) => {\n\n const distance2D = Number(ep1.coords.distanceTo(start)) + ep1.coords.distanceTo(end)\n - (ep2.coords.distanceTo(start) + ep2.coords.distanceTo(end))\n \n const levelDiffEp1Start = Math.abs(Level.diff(start.level, ep1.coords.level) || 0);\n const levelDiffEp1End = Math.abs(Level.diff(end.level, ep1.coords.level) || 0);\n const levelDiffEp2Start = Math.abs(Level.diff(start.level, ep2.coords.level) || 0);\n const levelDiffEp2End = Math.abs(Level.diff(end.level, ep2.coords.level) || 0);\n const levelDiff = levelDiffEp1Start + levelDiffEp1End - (levelDiffEp2Start + levelDiffEp2End);\n \n return distance2D + levelDiff * levelDiffFactor;\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: GeoGraphRouterOptions) {\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: GeoGraphRouterOptions) {\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: GeoGraphRouterOptions) {\n // Call the Wemap router to get the shortest path\n return this.router.getItinerary(start, end, options);\n }\n\n getTripInsideMap(waypoints: Coordinates[], options: GeoGraphRouterOptions) {\n // Call the Wemap router to get the shortest trip itinerary\n return this.router.getTripItinerary(waypoints, options);\n }\n\n enableWay(osmId: number) {\n this.graph.edges\n .filter(edge => edge.data.id === osmId)\n .forEach(e => this.router.disabledEdges.delete(e));\n this.disabledWays.delete(osmId);\n }\n\n disableWay(osmId: number) {\n this.graph.edges\n .filter(edge => edge.data.id === osmId)\n .forEach(e => this.router.disabledEdges.add(e));\n this.disabledWays.add(osmId);\n }\n}\n\nexport default CustomNetworkMap;\n","import { Coordinates, GeoGraphEdge, GeoGraphProjection, GeoGraphProjectionHandler, GeoGraphVertex } 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: GeoGraphProjection<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 _geoGraphProjectionHandler: GeoGraphProjectionHandler | 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 graph = itinerary.toGraph();\n this._geoGraphProjectionHandler = new GeoGraphProjectionHandler(graph);\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._geoGraphProjectionHandler) {\n return null;\n }\n\n const projection = this._geoGraphProjectionHandler.getProjection(position);\n if (!projection) {\n return null;\n }\n\n let itineraryInfo: ItineraryInfo<U> | null = null;\n\n if (projection.nearestElement instanceof GeoGraphVertex) {\n const idx = this._itinerary.coords.findIndex(\n coords => (projection.nearestElement as GeoGraphVertex).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 GeoGraphEdge) {\n\n let firstNode = projection.nearestElement.vertex1.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.vertex2.coords\n ) {\n firstNode = projection.nearestElement.vertex2.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":["deg2rad","Level","diffAngle","Coordinates","GeoUtils","GeoGraph","GeoGraphVertex","GeoGraphEdge","GeoGraphRouter","OsmWay","rad2deg","salesman","GeoGraphItinerary","NoRouteFoundError","jsonToCoordinates","inputModeCorrespondance","routingModeCorrespondance","Logger","positiveMod","Polyline","CitywayRemoteRouter","DeutscheBahnRemoteRouter","IdfmRemoteRouter","OsrmRemoteRouter","OtpRemoteRouter","WemapMultiRemoteRouter","remoteRouters","map","RemoteRouterManager","convexHullFn","OsmParser","pointInPolygon","GeoGraphProjectionHandler"],"mappings":"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"}
|