@wemap/routers 12.2.0 → 12.3.0

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.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/model/RouterRequest.ts","../src/graph/Edge.ts","../src/graph/GraphProjection.ts","../src/graph/Vertex.ts","../src/graph/Graph.ts","../src/Utils.ts","../src/model/TransitMode.ts","../src/model/Step.ts","../src/graph/GraphRoute.ts","../src/model/StepsBuilder.ts","../src/model/Leg.ts","../src/model/Itinerary.ts","../src/graph/GraphRouterOptionsBuilder.ts","../src/graph/GraphRouterEngine.ts","../src/graph/GraphRouter.ts","../src/graph/NoRouteFoundError.ts","../src/wemap-osm/OsmGraphUtils.ts","../src/remote/RemoteRouter.ts","../src/StatusCode.ts","../src/RoutingError.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/WemapMultiRemoteRouter.ts","../src/remote/RemoteRouterManager.ts","../src/wemap-multi/WemapMultiRouter.ts","../src/wemap-multi/CustomNetworkMap.ts","../src/ItineraryInfoManager.ts"],"sourcesContent":["import { Coordinates } from \"@wemap/geo\"\n\nimport { TravelMode, TravelModePreference } from \"./TravelMode\"\n\nexport type RouterRequest = {\n origin: Coordinates,\n destination: Coordinates,\n travelMode: TravelMode,\n travelModePreference?: TravelModePreference,\n provideItineraryAlternatives?: boolean,\n waypoints?: Coordinates[],\n optimizeWaypoints?: boolean,\n itineraryModifiers?: {\n avoidStairs?: boolean,\n avoidEscalators?: boolean,\n avoidElevator?: boolean,\n avoidMovingWalkway?: boolean,\n avoidTicketRestrictedAreas?: boolean\n }\n output?: {\n distanceAndDurationOnly?: boolean\n }\n}\n\nexport function routerRequestToJson(routerRequest: RouterRequest) {\n const { origin, destination, waypoints, ...rest } = routerRequest;\n return {\n origin: origin.toJson(),\n destination: destination.toJson(),\n ...(waypoints && { waypoints: waypoints.map(w => w.toJson()) }),\n ...rest\n }\n}","import { Level, type Level_t } from '@wemap/geo';\n\nimport Vertex from './Vertex.js';\n\nexport type EdgeProperties = {\n \n name?: string;\n externalId?: string | number;\n\n isOneway?: boolean;\n areStairs?: boolean;\n isElevator?: boolean;\n areEscalators?: boolean;\n isMovingWalkway?: boolean;\n needTicket?: boolean;\n incline?: 'up' | 'down';\n}\n\n/**\n * An Edge is a segment composed of two Vertex\n * An edge is mostly issued from an OsmWay, but this is not always the case.\n * For example, edges created by mapmatching.\n */\nexport default class Edge {\n\n static currentUniqueId = 0;\n public readonly id = Edge.currentUniqueId++;\n\n public readonly level: Level_t;\n\n /** Edge bearing from vertex1 to vertex2 */\n public readonly bearing: number;\n public readonly length: number;\n\n constructor(\n public vertex1: Vertex,\n public vertex2: Vertex,\n public properties: EdgeProperties = {}\n ) {\n this.level = Level.union(vertex1.coords.level, vertex2.coords.level)\n this.length = this.vertex1.distanceTo(this.vertex2);\n this.bearing = this.vertex1.bearingTo(this.vertex2);\n }\n\n static getEdgeByVertices(\n edges: Edge[],\n vertex1: Vertex,\n vertex2: Vertex\n ) {\n return edges.find(edge => vertex1 === edge.vertex1 && vertex2 === edge.vertex2\n || vertex2 === edge.vertex1 && vertex1 === edge.vertex2\n );\n }\n\n reverseProperties() {\n const { properties } = this;\n if (properties.incline) {\n properties.incline = properties.incline === 'up' ? 'down' : 'up';\n }\n if (properties.isOneway) {\n properties.isOneway = false;\n }\n }\n}\n","import { Coordinates, UserPosition } from '@wemap/geo';\n\nimport Edge from './Edge.js';\nimport Vertex from './Vertex.js';\n\nclass GraphProjection<U extends Coordinates | UserPosition = Coordinates> {\n constructor(\n public readonly origin: U,\n public readonly distanceFromNearestElement: number,\n public readonly coords: U,\n public readonly nearestElement: Vertex | Edge\n ) { }\n}\n\nexport default GraphProjection;\n","import { Coordinates } from '@wemap/geo';\n\nimport { GraphVertexJson } from '../types.js';\n\nexport type VertexProperties = {\n\n name?: string;\n externalId?: string | number;\n\n isGate?: boolean;\n isSubwayEntrance?: boolean;\n subwayEntranceRef?: string;\n}\n\nexport default class Vertex {\n\n public id = -1;\n\n constructor(public coords: Coordinates, public properties: VertexProperties = {}) { }\n\n distanceTo(other: Vertex) {\n return this.coords.distanceTo(other.coords);\n }\n\n bearingTo(other: Vertex) {\n return this.coords.bearingTo(other.coords);\n }\n\n toJson(): GraphVertexJson {\n return this.coords.toCompressedJson();\n }\n\n static fromJson(json: GraphVertexJson) {\n return new Vertex(Coordinates.fromCompressedJson(json));\n }\n}\n","import { diffAngleLines } from '@wemap/maths';\nimport { BoundingBox, Coordinates, Level, UserPosition, Level_t, Constants as GeoConstants } from '@wemap/geo';\n\nimport Edge from './Edge.js';\nimport GraphProjection from './GraphProjection.js';\nimport Vertex from './Vertex.js';\nimport { type GeoGraphJson } from '../types.js';\nimport { type GraphProjectionOptions } from './GraphProjectionOptions.js';\n\n\nclass Graph {\n\n /**\n * exitVertices are vertices that have at least one indoor edge and one outdoor edge\n * They are stored because the Level model cannot handle an indoor and outdoor state like [null, 1] or [null, [1,2]]\n * This vertices are used to cover the projection case:\n * - if projection origin is null, an exit vertex can be used\n * - if projection origin is not null, the intersection level with an exit vertex can be used\n */\n public readonly exitVertices: Set<Vertex>;\n\n constructor(public readonly vertices: Vertex[], public readonly edges: Edge[]) {\n const nullVertices = edges.filter(e => e.level === null).map(e => [e.vertex1, e.vertex2]).flat();\n const levelVertices = edges.filter(e => e.level !== null).map(e => [e.vertex1, e.vertex2]).flat();\n this.exitVertices = new Set(nullVertices.filter(v1 => levelVertices.includes(v1)));\n }\n\n getEdgeByVertices(vertex1: Vertex, vertex2: Vertex) {\n return Edge.getEdgeByVertices(this.edges, vertex1, vertex2);\n }\n\n getVertexByCoords(coords: Coordinates) {\n return Graph.getVertexByCoords(this.vertices, coords);\n }\n\n static getVertexByCoords(vertices: Vertex[], coords: Coordinates) {\n return vertices.find(vertex => vertex.coords.equals(coords));\n }\n\n getVertexByName(name: string) {\n return this.vertices.find(vertex => vertex.properties.name === name);\n }\n\n getEdgeByName(name: string) {\n return this.edges.find(edge => edge.properties.name === name);\n }\n\n getBoundingBox(extendedMeasure?: number) {\n if (!this.vertices.length) {\n return null;\n }\n const boundingBox = BoundingBox.fromCoordinates(this.vertices.map(vertex => vertex.coords)) as BoundingBox;\n if (extendedMeasure) {\n boundingBox.extendsWithMeasure(extendedMeasure);\n }\n return boundingBox;\n }\n\n getProjection<U extends (Coordinates | UserPosition)>(\n origin: U,\n options: GraphProjectionOptions = {}\n ): GraphProjection<U> | null {\n\n const useMaxDistance = 'maxDistance' in options;\n const maxDistance = options.maxDistance!\n\n const useMaxBearingAngle = 'maxBearingAngle' in options;\n if (useMaxBearingAngle && (!(origin instanceof UserPosition) || origin.bearing === null)) return null;\n const maxBearingAngle = options.maxBearingAngle!;\n\n const useAcceptEdgeFn = 'acceptEdgeFn' in options;\n\n const useMultiLevelSegments = !('useMultiLevelSegments' in options) || options.useMultiLevelSegments;\n\n let bestProjection: GraphProjection | null = null;\n\n this.edges.forEach(edge => {\n\n if (useAcceptEdgeFn && !options.acceptEdgeFn!(edge)) return;\n if (!useMultiLevelSegments && Level.isRange(edge.level)) return;\n if (!Level.intersect(edge.level, origin.level)) return;\n\n if (useMaxBearingAngle) {\n // Do not try to project if angle is greater than the threshold\n if (diffAngleLines(edge.bearing, (origin as UserPosition).bearing!) > maxBearingAngle) return;\n }\n\n const segmentProjection = origin.getSegmentProjection(edge.vertex1.coords, edge.vertex2.coords);\n if (!segmentProjection) return;\n const distanceToSegment = segmentProjection.distanceTo(origin);\n\n if (useMaxDistance && distanceToSegment > maxDistance) return;\n\n if (distanceToSegment < (bestProjection?.distanceFromNearestElement ?? Number.MAX_VALUE)) {\n bestProjection = new GraphProjection(origin, distanceToSegment, segmentProjection, edge);\n }\n });\n\n // if mapmatching bearing is enabled do not use vertices matching\n if (useMaxBearingAngle) {\n return bestProjection;\n }\n\n this.vertices.forEach(vertex => {\n let vertexCoords = vertex.coords;\n\n // Specific case of io nodes that have a non-null level but can be matched to a null origin level\n if (this.exitVertices.has(vertex) && origin.level === null) {\n vertexCoords = vertex.coords.clone();\n vertexCoords.level = null;\n }\n\n if (!useMultiLevelSegments && Level.isRange(vertexCoords.level)) return;\n if (!Level.intersect(vertexCoords.level, origin.level)) return;\n\n const distanceToVertex = vertexCoords.distanceTo(origin);\n\n // If distance below epsilon consider it as best projection\n if (distanceToVertex < GeoConstants.EPS_MM) {\n bestProjection = new GraphProjection(origin, 0, vertexCoords, vertex);\n return;\n }\n\n if (useMaxDistance && distanceToVertex > maxDistance) return;\n\n if (distanceToVertex < (bestProjection?.distanceFromNearestElement ?? Number.MAX_VALUE)) {\n bestProjection = new GraphProjection(origin, distanceToVertex, vertexCoords, vertex);\n }\n });\n\n return bestProjection;\n }\n\n\n toCompressedJson(): GeoGraphJson {\n return {\n vertices: this.vertices.map(vertex => vertex.toJson()),\n verticesIds: this.vertices.map(vertex => vertex.id),\n edges: this.edges.map(edge => {\n const vertex1Idx = this.vertices.indexOf(edge.vertex1);\n const vertex2Idx = this.vertices.indexOf(edge.vertex2);\n const edgeExtras = edge.properties;\n if (Object.keys(edgeExtras).length > 0) {\n return [vertex1Idx, vertex2Idx, edgeExtras];\n }\n return [vertex1Idx, vertex2Idx];\n })\n };\n }\n\n\n static fromCompressedJson(json: GeoGraphJson) {\n\n const vertices = json.vertices.map(vertex => Vertex.fromJson(vertex));\n const edges = json.edges.map(jsonEdge => new Edge(\n vertices[jsonEdge[0]],\n vertices[jsonEdge[1]],\n jsonEdge.length > 2 ? jsonEdge[2] : {}\n ));\n\n return new Graph(vertices, edges);\n }\n\n\n static fromCoordinatesSegments(segments: Coordinates[][]) {\n\n const vertices: Vertex[] = [];\n const edges: Edge[] = [];\n\n const getOrCreateVertex = (coords: Coordinates) => {\n const vertex = vertices.find(otherVertex => otherVertex.coords.equals(coords));\n if (vertex) {\n return vertex;\n }\n const newVertex = new Vertex(coords);\n vertices.push(newVertex);\n return newVertex;\n };\n\n for (const segment of segments) {\n\n let previousVertex = null;\n for (const coords of segment) {\n const currentVertex = getOrCreateVertex(coords);\n\n if (previousVertex) {\n edges.push(new Edge(currentVertex, previousVertex));\n }\n\n previousVertex = currentVertex;\n }\n }\n\n return new Graph(vertices, edges);\n }\n\n /**\n * Create edges From MultiLevel Itinerary for a given level\n * @param useMultiLevelEdges use segments which intersect both levels (stairs, elevators...)\n */\n getEdgesAtLevel(targetLevel: Level_t, useMultiLevelEdges = true) {\n return this.edges.filter(\n ({ level }) => useMultiLevelEdges\n ? Level.intersect(targetLevel, level)\n : Level.contains(targetLevel, level)\n );\n }\n\n\n toDetailedString() {\n let output\n = '--- Network ---\\n'\n + `Vertices: ${this.vertices.length}\\n`\n + `Edges: ${this.edges.length}\\n`\n + '---\\n'\n + 'Vertices\\n';\n this.vertices.forEach(vertex => {\n output += vertex.id;\n const vertexProps = vertex.properties;\n if (Object.keys(vertexProps).length !== 0) { output += ` ${vertexProps}` }\n });\n output += '---\\n'\n + 'Edges\\n';\n this.edges.forEach(edge => {\n output += `${edge.id} - [v1: ${edge.vertex1.id}, v2: ${edge.vertex2.id}]`;\n const edgeProps = edge.properties;\n if (Object.keys(edgeProps).length !== 0) { output += ` ${edgeProps}` }\n });\n output += '---';\n return output;\n }\n}\n\nexport default Graph;\n","/**\n * Get route duration\n * @param {Number} speed in km/h\n * @returns {Number} duration in seconds\n */\nexport function getDurationFromLength(length: number, speed = 5) {\n return length / (speed * 1000 / 3600);\n}\n","export type TransitMode = '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 isTransitModePublicTransport(routingMode: TransitMode): 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 { Coordinates } from '@wemap/geo';\n\nimport Graph from \"./Graph.js\";\nimport Edge from './Edge.js';\nimport Vertex from './Vertex.js';\nimport { getDurationFromLength } from '../Utils.js';\n\n\n/**\n * GraphRoute is an oriented graph\n */\nclass GraphRoute extends Graph {\n constructor(\n public start: Coordinates,\n public end: Coordinates,\n public vertices: Vertex[],\n public edges: Edge[],\n public edgesWeights: number[]\n ) {\n super(vertices, edges);\n }\n\n // /!\\ Does not clone vertices\n // /!\\ Create new Edges but does not deep clone properties\n // /!\\ Does not revert edge oneway property\n reverse() {\n const vertices = this.vertices.slice().reverse();\n const edges = this.edges.slice().reverse();\n const edgesWeights = this.edgesWeights.slice().reverse();\n edges.map(oldEdge => new Edge(oldEdge.vertex2, oldEdge.vertex1, oldEdge.properties));\n return new GraphRoute(this.start, this.end, vertices, edges, edgesWeights);\n }\n\n static fromCoordinates(start: Coordinates, end: Coordinates, coordinates: Coordinates[]) {\n const graph = Graph.fromCoordinatesSegments([coordinates]);\n const edgesWeights = graph.edges.map(e => getDurationFromLength(e.length));\n return new GraphRoute(start, end, graph.vertices, graph.edges, edgesWeights);\n }\n\n get hasRoute() { return Boolean(this.edges.length) }\n}\n\nexport default GraphRoute;\n","import { Coordinates, Level } from '@wemap/geo';\nimport Logger from '@wemap/logger';\nimport { diffAngle, deg2rad } from '@wemap/maths';\n\nimport { type LevelChange, type LevelChangeType } from './LevelChange.js';\nimport { type Step, type MinStepInfo } from './Step.js';\nimport { getDurationFromLength } from '../Utils.js';\nimport GraphRoute from '../graph/GraphRoute.js';\n\nconst SKIP_STEP_ANGLE_MAX = deg2rad(20);\n\nexport default class StepsBuilder {\n\n private start: Coordinates | null = null;\n private end: Coordinates | null = null;\n private pathCoords: Coordinates[] | null = null;\n private stepsInfo: MinStepInfo[] = [];\n\n setStart(start: Coordinates) {\n this.start = start;\n return this;\n }\n\n setEnd(end: Coordinates) {\n this.end = end;\n return this;\n }\n\n setPathCoords(pathCoords: Coordinates[]) {\n this.pathCoords = pathCoords;\n return this;\n }\n\n setStepsInfo(stepsInfo: MinStepInfo[]) {\n this.stepsInfo = stepsInfo;\n return this;\n }\n\n addStepInfo(stepInfo: MinStepInfo) {\n this.stepsInfo.push(stepInfo);\n return this;\n }\n\n setGraphRoute(graphRoute: GraphRoute) {\n\n const stepsInfo: MinStepInfo[] = [];\n\n const { start, end } = graphRoute;\n\n if (!graphRoute.hasRoute) { return this; }\n\n let currentStep: MinStepInfo | null = null;\n let previousBearing = start.bearingTo(graphRoute.vertices[0].coords);\n\n for (let i = 0; i < graphRoute.vertices.length - 1; i++) {\n\n const isFirstStep = i === 0;\n\n const vertex = graphRoute.vertices[i];\n const currentCoords = vertex.coords;\n const nextVertex = graphRoute.vertices[i + 1];\n const nextCoords = nextVertex.coords;\n\n const edge = graphRoute.edges[i];\n\n const nextBearing = vertex.bearingTo(nextVertex);\n const angle = diffAngle(previousBearing, nextBearing + Math.PI);\n\n const previousStep = stepsInfo.length ? stepsInfo[stepsInfo.length - 1] : null;\n\n const { isSubwayEntrance, isGate, subwayEntranceRef } = vertex.properties;\n const { isElevator, areEscalators, areStairs, isMovingWalkway, incline } = edge.properties;\n\n let levelChangeType: LevelChangeType | null = null;\n if (isElevator) {\n levelChangeType = 'elevator';\n } else if (areEscalators) {\n levelChangeType = 'escalator';\n } else if (areStairs) {\n levelChangeType = 'stairs';\n } else if (isMovingWalkway) {\n levelChangeType = 'moving walkway';\n }\n\n // Handle stairs/elevators/escalators/moving walkway without change in level coordinates\n let forceLevelChange: 'up' | 'down' | undefined;\n if (\n (areStairs || isElevator)\n && incline\n && !previousStep?.levelChange\n ) {\n forceLevelChange = incline;\n }\n\n const previousEdge = i > 0 ? graphRoute.edges[i - 1] : null;\n const previousEdgeProperties = previousEdge?.properties || {};\n const forceEndOfLevelChange = Boolean(\n previousEdgeProperties.incline && previousEdgeProperties.areStairs\n && (!incline || !areStairs)\n );\n const createNewStep = vertex.properties.isSubwayEntrance;\n\n const stepName = edge.properties.name || null;\n const duration = graphRoute.edgesWeights[i];\n const stepExtras = {\n ...(isSubwayEntrance && { isSubwayEntrance }),\n ...(subwayEntranceRef && { subwayEntranceRef }),\n ...(isGate && { isGate })\n };\n\n let splitByAngle = Math.abs(diffAngle(Math.PI, angle)) >= SKIP_STEP_ANGLE_MAX;\n\n const splitByLevel = Level.isRange(edge.level) && !Level.isRange(currentCoords.level) || forceLevelChange;\n splitByAngle = splitByAngle && !(currentCoords.level && Level.isRange(currentCoords.level));\n\n\n const splitByEndOfLevelChange = previousStep?.levelChange && !Level.isRange(currentCoords.level)\n || forceEndOfLevelChange;\n\n const splitStepCondition = splitByAngle || splitByLevel || splitByEndOfLevelChange || 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 (forceLevelChange) {\n direction = forceLevelChange;\n }\n levelChange = {\n difference, direction, ...(levelChangeType && { type: levelChangeType })\n };\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 ...(stepName && { name: stepName }),\n extras: stepExtras,\n levelChange,\n distance: 0,\n duration: 0\n };\n\n stepsInfo.push(currentStep);\n }\n\n currentStep!.distance! += currentCoords.distanceTo(nextCoords);\n if (duration) {\n currentStep!.duration! += duration;\n }\n previousBearing = nextBearing;\n }\n\n const lastCoords = graphRoute.vertices[graphRoute.vertices.length - 1].coords;\n\n // Create a last step if end is not on the graph\n if (!Coordinates.equals(lastCoords, end)) {\n stepsInfo.push({ coords: lastCoords });\n }\n\n this.setStart(start);\n this.setEnd(end);\n this.setPathCoords(graphRoute.vertices.map(v => v.coords));\n this.setStepsInfo(stepsInfo);\n\n return this;\n }\n\n build(): Step[] {\n\n const { pathCoords, start, end } = this;\n\n if (!pathCoords) {\n Logger.warn(`StepsBuilder: Missing \"pathCoords\" property to build steps`);\n return [];\n }\n\n if (!start) {\n Logger.warn(`StepsBuilder: Missing \"from\" property to build steps`);\n return [];\n }\n\n if (!end) {\n Logger.warn(`StepsBuilder: Missing \"to\" property to build steps`);\n return [];\n }\n\n if (this.stepsInfo.length === 0) {\n // If there is no steps info, steps coordinates are calculated using our steps calculation algorithm above.\n this.setGraphRoute(GraphRoute.fromCoordinates(start, end, pathCoords));\n }\n\n const { stepsInfo } = this;\n\n return stepsInfo.map((stepInfo, stepId) => {\n const coordsId = pathCoords.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 ? start : pathCoords[coordsId - 1];\n const coordsAfterStep = coordsId === pathCoords.length - 1\n ? end\n : pathCoords[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 : pathCoords[pathCoords.length - 1];\n let currentCoordsId = coordsId;\n while (!pathCoords[currentCoordsId].equals(coordsToStopCalculation)) {\n distance += pathCoords[currentCoordsId].distanceTo(pathCoords[currentCoordsId + 1]);\n currentCoordsId++;\n }\n if (currentCoordsId === pathCoords.length - 1) {\n distance += pathCoords[currentCoordsId].distanceTo(end);\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}\n","import {\n Coordinates, CoordinatesCompressedJson, Level, Utils as GeoUtils\n} from '@wemap/geo';\n\nimport Graph from '../graph/Graph.js';\nimport GraphRoute from '../graph/GraphRoute.js';\nimport { getDurationFromLength } from '../Utils.js';\nimport { TransitMode, isTransitModePublicTransport } from './TransitMode.js';\n\nimport { jsonToStep, Step, stepEquals, StepJson, stepToJson } from './Step.js'\nimport StepsBuilder from './StepsBuilder.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 transitMode: TransitMode,\n startTime?: number,\n endTime?: number,\n transportInfo?: TransportInfo,\n}\n\ntype LegConstructor =\n {\n start: DestinationConstructor,\n end: DestinationConstructor,\n coords: Coordinates[],\n steps?: Step[],\n duration?: number\n }\n & LegCommon;\n\nexport type LegJson = {\n start: DestinationJson,\n end: DestinationJson,\n coords: CoordinatesCompressedJson[],\n steps: StepJson[],\n distance: number,\n duration: number\n} & LegCommon;\n\nexport default class Leg {\n\n start: Destination;\n end: Destination;\n coords: Coordinates[];\n distance: number;\n transitMode: TransitMode;\n\n duration: number;\n startTime: number | null;\n endTime: number | null;\n\n steps: Step[];\n transportInfo: TransportInfo | null;\n\n constructor({\n start, end, coords, transitMode, duration,\n startTime, endTime, transportInfo, steps\n }: LegConstructor) {\n this.start = {\n name: start.name || null,\n coords: start.coords\n };\n this.end = {\n name: end.name || null,\n coords: end.coords\n };\n this.coords = coords;\n this.transitMode = transitMode;\n this.distance = GeoUtils.calcDistance(coords)\n this.duration = typeof duration === 'number' ? duration : getDurationFromLength(this.distance);\n this.startTime = typeof startTime === 'number' ? startTime : null;\n this.endTime = typeof endTime === 'number' ? endTime : null;\n this.transportInfo = transportInfo || null;\n this.steps = Array.isArray(steps)\n ? steps\n : new StepsBuilder().setStart(start.coords).setEnd(end.coords).setPathCoords(coords).build();\n }\n\n isPublicTransport() {\n return isTransitModePublicTransport(this.transitMode);\n }\n\n toGraph() {\n return Graph.fromCoordinatesSegments([this.coords]);\n }\n\n static equals(obj1: Leg, obj2: Leg) {\n const intermediate = obj1.transitMode === obj2.transitMode\n && Math.abs(obj1.duration - obj2.duration) <= 0.05\n && obj1.startTime === obj2.startTime\n && obj1.endTime === obj2.endTime\n && obj1.start.name === obj2.start.name\n && obj1.start.coords.equals(obj2.start.coords)\n && obj1.end.name === obj2.end.name\n && obj1.end.coords.equals(obj2.end.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 transitMode: this.transitMode,\n start: {\n coords: this.start.coords.toCompressedJson(),\n ...(this.start.name && { name: this.start.name }),\n },\n end: {\n coords: this.end.coords.toCompressedJson(),\n ...(this.end.name && { name: this.end.name }),\n },\n distance: Number(this.distance.toFixed(1)),\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 start: {\n coords: Coordinates.fromCompressedJson(json.start.coords),\n name: json.start.name || null\n },\n end: {\n coords: Coordinates.fromCompressedJson(json.end.coords),\n name: json.end.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 static fromGraphRoute(\n graphRoute: GraphRoute,\n transitMode: TransitMode = 'WALK'\n ) {\n return new Leg({\n start: { coords: graphRoute.start },\n end: { coords: graphRoute.end },\n coords: graphRoute.vertices.map(vertex => vertex.coords),\n duration: graphRoute.edgesWeights.reduce((acc, weight) => acc + weight, 0),\n transitMode,\n steps: new StepsBuilder().setGraphRoute(graphRoute).build()\n });\n }\n\n // TODO: Remove when possible...\n // Livemap specific\n multiplyLevel(levelFactor: number) {\n this.start.coords.level = Level.multiplyBy(this.start.coords.level, levelFactor);\n this.end.coords.level = Level.multiplyBy(this.end.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","import { Feature, FeatureCollection, MultiLineString, Point } from 'geojson';\nimport { Coordinates, Level, Utils as GeoUtils, CoordinatesJson, Level_t } from '@wemap/geo';\nimport { diffAngle, Point2_t, Vector3_t } from '@wemap/maths';\n\nimport Graph from '../graph/Graph.js';\nimport Leg, { type LegJson } from './Leg.js';\nimport { isTransitModePublicTransport, type TransitMode } from './TransitMode.js';\nimport { Step } from './Step.js';\nimport { getDurationFromLength } from '../Utils.js';\nimport StepsBuilder from './StepsBuilder.js';\nimport GraphRoute from '../graph/GraphRoute.js';\n\n\nexport type ItineraryCommon = {\n startTime?: number,\n endTime?: number\n};\n\nexport type ItineraryJson = {\n transitMode: TransitMode,\n origin: CoordinatesJson,\n destination: CoordinatesJson,\n distance: number,\n duration: number,\n legs: LegJson[]\n} & ItineraryCommon;\n\n\nexport type ItineraryConstructor = {\n origin: Coordinates,\n destination: 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 origin: Coordinates;\n destination: Coordinates;\n duration: number;\n readonly legs: Leg[];\n\n private _transitMode: TransitMode | 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 origin, destination, duration, legs, startTime, endTime\n }: ItineraryConstructor) {\n this.origin = origin;\n this.destination = destination;\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 transitMode(_) {\n throw new Error('Itinerary.mode cannot be set. They are calculated from Itinerary.legs.');\n }\n\n get transitMode() {\n if (!this._transitMode) {\n let isPublicTransport = false;\n let isBicycle = false;\n let isDriving = false;\n\n this.legs.forEach((leg) => {\n isPublicTransport = isPublicTransport || isTransitModePublicTransport(leg.transitMode);\n isBicycle = isBicycle || leg.transitMode === 'BIKE';\n isDriving = isDriving || leg.transitMode === 'CAR';\n });\n\n if (isPublicTransport) {\n this._transitMode = 'MULTI';\n } else if (isDriving) {\n this._transitMode = 'CAR';\n } else if (isBicycle) {\n this._transitMode = 'BIKE';\n } else {\n this._transitMode = 'WALK';\n }\n }\n\n return this._transitMode;\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 Graph.fromCoordinatesSegments([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 origin: itineraries[0].origin,\n destination: itineraries[itineraries.length - 1].destination,\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 origin: Coordinates,\n destination: Coordinates,\n transitMode: TransitMode = 'WALK'\n ) {\n\n const steps = new StepsBuilder().setPathCoords(coords).setStart(origin).setEnd(destination).build();\n\n const leg = new Leg({\n start: { coords: origin },\n end: { coords: destination },\n coords,\n transitMode,\n steps\n });\n\n return new Itinerary({ origin, destination, legs: [leg] });\n }\n\n\n static equals(obj1: Itinerary, obj2: Itinerary) {\n const intermediate = obj1.origin.equals(obj2.origin)\n && obj1.destination.equals(obj2.destination)\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 origin: this.origin.toJson(),\n destination: this.destination.toJson(),\n distance: Number(this.distance.toFixed(1)),\n duration: Number(this.duration.toFixed(1)),\n transitMode: this.transitMode,\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 origin: Coordinates.fromJson(json.origin),\n destination: Coordinates.fromJson(json.destination),\n duration: json.duration,\n legs: json.legs.map(Leg.fromJson),\n startTime: json.startTime,\n endTime: json.endTime\n });\n }\n\n static fromGraphRoute(graphRoute: GraphRoute, transitMode: TransitMode = 'WALK') {\n const leg = Leg.fromGraphRoute(graphRoute, transitMode);\n return new Itinerary({\n origin: graphRoute.start,\n destination: graphRoute.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.origin.level = Level.multiplyBy(this.origin.level, levelFactor);\n this.destination.level = Level.multiplyBy(this.destination.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.origin.level = this.origin.level || 0;\n this.destination.level = this.destination.level || 0;\n\n for (const leg of this.legs) {\n leg.start.coords.level = leg.start.coords.level || 0;\n leg.end.coords.level = leg.end.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(): FeatureCollection {\n const transformToPoint = (point: Coordinates, name?: string, type?: string): Feature<Point> => ({\n type: \"Feature\",\n properties: { name, level: point.level, ...(type && { type }) },\n geometry: {\n type: 'Point',\n coordinates: [point.lng, point.lat]\n }\n });\n const transformToMultiLineStrings = (segments: Coordinates[][], level: Level_t): Feature<MultiLineString> => ({\n type: \"Feature\",\n properties: { level, name: level?.toString() },\n geometry: {\n type: 'MultiLineString',\n coordinates: segments.map(s => s.map(({ lat, lng }) => [lng, lat]))\n }\n });\n\n const levelsOfItinerary = [...new Set(this.coords.map(c => Level.toString(c.level)))].map(Level.fromString);\n const segmentsSplitted: [Level_t, Coordinates[][]][] = levelsOfItinerary.map(loi => [loi, GeoUtils.createSegmentsAtLevel(this.coords, loi, true)]);\n const multiLineStrings = segmentsSplitted.map(([loi, segments]) => transformToMultiLineStrings(segments, loi))\n const legsStarts = this.legs.map((leg, idx) => transformToPoint(leg.start.coords, `Leg ${idx} start`, 'leg-start'));\n const legsEnds = this.legs.map((leg, idx) => transformToPoint(leg.end.coords, `Leg ${idx} end`, 'leg-end'));\n const steps = this.steps.map(step => transformToPoint(step.coords, `Step ${step.number}`, 'step'))\n return {\n type: \"FeatureCollection\",\n features: [\n transformToPoint(this.origin, 'origin', 'origin'),\n transformToPoint(this.destination, 'destination', 'destination'),\n ...multiLineStrings,\n ...legsStarts,\n ...legsEnds,\n ...steps\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.origin : itineraryCoords[coordsId - 1];\n const coordsAfterStep = coordsId === itineraryCoords.length - 1\n ? this.destination\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.destination);\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 Edge from './Edge.js';\nimport { getDurationFromLength } from '../Utils.js';\nimport { GraphRouterOptionsJson, type GraphRouterOptions } from './GraphRouterOptions.js';\n\nexport default class GraphRouterOptionsBuilder {\n\n public avoidStairs = false;\n public avoidEscalators = false;\n public avoidElevators = false;\n public avoidMovingWalkway = false;\n public avoidTicketRestrictedAreas = false;\n\n public projectionMaxDistance?: number;\n\n static DEFAULT = new GraphRouterOptionsBuilder().build();\n static WITHOUT_STAIRS = new GraphRouterOptionsBuilder().setAvoidStairs(true).build();\n\n setAvoidStairs(avoidStairs: boolean) {\n this.avoidStairs = avoidStairs;\n return this;\n }\n\n setAvoidEscalators(avoidEscalators: boolean) {\n this.avoidEscalators = avoidEscalators;\n return this;\n }\n\n setAvoidElevators(avoidElevators: boolean) {\n this.avoidElevators = avoidElevators;\n return this;\n }\n\n setAvoidMovingWalkway(avoidMovingWalkway: boolean) {\n this.avoidMovingWalkway = avoidMovingWalkway;\n return this;\n }\n\n setAvoidTicketRestrictedAreas(avoidTicketRestrictedAreas: boolean) {\n this.avoidTicketRestrictedAreas = avoidTicketRestrictedAreas;\n return this;\n }\n\n static fromJson(options: GraphRouterOptionsJson) {\n const builder = new GraphRouterOptionsBuilder();\n Object.assign(builder, options);\n return builder.build();\n }\n\n build(): GraphRouterOptions {\n\n const weightEdgeFn = (edge: Edge) => {\n if (edge.properties.isElevator) {\n return 90;\n }\n let duration = getDurationFromLength(edge.length, 4);\n if (edge.properties.areStairs) {\n duration *= 3;\n }\n return duration;\n }\n\n const acceptEdgeFn = (edge: Edge) => {\n\n if (this.avoidStairs && edge.properties.areStairs) return false;\n if (this.avoidEscalators && edge.properties.areEscalators) return false;\n if (this.avoidElevators && edge.properties.isElevator) return false;\n if (this.avoidMovingWalkway && edge.properties.isMovingWalkway) return false;\n if (this.avoidTicketRestrictedAreas && edge.properties.needTicket) return false;\n\n return true;\n };\n\n return {\n input: {\n avoidStairs: this.avoidStairs,\n avoidEscalators: this.avoidEscalators,\n avoidElevators: this.avoidElevators,\n avoidMovingWalkway: this.avoidMovingWalkway,\n avoidTicketRestrictedAreas: this.avoidTicketRestrictedAreas,\n projectionMaxDistance: this.projectionMaxDistance\n },\n weightEdgeFn,\n acceptEdgeFn,\n projectionMaxDistance: this.projectionMaxDistance\n };\n }\n\n}\n","\nimport Edge from './Edge.js';\nimport Graph from './Graph.js';\nimport GraphRoute from './GraphRoute.js';\nimport { type GraphRouterOptions } from './GraphRouterOptions.js';\nimport GraphRouterOptionsBuilder from './GraphRouterOptionsBuilder.js';\nimport Vertex from './Vertex.js';\n\nexport class GraphRouterEngineResults {\n constructor(\n public prev: Array<Vertex | null>,\n public dist: number[],\n public source: Vertex,\n public targets: Vertex[],\n public edges: Edge[]\n ) { }\n\n routeVertices(to = this.targets[0], list: Vertex[] = []): Vertex[] {\n const last = this.prev[to.id];\n if (last === null) return this.source === to ? [...list, to] : [];\n return [...this.routeVertices(last, list), to];\n }\n\n weightedDistance(to = this.targets[0]) {\n const distance = this.dist[to.id];\n return distance === Number.MAX_VALUE ? null : distance;\n }\n\n route(to = this.targets[0]) {\n\n const path = this.routeVertices(to);\n\n const edges = [];\n const edgesWeights = [];\n for (let i = 1; i < path.length; i++) {\n const v1 = path[i - 1];\n const v2 = path[i];\n const graphEdge = Edge.getEdgeByVertices(this.edges, v1, v2)!;\n const clonedEdge = new Edge(v1, v2, Object.assign({}, graphEdge.properties));\n const isReversed = graphEdge.vertex1 === clonedEdge.vertex2;\n if (isReversed) {\n clonedEdge.reverseProperties();\n }\n edges.push(clonedEdge);\n edgesWeights.push(this.dist[v2.id] - this.dist[v1.id]);\n }\n return new GraphRoute(this.source.coords, to.coords, path, edges, edgesWeights);\n }\n\n toGeoJson(graph: Graph) {\n return {\n type: \"FeatureCollection\",\n features: [\n ...graph.vertices.map(v => {\n const prev = this.prev[v.id];\n const dist = this.dist[v.id];\n const isSource = v === this.source;\n const isTarget = this.targets.includes(v);\n const level = v.coords.level;\n return {\n type: \"Feature\",\n properties: {\n id: v.id,\n ...(prev && { prev: prev.id }),\n dist: dist === Number.MAX_VALUE ? 'infinity' : dist,\n ...(isSource && { name: 'source' }),\n ...(isTarget && { name: 'target' }),\n ...(level !== null && { level }),\n ...v.properties\n },\n geometry: {\n type: 'Point',\n coordinates: [v.coords.lng, v.coords.lat]\n }\n }\n }),\n ...graph.edges.map(e => {\n const level = e.level;\n return {\n type: \"Feature\",\n properties: {\n id: e.id,\n ...(level !== null && { level }),\n ...e.properties\n },\n geometry: {\n type: 'LineString',\n coordinates: [\n [e.vertex1.coords.lng, e.vertex1.coords.lat],\n [e.vertex2.coords.lng, e.vertex2.coords.lat]\n ]\n }\n }\n })\n ]\n };\n }\n}\n\nexport default class GraphRouterEngine {\n\n disabledEdges: Set<Edge> = new Set();\n\n constructor(public readonly graph: Graph) {\n let vertexId = 0;\n graph.vertices.forEach(vertex => vertex.id = vertexId++);\n }\n\n calculateShortestPathToMultipleDestinationsByVertex(\n source: Vertex,\n targets: Vertex[],\n options: GraphRouterOptions = GraphRouterOptionsBuilder.DEFAULT,\n inputVertices = this.graph.vertices,\n inputEdges = this.graph.edges\n ): GraphRouterEngineResults {\n\n const q = new Set(inputVertices);\n const dist = Array(q.size).fill(Number.MAX_VALUE);\n const prev = new Array<Vertex | null>(q.size).fill(null);\n const edges = inputEdges.filter(e => (options.acceptEdgeFn?.(e) ?? true) && !this.disabledEdges.has(e));\n const weightEdgeFn = options.weightEdgeFn || ((edge: Edge) => edge.length);\n\n const getVertexWithMinDistance = (vertices: Set<Vertex>): Vertex | null => {\n let minDistance = Number.MAX_VALUE;\n let vertex: Vertex | null = null;\n vertices.forEach(_vertex => {\n const distance = dist[_vertex.id];\n if (distance <= minDistance) {\n minDistance = distance;\n vertex = _vertex;\n }\n });\n return vertex;\n }\n\n\n const remainingNodesToFind = new Set(targets);\n\n dist[source.id] = 0;\n\n while (q.size > 0) {\n const u = getVertexWithMinDistance(q)!;\n q.delete(u);\n\n if (targets.includes(u)) {\n remainingNodesToFind.delete(u);\n if (remainingNodesToFind.size === 0) {\n break;\n }\n }\n\n edges\n .filter(edge => edge.vertex1 == u || !edge.properties.isOneway && edge.vertex2 == u)\n .forEach(edge => {\n const v = u === edge.vertex1 ? edge.vertex2 : edge.vertex1;\n const distance = weightEdgeFn(edge);\n const alt = dist[u.id] + distance;\n if (alt < dist[v.id]) {\n dist[v.id] = alt;\n prev[v.id] = u\n }\n });\n }\n\n return new GraphRouterEngineResults(prev, dist, source, targets, edges);\n }\n\n calculateShortestPathByVertex(\n source: Vertex,\n target: Vertex,\n options: GraphRouterOptions = GraphRouterOptionsBuilder.DEFAULT,\n inputVertices = this.graph.vertices,\n inputEdges = this.graph.edges\n ): GraphRouterEngineResults {\n return this.calculateShortestPathToMultipleDestinationsByVertex(source, [target], options, inputVertices, inputEdges);\n }\n\n // https://en.wikipedia.org/wiki/Component_(graph_theory)\n calculateComponents() {\n\n function shiftSet<T>(set: Set<T>): T {\n const firstValue = set.values().next().value as T;\n set.delete(firstValue);\n return firstValue;\n }\n\n const verticesToTest = new Set<Vertex>(this.graph.vertices);\n let components: Vertex[][] = [];\n\n while (verticesToTest.size > 0) {\n const vertexToTest = shiftSet(verticesToTest);\n const otherVertices = this.graph.vertices.filter(v => v.id !== vertexToTest.id);\n const result = this.calculateShortestPathToMultipleDestinationsByVertex(vertexToTest, otherVertices);\n const reachedVertices = otherVertices.filter(ov => result.weightedDistance(ov) !== null);\n\n components.push([vertexToTest, ...reachedVertices]);\n reachedVertices.forEach(rv => verticesToTest.delete(rv));\n }\n\n // As graph is ordered, fuse components with same vertices\n for (let i = 0; i < components.length - 1; i++) {\n const component1 = components[i];\n for (let j = i + 1; j < components.length; j++) {\n const component2 = components[j];\n const componentsIntersect = component2.some(v => component1.includes(v));\n if (componentsIntersect) {\n component1.push(...component2);\n components = components.filter(component => component !== component2);\n }\n }\n }\n\n return components.map(c => [... new Set(c)]);\n }\n\n}\n","import salesman from '@wemap/salesman.js';\n\nimport { Coordinates } from '@wemap/geo';\n\nimport Vertex from './Vertex.js';\nimport Edge, { EdgeProperties } from './Edge.js';\nimport GraphRoute from './GraphRoute.js';\nimport GraphRouterEngine, { GraphRouterEngineResults } from './GraphRouterEngine.js';\nimport { type GraphRouterOptions } from './GraphRouterOptions.js';\nimport GraphRouterOptionsBuilder from './GraphRouterOptionsBuilder.js';\n\nexport class GraphRouterResults extends GraphRouterEngineResults {\n\n constructor(\n engineResults: GraphRouterEngineResults,\n public sourceProjection: [Coordinates, Vertex | null],\n public targetsProjections: [Coordinates, Vertex | null][]\n\n ) {\n super(engineResults.prev, engineResults.dist, engineResults.source, engineResults.targets, engineResults.edges);\n }\n\n static createEmpty(source: Coordinates, targets: Coordinates[]) {\n const length = targets.length;\n const engineResults = new GraphRouterEngineResults(\n new Array(length).fill(null),\n new Array(length).fill(Number.MAX_VALUE),\n new Vertex(source),\n targets.map(target => new Vertex(target)),\n []\n );\n const sourceProjection: [Coordinates, null] = [source, null];\n const targetsProjections: [Coordinates, null][] = targets.map(target => [target, null]);\n return new GraphRouterResults(engineResults, sourceProjection, targetsProjections);\n }\n\n routeVertices(to: Coordinates | Vertex = this.targetsProjections[0][0]): Vertex[] {\n\n if (to instanceof Vertex) {\n return super.routeVertices(to);\n }\n\n const sourceVertex = this.sourceProjection[1];\n if (!sourceVertex) return [];\n\n const toVertex = this.targetsProjections.find(([coord]) => coord === to)?.[1];\n if (!toVertex) return [];\n\n return super.routeVertices(toVertex);\n }\n\n weightedDistance(to: Coordinates | Vertex = this.targetsProjections[0][0]) {\n\n if (to instanceof Vertex) {\n return super.weightedDistance(to);\n }\n\n const sourceVertex = this.sourceProjection[1];\n if (!sourceVertex) return null;\n\n const toVertex = this.targetsProjections.find(([coord]) => coord === to)?.[1];\n if (!toVertex) return null;\n\n return super.weightedDistance(toVertex);\n }\n\n route(to: Coordinates | Vertex = this.targetsProjections[0][0]) {\n\n if (to instanceof Vertex) {\n return super.route(to);\n }\n\n const toVertex = this.targetsProjections.find(([coord]) => coord === to)?.[1];\n if (!toVertex) return new GraphRoute(this.sourceProjection[0], to, [], [], []);\n\n const route = super.route(toVertex);\n route.start = this.sourceProjection[0];\n route.end = to;\n return route;\n }\n}\n\n\nclass GraphRouter extends GraphRouterEngine {\n\n calculateShortestPathToMultipleDestinations(\n source: Coordinates,\n targets: Coordinates[],\n options: GraphRouterOptions = GraphRouterOptionsBuilder.DEFAULT,\n ): GraphRouterResults {\n\n const createdVertices = new Set<Vertex>();\n const createdEdges = new Set<Edge>();\n const createdVerticesByOriginalEdges: [Edge, Vertex[]][] = []\n\n const projectionsOptions = {\n maxDistance: options.projectionMaxDistance,\n acceptEdgeFn: options.acceptEdgeFn\n };\n\n const getOrCreateVertex = (coords: Coordinates): Vertex | null => {\n const projection = this.graph.getProjection(coords, projectionsOptions);\n if (projection === null) return null;\n if (projection.nearestElement instanceof Vertex) {\n return projection.nearestElement;\n }\n if (projection.nearestElement instanceof Edge) {\n const edge = projection.nearestElement;\n const newVertex = new Vertex(projection.coords, {\n name: `proj on ${edge.properties.name || null} (tmp)`,\n ...(typeof edge.properties.externalId !== 'undefined' && { externalId: edge.properties.externalId })\n });\n newVertex.id = this.graph.vertices.length + createdVertices.size;\n const newEdgesOptions: EdgeProperties = {\n ...edge.properties,\n name: `splitted ${edge.properties.name || null} (tmp)`,\n ...(typeof edge.properties.externalId !== 'undefined' && { externalId: edge.properties.externalId })\n };\n const newEdge1 = new Edge(edge.vertex1, newVertex, newEdgesOptions);\n const newEdge2 = new Edge(newVertex, edge.vertex2, newEdgesOptions);\n\n createdVertices.add(newVertex);\n createdEdges.add(newEdge1);\n createdEdges.add(newEdge2);\n\n const createdVerticesByOriginalEdge = createdVerticesByOriginalEdges.find(p => p[0] === edge)\n if (!createdVerticesByOriginalEdge) {\n createdVerticesByOriginalEdges.push([edge, [newVertex]])\n } else {\n createdVerticesByOriginalEdge[1].push(newVertex);\n }\n return newVertex;\n }\n\n return null; // Should never happens\n }\n\n const sourceVertex = getOrCreateVertex(source);\n if (!sourceVertex) return GraphRouterResults.createEmpty(source, targets);\n\n const targetsProjections: [Coordinates, Vertex | null][] = targets.map(target => [target, getOrCreateVertex(target)]);\n const targetsVertices = targetsProjections.map(([, vertex]) => vertex).filter(p => p !== null) as Vertex[];\n\n // In some specific cases, more than one vertex is created from an original edge.\n // And this vertices need to be connected together.\n createdVerticesByOriginalEdges.filter(pair => pair[1].length >= 2);\n createdVerticesByOriginalEdges.forEach(([edge, vertices]) => {\n const newEdgesOptions: EdgeProperties = {\n ...edge.properties,\n name: `splitted ${edge.properties.name || null} (tmp)`,\n };\n for (let i = 0; i < vertices.length; i++) {\n const vertexA = vertices[i];\n const distVertexAVertex1 = vertexA.distanceTo(edge.vertex1)\n for (let j = i + 1; j < vertices.length; j++) {\n const vertexB = vertices[j];\n const distVertexBVertex1 = vertexA.distanceTo(edge.vertex1)\n const reverse = distVertexBVertex1 < distVertexAVertex1;\n const newEdge = !reverse\n ? new Edge(vertexA, vertexB, newEdgesOptions)\n : new Edge(vertexB, vertexA, newEdgesOptions);\n createdEdges.add(newEdge);\n }\n }\n })\n\n\n const engineResults = this.calculateShortestPathToMultipleDestinationsByVertex(\n sourceVertex, targetsVertices, options,\n [...this.graph.vertices, ...createdVertices],\n [...this.graph.edges, ...createdEdges],\n );\n\n return new GraphRouterResults(engineResults, [source, sourceVertex], targetsProjections);\n }\n\n calculateShortestPath(\n source: Coordinates,\n target: Coordinates,\n options: GraphRouterOptions = GraphRouterOptionsBuilder.DEFAULT,\n ): GraphRouterResults {\n return this.calculateShortestPathToMultipleDestinations(source, [target], options);\n }\n\n\n // TODO: Verify if it works well with oneway edges\n getShortestTrip(waypoints: Coordinates[], options?: GraphRouterOptions, tspTempCoeff = 0.99) {\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 graphRoutesCache: GraphRoute[] = [];\n const solution = salesman.solve(points, tspTempCoeff, undefined, (p: salesman.Point, q: salesman.Point) => {\n const route = this.calculateShortestPath(\n (p as CustomPoint).coords,\n (q as CustomPoint).coords,\n options\n ).route();\n graphRoutesCache.push(route);\n if (!route.hasRoute) { return Number.MAX_VALUE }\n return route.edgesWeights.reduce((acc, weight) => acc + weight, 0);\n });\n\n const orderedPoints = solution.map(i => points[i]);\n const orderedRoutes = [];\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 cachedRoute = graphRoutesCache.find(route => route.start === p.coords && route.end === q.coords || route.end === p.coords && route.start === q.coords);\n if (cachedRoute?.end === p.coords) {\n // Need to revert route due to salesman bijectivity\n cachedRoute = cachedRoute.reverse();\n }\n if (cachedRoute) {\n orderedRoutes.push(cachedRoute);\n }\n }\n\n if (orderedRoutes.some(route => !route.hasRoute)) return [];\n\n return orderedRoutes;\n }\n\n\n}\nexport default GraphRouter;\n","import { Coordinates } from '@wemap/geo';\n\nimport Vertex from './Vertex.js';\n\nclass NoRouteFoundError extends Error {\n\n constructor(\n public start: Vertex | Coordinates,\n public end: Vertex | Coordinates | (Coordinates | Vertex)[],\n public details: string | null = null\n ) { super(); }\n\n get startStr() {\n if (this.start instanceof Vertex) {\n return `Vertex ${this.start.coords.toString()}`;\n }\n return this.start.toString();\n }\n\n get endStr() {\n if (this.end instanceof Vertex) {\n return `Vertex ${this.end.coords.toString()}`;\n }\n if (Array.isArray(this.end)) {\n return this.end.map(p => p instanceof Vertex ? p.coords.toString() : p.toString()).join(',');\n }\n return this.end.toString();\n }\n\n get message() {\n let message = `No route found from ${this.startStr} to ${this.endStr}.`;\n if (this.details) {\n message += ` Details: ${this.details}`;\n }\n return message;\n }\n}\n\nexport default NoRouteFoundError;\n","import { Coordinates, Level, Level_t } from '@wemap/geo';\nimport { OsmModel, OsmNode, OsmWay } from '@wemap/osm';\n\nimport Graph from '../graph/Graph.js';\nimport { default as Edge, type EdgeProperties } from '../graph/Edge.js';\nimport { default as Vertex, type VertexProperties } from '../graph/Vertex.js';\n\n\nexport default class OsmGraphUtils {\n\n static RESTRICTED_PEDESTRIANS_HIGHWAYS = ['motorway', 'motorway_link'];\n\n static DEFAULT_WAY_SELECTOR = (way: OsmWay) => {\n if (way.isArea) return false;\n const isElevatorArea = way.tags.highway === 'elevator' && way.isGeometryClosed\n return way.tags.highway && !OsmGraphUtils.RESTRICTED_PEDESTRIANS_HIGHWAYS.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\n static parseNodeProperties(osmNode: OsmNode): VertexProperties {\n return {\n ...(osmNode.name && { name: osmNode.name }),\n ...(osmNode.id && { externalId: osmNode.id }),\n ...(osmNode.isGate && { isGate: osmNode.isGate }),\n ...(osmNode.isSubwayEntrance && { isSubwayEntrance: osmNode.isSubwayEntrance }),\n ...(osmNode.subwayEntranceRef && { subwayEntrsanceRef: osmNode.subwayEntranceRef })\n }\n }\n\n static parseWayProperties(osmWay: OsmWay): EdgeProperties {\n return {\n ...(osmWay.name && { name: osmWay.name }),\n ...(osmWay.id && { externalId: osmWay.id }),\n ...(osmWay.isOneway && { isOneway: osmWay.isOneway }),\n ...(osmWay.areStairs && { areStairs: osmWay.areStairs }),\n ...(osmWay.isElevator && { isElevator: osmWay.isElevator }),\n ...(osmWay.areEscalators && { areEscalators: osmWay.areEscalators }),\n ...(osmWay.isMovingWalkway && { isMovingWalkway: osmWay.isMovingWalkway }),\n ...(osmWay.needTicket && { needTicket: osmWay.needTicket }),\n ...(osmWay.incline && { incline: osmWay.incline })\n }\n }\n\n static createGraphFromOsmModel(\n osmModel: OsmModel,\n waySelectionFilter = OsmGraphUtils.DEFAULT_WAY_SELECTOR,\n callbackVerticesMapping?: (mapping: [nodeId: number, vertex: Vertex][]) => void\n ) {\n\n const edges: Edge[] = [];\n const verticesMapping: [nodeId: number, vertex: Vertex][] = [];\n const elevatorVertices: [id: number, name: string | undefined, vertices: Vertex[]][] = [];\n\n // 1. Create a function to retrieve a vertex which has already been created and avoid duplicates\n const getOrCreateVertex = (osmNode: OsmNode, nodeLevel: Level_t) => {\n\n // Check if a vertex with same coordinates already exists\n let vertex: Vertex | null = verticesMapping\n .find(([nodeId, v]) => {\n if (nodeId !== osmNode.id) return false;\n if (Level.intersect(v.coords.level, nodeLevel)) return true;\n // Specific case of exits\n return v.coords.level === null || nodeLevel === null;\n })?.[1] || null;\n\n // If the vertex already exists, return it\n if (vertex) {\n // In the case where vertices are linked to edges with level change\n if (!Level.equals(vertex.coords.level, nodeLevel)) {\n vertex.coords.level = Level.intersection(vertex.coords.level, nodeLevel);\n }\n return vertex;\n }\n\n // If it does not exist, create it\n const newCoords = new Coordinates(osmNode.coords.lat, osmNode.coords.lng, null, nodeLevel)\n vertex = new Vertex(newCoords, this.parseNodeProperties(osmNode));\n\n verticesMapping.push([osmNode.id, vertex]);\n\n if (osmNode.isElevator) {\n let elevatorEntry = elevatorVertices.find(([id]) => osmNode.id === id);\n if (!elevatorEntry) {\n elevatorEntry = [osmNode.id, osmNode.name, []];\n elevatorVertices.push(elevatorEntry);\n }\n elevatorEntry[2].push(vertex);\n }\n\n return vertex;\n };\n\n // 2. Go through OSM ways to create edges and vertices\n osmModel.ways.forEach(way => {\n if (!waySelectionFilter(way)) {\n return;\n }\n\n const edgeProperties = this.parseWayProperties(way);\n\n const processWayForLevel = (_level: Level_t) => {\n for (let i = 1; i < way.nodes.length; i++) {\n\n let firstVertex = getOrCreateVertex(way.nodes[i - 1], _level);\n let secondVertex = getOrCreateVertex(way.nodes[i], _level);\n\n if (way.isOnewayBackward) {\n const tmpVertex = secondVertex;\n secondVertex = firstVertex;\n firstVertex = tmpVertex;\n }\n\n const edge = new Edge(firstVertex, secondVertex, edgeProperties);\n edges.push(edge);\n }\n }\n\n processWayForLevel(way.level);\n if ('repeat_on' in way.tags) {\n way.tags.repeat_on.split(';').map(Level.fromString).forEach(processWayForLevel);\n }\n\n });\n\n // 3. Manage elevators without explicit navigation graph inside.\n // It creates a graph from entries to the center of the elevator shape.\n let fakeOsmNodeId = -1;\n osmModel.ways\n .filter(way => way.isElevator)\n .forEach(way => {\n const entryVertices = way.nodes.map(node => verticesMapping.filter(([osmId]) => osmId === node.id).map(vm => vm[1])).flat();\n\n // Horrible method but works for macro-problems\n const elevatorCenter = way.nodes\n .reduce((acc, node) => [acc[0] + node.coords.lat, acc[1] + node.coords.lng], [0, 0])\n .map(val => val / way.nodes.length);\n const elevatorLevel = entryVertices.reduce((acc, v) => Level.union(acc, v.coords.level), null as Level_t);\n const elevatorCenterCoords = new Coordinates(elevatorCenter[0], elevatorCenter[1], null, elevatorLevel);\n\n const elevatorCenterFakeOsmNode = new OsmNode(fakeOsmNodeId--, elevatorCenterCoords, { highway: 'elevator' });\n\n entryVertices.forEach(entryVertex => {\n const vertexCenter = getOrCreateVertex(elevatorCenterFakeOsmNode, entryVertex.coords.level);\n edges.push(new Edge(vertexCenter, entryVertex, { externalId: way.id }));\n })\n });\n\n\n // 4. Link elevators vertices\n elevatorVertices.forEach(([id, name, verticesOfEachLevel]) => {\n const elevatorEdgeProps = { name, isElevator: true, externalId: id };\n // Link vertices of each level together\n for (let i = 0; i < verticesOfEachLevel.length; i++) {\n for (let j = i + 1; j < verticesOfEachLevel.length; j++) {\n edges.push(new Edge(verticesOfEachLevel[i], verticesOfEachLevel[j], elevatorEdgeProps));\n }\n }\n });\n\n callbackVerticesMapping?.(verticesMapping);\n\n return new Graph(verticesMapping.map(v => v[1]), edges);\n }\n\n}","import { RouterRequest } from '../model/RouterRequest.js';\nimport Itinerary from '../model/Itinerary.js';\n\nabstract class RemoteRouter {\n\n /**\n * Get the router name\n */\n abstract get rname(): string;\n\n abstract getItineraries(endpointUrl: string, routerRequest: RouterRequest): Promise<Itinerary[]>;\n\n}\n\nexport default RemoteRouter;\n","// https://developers.google.com/actions-center/reference/grpc-api/status_codes\nexport enum StatusCode {\n OK = 0,\n CANCELLED = 1,\n UNKNOWN = 2,\n INVALID_ARGUMENT = 3,\n NOT_FOUND = 5,\n UNIMPLEMENTED = 12,\n INTERNAL = 13,\n UNAVAILABLE = 14\n}","// Based on GRPC status code\n\nimport { StatusCode } from \"./StatusCode\";\nimport { TravelMode } from \"./model/TravelMode\";\n\n\nexport class RoutingError extends Error {\n\n public customMapName?: string | null;\n\n constructor(public code = StatusCode.UNKNOWN, message?: string) {\n super(message)\n }\n\n static notFound(details?: string) {\n return new RoutingError(StatusCode.NOT_FOUND, `Cannot found an itinerary. Details: ${details}`)\n }\n}\n\n\nexport class WemapMultiRoutingError extends RoutingError {\n \n constructor(public code = StatusCode.UNKNOWN, public mapName: string | null, message?: string) {\n super(code, message);\n this.mapName = mapName;\n }\n\n static notFound(mapName: string, details?: string) {\n return new WemapMultiRoutingError(StatusCode.NOT_FOUND, mapName, `Cannot found an itinerary in map ${mapName}. Details: ${details}`)\n }\n\n}\n\nexport class RemoteRoutingError extends RoutingError {\n \n constructor(public code = StatusCode.UNKNOWN, public routerName: string, message?: string) {\n super(code, message);\n this.routerName = routerName;\n }\n\n static notFound(routerName: string, details?: string) {\n return new RemoteRoutingError(StatusCode.NOT_FOUND, routerName, `Cannot found an itinerary with ${routerName}. Details: ${details}`)\n }\n\n static unreachableServer(routerName: string, url: string) {\n return new RemoteRoutingError(StatusCode.NOT_FOUND, routerName, `Remote router server ${routerName} is unreachable. URL: ${url}`)\n }\n\n static responseNotParsing(routerName: string, url: string) {\n return new RemoteRoutingError(StatusCode.NOT_FOUND, routerName, `Remote router server response ${routerName} cannot be parsed. URL: ${url}`)\n }\n\n static travelModeUnimplemented(routerName: string, travelMode: TravelMode) {\n return new RemoteRoutingError(StatusCode.UNIMPLEMENTED, routerName, `Travel mode \"${travelMode}\" is not implemented for ${routerName}`)\n }\n}","import { RoutingError } from \"../RoutingError\";\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 RoutingError;\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 { dateWithTimeZone } from '../RemoteRouterUtils.js';\nimport { TransitMode, isTransitModePublicTransport } from '../../model/TransitMode.js';\nimport StepsBuilder from '../../model/StepsBuilder.js';\nimport { type TravelMode } from '../../model/TravelMode.js';\nimport { type RouterRequest } from '../../model/RouterRequest.js';\nimport { RemoteRoutingError } from '../../RoutingError.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 Message: string,\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<TravelMode, string>();\ninputModeCorrespondance.set('CAR', 'Car');\ninputModeCorrespondance.set('WALK', 'Walk');\ninputModeCorrespondance.set('BIKE', 'Bike');\ninputModeCorrespondance.set('TRANSIT', 'PT');\n\n\n/**\n * List of all routing modes supported by the API\n */\nconst transitModeCorrespondance = new Map<string, TransitMode>();\ntransitModeCorrespondance.set('WALK', 'WALK');\ntransitModeCorrespondance.set('BICYCLE', 'BIKE');\ntransitModeCorrespondance.set('TRAMWAY', 'TRAM');\ntransitModeCorrespondance.set('METRO', 'METRO');\ntransitModeCorrespondance.set('FUNICULAR', 'FUNICULAR');\ntransitModeCorrespondance.set('BUS', 'BUS');\ntransitModeCorrespondance.set('COACH', 'BUS');\ntransitModeCorrespondance.set('SCHOOL', 'BUS');\ntransitModeCorrespondance.set('BUS_PMR', 'BUS');\ntransitModeCorrespondance.set('MINIBUS', 'BUS');\ntransitModeCorrespondance.set('TROLLEY_BUS', 'BUS');\ntransitModeCorrespondance.set('TAXIBUS', 'BUS');\ntransitModeCorrespondance.set('SHUTTLE', 'BUS');\ntransitModeCorrespondance.set('TRAIN', 'TRAIN');\ntransitModeCorrespondance.set('HST', 'TRAIN');\ntransitModeCorrespondance.set('LOCAL_TRAIN', 'TRAIN');\ntransitModeCorrespondance.set('AIR', 'AIRPLANE');\ntransitModeCorrespondance.set('FERRY', 'BOAT');\ntransitModeCorrespondance.set('TAXI', 'UNKNOWN');\ntransitModeCorrespondance.set('CAR_POOL', 'UNKNOWN');\ntransitModeCorrespondance.set('PRIVATE_VEHICLE', 'CAR');\ntransitModeCorrespondance.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 get rname() { return 'cityway' as const; }\n\n async getItineraries(endpointUrl: string, routerRequest: RouterRequest) {\n const url = this.getURL(endpointUrl, routerRequest);\n const res = await (fetch(url).catch(() => {\n throw RemoteRoutingError.unreachableServer(this.rname, url);\n }));\n\n const jsonResponse = await res.json().catch(() => {\n throw RemoteRoutingError.responseNotParsing(this.rname, url);\n });\n return this.parseResponse(jsonResponse);\n }\n\n\n getURL(endpointUrl: string, routerRequest: RouterRequest) {\n\n const { origin, destination, travelMode, waypoints } = routerRequest;\n const citywayMode = inputModeCorrespondance.get(travelMode);\n if (!citywayMode) {\n throw RemoteRoutingError.travelModeUnimplemented(this.rname, travelMode);\n }\n\n if ((waypoints || []).length > 0) {\n Logger.warn(`${this.rname} router uses only the first 2 waypoints (asked ${waypoints?.length})`);\n }\n\n const fromPlace = `DepartureLatitude=${origin.latitude}&DepartureLongitude=${origin.longitude}`;\n const toPlace = `ArrivalLatitude=${destination.latitude}&ArrivalLongitude=${destination.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 * @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 parseResponse(json: CitywayJson) {\n\n if (json.StatusCode !== 200 || !json.Data || !json.Data.length) {\n throw RemoteRoutingError.notFound(this.rname, json.Message);\n }\n\n const itineraries = [];\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 = transitModeCorrespondance.get(jsonLeg.TransportMode)!;\n const legCoords: Coordinates[] = [];\n let legStart, legEnd;\n let transportInfo: TransportInfo | undefined;\n const stepsBuilder = new StepsBuilder();\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 legStart = {\n name: jsonLeg.Departure.Site.Name,\n coords: jsonToCoordinates(jsonLeg.Departure.Site.Position)\n };\n legEnd = {\n name: jsonLeg.Arrival.Site.Name,\n coords: jsonToCoordinates(jsonLeg.Arrival.Site.Position)\n };\n\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 = [legStart.coords, legEnd.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 stepsBuilder.addStepInfo({\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 stepsBuilder.addStepInfo({\n coords: legCoords[legCoords.length - 1]\n });\n }\n\n } else if (isTransitModePublicTransport(legMode)) {\n\n legStart = {\n name: jsonLeg.Departure.StopPlace.Name,\n coords: jsonToCoordinates(jsonLeg.Departure.StopPlace.Position)\n };\n legEnd = {\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 stepsBuilder.addStepInfo({\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 stepsBuilder.setStart(legStart.coords);\n stepsBuilder.setEnd(legEnd.coords);\n stepsBuilder.setPathCoords(legCoords);\n\n const leg = new Leg({\n transitMode: legMode,\n duration: this.parseDuration(jsonLeg.Duration),\n startTime: jsonDateToTimestamp(jsonLeg.Departure.Time),\n endTime: jsonDateToTimestamp(jsonLeg.Arrival.Time),\n coords: legCoords,\n start: legStart,\n end: legEnd,\n transportInfo,\n steps: stepsBuilder.build()\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 origin: jsonToCoordinates(trip.Departure.Site.Position),\n endTime: jsonDateToTimestamp(trip.Arrival.Time),\n destination: jsonToCoordinates(trip.Arrival.Site.Position),\n legs\n });\n\n itineraries.push(itinerary);\n }\n\n return itineraries;\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 Leg from '../../model/Leg.js';\nimport { type RouterRequest } from '../../model/RouterRequest.js';\nimport { RemoteRoutingError } from '../../RoutingError.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 */\n async getItineraries(endpointUrl: string, routerRequest: RouterRequest) {\n const url = this.getURL(endpointUrl, routerRequest);\n const res = await (fetch(url).catch(() => {\n throw RemoteRoutingError.unreachableServer(this.rname, url);\n }));\n\n const jsonResponse = await res.json().catch(() => {\n throw RemoteRoutingError.responseNotParsing(this.rname, url);\n });\n return this.parseResponse(jsonResponse, routerRequest.origin, routerRequest.destination);\n }\n\n getURL(endpointUrl: string, routerRequest: RouterRequest) {\n let url = endpointUrl + '/route/v1/walking/';\n const waypoints = [routerRequest.origin, ...routerRequest.waypoints || [], routerRequest.destination];\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 parseResponse(json: DBJson, origin: Coordinates, destination: Coordinates) {\n\n if (!json.segments) {\n throw RemoteRoutingError.notFound(this.rname);\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 transitMode: 'WALK',\n coords,\n start: { coords: coords[0] },\n end: { coords: coords[coords.length - 1] },\n })\n });\n\n return [new Itinerary({ origin, destination, legs })];\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 { dateWithTimeZone } from '../RemoteRouterUtils.js';\nimport StepsBuilder from '../../model/StepsBuilder.js';\nimport RemoteRouter from '../RemoteRouter.js';\nimport { type TransitMode } from '../../model/TransitMode.js';\nimport { type MinStepInfo } from '../../model/Step.js';\nimport { RouterRequest } from '../../model/RouterRequest.js';\nimport { RemoteRoutingError } from '../../RoutingError.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 error: {\n message?: 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 transitModeCorrespondance = new Map<string, TransitMode>();\ntransitModeCorrespondance.set('Air', 'AIRPLANE');\ntransitModeCorrespondance.set('Boat', 'BOAT');\ntransitModeCorrespondance.set('Bus', 'BUS');\ntransitModeCorrespondance.set('BusRapidTransit', 'BUS');\ntransitModeCorrespondance.set('Coach', 'BUS');\ntransitModeCorrespondance.set('Ferry', 'FERRY');\ntransitModeCorrespondance.set('Funicular', 'FUNICULAR');\ntransitModeCorrespondance.set('LocalTrain', 'TRAIN');\ntransitModeCorrespondance.set('LongDistanceTrain', 'TRAIN');\ntransitModeCorrespondance.set('Metro', 'METRO');\ntransitModeCorrespondance.set('Métro', 'METRO');\ntransitModeCorrespondance.set('RailShuttle', 'TRAIN');\ntransitModeCorrespondance.set('RapidTransit', 'BUS');\ntransitModeCorrespondance.set('Shuttle', 'BUS');\ntransitModeCorrespondance.set('SuspendedCableCar', 'FUNICULAR');\ntransitModeCorrespondance.set('Taxi', 'TAXI');\ntransitModeCorrespondance.set('Train', 'TRAIN');\ntransitModeCorrespondance.set('RER', 'TRAIN');\ntransitModeCorrespondance.set('Tramway', 'TRAM');\ntransitModeCorrespondance.set('walking', 'WALK');\ntransitModeCorrespondance.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<T>(array: T[]) {\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 async getItineraries(endpointUrl: string, routerRequest: RouterRequest) {\n const url = this.getURL(endpointUrl, routerRequest);\n\n const res = await (fetch(url, {\n method: 'GET',\n headers: { apiKey }\n }).catch(() => {\n throw RemoteRoutingError.unreachableServer(this.rname, url);\n }));\n\n\n const jsonResponse: IdfmJson = await res.json().catch(() => {\n throw RemoteRoutingError.responseNotParsing(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 throw RemoteRoutingError.notFound(this.rname, jsonResponse.error.message);\n }\n\n const itineraries = this.parseResponse(jsonResponse);\n\n const sameModeFound = itineraries.some((itinerary) => itinerary.transitMode === routerRequest.travelMode);\n\n if (!sameModeFound) {\n throw RemoteRoutingError.notFound(\n this.rname,\n 'Selected mode of transport was not found for this itinerary.'\n )\n }\n\n return itineraries;\n }\n\n getURL(endpointUrl: string, routerRequest: RouterRequest) {\n const { origin, destination, waypoints, travelMode } = routerRequest;\n\n if ((waypoints || []).length > 0) {\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', `${origin.longitude};${origin.latitude}`);\n coreParams.set('to', `${destination.longitude};${destination.latitude}`);\n\n if (routerRequest.itineraryModifiers?.avoidStairs) {\n coreParams.set('wheelchair', 'true')\n }\n\n let queryParams: URLSearchParams = new URLSearchParams();\n switch (travelMode) {\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 parseResponse(json: IdfmJson) {\n\n if (!json || !json.journeys) {\n throw RemoteRoutingError.notFound(this.rname, json.error?.message);\n }\n\n const itineraries = [];\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: startSection, to: endSection } = 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 const stepsBuilder = new StepsBuilder().setStart(startSection).setEnd(endSection).setPathCoords(legCoords);\n let transportInfo: TransportInfo | undefined;\n let transitMode = transitModeCorrespondance.get(jsonSection.mode) as TransitMode;\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 stepsBuilder.setStepsInfo(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 transitMode = transitModeCorrespondance.get(jsonSection.display_informations.physical_mode) as TransitMode;\n\n const legStep: MinStepInfo = {\n coords: legCoords[0],\n name: transportInfo.directionName,\n distance: jsonSection.geojson.properties[0].length\n };\n stepsBuilder.setStepsInfo([legStep]);\n }\n\n const leg = new Leg({\n transitMode,\n duration: jsonSection.duration,\n startTime: dateStringToTimestamp(jsonSection.departure_date_time, timeZone),\n endTime: dateStringToTimestamp(jsonSection.arrival_date_time, timeZone),\n start: {\n name: jsonSection.from.name,\n coords: startSection\n },\n end: {\n name: jsonSection.to.name,\n coords: endSection\n },\n coords: legCoords,\n transportInfo,\n steps: stepsBuilder.build()\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 origin: this.getSectionCoords(jsonItinerary.sections[0]).from,\n destination: this.getSectionCoords(last(jsonItinerary.sections)).to,\n legs\n });\n\n itineraries.push(itinerary);\n }\n\n return itineraries;\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 Leg from '../../model/Leg.js';\nimport StepsBuilder from '../../model/StepsBuilder.js';\nimport RemoteRouter from '../RemoteRouter.js';\nimport { type TravelMode } from '../../model/TravelMode.js';\nimport { type TransitMode } from '../../model/TransitMode.js';\nimport { type RouterRequest } from '../../model/RouterRequest.js';\nimport { RemoteRoutingError } from '../../RoutingError.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 message?: 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' | 'pmr' | 'bike-safest' | 'bike-fastest';\n\nconst outputModeCorrespondance = new Map<TravelMode, TransitMode>();\noutputModeCorrespondance.set('CAR', 'CAR');\noutputModeCorrespondance.set('WALK', 'WALK');\noutputModeCorrespondance.set('BIKE', 'BIKE');\n\n/**\n * Singleton.\n */\nclass OsrmRemoteRouter extends RemoteRouter {\n\n get rname() { return 'osrm' as const; }\n\n async getItineraries(endpointUrl: string, routerRequest: RouterRequest) {\n const url = this.getURL(endpointUrl, routerRequest);\n\n const res = await (fetch(url).catch(() => {\n throw RemoteRoutingError.unreachableServer(this.rname, url);\n }));\n\n const jsonResponse = await res.json().catch(() => {\n throw RemoteRoutingError.responseNotParsing(this.rname, url);\n });\n\n return this.parseResponse(jsonResponse, routerRequest.origin, routerRequest.destination, routerRequest.travelMode);\n }\n\n /**\n * @throws {TravelModeCorrespondanceNotFound}\n */\n getURL(endpointUrl: string, routerRequest: RouterRequest) {\n const { origin, destination } = routerRequest;\n\n const osrmMode = this.inputModeCorrespondance(routerRequest);\n const waypoints = [origin, ...routerRequest.waypoints || [], destination];\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 routerRequest.provideItineraryAlternatives && (url += '&alternatives=true')\n return url;\n }\n\n inputModeCorrespondance = (routerRequest: RouterRequest): OsrmMode => {\n const { travelMode, travelModePreference: preference } = routerRequest;\n if (travelMode === 'WALK' && routerRequest.itineraryModifiers?.avoidStairs) return 'pmr';\n if (travelMode === 'WALK') return 'walking';\n if (travelMode === 'BIKE') {\n if (preference === 'FASTEST') return 'bike-fastest';\n if (preference === 'SAFEST') return 'bike-safest';\n if (preference === 'TOURISM') return 'bike-safest';\n return 'bike-safest';\n }\n if (travelMode === 'CAR') return 'driving';\n throw RemoteRoutingError.travelModeUnimplemented(this.rname, travelMode);\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 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 parseResponse(json: OsrmJson, origin: Coordinates, destination: Coordinates, travelMode: TravelMode) {\n\n const transitMode = outputModeCorrespondance.get(travelMode)!;\n\n const { routes: jsonRoutes } = json;\n if (!jsonRoutes) {\n throw RemoteRoutingError.notFound(this.rname, json.message);\n }\n\n return jsonRoutes.map(jsonItinerary => {\n\n const legs = jsonItinerary.legs.map((jsonLeg) => {\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 startCoords = legCoords[0];\n const endCoords = legCoords[legCoords.length - 1];\n\n const stepsBuilder = new StepsBuilder().setPathCoords(legCoords).setStart(startCoords).setEnd(endCoords);\n jsonLeg.steps?.forEach(({ 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-orsm.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 stepsBuilder.addStepInfo({\n coords: legCoords[idStepCoordsInLeg],\n name,\n distance,\n duration\n });\n })\n\n return new Leg({\n transitMode,\n duration: jsonLeg.duration,\n coords: legCoords,\n start: {\n coords: startCoords\n },\n end: {\n coords: endCoords\n },\n steps: stepsBuilder.build()\n });\n });\n\n return new Itinerary({\n duration: jsonItinerary.duration,\n origin,\n destination,\n legs\n });\n });\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, { type TransportInfo } from '../../model/Leg.js';\nimport StepsBuilder from '../../model/StepsBuilder.js';\nimport RemoteRouter from '../RemoteRouter.js';\nimport { type TravelMode } from '../../model/TravelMode.js';\nimport { type RouterRequest } from '../../model/RouterRequest.js';\nimport { RemoteRoutingError } from '../../RoutingError.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<TravelMode, string>();\ninputModeCorrespondance.set('CAR', 'CAR');\ninputModeCorrespondance.set('WALK', 'WALK');\ninputModeCorrespondance.set('BIKE', 'BICYCLE');\ninputModeCorrespondance.set('TRANSIT', 'WALK,TRANSIT');\n\n/**\n * Singleton.\n */\nclass OtpRemoteRouter extends RemoteRouter {\n\n get rname() { return 'otp' as const; }\n\n async getItineraries(endpointUrl: string, routerRequest: RouterRequest) {\n const url = this.getURL(endpointUrl, routerRequest);\n const res = await (fetch(url).catch(() => {\n throw RemoteRoutingError.unreachableServer(this.rname, url);\n }));\n\n const jsonResponse = await res.json().catch(() => {\n throw RemoteRoutingError.responseNotParsing(this.rname, url);\n });\n return this.parseResponse(jsonResponse);\n }\n\n getURL(endpointUrl: string, routerRequest: RouterRequest) {\n const { origin, destination, waypoints, travelMode } = routerRequest;\n\n const otpMode = inputModeCorrespondance.get(travelMode);\n if (!otpMode) {\n throw RemoteRoutingError.travelModeUnimplemented(this.rname, travelMode);\n }\n\n if ((waypoints || []).length > 0) {\n Logger.warn(`${this.rname} router uses only the first 2 waypoints (asked ${waypoints?.length})`);\n }\n\n const fromPlace = `fromPlace=${origin.latitude},${origin.longitude}`;\n const toPlace = `toPlace=${destination.latitude},${destination.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 parseResponse(json: OtpJson) {\n\n const { plan: jsonPlan } = json;\n if (!jsonPlan) {\n throw RemoteRoutingError.notFound(this.rname);\n }\n\n const itineraries = [];\n\n const itinerariesOrigin = jsonToCoordinates(jsonPlan.from);\n const itinerariesDestination = 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 startCoordinates = jsonToCoordinates(jsonLeg.from);\n const endCoordinates = jsonToCoordinates(jsonLeg.to);\n\n const legCoords = Polyline.decode(jsonLeg.legGeometry.points)\n .map(([lat, lon]) => new Coordinates(lat, lon));\n\n let transportInfo: TransportInfo | undefined;\n const stepsBuilder = new StepsBuilder().setStart(startCoordinates).setEnd(endCoordinates).setPathCoords(legCoords);\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 stepsBuilder.addStepInfo({\n coords: legCoords[0],\n name: jsonLeg.headsign\n });\n\n } else {\n\n jsonLeg.steps.forEach(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 stepsBuilder.addStepInfo({\n coords: legCoords[idStepCoordsInLeg],\n name: jsonStep.streetName\n });\n })\n }\n\n\n const leg = new Leg({\n transitMode: jsonLeg.mode,\n duration: jsonLeg.duration,\n startTime: jsonLeg.startTime,\n endTime: jsonLeg.endTime,\n start: {\n name: jsonLeg.from.name,\n coords: jsonToCoordinates(jsonLeg.from)\n },\n end: {\n name: jsonLeg.to.name,\n coords: jsonToCoordinates(jsonLeg.to)\n },\n coords: legCoords,\n transportInfo,\n steps: stepsBuilder.build()\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 origin: itinerariesOrigin,\n destination: itinerariesDestination,\n legs\n });\n itineraries.push(itinerary);\n }\n\n return itineraries;\n }\n}\n\nexport default new OtpRemoteRouter();\n","import { Coordinates } from '@wemap/geo';\n\nimport RemoteRouter from '../RemoteRouter.js';\nimport { RouterRequest } from '../../model/RouterRequest.js';\nimport Itinerary from '../../model/Itinerary.js';\nimport { RemoteRoutingError } from '../../RoutingError.js';\n\n\ntype WemapRouterRequest = Omit<RouterRequest, 'origin' | 'destination' | 'waypoints'> & {\n mapId?: number,\n origin: Coordinates | number | string\n destination: Coordinates | number | string\n waypoints?: (Coordinates | number | string)[]\n}\n\n/**\n * Singleton.\n */\nclass WemapMultiRemoteRouter extends RemoteRouter {\n\n get rname() { return 'wemap-multi' as const; }\n\n async getItineraries(endpointUrl: string, routerRequest: WemapRouterRequest) {\n const { origin, destination, waypoints } = routerRequest;\n const payload = {\n ...routerRequest,\n origin: origin instanceof Coordinates ? origin.toJson() : origin,\n destination: destination instanceof Coordinates ? destination.toJson() : destination,\n ...(waypoints && {waypoints: waypoints.map(w => w instanceof Coordinates ? w.toJson() : w)})\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)\n }).catch(() => {\n throw RemoteRoutingError.unreachableServer(this.rname, endpointUrl);\n }));\n\n const jsonResponse = await res.json().catch(() => {\n throw RemoteRoutingError.responseNotParsing(this.rname, endpointUrl);\n });\n\n if (jsonResponse.error) {\n throw RemoteRoutingError.notFound(this.rname, jsonResponse.error)\n }\n\n return (jsonResponse.itineraries || []).map(Itinerary.fromJson) as Itinerary[];\n }\n\n}\n\nexport default new WemapMultiRemoteRouter();\n","import 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 { RouterRequest } from '../model/RouterRequest.js';\nimport { RemoteRoutingError } from '../RoutingError.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\nexport type RoutingFallbackStrategy = { name: RemoteRouterName, endpointUrl: string }[];\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 async getItineraries(name: RemoteRouterName, endpointUrl: string, routerRequest: RouterRequest) {\n const router = this.getRouterByName(name);\n if (!router) {\n throw RemoteRoutingError.notFound(name, `Unknown \"${name}\" remote router`);\n }\n return router.getItineraries(endpointUrl, routerRequest);\n }\n\n async getItinerariesWithFallback(routerRequest: RouterRequest, fallbackStrategy: RoutingFallbackStrategy) {\n let itineraries;\n for (const { name, endpointUrl } of fallbackStrategy) {\n itineraries = await this.getItineraries(name, endpointUrl, routerRequest);\n if (itineraries.length) {\n return itineraries;\n }\n }\n\n const routersNames = fallbackStrategy.map(({ name }) => name).join(',');\n throw RemoteRoutingError.notFound(routersNames, `Could not find an itinerary with any of following servers: ${routersNames}`)\n }\n}\n\nexport default new RemoteRouterManager();\n","/* eslint-disable complexity */\n/* eslint-disable max-statements */\n\nimport CustomNetworkMap from './CustomNetworkMap.js';\nimport RemoteRouterManager, { type RoutingFallbackStrategy } from '../remote/RemoteRouterManager.js';\nimport Itinerary from '../model/Itinerary.js';\nimport WemapMultiRemoteRouter from '../remote/wemap-multi/WemapMultiRemoteRouter.js';\nimport GraphRoute from '../graph/GraphRoute.js';\nimport GraphRouterOptionsBuilder from '../graph/GraphRouterOptionsBuilder.js';\nimport { type RouterRequest } from '../model/RouterRequest.js';\nimport { RemoteRoutingError, WemapMultiRoutingError } from '../RoutingError.js';\n\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 removeAllMaps() {\n this.maps = [];\n }\n\n getMapByName(mapId: string) {\n return this.maps.find(map => map.name === mapId);\n }\n\n async getItineraries(routerRequest: RouterRequest, fallbackStrategy: RoutingFallbackStrategy = [], targetMaps = this.maps): Promise<Itinerary[]> {\n\n const { origin, destination } = routerRequest;\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 // Avoid cycles on remoteRouters\n fallbackStrategy = fallbackStrategy.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 // TODO: map it with Wemap backend\n const ioMapsToTest = targetMaps;\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 return await RemoteRouterManager.getItinerariesWithFallback(routerRequest, fallbackStrategy);\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 ioMapRoute: GraphRoute | null;\n let ioMapItinerary: Itinerary;\n\n // Find the first map where the \"origin\" is inside.\n const mapWithOrigin = ioMapsToTest.find(map => map.isPointInside(origin));\n\n\n // Create GraphRouterOptions from request\n const routerOptions = GraphRouterOptionsBuilder.fromJson(routerRequest.itineraryModifiers || {});\n\n /*\n * Case 1\n *\n * If \"origin\" and \"destination\" are in the same map, use the local router.\n */\n if (mapWithOrigin && mapWithOrigin.isPointInside(destination)) {\n\n ioMapRoute = mapWithOrigin.getRouteInsideMap(origin, destination, routerOptions);\n if (!ioMapRoute) {\n throw WemapMultiRoutingError.notFound(mapWithOrigin.name || \"\")\n }\n\n return [Itinerary.fromGraphRoute(ioMapRoute)];\n }\n\n // Find the first map where the \"destination\" is inside.\n // Note: At this step, mapWithDestination is necessarily different from mapWithOrigin\n const mapWithDestination = ioMapsToTest.find(map => map.isPointInside(destination));\n\n\n let remoteRouterItineraries: Itinerary[];\n\n /*\n * Case 2\n *\n * If no io map have been found for \"origin\" and \"destination\", therefore use remote router.\n */\n if (!mapWithOrigin && !mapWithDestination) {\n return await RemoteRouterManager.getItinerariesWithFallback(routerRequest, fallbackStrategy);\n }\n\n /**\n * Case 3\n *\n * If a map has been found for the \"origin\" but not for the \"destination\", so:\n * - A first itinerary (firstRoute) is calculated from \"origin\" 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 * \"destination\" using remote routers.\n * Itinerary returned is the concatenation of the both itineraries.\n *\n * Note: Check the mapWithDestination.getBestItineraryFromEntryPointsToDestination to understand\n * which \"entrypoint\" is chosen by the algorithm\n */\n if (mapWithOrigin && !mapWithDestination) {\n\n if (!mapWithOrigin.entryPoints.length) {\n throw WemapMultiRoutingError.notFound(mapWithOrigin.name || '',\n `A map including the \"origin\" but the \"destination\" has been \n found (${mapWithOrigin.name}), however, no \"entrypoints\" have been found to go out`\n )\n }\n\n const customError = (details: string) => 'Tried to calculate an itinerary from \"origin\" '\n + `to \"entrypoints\" using wemap router on local map \"${mapWithOrigin.name}\" and `\n + 'an itinerary from \"entrypoints\" to \"destination\" using remote routers '\n + `(${fallbackStrategy.map(r => r.name).join(', ')}), but failed. `\n + `Details: ${details}.`;\n\n ioMapRoute = mapWithOrigin.getBestRouteFromOriginToEntryPoints(origin, destination, routerOptions);\n if (!ioMapRoute) {\n const details = `No route found from ${origin.toString()} to entry points in map: ${mapWithOrigin.name}`;\n throw WemapMultiRoutingError.notFound(mapWithOrigin.name || \"\", customError(details))\n }\n\n const newRouterRequest: RouterRequest = {\n ...routerRequest,\n origin: ioMapRoute.end,\n destination,\n waypoints: []\n };\n try {\n remoteRouterItineraries = await RemoteRouterManager.getItinerariesWithFallback(newRouterRequest, fallbackStrategy);\n } catch (e) {\n if (e instanceof RemoteRoutingError) {\n e.message = customError(e.message);\n }\n throw e;\n }\n\n // Concat the the IO map itinerary with the remote router response (for each itinerary)\n ioMapItinerary = Itinerary.fromGraphRoute(ioMapRoute);\n return remoteRouterItineraries.map(\n remoteRouterItinerary => Itinerary.fromItineraries(ioMapItinerary, remoteRouterItinerary)\n );\n }\n\n /*\n * Case 4\n *\n * If a map has been found for the \"destination\" but not for the \"origin\", so:\n * - A first itinerary (remoteRouterResponse) is calculated from \"origin\" 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 * \"destination\" using the wemap router.\n * Itinerary returned is the concatenation of the both itineraries.\n *\n * Note: Check the mapWithDestination.getBestItineraryFromEntryPointsToDestination to understand\n * which \"entrypoint\" is chosen by the algorithm\n */\n if (!mapWithOrigin && mapWithDestination) {\n\n if (!mapWithDestination.entryPoints.length) {\n throw WemapMultiRoutingError.notFound(mapWithDestination.name || '',\n `A map including the \"destination\" but the \"origin\" has been \n found (${mapWithDestination.name}), however, no \"entrypoints\" have been found to go in`\n )\n }\n\n const customError = (details: string) => 'Tried to calculate an itinerary from \"origin\" to \"entrypoints\" '\n + `using remote routers (${fallbackStrategy.map(r => r.name).join(', ')}) and an `\n + 'itinerary from \"entrypoints\" to \"destination\" using wemap router on local map '\n + `\"${mapWithDestination.name}\", but failed. `\n + `Details: ${details}.`\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 ioMapRoute = mapWithDestination.getBestRouteFromEntryPointsToDestination(origin, destination, routerOptions);\n if (!ioMapRoute) {\n const details = `No route found from entry points to ${destination.toString()} in map: ${mapWithDestination.name}`;\n throw WemapMultiRoutingError.notFound(mapWithDestination.name || \"\", customError(details))\n }\n\n const newRouterRequest: RouterRequest = {\n ...routerRequest,\n origin,\n destination: ioMapRoute.start,\n waypoints: []\n };\n try {\n remoteRouterItineraries = await RemoteRouterManager.getItinerariesWithFallback(newRouterRequest, fallbackStrategy);\n } catch (e) {\n if (e instanceof RemoteRoutingError) {\n e.message = customError(e.message);\n }\n throw e;\n }\n\n // Concat the remote router response (for each itinerary) with the IO map itinerary\n ioMapItinerary = Itinerary.fromGraphRoute(ioMapRoute);\n return remoteRouterItineraries.map(\n remoteRouterItinerary => Itinerary.fromItineraries(remoteRouterItinerary, ioMapItinerary)\n );\n }\n\n /**\n * Case 5\n *\n * If maps have been found for the \"origin\" and the \"destination\" but they are different, so:\n * - A first itinerary (ioMapItinerary1) is calculated from \"origin\" to an \"entrypoint\" of\n * the mapWithOrigin using the wemap router.\n * - A second itinerary (remoteRouterResponse) is calculated from an \"entrypoint\" of the\n * mapWithOrigin to an \"entrypoint\" of the destinationWithMap using remote routers.\n * - A third itinerary (ioMapItinerary2) is calculated from an \"entrypoint\" of the mapWithDestination\n * to the \"destination\" using the wemap router.\n * Itinerary returned is the concatenation of the three itineraries.\n */\n if (mapWithOrigin && mapWithDestination) {\n\n if (!mapWithOrigin.entryPoints.length) {\n throw WemapMultiRoutingError.notFound(mapWithOrigin.name || '',\n `One map including the \"origin\" (${mapWithOrigin.name}) and another \n including the \"destination\" (${mapWithDestination.name}) has been found, however, no \"entrypoints\" have \n been found to go out of the origin map`\n );\n }\n\n if (!mapWithDestination.entryPoints.length) {\n throw WemapMultiRoutingError.notFound(mapWithDestination.name || '',\n `One map including the \"origin\" (${mapWithOrigin.name}) and another \n including the \"destination\" (${mapWithDestination.name}) has been found, however, no \"entrypoints\" have \n been found to go in the second map`\n );\n }\n\n const customError = (details: string) => 'Tried to calculate an itinerary from \"origin\" to \"entrypoints1\" '\n + `using wemap router on local map \"${mapWithOrigin.name}\", an itinerary from `\n + '\"entrypoints1\" to \"entrypoints2\" using remote routers '\n + `(${fallbackStrategy.map(r => r.name).join(', ')}) and an itinerary from \"entrypoints2\" `\n + `to \"destination\" using wemap router on local map \"${mapWithDestination.name}\", but failed. `\n + `Details: ${details}.`;\n\n\n const ioMapRoute1 = mapWithOrigin.getBestRouteFromOriginToEntryPoints(origin, destination, routerOptions);\n if (!ioMapRoute1) {\n const details = `No route found from ${origin.toString()} to entry points in map: ${mapWithOrigin.name}`;\n throw WemapMultiRoutingError.notFound(mapWithOrigin.name || \"\", customError(details))\n }\n\n const ioMapRoute2 = mapWithDestination.getBestRouteFromEntryPointsToDestination(origin, destination, routerOptions);\n if (!ioMapRoute2) {\n const details = `No route found from entry points to ${destination.toString()} in map: ${mapWithDestination.name}`;\n throw WemapMultiRoutingError.notFound(mapWithDestination.name || \"\", customError(details))\n }\n\n const newRouterRequest: RouterRequest = {\n ...routerRequest,\n origin: ioMapRoute1.end,\n destination: ioMapRoute2.start,\n waypoints: []\n };\n try {\n remoteRouterItineraries = await RemoteRouterManager.getItinerariesWithFallback(newRouterRequest, fallbackStrategy);\n } catch (e) {\n if (e instanceof RemoteRoutingError) {\n e.message = customError(e.message);\n }\n throw e;\n }\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 return remoteRouterItineraries.map(remoteRouterItinerary =>\n Itinerary.fromItineraries(\n Itinerary.fromGraphRoute(ioMapRoute1),\n remoteRouterItinerary,\n Itinerary.fromGraphRoute(ioMapRoute2)\n )\n );\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, Level } from '@wemap/geo';\nimport Logger from '@wemap/logger';\nimport { OsmParser } from '@wemap/osm';\n\nimport Graph from '../graph/Graph.js';\nimport GraphRouter from '../graph/GraphRouter.js';\nimport { GraphRouterOptions } from '../graph/GraphRouterOptions.js';\nimport Vertex from '../graph/Vertex.js';\nimport OsmGraphUtils from '../wemap-osm/OsmGraphUtils.js';\n\nclass CustomNetworkMap {\n\n name: string | null;\n graph: Graph;\n router: GraphRouter;\n bounds: MultiPolygon;\n entryPoints: Vertex[];\n\n constructor(\n graph: Graph,\n entryPoints: Vertex[],\n bounds: MultiPolygon | null = null,\n name: string | null = null) {\n\n this.name = name;\n this.graph = graph;\n this.router = new GraphRouter(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 graph \"${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 graph \"${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 let verticesMapping: [nodeId: number, vertex: Vertex][] = []\n const graph = OsmGraphUtils.createGraphFromOsmModel(osmModel, OsmGraphUtils.DEFAULT_WAY_SELECTOR, vm => (verticesMapping = vm));\n\n const entryPointsOsmNodes = osmModel.nodes.filter(node => node.tags['wemap:routing-io']);\n const entryPointsToCheck = entryPointsOsmNodes.map(node => {\n const vertex = verticesMapping.find(v => v[0] === node.id)?.[1]\n if (!vertex) {\n Logger.warn(`Could not parse this wemap:routing-io correctly: ${JSON.stringify(node.coords.toJson())}`)\n }\n return vertex || null;\n });\n const entryPoints = entryPointsToCheck.filter(it => it !== null) as Vertex[];\n entryPoints.forEach(v => graph.exitVertices.add(v));\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 getBestRouteFromEntryPointsToDestination(start: Coordinates, end: Coordinates, options: GraphRouterOptions) {\n // TODO: use multiple-destinations algorithm\n const sortedEntryPoints = this.getOrderedEntryPointsSortedByDistance(start, end);\n for (const entryPoint of sortedEntryPoints) {\n const route = this.router.calculateShortestPath(entryPoint.coords, end, options).route();\n if (route.hasRoute) {\n return route;\n }\n // no route found\n }\n return null;\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 getBestRouteFromOriginToEntryPoints(start: Coordinates, end: Coordinates, options: GraphRouterOptions) {\n // TODO: use multiple-destinations algorithm\n const sortedEntryPoints = this.getOrderedEntryPointsSortedByDistance(start, end);\n for (const entryPoint of sortedEntryPoints) {\n const route = this.router.calculateShortestPath(start, entryPoint.coords, options).route();\n if (route.hasRoute) {\n return route;\n }\n // no route found\n }\n return null;\n }\n\n getRouteInsideMap(start: Coordinates, end: Coordinates, options: GraphRouterOptions) {\n // Call the Wemap router to get the shortest path\n return this.router.calculateShortestPath(start, end, options).route();\n }\n\n getTripInsideMap(waypoints: Coordinates[], options: GraphRouterOptions) {\n // Call the Wemap router to get the shortest trip itinerary\n return this.router.getShortestTrip(waypoints, options);\n }\n\n getRoutesMultipleDestinationsInsideMap(start: Coordinates, ends: Coordinates[], options: GraphRouterOptions) {\n // Call the Wemap router to get the shortest path for all the input destinations\n return this.router.calculateShortestPathToMultipleDestinations(start, ends, options);\n }\n\n}\n\nexport default CustomNetworkMap;\n","import { Coordinates } from '@wemap/geo';\n\nimport Itinerary from './model/Itinerary.js';\nimport Leg from './model/Leg.js';\nimport { Step } from './model/Step.js';\nimport Graph from './graph/Graph.js';\nimport GraphProjection from './graph/GraphProjection.js';\nimport Vertex from './graph/Vertex.js';\nimport Edge from './graph/Edge.js';\n\nexport type ItineraryInfo<U extends Coordinates = Coordinates> = {\n nextStep: Step | null;\n previousStep: Step | null;\n projection: GraphProjection<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 _graph: Graph | 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 this._graph = itinerary.toGraph();\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._graph) {\n return null;\n }\n\n const projection = this._graph.getProjection(position);\n if (!projection) {\n return null;\n }\n\n let itineraryInfo: ItineraryInfo<U> | null = null;\n\n if (projection.nearestElement instanceof Vertex) {\n const idx = this._itinerary.coords.findIndex(\n coords => (projection.nearestElement as Vertex).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 Edge) {\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":["Level","Coordinates","BoundingBox","UserPosition","diffAngleLines","GeoConstants","deg2rad","diffAngle","GeoUtils","last","OsmNode","StatusCode","jsonToCoordinates","inputModeCorrespondance","transitModeCorrespondance","positiveMod","rad2deg","CitywayRemoteRouter","DeutscheBahnRemoteRouter","IdfmRemoteRouter","OsrmRemoteRouter","OtpRemoteRouter","WemapMultiRemoteRouter","RemoteRouterManager","OsmParser"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../src/model/RouterRequest.ts","../src/graph/Edge.ts","../src/graph/GraphProjection.ts","../src/graph/Vertex.ts","../src/graph/Graph.ts","../src/Utils.ts","../src/model/TransitMode.ts","../src/model/Step.ts","../src/graph/GraphRoute.ts","../src/model/StepsBuilder.ts","../src/model/Leg.ts","../src/model/Itinerary.ts","../src/graph/GraphRouterOptionsBuilder.ts","../src/graph/GraphRouterEngine.ts","../src/graph/GraphRouter.ts","../src/graph/NoRouteFoundError.ts","../src/wemap-osm/OsmGraphUtils.ts","../src/remote/RemoteRouter.ts","../src/StatusCode.ts","../src/RoutingError.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/WemapMultiRemoteRouter.ts","../src/remote/RemoteRouterManager.ts","../src/wemap-multi/WemapMultiRouter.ts","../src/wemap-multi/CustomNetworkMap.ts","../src/ItineraryInfoManager.ts"],"sourcesContent":["import { Coordinates } from \"@wemap/geo\"\n\nimport { TravelMode, TravelModePreference } from \"./TravelMode\"\n\nexport type RouterRequest = {\n origin: Coordinates,\n destination: Coordinates,\n travelMode: TravelMode,\n travelModePreference?: TravelModePreference,\n provideItineraryAlternatives?: boolean,\n waypoints?: Coordinates[],\n optimizeWaypoints?: boolean,\n itineraryModifiers?: {\n avoidStairs?: boolean,\n avoidEscalators?: boolean,\n avoidElevator?: boolean,\n avoidMovingWalkway?: boolean,\n avoidTicketRestrictedAreas?: boolean\n }\n output?: {\n distanceAndDurationOnly?: boolean\n }\n}\n\nexport function routerRequestToJson(routerRequest: RouterRequest) {\n const { origin, destination, waypoints, ...rest } = routerRequest;\n return {\n origin: origin.toJson(),\n destination: destination.toJson(),\n ...(waypoints && { waypoints: waypoints.map(w => w.toJson()) }),\n ...rest\n }\n}","import { Level, type Level_t } from '@wemap/geo';\n\nimport Vertex from './Vertex.js';\n\nexport type EdgeProperties = {\n \n name?: string;\n externalId?: string | number;\n\n isOneway?: boolean;\n areStairs?: boolean;\n isElevator?: boolean;\n areEscalators?: boolean;\n isMovingWalkway?: boolean;\n needTicket?: boolean;\n incline?: 'up' | 'down';\n}\n\n/**\n * An Edge is a segment composed of two Vertex\n * An edge is mostly issued from an OsmWay, but this is not always the case.\n * For example, edges created by mapmatching.\n */\nexport default class Edge {\n\n static currentUniqueId = 0;\n public readonly id = Edge.currentUniqueId++;\n\n public readonly level: Level_t;\n\n /** Edge bearing from vertex1 to vertex2 */\n public readonly bearing: number;\n public readonly length: number;\n\n constructor(\n public vertex1: Vertex,\n public vertex2: Vertex,\n public properties: EdgeProperties = {}\n ) {\n this.level = Level.union(vertex1.coords.level, vertex2.coords.level)\n this.length = this.vertex1.distanceTo(this.vertex2);\n this.bearing = this.vertex1.bearingTo(this.vertex2);\n }\n\n static getEdgeByVertices(\n edges: Edge[],\n vertex1: Vertex,\n vertex2: Vertex\n ) {\n return edges.find(edge => vertex1 === edge.vertex1 && vertex2 === edge.vertex2\n || vertex2 === edge.vertex1 && vertex1 === edge.vertex2\n );\n }\n\n reverseProperties() {\n const { properties } = this;\n if (properties.incline) {\n properties.incline = properties.incline === 'up' ? 'down' : 'up';\n }\n if (properties.isOneway) {\n properties.isOneway = false;\n }\n }\n}\n","import { Coordinates, UserPosition } from '@wemap/geo';\n\nimport Edge from './Edge.js';\nimport Vertex from './Vertex.js';\n\nclass GraphProjection<U extends Coordinates | UserPosition = Coordinates> {\n constructor(\n public readonly origin: U,\n public readonly distanceFromNearestElement: number,\n public readonly coords: U,\n public readonly nearestElement: Vertex | Edge\n ) { }\n}\n\nexport default GraphProjection;\n","import { Coordinates } from '@wemap/geo';\n\nimport { GraphVertexJson } from '../types.js';\n\nexport type VertexProperties = {\n\n name?: string;\n externalId?: string | number;\n\n isGate?: boolean;\n isSubwayEntrance?: boolean;\n subwayEntranceRef?: string;\n}\n\nexport default class Vertex {\n\n public id = -1;\n\n constructor(public coords: Coordinates, public properties: VertexProperties = {}) { }\n\n distanceTo(other: Vertex) {\n return this.coords.distanceTo(other.coords);\n }\n\n bearingTo(other: Vertex) {\n return this.coords.bearingTo(other.coords);\n }\n\n toJson(): GraphVertexJson {\n return this.coords.toCompressedJson();\n }\n\n static fromJson(json: GraphVertexJson) {\n return new Vertex(Coordinates.fromCompressedJson(json));\n }\n}\n","import { diffAngleLines } from '@wemap/maths';\nimport { BoundingBox, Coordinates, Level, UserPosition, Level_t, Constants as GeoConstants } from '@wemap/geo';\n\nimport Edge from './Edge.js';\nimport GraphProjection from './GraphProjection.js';\nimport Vertex from './Vertex.js';\nimport { type GeoGraphJson } from '../types.js';\nimport { type GraphProjectionOptions } from './GraphProjectionOptions.js';\n\n\nclass Graph {\n\n /**\n * exitVertices are vertices that have at least one indoor edge and one outdoor edge\n * They are stored because the Level model cannot handle an indoor and outdoor state like [null, 1] or [null, [1,2]]\n * This vertices are used to cover the projection case:\n * - if projection origin is null, an exit vertex can be used\n * - if projection origin is not null, the intersection level with an exit vertex can be used\n */\n public readonly exitVertices: Set<Vertex>;\n\n constructor(public readonly vertices: Vertex[], public readonly edges: Edge[]) {\n const nullVertices = edges.filter(e => e.level === null).map(e => [e.vertex1, e.vertex2]).flat();\n const levelVertices = edges.filter(e => e.level !== null).map(e => [e.vertex1, e.vertex2]).flat();\n this.exitVertices = new Set(nullVertices.filter(v1 => levelVertices.includes(v1)));\n }\n\n getEdgeByVertices(vertex1: Vertex, vertex2: Vertex) {\n return Edge.getEdgeByVertices(this.edges, vertex1, vertex2);\n }\n\n getVertexByCoords(coords: Coordinates) {\n return Graph.getVertexByCoords(this.vertices, coords);\n }\n\n static getVertexByCoords(vertices: Vertex[], coords: Coordinates) {\n return vertices.find(vertex => vertex.coords.equals(coords));\n }\n\n getVertexByName(name: string) {\n return this.vertices.find(vertex => vertex.properties.name === name);\n }\n\n getEdgeByName(name: string) {\n return this.edges.find(edge => edge.properties.name === name);\n }\n\n getBoundingBox(extendedMeasure?: number) {\n if (!this.vertices.length) {\n return null;\n }\n const boundingBox = BoundingBox.fromCoordinates(this.vertices.map(vertex => vertex.coords)) as BoundingBox;\n if (extendedMeasure) {\n boundingBox.extendsWithMeasure(extendedMeasure);\n }\n return boundingBox;\n }\n\n getProjection<U extends (Coordinates | UserPosition)>(\n origin: U,\n options: GraphProjectionOptions = {}\n ): GraphProjection<U> | null {\n\n const useMaxDistance = 'maxDistance' in options;\n const maxDistance = options.maxDistance!\n\n const useMaxBearingAngle = 'maxBearingAngle' in options;\n if (useMaxBearingAngle && (!(origin instanceof UserPosition) || origin.bearing === null)) return null;\n const maxBearingAngle = options.maxBearingAngle!;\n\n const useAcceptEdgeFn = 'acceptEdgeFn' in options;\n\n const useMultiLevelSegments = !('useMultiLevelSegments' in options) || options.useMultiLevelSegments;\n\n let bestProjection: GraphProjection | null = null;\n\n this.edges.forEach(edge => {\n\n if (useAcceptEdgeFn && !options.acceptEdgeFn!(edge)) return;\n if (!useMultiLevelSegments && Level.isRange(edge.level)) return;\n if (!Level.intersect(edge.level, origin.level)) return;\n\n if (useMaxBearingAngle) {\n // Do not try to project if angle is greater than the threshold\n if (diffAngleLines(edge.bearing, (origin as UserPosition).bearing!) > maxBearingAngle) return;\n }\n\n const segmentProjection = origin.getSegmentProjection(edge.vertex1.coords, edge.vertex2.coords);\n if (!segmentProjection) return;\n const distanceToSegment = segmentProjection.distanceTo(origin);\n\n if (useMaxDistance && distanceToSegment > maxDistance) return;\n\n if (distanceToSegment < (bestProjection?.distanceFromNearestElement ?? Number.MAX_VALUE)) {\n bestProjection = new GraphProjection(origin, distanceToSegment, segmentProjection, edge);\n }\n });\n\n // if mapmatching bearing is enabled do not use vertices matching\n if (useMaxBearingAngle) {\n return bestProjection;\n }\n\n this.vertices.forEach(vertex => {\n let vertexCoords = vertex.coords;\n\n // Specific case of io nodes that have a non-null level but can be matched to a null origin level\n if (this.exitVertices.has(vertex) && origin.level === null) {\n vertexCoords = vertex.coords.clone();\n vertexCoords.level = null;\n }\n\n if (!useMultiLevelSegments && Level.isRange(vertexCoords.level)) return;\n if (!Level.intersect(vertexCoords.level, origin.level)) return;\n\n const distanceToVertex = vertexCoords.distanceTo(origin);\n\n // If distance below epsilon consider it as best projection\n if (distanceToVertex < GeoConstants.EPS_MM) {\n bestProjection = new GraphProjection(origin, 0, vertexCoords, vertex);\n return;\n }\n\n if (useMaxDistance && distanceToVertex > maxDistance) return;\n\n if (distanceToVertex < (bestProjection?.distanceFromNearestElement ?? Number.MAX_VALUE)) {\n bestProjection = new GraphProjection(origin, distanceToVertex, vertexCoords, vertex);\n }\n });\n\n return bestProjection;\n }\n\n\n toCompressedJson(): GeoGraphJson {\n return {\n vertices: this.vertices.map(vertex => vertex.toJson()),\n verticesIds: this.vertices.map(vertex => vertex.id),\n edges: this.edges.map(edge => {\n const vertex1Idx = this.vertices.indexOf(edge.vertex1);\n const vertex2Idx = this.vertices.indexOf(edge.vertex2);\n const edgeExtras = edge.properties;\n if (Object.keys(edgeExtras).length > 0) {\n return [vertex1Idx, vertex2Idx, edgeExtras];\n }\n return [vertex1Idx, vertex2Idx];\n })\n };\n }\n\n\n static fromCompressedJson(json: GeoGraphJson) {\n\n const vertices = json.vertices.map(vertex => Vertex.fromJson(vertex));\n const edges = json.edges.map(jsonEdge => new Edge(\n vertices[jsonEdge[0]],\n vertices[jsonEdge[1]],\n jsonEdge.length > 2 ? jsonEdge[2] : {}\n ));\n\n return new Graph(vertices, edges);\n }\n\n\n static fromCoordinatesSegments(segments: Coordinates[][]) {\n\n const vertices: Vertex[] = [];\n const edges: Edge[] = [];\n\n const getOrCreateVertex = (coords: Coordinates) => {\n const vertex = vertices.find(otherVertex => otherVertex.coords.equals(coords));\n if (vertex) {\n return vertex;\n }\n const newVertex = new Vertex(coords);\n vertices.push(newVertex);\n return newVertex;\n };\n\n for (const segment of segments) {\n\n let previousVertex = null;\n for (const coords of segment) {\n const currentVertex = getOrCreateVertex(coords);\n\n if (previousVertex) {\n edges.push(new Edge(currentVertex, previousVertex));\n }\n\n previousVertex = currentVertex;\n }\n }\n\n return new Graph(vertices, edges);\n }\n\n /**\n * Create edges From MultiLevel Itinerary for a given level\n * @param useMultiLevelEdges use segments which intersect both levels (stairs, elevators...)\n */\n getEdgesAtLevel(targetLevel: Level_t, useMultiLevelEdges = true) {\n return this.edges.filter(\n ({ level }) => useMultiLevelEdges\n ? Level.intersect(targetLevel, level)\n : Level.contains(targetLevel, level)\n );\n }\n\n\n toDetailedString() {\n let output\n = '--- Network ---\\n'\n + `Vertices: ${this.vertices.length}\\n`\n + `Edges: ${this.edges.length}\\n`\n + '---\\n'\n + 'Vertices\\n';\n this.vertices.forEach(vertex => {\n output += vertex.id;\n const vertexProps = vertex.properties;\n if (Object.keys(vertexProps).length !== 0) { output += ` ${vertexProps}` }\n });\n output += '---\\n'\n + 'Edges\\n';\n this.edges.forEach(edge => {\n output += `${edge.id} - [v1: ${edge.vertex1.id}, v2: ${edge.vertex2.id}]`;\n const edgeProps = edge.properties;\n if (Object.keys(edgeProps).length !== 0) { output += ` ${edgeProps}` }\n });\n output += '---';\n return output;\n }\n}\n\nexport default Graph;\n","/**\n * Get route duration\n * @param {Number} speed in km/h\n * @returns {Number} duration in seconds\n */\nexport function getDurationFromLength(length: number, speed = 5) {\n return length / (speed * 1000 / 3600);\n}\n","export type TransitMode = '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 isTransitModePublicTransport(routingMode: TransitMode): 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 { Coordinates } from '@wemap/geo';\n\nimport Graph from \"./Graph.js\";\nimport Edge from './Edge.js';\nimport Vertex from './Vertex.js';\nimport { getDurationFromLength } from '../Utils.js';\n\n\n/**\n * GraphRoute is an oriented graph\n */\nclass GraphRoute extends Graph {\n constructor(\n public start: Coordinates,\n public end: Coordinates,\n public vertices: Vertex[],\n public edges: Edge[],\n public edgesWeights: number[]\n ) {\n super(vertices, edges);\n }\n\n // /!\\ Does not clone vertices\n // /!\\ Create new Edges but does not deep clone properties\n // /!\\ Does not revert edge oneway property\n reverse() {\n const vertices = this.vertices.slice().reverse();\n const edges = this.edges.slice().reverse();\n const edgesWeights = this.edgesWeights.slice().reverse();\n edges.map(oldEdge => new Edge(oldEdge.vertex2, oldEdge.vertex1, oldEdge.properties));\n return new GraphRoute(this.start, this.end, vertices, edges, edgesWeights);\n }\n\n static fromCoordinates(start: Coordinates, end: Coordinates, coordinates: Coordinates[]) {\n const graph = Graph.fromCoordinatesSegments([coordinates]);\n const edgesWeights = graph.edges.map(e => getDurationFromLength(e.length));\n return new GraphRoute(start, end, graph.vertices, graph.edges, edgesWeights);\n }\n\n get hasRoute() { return Boolean(this.edges.length) }\n}\n\nexport default GraphRoute;\n","import { Coordinates, Level } from '@wemap/geo';\nimport Logger from '@wemap/logger';\nimport { diffAngle, deg2rad } from '@wemap/maths';\n\nimport { type LevelChange, type LevelChangeType } from './LevelChange.js';\nimport { type Step, type MinStepInfo } from './Step.js';\nimport { getDurationFromLength } from '../Utils.js';\nimport GraphRoute from '../graph/GraphRoute.js';\n\nconst SKIP_STEP_ANGLE_MAX = deg2rad(20);\n\nexport default class StepsBuilder {\n\n private start: Coordinates | null = null;\n private end: Coordinates | null = null;\n private pathCoords: Coordinates[] | null = null;\n private stepsInfo: MinStepInfo[] = [];\n\n setStart(start: Coordinates) {\n this.start = start;\n return this;\n }\n\n setEnd(end: Coordinates) {\n this.end = end;\n return this;\n }\n\n setPathCoords(pathCoords: Coordinates[]) {\n this.pathCoords = pathCoords;\n return this;\n }\n\n setStepsInfo(stepsInfo: MinStepInfo[]) {\n this.stepsInfo = stepsInfo;\n return this;\n }\n\n addStepInfo(stepInfo: MinStepInfo) {\n this.stepsInfo.push(stepInfo);\n return this;\n }\n\n setGraphRoute(graphRoute: GraphRoute) {\n\n const stepsInfo: MinStepInfo[] = [];\n\n const { start, end } = graphRoute;\n\n if (!graphRoute.hasRoute) { return this; }\n\n let currentStep: MinStepInfo | null = null;\n let previousBearing = start.bearingTo(graphRoute.vertices[0].coords);\n\n for (let i = 0; i < graphRoute.vertices.length - 1; i++) {\n\n const isFirstStep = i === 0;\n\n const vertex = graphRoute.vertices[i];\n const currentCoords = vertex.coords;\n const nextVertex = graphRoute.vertices[i + 1];\n const nextCoords = nextVertex.coords;\n\n const edge = graphRoute.edges[i];\n\n const nextBearing = vertex.bearingTo(nextVertex);\n const angle = diffAngle(previousBearing, nextBearing + Math.PI);\n\n const previousStep = stepsInfo.length ? stepsInfo[stepsInfo.length - 1] : null;\n\n const { isSubwayEntrance, isGate, subwayEntranceRef } = vertex.properties;\n const { isElevator, areEscalators, areStairs, isMovingWalkway, incline } = edge.properties;\n\n let levelChangeType: LevelChangeType | null = null;\n if (isElevator) {\n levelChangeType = 'elevator';\n } else if (areEscalators) {\n levelChangeType = 'escalator';\n } else if (areStairs) {\n levelChangeType = 'stairs';\n } else if (isMovingWalkway) {\n levelChangeType = 'moving walkway';\n }\n\n // Handle stairs/elevators/escalators/moving walkway without change in level coordinates\n let forceLevelChange: 'up' | 'down' | undefined;\n if (\n (areStairs || isElevator)\n && incline\n && !previousStep?.levelChange\n ) {\n forceLevelChange = incline;\n }\n\n const previousEdge = i > 0 ? graphRoute.edges[i - 1] : null;\n const previousEdgeProperties = previousEdge?.properties || {};\n const forceEndOfLevelChange = Boolean(\n previousEdgeProperties.incline && previousEdgeProperties.areStairs\n && (!incline || !areStairs)\n );\n const createNewStep = vertex.properties.isSubwayEntrance;\n\n const stepName = edge.properties.name || null;\n const duration = graphRoute.edgesWeights[i];\n const stepExtras = {\n ...(isSubwayEntrance && { isSubwayEntrance }),\n ...(subwayEntranceRef && { subwayEntranceRef }),\n ...(isGate && { isGate })\n };\n\n let splitByAngle = Math.abs(diffAngle(Math.PI, angle)) >= SKIP_STEP_ANGLE_MAX;\n\n const splitByLevel = Level.isRange(edge.level) && !Level.isRange(currentCoords.level) || forceLevelChange;\n splitByAngle = splitByAngle && !(currentCoords.level && Level.isRange(currentCoords.level));\n\n\n const splitByEndOfLevelChange = previousStep?.levelChange && !Level.isRange(currentCoords.level)\n || forceEndOfLevelChange;\n\n const splitStepCondition = splitByAngle || splitByLevel || splitByEndOfLevelChange || 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 (forceLevelChange) {\n direction = forceLevelChange;\n }\n levelChange = {\n difference, direction, ...(levelChangeType && { type: levelChangeType })\n };\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 ...(stepName && { name: stepName }),\n extras: stepExtras,\n levelChange,\n distance: 0,\n duration: 0\n };\n\n stepsInfo.push(currentStep);\n }\n\n currentStep!.distance! += currentCoords.distanceTo(nextCoords);\n if (duration) {\n currentStep!.duration! += duration;\n }\n previousBearing = nextBearing;\n }\n\n const lastCoords = graphRoute.vertices[graphRoute.vertices.length - 1].coords;\n\n // Create a last step if end is not on the graph\n if (!Coordinates.equals(lastCoords, end)) {\n stepsInfo.push({ coords: lastCoords });\n }\n\n this.setStart(start);\n this.setEnd(end);\n this.setPathCoords(graphRoute.vertices.map(v => v.coords));\n this.setStepsInfo(stepsInfo);\n\n return this;\n }\n\n build(): Step[] {\n\n const { pathCoords, start, end } = this;\n\n if (!pathCoords) {\n Logger.warn(`StepsBuilder: Missing \"pathCoords\" property to build steps`);\n return [];\n }\n\n if (!start) {\n Logger.warn(`StepsBuilder: Missing \"from\" property to build steps`);\n return [];\n }\n\n if (!end) {\n Logger.warn(`StepsBuilder: Missing \"to\" property to build steps`);\n return [];\n }\n\n if (this.stepsInfo.length === 0) {\n // If there is no steps info, steps coordinates are calculated using our steps calculation algorithm above.\n this.setGraphRoute(GraphRoute.fromCoordinates(start, end, pathCoords));\n }\n\n const { stepsInfo } = this;\n\n return stepsInfo.map((stepInfo, stepId) => {\n const coordsId = pathCoords.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 ? start : pathCoords[coordsId - 1];\n const coordsAfterStep = coordsId === pathCoords.length - 1\n ? end\n : pathCoords[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 : pathCoords[pathCoords.length - 1];\n let currentCoordsId = coordsId;\n while (!pathCoords[currentCoordsId].equals(coordsToStopCalculation)) {\n distance += pathCoords[currentCoordsId].distanceTo(pathCoords[currentCoordsId + 1]);\n currentCoordsId++;\n }\n if (currentCoordsId === pathCoords.length - 1) {\n distance += pathCoords[currentCoordsId].distanceTo(end);\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}\n","import {\n Coordinates, CoordinatesCompressedJson, Level, Utils as GeoUtils\n} from '@wemap/geo';\n\nimport Graph from '../graph/Graph.js';\nimport GraphRoute from '../graph/GraphRoute.js';\nimport { getDurationFromLength } from '../Utils.js';\nimport { TransitMode, isTransitModePublicTransport } from './TransitMode.js';\n\nimport { jsonToStep, Step, stepEquals, StepJson, stepToJson } from './Step.js'\nimport StepsBuilder from './StepsBuilder.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 transitMode: TransitMode,\n startTime?: number,\n endTime?: number,\n transportInfo?: TransportInfo,\n}\n\ntype LegConstructor =\n {\n start: DestinationConstructor,\n end: DestinationConstructor,\n coords: Coordinates[],\n steps?: Step[],\n duration?: number\n }\n & LegCommon;\n\nexport type LegJson = {\n start: DestinationJson,\n end: DestinationJson,\n coords: CoordinatesCompressedJson[],\n steps: StepJson[],\n distance: number,\n duration: number\n} & LegCommon;\n\nexport default class Leg {\n\n start: Destination;\n end: Destination;\n coords: Coordinates[];\n distance: number;\n transitMode: TransitMode;\n\n duration: number;\n startTime: number | null;\n endTime: number | null;\n\n steps: Step[];\n transportInfo: TransportInfo | null;\n\n constructor({\n start, end, coords, transitMode, duration,\n startTime, endTime, transportInfo, steps\n }: LegConstructor) {\n this.start = {\n name: start.name || null,\n coords: start.coords\n };\n this.end = {\n name: end.name || null,\n coords: end.coords\n };\n this.coords = coords;\n this.transitMode = transitMode;\n this.distance = GeoUtils.calcDistance(coords)\n this.duration = typeof duration === 'number' ? duration : getDurationFromLength(this.distance);\n this.startTime = typeof startTime === 'number' ? startTime : null;\n this.endTime = typeof endTime === 'number' ? endTime : null;\n this.transportInfo = transportInfo || null;\n this.steps = Array.isArray(steps)\n ? steps\n : new StepsBuilder().setStart(start.coords).setEnd(end.coords).setPathCoords(coords).build();\n }\n\n isPublicTransport() {\n return isTransitModePublicTransport(this.transitMode);\n }\n\n toGraph() {\n return Graph.fromCoordinatesSegments([this.coords]);\n }\n\n static equals(obj1: Leg, obj2: Leg) {\n const intermediate = obj1.transitMode === obj2.transitMode\n && Math.abs(obj1.duration - obj2.duration) <= 0.05\n && obj1.startTime === obj2.startTime\n && obj1.endTime === obj2.endTime\n && obj1.start.name === obj2.start.name\n && obj1.start.coords.equals(obj2.start.coords)\n && obj1.end.name === obj2.end.name\n && obj1.end.coords.equals(obj2.end.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 transitMode: this.transitMode,\n start: {\n coords: this.start.coords.toCompressedJson(),\n ...(this.start.name && { name: this.start.name }),\n },\n end: {\n coords: this.end.coords.toCompressedJson(),\n ...(this.end.name && { name: this.end.name }),\n },\n distance: Number(this.distance.toFixed(1)),\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 start: {\n coords: Coordinates.fromCompressedJson(json.start.coords),\n name: json.start.name || null\n },\n end: {\n coords: Coordinates.fromCompressedJson(json.end.coords),\n name: json.end.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 static fromGraphRoute(\n graphRoute: GraphRoute,\n transitMode: TransitMode = 'WALK'\n ) {\n return new Leg({\n start: { coords: graphRoute.start },\n end: { coords: graphRoute.end },\n coords: graphRoute.vertices.map(vertex => vertex.coords),\n duration: graphRoute.edgesWeights.reduce((acc, weight) => acc + weight, 0),\n transitMode,\n steps: new StepsBuilder().setGraphRoute(graphRoute).build()\n });\n }\n\n // TODO: Remove when possible...\n // Livemap specific\n multiplyLevel(levelFactor: number) {\n this.start.coords.level = Level.multiplyBy(this.start.coords.level, levelFactor);\n this.end.coords.level = Level.multiplyBy(this.end.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","import { Feature, FeatureCollection, MultiLineString, Point } from 'geojson';\nimport { Coordinates, Level, Utils as GeoUtils, CoordinatesJson, Level_t } from '@wemap/geo';\nimport { diffAngle, Point2_t, Vector3_t } from '@wemap/maths';\n\nimport Graph from '../graph/Graph.js';\nimport Leg, { type LegJson } from './Leg.js';\nimport { isTransitModePublicTransport, type TransitMode } from './TransitMode.js';\nimport { Step } from './Step.js';\nimport { getDurationFromLength } from '../Utils.js';\nimport StepsBuilder from './StepsBuilder.js';\nimport GraphRoute from '../graph/GraphRoute.js';\n\n\nexport type ItineraryCommon = {\n startTime?: number,\n endTime?: number\n};\n\nexport type ItineraryJson = {\n transitMode: TransitMode,\n origin: CoordinatesJson,\n destination: CoordinatesJson,\n distance: number,\n duration: number,\n legs: LegJson[]\n} & ItineraryCommon;\n\n\nexport type ItineraryConstructor = {\n origin: Coordinates,\n destination: 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 origin: Coordinates;\n destination: Coordinates;\n duration: number;\n readonly legs: Leg[];\n\n private _transitMode: TransitMode | 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 origin, destination, duration, legs, startTime, endTime\n }: ItineraryConstructor) {\n this.origin = origin;\n this.destination = destination;\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 transitMode(_) {\n throw new Error('Itinerary.mode cannot be set. They are calculated from Itinerary.legs.');\n }\n\n get transitMode() {\n if (!this._transitMode) {\n let isPublicTransport = false;\n let isBicycle = false;\n let isDriving = false;\n\n this.legs.forEach((leg) => {\n isPublicTransport = isPublicTransport || isTransitModePublicTransport(leg.transitMode);\n isBicycle = isBicycle || leg.transitMode === 'BIKE';\n isDriving = isDriving || leg.transitMode === 'CAR';\n });\n\n if (isPublicTransport) {\n this._transitMode = 'MULTI';\n } else if (isDriving) {\n this._transitMode = 'CAR';\n } else if (isBicycle) {\n this._transitMode = 'BIKE';\n } else {\n this._transitMode = 'WALK';\n }\n }\n\n return this._transitMode;\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 Graph.fromCoordinatesSegments([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 origin: itineraries[0].origin,\n destination: itineraries[itineraries.length - 1].destination,\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 origin: Coordinates,\n destination: Coordinates,\n transitMode: TransitMode = 'WALK'\n ) {\n\n const steps = new StepsBuilder().setPathCoords(coords).setStart(origin).setEnd(destination).build();\n\n const leg = new Leg({\n start: { coords: origin },\n end: { coords: destination },\n coords,\n transitMode,\n steps\n });\n\n return new Itinerary({ origin, destination, legs: [leg] });\n }\n\n\n static equals(obj1: Itinerary, obj2: Itinerary) {\n const intermediate = obj1.origin.equals(obj2.origin)\n && obj1.destination.equals(obj2.destination)\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 origin: this.origin.toJson(),\n destination: this.destination.toJson(),\n distance: Number(this.distance.toFixed(1)),\n duration: Number(this.duration.toFixed(1)),\n transitMode: this.transitMode,\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 origin: Coordinates.fromJson(json.origin),\n destination: Coordinates.fromJson(json.destination),\n duration: json.duration,\n legs: json.legs.map(Leg.fromJson),\n startTime: json.startTime,\n endTime: json.endTime\n });\n }\n\n static fromGraphRoute(graphRoute: GraphRoute, transitMode: TransitMode = 'WALK') {\n const leg = Leg.fromGraphRoute(graphRoute, transitMode);\n return new Itinerary({\n origin: graphRoute.start,\n destination: graphRoute.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.origin.level = Level.multiplyBy(this.origin.level, levelFactor);\n this.destination.level = Level.multiplyBy(this.destination.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.origin.level = this.origin.level || 0;\n this.destination.level = this.destination.level || 0;\n\n for (const leg of this.legs) {\n leg.start.coords.level = leg.start.coords.level || 0;\n leg.end.coords.level = leg.end.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(): FeatureCollection {\n const transformToPoint = (point: Coordinates, name?: string, type?: string): Feature<Point> => ({\n type: \"Feature\",\n properties: { name, level: point.level, ...(type && { type }) },\n geometry: {\n type: 'Point',\n coordinates: [point.lng, point.lat]\n }\n });\n const transformToMultiLineStrings = (segments: Coordinates[][], level: Level_t): Feature<MultiLineString> => ({\n type: \"Feature\",\n properties: { level, name: level?.toString() },\n geometry: {\n type: 'MultiLineString',\n coordinates: segments.map(s => s.map(({ lat, lng }) => [lng, lat]))\n }\n });\n\n const levelsOfItinerary = [...new Set(this.coords.map(c => Level.toString(c.level)))].map(Level.fromString);\n const segmentsSplitted: [Level_t, Coordinates[][]][] = levelsOfItinerary.map(loi => [loi, GeoUtils.createSegmentsAtLevel(this.coords, loi, true)]);\n const multiLineStrings = segmentsSplitted.map(([loi, segments]) => transformToMultiLineStrings(segments, loi))\n const legsStarts = this.legs.map((leg, idx) => transformToPoint(leg.start.coords, `Leg ${idx} start`, 'leg-start'));\n const legsEnds = this.legs.map((leg, idx) => transformToPoint(leg.end.coords, `Leg ${idx} end`, 'leg-end'));\n const steps = this.steps.map(step => transformToPoint(step.coords, `Step ${step.number}`, 'step'))\n return {\n type: \"FeatureCollection\",\n features: [\n transformToPoint(this.origin, 'origin', 'origin'),\n transformToPoint(this.destination, 'destination', 'destination'),\n ...multiLineStrings,\n ...legsStarts,\n ...legsEnds,\n ...steps\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.origin : itineraryCoords[coordsId - 1];\n const coordsAfterStep = coordsId === itineraryCoords.length - 1\n ? this.destination\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.destination);\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 Edge from './Edge.js';\nimport { getDurationFromLength } from '../Utils.js';\nimport { GraphRouterOptionsJson, type GraphRouterOptions } from './GraphRouterOptions.js';\n\nexport default class GraphRouterOptionsBuilder {\n\n public avoidStairs = false;\n public avoidEscalators = false;\n public avoidElevators = false;\n public avoidMovingWalkway = false;\n public avoidTicketRestrictedAreas = false;\n\n public projectionMaxDistance?: number;\n\n static DEFAULT = new GraphRouterOptionsBuilder().build();\n static WITHOUT_STAIRS = new GraphRouterOptionsBuilder().setAvoidStairs(true).build();\n\n setAvoidStairs(avoidStairs: boolean) {\n this.avoidStairs = avoidStairs;\n return this;\n }\n\n setAvoidEscalators(avoidEscalators: boolean) {\n this.avoidEscalators = avoidEscalators;\n return this;\n }\n\n setAvoidElevators(avoidElevators: boolean) {\n this.avoidElevators = avoidElevators;\n return this;\n }\n\n setAvoidMovingWalkway(avoidMovingWalkway: boolean) {\n this.avoidMovingWalkway = avoidMovingWalkway;\n return this;\n }\n\n setAvoidTicketRestrictedAreas(avoidTicketRestrictedAreas: boolean) {\n this.avoidTicketRestrictedAreas = avoidTicketRestrictedAreas;\n return this;\n }\n\n static fromJson(options: GraphRouterOptionsJson) {\n const builder = new GraphRouterOptionsBuilder();\n Object.assign(builder, options);\n return builder.build();\n }\n\n build(): GraphRouterOptions {\n\n const weightEdgeFn = (edge: Edge) => {\n if (edge.properties.isElevator) {\n return 90;\n }\n let duration = getDurationFromLength(edge.length, 4);\n if (edge.properties.areStairs) {\n duration *= 3;\n }\n return duration;\n }\n\n const acceptEdgeFn = (edge: Edge) => {\n\n if (this.avoidStairs && edge.properties.areStairs) return false;\n if (this.avoidEscalators && edge.properties.areEscalators) return false;\n if (this.avoidElevators && edge.properties.isElevator) return false;\n if (this.avoidMovingWalkway && edge.properties.isMovingWalkway) return false;\n if (this.avoidTicketRestrictedAreas && edge.properties.needTicket) return false;\n\n return true;\n };\n\n return {\n input: {\n avoidStairs: this.avoidStairs,\n avoidEscalators: this.avoidEscalators,\n avoidElevators: this.avoidElevators,\n avoidMovingWalkway: this.avoidMovingWalkway,\n avoidTicketRestrictedAreas: this.avoidTicketRestrictedAreas,\n projectionMaxDistance: this.projectionMaxDistance\n },\n weightEdgeFn,\n acceptEdgeFn,\n projectionMaxDistance: this.projectionMaxDistance\n };\n }\n\n}\n","\nimport Edge from './Edge.js';\nimport Graph from './Graph.js';\nimport GraphRoute from './GraphRoute.js';\nimport { type GraphRouterOptions } from './GraphRouterOptions.js';\nimport GraphRouterOptionsBuilder from './GraphRouterOptionsBuilder.js';\nimport Vertex from './Vertex.js';\n\nexport class GraphRouterEngineResults {\n constructor(\n public prev: Array<Vertex | null>,\n public dist: number[],\n public source: Vertex,\n public targets: Vertex[],\n public edges: Edge[]\n ) { }\n\n routeVertices(to = this.targets[0], list: Vertex[] = []): Vertex[] {\n const last = this.prev[to.id];\n if (last === null) return this.source === to ? [...list, to] : [];\n return [...this.routeVertices(last, list), to];\n }\n\n weightedDistance(to = this.targets[0]) {\n const distance = this.dist[to.id];\n return distance === Number.MAX_VALUE ? null : distance;\n }\n\n route(to = this.targets[0]) {\n\n const path = this.routeVertices(to);\n\n const edges = [];\n const edgesWeights = [];\n for (let i = 1; i < path.length; i++) {\n const v1 = path[i - 1];\n const v2 = path[i];\n const graphEdge = Edge.getEdgeByVertices(this.edges, v1, v2)!;\n const clonedEdge = new Edge(v1, v2, Object.assign({}, graphEdge.properties));\n const isReversed = graphEdge.vertex1 === clonedEdge.vertex2;\n if (isReversed) {\n clonedEdge.reverseProperties();\n }\n edges.push(clonedEdge);\n edgesWeights.push(this.dist[v2.id] - this.dist[v1.id]);\n }\n return new GraphRoute(this.source.coords, to.coords, path, edges, edgesWeights);\n }\n\n toGeoJson(graph: Graph) {\n return {\n type: \"FeatureCollection\",\n features: [\n ...graph.vertices.map(v => {\n const prev = this.prev[v.id];\n const dist = this.dist[v.id];\n const isSource = v === this.source;\n const isTarget = this.targets.includes(v);\n const level = v.coords.level;\n return {\n type: \"Feature\",\n properties: {\n id: v.id,\n ...(prev && { prev: prev.id }),\n dist: dist === Number.MAX_VALUE ? 'infinity' : dist,\n ...(isSource && { name: 'source' }),\n ...(isTarget && { name: 'target' }),\n ...(level !== null && { level }),\n ...v.properties\n },\n geometry: {\n type: 'Point',\n coordinates: [v.coords.lng, v.coords.lat]\n }\n }\n }),\n ...graph.edges.map(e => {\n const level = e.level;\n return {\n type: \"Feature\",\n properties: {\n id: e.id,\n ...(level !== null && { level }),\n ...e.properties\n },\n geometry: {\n type: 'LineString',\n coordinates: [\n [e.vertex1.coords.lng, e.vertex1.coords.lat],\n [e.vertex2.coords.lng, e.vertex2.coords.lat]\n ]\n }\n }\n })\n ]\n };\n }\n}\n\nexport default class GraphRouterEngine {\n\n disabledEdges: Set<Edge> = new Set();\n\n constructor(public readonly graph: Graph) {\n let vertexId = 0;\n graph.vertices.forEach(vertex => vertex.id = vertexId++);\n }\n\n calculateShortestPathToMultipleDestinationsByVertex(\n source: Vertex,\n targets: Vertex[],\n options: GraphRouterOptions = GraphRouterOptionsBuilder.DEFAULT,\n inputVertices = this.graph.vertices,\n inputEdges = this.graph.edges\n ): GraphRouterEngineResults {\n\n const q = new Set(inputVertices);\n const dist = Array(q.size).fill(Number.MAX_VALUE);\n const prev = new Array<Vertex | null>(q.size).fill(null);\n const edges = inputEdges.filter(e => (options.acceptEdgeFn?.(e) ?? true) && !this.disabledEdges.has(e));\n const weightEdgeFn = options.weightEdgeFn || ((edge: Edge) => edge.length);\n\n const getVertexWithMinDistance = (vertices: Set<Vertex>): Vertex | null => {\n let minDistance = Number.MAX_VALUE;\n let vertex: Vertex | null = null;\n vertices.forEach(_vertex => {\n const distance = dist[_vertex.id];\n if (distance <= minDistance) {\n minDistance = distance;\n vertex = _vertex;\n }\n });\n return vertex;\n }\n\n\n const remainingNodesToFind = new Set(targets);\n\n dist[source.id] = 0;\n\n while (q.size > 0) {\n const u = getVertexWithMinDistance(q)!;\n q.delete(u);\n\n if (targets.includes(u)) {\n remainingNodesToFind.delete(u);\n if (remainingNodesToFind.size === 0) {\n break;\n }\n }\n\n edges\n .filter(edge => edge.vertex1 == u || !edge.properties.isOneway && edge.vertex2 == u)\n .forEach(edge => {\n const v = u === edge.vertex1 ? edge.vertex2 : edge.vertex1;\n const distance = weightEdgeFn(edge);\n const alt = dist[u.id] + distance;\n if (alt < dist[v.id]) {\n dist[v.id] = alt;\n prev[v.id] = u\n }\n });\n }\n\n return new GraphRouterEngineResults(prev, dist, source, targets, edges);\n }\n\n calculateShortestPathByVertex(\n source: Vertex,\n target: Vertex,\n options: GraphRouterOptions = GraphRouterOptionsBuilder.DEFAULT,\n inputVertices = this.graph.vertices,\n inputEdges = this.graph.edges\n ): GraphRouterEngineResults {\n return this.calculateShortestPathToMultipleDestinationsByVertex(source, [target], options, inputVertices, inputEdges);\n }\n\n // https://en.wikipedia.org/wiki/Component_(graph_theory)\n calculateComponents() {\n\n function shiftSet<T>(set: Set<T>): T {\n const firstValue = set.values().next().value as T;\n set.delete(firstValue);\n return firstValue;\n }\n\n const verticesToTest = new Set<Vertex>(this.graph.vertices);\n let components: Vertex[][] = [];\n\n while (verticesToTest.size > 0) {\n const vertexToTest = shiftSet(verticesToTest);\n const otherVertices = this.graph.vertices.filter(v => v.id !== vertexToTest.id);\n const result = this.calculateShortestPathToMultipleDestinationsByVertex(vertexToTest, otherVertices);\n const reachedVertices = otherVertices.filter(ov => result.weightedDistance(ov) !== null);\n\n components.push([vertexToTest, ...reachedVertices]);\n reachedVertices.forEach(rv => verticesToTest.delete(rv));\n }\n\n // As graph is ordered, fuse components with same vertices\n for (let i = 0; i < components.length - 1; i++) {\n const component1 = components[i];\n for (let j = i + 1; j < components.length; j++) {\n const component2 = components[j];\n const componentsIntersect = component2.some(v => component1.includes(v));\n if (componentsIntersect) {\n component1.push(...component2);\n components = components.filter(component => component !== component2);\n }\n }\n }\n\n return components.map(c => [... new Set(c)]);\n }\n\n}\n","import salesman from '@wemap/salesman.js';\n\nimport { Coordinates } from '@wemap/geo';\n\nimport Vertex from './Vertex.js';\nimport Edge, { EdgeProperties } from './Edge.js';\nimport GraphRoute from './GraphRoute.js';\nimport GraphRouterEngine, { GraphRouterEngineResults } from './GraphRouterEngine.js';\nimport { type GraphRouterOptions } from './GraphRouterOptions.js';\nimport GraphRouterOptionsBuilder from './GraphRouterOptionsBuilder.js';\n\nexport class GraphRouterResults extends GraphRouterEngineResults {\n\n constructor(\n engineResults: GraphRouterEngineResults,\n public sourceProjection: [Coordinates, Vertex | null],\n public targetsProjections: [Coordinates, Vertex | null][]\n\n ) {\n super(engineResults.prev, engineResults.dist, engineResults.source, engineResults.targets, engineResults.edges);\n }\n\n static createEmpty(source: Coordinates, targets: Coordinates[]) {\n const length = targets.length;\n const engineResults = new GraphRouterEngineResults(\n new Array(length).fill(null),\n new Array(length).fill(Number.MAX_VALUE),\n new Vertex(source),\n targets.map(target => new Vertex(target)),\n []\n );\n const sourceProjection: [Coordinates, null] = [source, null];\n const targetsProjections: [Coordinates, null][] = targets.map(target => [target, null]);\n return new GraphRouterResults(engineResults, sourceProjection, targetsProjections);\n }\n\n routeVertices(to: Coordinates | Vertex = this.targetsProjections[0][0]): Vertex[] {\n\n if (to instanceof Vertex) {\n return super.routeVertices(to);\n }\n\n const sourceVertex = this.sourceProjection[1];\n if (!sourceVertex) return [];\n\n const toVertex = this.targetsProjections.find(([coord]) => coord === to)?.[1];\n if (!toVertex) return [];\n\n return super.routeVertices(toVertex);\n }\n\n weightedDistance(to: Coordinates | Vertex = this.targetsProjections[0][0]) {\n\n if (to instanceof Vertex) {\n return super.weightedDistance(to);\n }\n\n const sourceVertex = this.sourceProjection[1];\n if (!sourceVertex) return null;\n\n const toVertex = this.targetsProjections.find(([coord]) => coord === to)?.[1];\n if (!toVertex) return null;\n\n return super.weightedDistance(toVertex);\n }\n\n route(to: Coordinates | Vertex = this.targetsProjections[0][0]) {\n\n if (to instanceof Vertex) {\n return super.route(to);\n }\n\n const toVertex = this.targetsProjections.find(([coord]) => coord === to)?.[1];\n if (!toVertex) return new GraphRoute(this.sourceProjection[0], to, [], [], []);\n\n const route = super.route(toVertex);\n route.start = this.sourceProjection[0];\n route.end = to;\n return route;\n }\n}\n\n\nclass GraphRouter extends GraphRouterEngine {\n\n calculateShortestPathToMultipleDestinations(\n source: Coordinates,\n targets: Coordinates[],\n options: GraphRouterOptions = GraphRouterOptionsBuilder.DEFAULT,\n ): GraphRouterResults {\n\n const createdVertices = new Set<Vertex>();\n const createdEdges = new Set<Edge>();\n const createdVerticesByOriginalEdges: [Edge, Vertex[]][] = []\n\n const projectionsOptions = {\n maxDistance: options.projectionMaxDistance,\n acceptEdgeFn: options.acceptEdgeFn\n };\n\n const getOrCreateVertex = (coords: Coordinates): Vertex | null => {\n const projection = this.graph.getProjection(coords, projectionsOptions);\n if (projection === null) return null;\n if (projection.nearestElement instanceof Vertex) {\n return projection.nearestElement;\n }\n if (projection.nearestElement instanceof Edge) {\n const edge = projection.nearestElement;\n const newVertex = new Vertex(projection.coords, {\n name: `proj on ${edge.properties.name || null} (tmp)`,\n ...(typeof edge.properties.externalId !== 'undefined' && { externalId: edge.properties.externalId })\n });\n newVertex.id = this.graph.vertices.length + createdVertices.size;\n const newEdgesOptions: EdgeProperties = {\n ...edge.properties,\n name: `splitted ${edge.properties.name || null} (tmp)`,\n ...(typeof edge.properties.externalId !== 'undefined' && { externalId: edge.properties.externalId })\n };\n const newEdge1 = new Edge(edge.vertex1, newVertex, newEdgesOptions);\n const newEdge2 = new Edge(newVertex, edge.vertex2, newEdgesOptions);\n\n createdVertices.add(newVertex);\n createdEdges.add(newEdge1);\n createdEdges.add(newEdge2);\n\n const createdVerticesByOriginalEdge = createdVerticesByOriginalEdges.find(p => p[0] === edge)\n if (!createdVerticesByOriginalEdge) {\n createdVerticesByOriginalEdges.push([edge, [newVertex]])\n } else {\n createdVerticesByOriginalEdge[1].push(newVertex);\n }\n return newVertex;\n }\n\n return null; // Should never happens\n }\n\n const sourceVertex = getOrCreateVertex(source);\n if (!sourceVertex) return GraphRouterResults.createEmpty(source, targets);\n\n const targetsProjections: [Coordinates, Vertex | null][] = targets.map(target => [target, getOrCreateVertex(target)]);\n const targetsVertices = targetsProjections.map(([, vertex]) => vertex).filter(p => p !== null) as Vertex[];\n\n // In some specific cases, more than one vertex is created from an original edge.\n // And this vertices need to be connected together.\n createdVerticesByOriginalEdges.filter(pair => pair[1].length >= 2);\n createdVerticesByOriginalEdges.forEach(([edge, vertices]) => {\n const newEdgesOptions: EdgeProperties = {\n ...edge.properties,\n name: `splitted ${edge.properties.name || null} (tmp)`,\n };\n for (let i = 0; i < vertices.length; i++) {\n const vertexA = vertices[i];\n const distVertexAVertex1 = vertexA.distanceTo(edge.vertex1)\n for (let j = i + 1; j < vertices.length; j++) {\n const vertexB = vertices[j];\n const distVertexBVertex1 = vertexA.distanceTo(edge.vertex1)\n const reverse = distVertexBVertex1 < distVertexAVertex1;\n const newEdge = !reverse\n ? new Edge(vertexA, vertexB, newEdgesOptions)\n : new Edge(vertexB, vertexA, newEdgesOptions);\n createdEdges.add(newEdge);\n }\n }\n })\n\n\n const engineResults = this.calculateShortestPathToMultipleDestinationsByVertex(\n sourceVertex, targetsVertices, options,\n [...this.graph.vertices, ...createdVertices],\n [...this.graph.edges, ...createdEdges],\n );\n\n return new GraphRouterResults(engineResults, [source, sourceVertex], targetsProjections);\n }\n\n calculateShortestPath(\n source: Coordinates,\n target: Coordinates,\n options: GraphRouterOptions = GraphRouterOptionsBuilder.DEFAULT,\n ): GraphRouterResults {\n return this.calculateShortestPathToMultipleDestinations(source, [target], options);\n }\n\n\n // TODO: Verify if it works well with oneway edges\n getShortestTrip(waypoints: Coordinates[], options?: GraphRouterOptions, tspTempCoeff = 0.99) {\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 graphRoutesCache: GraphRoute[] = [];\n const solution = salesman.solve(points, tspTempCoeff, undefined, (p: salesman.Point, q: salesman.Point) => {\n const route = this.calculateShortestPath(\n (p as CustomPoint).coords,\n (q as CustomPoint).coords,\n options\n ).route();\n graphRoutesCache.push(route);\n if (!route.hasRoute) { return Number.MAX_VALUE }\n return route.edgesWeights.reduce((acc, weight) => acc + weight, 0);\n });\n\n const orderedPoints = solution.map(i => points[i]);\n const orderedRoutes = [];\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 cachedRoute = graphRoutesCache.find(route => route.start === p.coords && route.end === q.coords || route.end === p.coords && route.start === q.coords);\n if (cachedRoute?.end === p.coords) {\n // Need to revert route due to salesman bijectivity\n cachedRoute = cachedRoute.reverse();\n }\n if (cachedRoute) {\n orderedRoutes.push(cachedRoute);\n }\n }\n\n if (orderedRoutes.some(route => !route.hasRoute)) return [];\n\n return orderedRoutes;\n }\n\n\n}\nexport default GraphRouter;\n","import { Coordinates } from '@wemap/geo';\n\nimport Vertex from './Vertex.js';\n\nclass NoRouteFoundError extends Error {\n\n constructor(\n public start: Vertex | Coordinates,\n public end: Vertex | Coordinates | (Coordinates | Vertex)[],\n public details: string | null = null\n ) { super(); }\n\n get startStr() {\n if (this.start instanceof Vertex) {\n return `Vertex ${this.start.coords.toString()}`;\n }\n return this.start.toString();\n }\n\n get endStr() {\n if (this.end instanceof Vertex) {\n return `Vertex ${this.end.coords.toString()}`;\n }\n if (Array.isArray(this.end)) {\n return this.end.map(p => p instanceof Vertex ? p.coords.toString() : p.toString()).join(',');\n }\n return this.end.toString();\n }\n\n get message() {\n let message = `No route found from ${this.startStr} to ${this.endStr}.`;\n if (this.details) {\n message += ` Details: ${this.details}`;\n }\n return message;\n }\n}\n\nexport default NoRouteFoundError;\n","import { Coordinates, Level, Level_t } from '@wemap/geo';\nimport { OsmModel, OsmNode, OsmWay } from '@wemap/osm';\n\nimport Graph from '../graph/Graph.js';\nimport { default as Edge, type EdgeProperties } from '../graph/Edge.js';\nimport { default as Vertex, type VertexProperties } from '../graph/Vertex.js';\n\n\nexport default class OsmGraphUtils {\n\n static RESTRICTED_PEDESTRIANS_HIGHWAYS = ['motorway', 'motorway_link'];\n\n static DEFAULT_WAY_SELECTOR = (way: OsmWay) => {\n if (way.isArea) return false;\n const isElevatorArea = way.tags.highway === 'elevator' && way.isGeometryClosed\n return way.tags.highway && !OsmGraphUtils.RESTRICTED_PEDESTRIANS_HIGHWAYS.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\n static parseNodeProperties(osmNode: OsmNode): VertexProperties {\n return {\n ...(osmNode.name && { name: osmNode.name }),\n ...(osmNode.id && { externalId: osmNode.id }),\n ...(osmNode.isGate && { isGate: osmNode.isGate }),\n ...(osmNode.isSubwayEntrance && { isSubwayEntrance: osmNode.isSubwayEntrance }),\n ...(osmNode.subwayEntranceRef && { subwayEntrsanceRef: osmNode.subwayEntranceRef })\n }\n }\n\n static parseWayProperties(osmWay: OsmWay): EdgeProperties {\n return {\n ...(osmWay.name && { name: osmWay.name }),\n ...(osmWay.id && { externalId: osmWay.id }),\n ...(osmWay.isOneway && { isOneway: osmWay.isOneway }),\n ...(osmWay.areStairs && { areStairs: osmWay.areStairs }),\n ...(osmWay.isElevator && { isElevator: osmWay.isElevator }),\n ...(osmWay.areEscalators && { areEscalators: osmWay.areEscalators }),\n ...(osmWay.isMovingWalkway && { isMovingWalkway: osmWay.isMovingWalkway }),\n ...(osmWay.needTicket && { needTicket: osmWay.needTicket }),\n ...(osmWay.incline && { incline: osmWay.incline })\n }\n }\n\n static createGraphFromOsmModel(\n osmModel: OsmModel,\n waySelectionFilter = OsmGraphUtils.DEFAULT_WAY_SELECTOR,\n callbackVerticesMapping?: (mapping: [nodeId: number, vertex: Vertex][]) => void\n ) {\n\n const edges: Edge[] = [];\n const verticesMapping: [nodeId: number, vertex: Vertex][] = [];\n const elevatorVertices: [id: number, name: string | undefined, vertices: Vertex[]][] = [];\n\n // 1. Create a function to retrieve a vertex which has already been created and avoid duplicates\n const getOrCreateVertex = (osmNode: OsmNode, nodeLevel: Level_t) => {\n\n // Check if a vertex with same coordinates already exists\n let vertex: Vertex | null = verticesMapping\n .find(([nodeId, v]) => {\n if (nodeId !== osmNode.id) return false;\n if (Level.intersect(v.coords.level, nodeLevel)) return true;\n // Specific case of exits\n return v.coords.level === null || nodeLevel === null;\n })?.[1] || null;\n\n // If the vertex already exists, return it\n if (vertex) {\n // In the case where vertices are linked to edges with level change\n if (!Level.equals(vertex.coords.level, nodeLevel)) {\n vertex.coords.level = Level.intersection(vertex.coords.level, nodeLevel);\n }\n return vertex;\n }\n\n // If it does not exist, create it\n const newCoords = new Coordinates(osmNode.coords.lat, osmNode.coords.lng, null, nodeLevel)\n vertex = new Vertex(newCoords, this.parseNodeProperties(osmNode));\n\n verticesMapping.push([osmNode.id, vertex]);\n\n if (osmNode.isElevator) {\n let elevatorEntry = elevatorVertices.find(([id]) => osmNode.id === id);\n if (!elevatorEntry) {\n elevatorEntry = [osmNode.id, osmNode.name, []];\n elevatorVertices.push(elevatorEntry);\n }\n elevatorEntry[2].push(vertex);\n }\n\n return vertex;\n };\n\n // 2. Go through OSM ways to create edges and vertices\n osmModel.ways.forEach(way => {\n if (!waySelectionFilter(way)) {\n return;\n }\n\n const edgeProperties = this.parseWayProperties(way);\n\n const processWayForLevel = (_level: Level_t) => {\n for (let i = 1; i < way.nodes.length; i++) {\n\n let firstVertex = getOrCreateVertex(way.nodes[i - 1], _level);\n let secondVertex = getOrCreateVertex(way.nodes[i], _level);\n\n if (way.isOnewayBackward) {\n const tmpVertex = secondVertex;\n secondVertex = firstVertex;\n firstVertex = tmpVertex;\n }\n\n const edge = new Edge(firstVertex, secondVertex, edgeProperties);\n edges.push(edge);\n }\n }\n\n processWayForLevel(way.level);\n if ('repeat_on' in way.tags) {\n way.tags.repeat_on.split(';').map(Level.fromString).forEach(processWayForLevel);\n }\n\n });\n\n // 3. Manage elevators without explicit navigation graph inside.\n // It creates a graph from entries to the center of the elevator shape.\n let fakeOsmNodeId = -1;\n osmModel.ways\n .filter(way => way.isElevator)\n .forEach(way => {\n const entryVertices = way.nodes.map(node => verticesMapping.filter(([osmId]) => osmId === node.id).map(vm => vm[1])).flat();\n\n // Horrible method but works for macro-problems\n const elevatorCenter = way.nodes\n .reduce((acc, node) => [acc[0] + node.coords.lat, acc[1] + node.coords.lng], [0, 0])\n .map(val => val / way.nodes.length);\n const elevatorLevel = entryVertices.reduce((acc, v) => Level.union(acc, v.coords.level), null as Level_t);\n const elevatorCenterCoords = new Coordinates(elevatorCenter[0], elevatorCenter[1], null, elevatorLevel);\n\n const elevatorCenterFakeOsmNode = new OsmNode(fakeOsmNodeId--, elevatorCenterCoords, { highway: 'elevator' });\n\n entryVertices.forEach(entryVertex => {\n const vertexCenter = getOrCreateVertex(elevatorCenterFakeOsmNode, entryVertex.coords.level);\n edges.push(new Edge(vertexCenter, entryVertex, { externalId: way.id }));\n })\n });\n\n\n // 4. Link elevators vertices\n elevatorVertices.forEach(([id, name, verticesOfEachLevel]) => {\n const elevatorEdgeProps = { name, isElevator: true, externalId: id };\n // Link vertices of each level together\n for (let i = 0; i < verticesOfEachLevel.length; i++) {\n for (let j = i + 1; j < verticesOfEachLevel.length; j++) {\n edges.push(new Edge(verticesOfEachLevel[i], verticesOfEachLevel[j], elevatorEdgeProps));\n }\n }\n });\n\n callbackVerticesMapping?.(verticesMapping);\n\n return new Graph(verticesMapping.map(v => v[1]), edges);\n }\n\n}","import { RouterRequest } from '../model/RouterRequest.js';\nimport Itinerary from '../model/Itinerary.js';\n\nabstract class RemoteRouter {\n\n /**\n * Get the router name\n */\n abstract get rname(): string;\n\n abstract getItineraries(endpointUrl: string, routerRequest: RouterRequest): Promise<Itinerary[]>;\n\n}\n\nexport default RemoteRouter;\n","// https://developers.google.com/actions-center/reference/grpc-api/status_codes\nexport enum StatusCode {\n OK = 0,\n CANCELLED = 1,\n UNKNOWN = 2,\n INVALID_ARGUMENT = 3,\n NOT_FOUND = 5,\n UNIMPLEMENTED = 12,\n INTERNAL = 13,\n UNAVAILABLE = 14\n}","// Based on GRPC status code\n\nimport { StatusCode } from \"./StatusCode\";\nimport { TravelMode } from \"./model/TravelMode\";\n\n\nexport class RoutingError extends Error {\n\n public customMapName?: string | null;\n\n constructor(public code = StatusCode.UNKNOWN, message?: string) {\n super(message)\n }\n\n static notFound(details?: string) {\n return new RoutingError(StatusCode.NOT_FOUND, `Cannot found an itinerary. Details: ${details}`)\n }\n}\n\n\nexport class WemapMultiRoutingError extends RoutingError {\n \n constructor(public code = StatusCode.UNKNOWN, public mapName: string | null, message?: string) {\n super(code, message);\n this.mapName = mapName;\n }\n\n static notFound(mapName: string, details?: string) {\n return new WemapMultiRoutingError(StatusCode.NOT_FOUND, mapName, `Cannot found an itinerary in map ${mapName}. Details: ${details}`)\n }\n\n}\n\nexport class RemoteRoutingError extends RoutingError {\n \n constructor(public code = StatusCode.UNKNOWN, public routerName: string, message?: string) {\n super(code, message);\n this.routerName = routerName;\n }\n\n static notFound(routerName: string, details?: string) {\n return new RemoteRoutingError(StatusCode.NOT_FOUND, routerName, `Cannot found an itinerary with ${routerName}. Details: ${details}`)\n }\n\n static unreachableServer(routerName: string, url: string) {\n return new RemoteRoutingError(StatusCode.NOT_FOUND, routerName, `Remote router server ${routerName} is unreachable. URL: ${url}`)\n }\n\n static responseNotParsing(routerName: string, url: string) {\n return new RemoteRoutingError(StatusCode.NOT_FOUND, routerName, `Remote router server response ${routerName} cannot be parsed. URL: ${url}`)\n }\n\n static travelModeUnimplemented(routerName: string, travelMode: TravelMode) {\n return new RemoteRoutingError(StatusCode.UNIMPLEMENTED, routerName, `Travel mode \"${travelMode}\" is not implemented for ${routerName}`)\n }\n}","import { RoutingError } from \"../RoutingError\";\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 RoutingError;\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 { dateWithTimeZone } from '../RemoteRouterUtils.js';\nimport { TransitMode, isTransitModePublicTransport } from '../../model/TransitMode.js';\nimport StepsBuilder from '../../model/StepsBuilder.js';\nimport { type TravelMode } from '../../model/TravelMode.js';\nimport { type RouterRequest } from '../../model/RouterRequest.js';\nimport { RemoteRoutingError } from '../../RoutingError.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 Message: string,\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<TravelMode, string>();\ninputModeCorrespondance.set('CAR', 'Car');\ninputModeCorrespondance.set('WALK', 'Walk');\ninputModeCorrespondance.set('BIKE', 'Bike');\ninputModeCorrespondance.set('TRANSIT', 'PT');\n\n\n/**\n * List of all routing modes supported by the API\n */\nconst transitModeCorrespondance = new Map<string, TransitMode>();\ntransitModeCorrespondance.set('WALK', 'WALK');\ntransitModeCorrespondance.set('BICYCLE', 'BIKE');\ntransitModeCorrespondance.set('TRAMWAY', 'TRAM');\ntransitModeCorrespondance.set('METRO', 'METRO');\ntransitModeCorrespondance.set('FUNICULAR', 'FUNICULAR');\ntransitModeCorrespondance.set('BUS', 'BUS');\ntransitModeCorrespondance.set('COACH', 'BUS');\ntransitModeCorrespondance.set('SCHOOL', 'BUS');\ntransitModeCorrespondance.set('BUS_PMR', 'BUS');\ntransitModeCorrespondance.set('MINIBUS', 'BUS');\ntransitModeCorrespondance.set('TROLLEY_BUS', 'BUS');\ntransitModeCorrespondance.set('TAXIBUS', 'BUS');\ntransitModeCorrespondance.set('SHUTTLE', 'BUS');\ntransitModeCorrespondance.set('TRAIN', 'TRAIN');\ntransitModeCorrespondance.set('HST', 'TRAIN');\ntransitModeCorrespondance.set('LOCAL_TRAIN', 'TRAIN');\ntransitModeCorrespondance.set('AIR', 'AIRPLANE');\ntransitModeCorrespondance.set('FERRY', 'BOAT');\ntransitModeCorrespondance.set('TAXI', 'UNKNOWN');\ntransitModeCorrespondance.set('CAR_POOL', 'UNKNOWN');\ntransitModeCorrespondance.set('PRIVATE_VEHICLE', 'CAR');\ntransitModeCorrespondance.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 get rname() { return 'cityway' as const; }\n\n async getItineraries(endpointUrl: string, routerRequest: RouterRequest) {\n const url = this.getURL(endpointUrl, routerRequest);\n const res = await (fetch(url).catch(() => {\n throw RemoteRoutingError.unreachableServer(this.rname, url);\n }));\n\n const jsonResponse = await res.json().catch(() => {\n throw RemoteRoutingError.responseNotParsing(this.rname, url);\n });\n return this.parseResponse(jsonResponse);\n }\n\n\n getURL(endpointUrl: string, routerRequest: RouterRequest) {\n\n const { origin, destination, travelMode, waypoints } = routerRequest;\n const citywayMode = inputModeCorrespondance.get(travelMode);\n if (!citywayMode) {\n throw RemoteRoutingError.travelModeUnimplemented(this.rname, travelMode);\n }\n\n if ((waypoints || []).length > 0) {\n Logger.warn(`${this.rname} router uses only the first 2 waypoints (asked ${waypoints?.length})`);\n }\n\n const fromPlace = `DepartureLatitude=${origin.latitude}&DepartureLongitude=${origin.longitude}`;\n const toPlace = `ArrivalLatitude=${destination.latitude}&ArrivalLongitude=${destination.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 * @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 parseResponse(json: CitywayJson) {\n\n if (json.StatusCode !== 200 || !json.Data || !json.Data.length) {\n throw RemoteRoutingError.notFound(this.rname, json.Message);\n }\n\n const itineraries = [];\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 = transitModeCorrespondance.get(jsonLeg.TransportMode)!;\n const legCoords: Coordinates[] = [];\n let legStart, legEnd;\n let transportInfo: TransportInfo | undefined;\n const stepsBuilder = new StepsBuilder();\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 legStart = {\n name: jsonLeg.Departure.Site.Name,\n coords: jsonToCoordinates(jsonLeg.Departure.Site.Position)\n };\n legEnd = {\n name: jsonLeg.Arrival.Site.Name,\n coords: jsonToCoordinates(jsonLeg.Arrival.Site.Position)\n };\n\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 = [legStart.coords, legEnd.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 stepsBuilder.addStepInfo({\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 stepsBuilder.addStepInfo({\n coords: legCoords[legCoords.length - 1]\n });\n }\n\n } else if (isTransitModePublicTransport(legMode)) {\n\n legStart = {\n name: jsonLeg.Departure.StopPlace.Name,\n coords: jsonToCoordinates(jsonLeg.Departure.StopPlace.Position)\n };\n legEnd = {\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 stepsBuilder.addStepInfo({\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 stepsBuilder.setStart(legStart.coords);\n stepsBuilder.setEnd(legEnd.coords);\n stepsBuilder.setPathCoords(legCoords);\n\n const leg = new Leg({\n transitMode: legMode,\n duration: this.parseDuration(jsonLeg.Duration),\n startTime: jsonDateToTimestamp(jsonLeg.Departure.Time),\n endTime: jsonDateToTimestamp(jsonLeg.Arrival.Time),\n coords: legCoords,\n start: legStart,\n end: legEnd,\n transportInfo,\n steps: stepsBuilder.build()\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 origin: jsonToCoordinates(trip.Departure.Site.Position),\n endTime: jsonDateToTimestamp(trip.Arrival.Time),\n destination: jsonToCoordinates(trip.Arrival.Site.Position),\n legs\n });\n\n itineraries.push(itinerary);\n }\n\n return itineraries;\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 Leg from '../../model/Leg.js';\nimport { type RouterRequest } from '../../model/RouterRequest.js';\nimport { RemoteRoutingError } from '../../RoutingError.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 */\n async getItineraries(endpointUrl: string, routerRequest: RouterRequest) {\n const url = this.getURL(endpointUrl, routerRequest);\n const res = await (fetch(url).catch(() => {\n throw RemoteRoutingError.unreachableServer(this.rname, url);\n }));\n\n const jsonResponse = await res.json().catch(() => {\n throw RemoteRoutingError.responseNotParsing(this.rname, url);\n });\n return this.parseResponse(jsonResponse, routerRequest.origin, routerRequest.destination);\n }\n\n getURL(endpointUrl: string, routerRequest: RouterRequest) {\n let url = endpointUrl + '/route/v1/walking/';\n const waypoints = [routerRequest.origin, ...routerRequest.waypoints || [], routerRequest.destination];\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 parseResponse(json: DBJson, origin: Coordinates, destination: Coordinates) {\n\n if (!json.segments) {\n throw RemoteRoutingError.notFound(this.rname);\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 transitMode: 'WALK',\n coords,\n start: { coords: coords[0] },\n end: { coords: coords[coords.length - 1] },\n })\n });\n\n return [new Itinerary({ origin, destination, legs })];\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 { dateWithTimeZone } from '../RemoteRouterUtils.js';\nimport StepsBuilder from '../../model/StepsBuilder.js';\nimport RemoteRouter from '../RemoteRouter.js';\nimport { type TransitMode } from '../../model/TransitMode.js';\nimport { type MinStepInfo } from '../../model/Step.js';\nimport { RouterRequest } from '../../model/RouterRequest.js';\nimport { RemoteRoutingError } from '../../RoutingError.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 error: {\n message?: 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 transitModeCorrespondance = new Map<string, TransitMode>();\ntransitModeCorrespondance.set('Air', 'AIRPLANE');\ntransitModeCorrespondance.set('Boat', 'BOAT');\ntransitModeCorrespondance.set('Bus', 'BUS');\ntransitModeCorrespondance.set('BusRapidTransit', 'BUS');\ntransitModeCorrespondance.set('Coach', 'BUS');\ntransitModeCorrespondance.set('Ferry', 'FERRY');\ntransitModeCorrespondance.set('Funicular', 'FUNICULAR');\ntransitModeCorrespondance.set('LocalTrain', 'TRAIN');\ntransitModeCorrespondance.set('LongDistanceTrain', 'TRAIN');\ntransitModeCorrespondance.set('Metro', 'METRO');\ntransitModeCorrespondance.set('Métro', 'METRO');\ntransitModeCorrespondance.set('RailShuttle', 'TRAIN');\ntransitModeCorrespondance.set('RapidTransit', 'BUS');\ntransitModeCorrespondance.set('Shuttle', 'BUS');\ntransitModeCorrespondance.set('SuspendedCableCar', 'FUNICULAR');\ntransitModeCorrespondance.set('Taxi', 'TAXI');\ntransitModeCorrespondance.set('Train', 'TRAIN');\ntransitModeCorrespondance.set('RER', 'TRAIN');\ntransitModeCorrespondance.set('Tramway', 'TRAM');\ntransitModeCorrespondance.set('walking', 'WALK');\ntransitModeCorrespondance.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<T>(array: T[]) {\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 async getItineraries(endpointUrl: string, routerRequest: RouterRequest) {\n const url = this.getURL(endpointUrl, routerRequest);\n\n const res = await (fetch(url, {\n method: 'GET',\n headers: { apiKey }\n }).catch(() => {\n throw RemoteRoutingError.unreachableServer(this.rname, url);\n }));\n\n\n const jsonResponse: IdfmJson = await res.json().catch(() => {\n throw RemoteRoutingError.responseNotParsing(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 throw RemoteRoutingError.notFound(this.rname, jsonResponse.error.message);\n }\n\n const itineraries = this.parseResponse(jsonResponse);\n\n const sameModeFound = itineraries.some((itinerary) => itinerary.transitMode === routerRequest.travelMode);\n\n if (!sameModeFound) {\n throw RemoteRoutingError.notFound(\n this.rname,\n 'Selected mode of transport was not found for this itinerary.'\n )\n }\n\n return itineraries;\n }\n\n getURL(endpointUrl: string, routerRequest: RouterRequest) {\n const { origin, destination, waypoints, travelMode } = routerRequest;\n\n if ((waypoints || []).length > 0) {\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', `${origin.longitude};${origin.latitude}`);\n coreParams.set('to', `${destination.longitude};${destination.latitude}`);\n\n if (routerRequest.itineraryModifiers?.avoidStairs) {\n coreParams.set('wheelchair', 'true')\n }\n\n let queryParams: URLSearchParams = new URLSearchParams();\n switch (travelMode) {\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 parseResponse(json: IdfmJson) {\n\n if (!json || !json.journeys) {\n throw RemoteRoutingError.notFound(this.rname, json.error?.message);\n }\n\n const itineraries = [];\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: startSection, to: endSection } = 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 const stepsBuilder = new StepsBuilder().setStart(startSection).setEnd(endSection).setPathCoords(legCoords);\n let transportInfo: TransportInfo | undefined;\n let transitMode = transitModeCorrespondance.get(jsonSection.mode) as TransitMode;\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 stepsBuilder.setStepsInfo(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 transitMode = transitModeCorrespondance.get(jsonSection.display_informations.physical_mode) as TransitMode;\n\n const legStep: MinStepInfo = {\n coords: legCoords[0],\n name: transportInfo.directionName,\n distance: jsonSection.geojson.properties[0].length\n };\n stepsBuilder.setStepsInfo([legStep]);\n }\n\n const leg = new Leg({\n transitMode,\n duration: jsonSection.duration,\n startTime: dateStringToTimestamp(jsonSection.departure_date_time, timeZone),\n endTime: dateStringToTimestamp(jsonSection.arrival_date_time, timeZone),\n start: {\n name: jsonSection.from.name,\n coords: startSection\n },\n end: {\n name: jsonSection.to.name,\n coords: endSection\n },\n coords: legCoords,\n transportInfo,\n steps: stepsBuilder.build()\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 origin: this.getSectionCoords(jsonItinerary.sections[0]).from,\n destination: this.getSectionCoords(last(jsonItinerary.sections)).to,\n legs\n });\n\n itineraries.push(itinerary);\n }\n\n return itineraries;\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 Leg from '../../model/Leg.js';\nimport StepsBuilder from '../../model/StepsBuilder.js';\nimport RemoteRouter from '../RemoteRouter.js';\nimport { type TravelMode } from '../../model/TravelMode.js';\nimport { type TransitMode } from '../../model/TransitMode.js';\nimport { type RouterRequest } from '../../model/RouterRequest.js';\nimport { RemoteRoutingError } from '../../RoutingError.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 message?: 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' | 'pmr' | 'bike-safest' | 'bike-fastest';\n\nconst outputModeCorrespondance = new Map<TravelMode, TransitMode>();\noutputModeCorrespondance.set('CAR', 'CAR');\noutputModeCorrespondance.set('WALK', 'WALK');\noutputModeCorrespondance.set('BIKE', 'BIKE');\n\n/**\n * Singleton.\n */\nclass OsrmRemoteRouter extends RemoteRouter {\n\n get rname() { return 'osrm' as const; }\n\n async getItineraries(endpointUrl: string, routerRequest: RouterRequest) {\n const url = this.getURL(endpointUrl, routerRequest);\n\n const res = await (fetch(url).catch(() => {\n throw RemoteRoutingError.unreachableServer(this.rname, url);\n }));\n\n const jsonResponse = await res.json().catch(() => {\n throw RemoteRoutingError.responseNotParsing(this.rname, url);\n });\n\n return this.parseResponse(jsonResponse, routerRequest.origin, routerRequest.destination, routerRequest.travelMode);\n }\n\n /**\n * @throws {TravelModeCorrespondanceNotFound}\n */\n getURL(endpointUrl: string, routerRequest: RouterRequest) {\n const { origin, destination } = routerRequest;\n\n const osrmMode = this.inputModeCorrespondance(routerRequest);\n const waypoints = [origin, ...routerRequest.waypoints || [], destination];\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 routerRequest.provideItineraryAlternatives && (url += '&alternatives=true')\n return url;\n }\n\n inputModeCorrespondance = (routerRequest: RouterRequest): OsrmMode => {\n const { travelMode, travelModePreference: preference } = routerRequest;\n if (travelMode === 'WALK' && routerRequest.itineraryModifiers?.avoidStairs) return 'pmr';\n if (travelMode === 'WALK') return 'walking';\n if (travelMode === 'BIKE') {\n if (preference === 'FASTEST') return 'bike-fastest';\n if (preference === 'SAFEST') return 'bike-safest';\n if (preference === 'TOURISM') return 'bike-safest';\n return 'bike-safest';\n }\n if (travelMode === 'CAR') return 'driving';\n throw RemoteRoutingError.travelModeUnimplemented(this.rname, travelMode);\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 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 parseResponse(json: OsrmJson, origin: Coordinates, destination: Coordinates, travelMode: TravelMode) {\n\n const transitMode = outputModeCorrespondance.get(travelMode)!;\n\n const { routes: jsonRoutes } = json;\n if (!jsonRoutes) {\n throw RemoteRoutingError.notFound(this.rname, json.message);\n }\n\n return jsonRoutes.map(jsonItinerary => {\n\n const legs = jsonItinerary.legs.map((jsonLeg) => {\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 startCoords = legCoords[0];\n const endCoords = legCoords[legCoords.length - 1];\n\n const stepsBuilder = new StepsBuilder().setPathCoords(legCoords).setStart(startCoords).setEnd(endCoords);\n jsonLeg.steps?.forEach(({ 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-orsm.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 stepsBuilder.addStepInfo({\n coords: legCoords[idStepCoordsInLeg],\n name,\n distance,\n duration\n });\n })\n\n return new Leg({\n transitMode,\n duration: jsonLeg.duration,\n coords: legCoords,\n start: {\n coords: startCoords\n },\n end: {\n coords: endCoords\n },\n steps: stepsBuilder.build()\n });\n });\n\n return new Itinerary({\n duration: jsonItinerary.duration,\n origin,\n destination,\n legs\n });\n });\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, { type TransportInfo } from '../../model/Leg.js';\nimport StepsBuilder from '../../model/StepsBuilder.js';\nimport RemoteRouter from '../RemoteRouter.js';\nimport { type TravelMode } from '../../model/TravelMode.js';\nimport { type RouterRequest } from '../../model/RouterRequest.js';\nimport { RemoteRoutingError } from '../../RoutingError.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<TravelMode, string>();\ninputModeCorrespondance.set('CAR', 'CAR');\ninputModeCorrespondance.set('WALK', 'WALK');\ninputModeCorrespondance.set('BIKE', 'BICYCLE');\ninputModeCorrespondance.set('TRANSIT', 'WALK,TRANSIT');\n\n/**\n * Singleton.\n */\nclass OtpRemoteRouter extends RemoteRouter {\n\n get rname() { return 'otp' as const; }\n\n async getItineraries(endpointUrl: string, routerRequest: RouterRequest) {\n const url = this.getURL(endpointUrl, routerRequest);\n const res = await (fetch(url).catch(() => {\n throw RemoteRoutingError.unreachableServer(this.rname, url);\n }));\n\n const jsonResponse = await res.json().catch(() => {\n throw RemoteRoutingError.responseNotParsing(this.rname, url);\n });\n return this.parseResponse(jsonResponse);\n }\n\n getURL(endpointUrl: string, routerRequest: RouterRequest) {\n const { origin, destination, waypoints, travelMode } = routerRequest;\n\n const otpMode = inputModeCorrespondance.get(travelMode);\n if (!otpMode) {\n throw RemoteRoutingError.travelModeUnimplemented(this.rname, travelMode);\n }\n\n if ((waypoints || []).length > 0) {\n Logger.warn(`${this.rname} router uses only the first 2 waypoints (asked ${waypoints?.length})`);\n }\n\n const fromPlace = `fromPlace=${origin.latitude},${origin.longitude}`;\n const toPlace = `toPlace=${destination.latitude},${destination.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 parseResponse(json: OtpJson) {\n\n const { plan: jsonPlan } = json;\n if (!jsonPlan) {\n throw RemoteRoutingError.notFound(this.rname);\n }\n\n const itineraries = [];\n\n const itinerariesOrigin = jsonToCoordinates(jsonPlan.from);\n const itinerariesDestination = 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 startCoordinates = jsonToCoordinates(jsonLeg.from);\n const endCoordinates = jsonToCoordinates(jsonLeg.to);\n\n const legCoords = Polyline.decode(jsonLeg.legGeometry.points)\n .map(([lat, lon]) => new Coordinates(lat, lon));\n\n let transportInfo: TransportInfo | undefined;\n const stepsBuilder = new StepsBuilder().setStart(startCoordinates).setEnd(endCoordinates).setPathCoords(legCoords);\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 stepsBuilder.addStepInfo({\n coords: legCoords[0],\n name: jsonLeg.headsign\n });\n\n } else {\n\n jsonLeg.steps.forEach(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 stepsBuilder.addStepInfo({\n coords: legCoords[idStepCoordsInLeg],\n name: jsonStep.streetName\n });\n })\n }\n\n\n const leg = new Leg({\n transitMode: jsonLeg.mode,\n duration: jsonLeg.duration,\n startTime: jsonLeg.startTime,\n endTime: jsonLeg.endTime,\n start: {\n name: jsonLeg.from.name,\n coords: jsonToCoordinates(jsonLeg.from)\n },\n end: {\n name: jsonLeg.to.name,\n coords: jsonToCoordinates(jsonLeg.to)\n },\n coords: legCoords,\n transportInfo,\n steps: stepsBuilder.build()\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 origin: itinerariesOrigin,\n destination: itinerariesDestination,\n legs\n });\n itineraries.push(itinerary);\n }\n\n return itineraries;\n }\n}\n\nexport default new OtpRemoteRouter();\n","import { Coordinates } from '@wemap/geo';\n\nimport RemoteRouter from '../RemoteRouter.js';\nimport { RouterRequest } from '../../model/RouterRequest.js';\nimport Itinerary from '../../model/Itinerary.js';\nimport { RemoteRoutingError } from '../../RoutingError.js';\n\n\ntype WemapRouterRequest = Omit<RouterRequest, 'origin' | 'destination' | 'waypoints'> & {\n mapId?: number,\n origin: Coordinates | number | string\n destination: Coordinates | number | string\n waypoints?: (Coordinates | number | string)[]\n}\n\n/**\n * Singleton.\n */\nclass WemapMultiRemoteRouter extends RemoteRouter {\n\n get rname() { return 'wemap-multi' as const; }\n\n async getItineraries(endpointUrl: string, routerRequest: WemapRouterRequest) {\n const { origin, destination, waypoints } = routerRequest;\n const payload = {\n ...routerRequest,\n origin: origin instanceof Coordinates ? origin.toJson() : origin,\n destination: destination instanceof Coordinates ? destination.toJson() : destination,\n ...(waypoints && {waypoints: waypoints.map(w => w instanceof Coordinates ? w.toJson() : w)})\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)\n }).catch(() => {\n throw RemoteRoutingError.unreachableServer(this.rname, endpointUrl);\n }));\n\n const jsonResponse = await res.json().catch(() => {\n throw RemoteRoutingError.responseNotParsing(this.rname, endpointUrl);\n });\n\n if (jsonResponse.error) {\n throw RemoteRoutingError.notFound(this.rname, jsonResponse.error)\n }\n\n return (jsonResponse.itineraries || []).map(Itinerary.fromJson) as Itinerary[];\n }\n\n}\n\nexport default new WemapMultiRemoteRouter();\n","import 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 { RouterRequest } from '../model/RouterRequest.js';\nimport { RemoteRoutingError } from '../RoutingError.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\nexport type RoutingFallbackStrategy = { name: RemoteRouterName, endpointUrl: string }[];\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 async getItineraries(name: RemoteRouterName, endpointUrl: string, routerRequest: RouterRequest) {\n const router = this.getRouterByName(name);\n if (!router) {\n throw RemoteRoutingError.notFound(name, `Unknown \"${name}\" remote router`);\n }\n return router.getItineraries(endpointUrl, routerRequest);\n }\n\n async getItinerariesWithFallback(routerRequest: RouterRequest, fallbackStrategy: RoutingFallbackStrategy) {\n let itineraries;\n for (const { name, endpointUrl } of fallbackStrategy) {\n itineraries = await this.getItineraries(name, endpointUrl, routerRequest);\n if (itineraries.length) {\n return itineraries;\n }\n }\n\n const routersNames = fallbackStrategy.map(({ name }) => name).join(',');\n throw RemoteRoutingError.notFound(routersNames, `Could not find an itinerary with any of following servers: ${routersNames}`)\n }\n}\n\nexport default new RemoteRouterManager();\n","/* eslint-disable complexity */\n/* eslint-disable max-statements */\n\nimport CustomNetworkMap from './CustomNetworkMap.js';\nimport RemoteRouterManager, { type RoutingFallbackStrategy } from '../remote/RemoteRouterManager.js';\nimport Itinerary from '../model/Itinerary.js';\nimport WemapMultiRemoteRouter from '../remote/wemap-multi/WemapMultiRemoteRouter.js';\nimport GraphRoute from '../graph/GraphRoute.js';\nimport GraphRouterOptionsBuilder from '../graph/GraphRouterOptionsBuilder.js';\nimport { type RouterRequest } from '../model/RouterRequest.js';\nimport { RemoteRoutingError, WemapMultiRoutingError } from '../RoutingError.js';\n\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 removeAllMaps() {\n this.maps = [];\n }\n\n getMapByName(mapId: string) {\n return this.maps.find(map => map.name === mapId);\n }\n\n async getItineraries(routerRequest: RouterRequest, fallbackStrategy: RoutingFallbackStrategy = [], targetMaps = this.maps): Promise<Itinerary[]> {\n\n const { origin, destination } = routerRequest;\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 // Avoid cycles on remoteRouters\n fallbackStrategy = fallbackStrategy.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 // TODO: map it with Wemap backend\n const ioMapsToTest = targetMaps;\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 return await RemoteRouterManager.getItinerariesWithFallback(routerRequest, fallbackStrategy);\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 ioMapRoute: GraphRoute | null;\n let ioMapItinerary: Itinerary;\n\n // Find the first map where the \"origin\" is inside.\n const mapWithOrigin = ioMapsToTest.find(map => map.isPointInside(origin));\n\n\n // Create GraphRouterOptions from request\n const routerOptions = GraphRouterOptionsBuilder.fromJson(routerRequest.itineraryModifiers || {});\n\n /*\n * Case 1\n *\n * If \"origin\" and \"destination\" are in the same map, use the local router.\n */\n if (mapWithOrigin && mapWithOrigin.isPointInside(destination)) {\n\n ioMapRoute = mapWithOrigin.getRouteInsideMap(origin, destination, routerOptions);\n if (!ioMapRoute) {\n throw WemapMultiRoutingError.notFound(mapWithOrigin.name || \"\")\n }\n\n return [Itinerary.fromGraphRoute(ioMapRoute)];\n }\n\n // Find the first map where the \"destination\" is inside.\n // Note: At this step, mapWithDestination is necessarily different from mapWithOrigin\n const mapWithDestination = ioMapsToTest.find(map => map.isPointInside(destination));\n\n\n let remoteRouterItineraries: Itinerary[];\n\n /*\n * Case 2\n *\n * If no io map have been found for \"origin\" and \"destination\", therefore use remote router.\n */\n if (!mapWithOrigin && !mapWithDestination) {\n return await RemoteRouterManager.getItinerariesWithFallback(routerRequest, fallbackStrategy);\n }\n\n /**\n * Case 3\n *\n * If a map has been found for the \"origin\" but not for the \"destination\", so:\n * - A first itinerary (firstRoute) is calculated from \"origin\" 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 * \"destination\" using remote routers.\n * Itinerary returned is the concatenation of the both itineraries.\n *\n * Note: Check the mapWithDestination.getBestItineraryFromEntryPointsToDestination to understand\n * which \"entrypoint\" is chosen by the algorithm\n */\n if (mapWithOrigin && !mapWithDestination) {\n\n if (!mapWithOrigin.entryPoints.length) {\n throw WemapMultiRoutingError.notFound(mapWithOrigin.name || '',\n `A map including the \"origin\" but the \"destination\" has been \n found (${mapWithOrigin.name}), however, no \"entrypoints\" have been found to go out`\n )\n }\n\n const customError = (details: string) => 'Tried to calculate an itinerary from \"origin\" '\n + `to \"entrypoints\" using wemap router on local map \"${mapWithOrigin.name}\" and `\n + 'an itinerary from \"entrypoints\" to \"destination\" using remote routers '\n + `(${fallbackStrategy.map(r => r.name).join(', ')}), but failed. `\n + `Details: ${details}.`;\n\n ioMapRoute = mapWithOrigin.getBestRouteFromOriginToEntryPoints(origin, destination, routerOptions);\n if (!ioMapRoute) {\n const details = `No route found from ${origin.toString()} to entry points in map: ${mapWithOrigin.name}`;\n throw WemapMultiRoutingError.notFound(mapWithOrigin.name || \"\", customError(details))\n }\n\n const newRouterRequest: RouterRequest = {\n ...routerRequest,\n origin: ioMapRoute.end,\n destination,\n waypoints: []\n };\n try {\n remoteRouterItineraries = await RemoteRouterManager.getItinerariesWithFallback(newRouterRequest, fallbackStrategy);\n } catch (e) {\n if (e instanceof RemoteRoutingError) {\n e.message = customError(e.message);\n }\n throw e;\n }\n\n // Concat the the IO map itinerary with the remote router response (for each itinerary)\n ioMapItinerary = Itinerary.fromGraphRoute(ioMapRoute);\n return remoteRouterItineraries.map(\n remoteRouterItinerary => Itinerary.fromItineraries(ioMapItinerary, remoteRouterItinerary)\n );\n }\n\n /*\n * Case 4\n *\n * If a map has been found for the \"destination\" but not for the \"origin\", so:\n * - A first itinerary (remoteRouterResponse) is calculated from \"origin\" 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 * \"destination\" using the wemap router.\n * Itinerary returned is the concatenation of the both itineraries.\n *\n * Note: Check the mapWithDestination.getBestItineraryFromEntryPointsToDestination to understand\n * which \"entrypoint\" is chosen by the algorithm\n */\n if (!mapWithOrigin && mapWithDestination) {\n\n if (!mapWithDestination.entryPoints.length) {\n throw WemapMultiRoutingError.notFound(mapWithDestination.name || '',\n `A map including the \"destination\" but the \"origin\" has been \n found (${mapWithDestination.name}), however, no \"entrypoints\" have been found to go in`\n )\n }\n\n const customError = (details: string) => 'Tried to calculate an itinerary from \"origin\" to \"entrypoints\" '\n + `using remote routers (${fallbackStrategy.map(r => r.name).join(', ')}) and an `\n + 'itinerary from \"entrypoints\" to \"destination\" using wemap router on local map '\n + `\"${mapWithDestination.name}\", but failed. `\n + `Details: ${details}.`\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 ioMapRoute = mapWithDestination.getBestRouteFromEntryPointsToDestination(origin, destination, routerOptions);\n if (!ioMapRoute) {\n const details = `No route found from entry points to ${destination.toString()} in map: ${mapWithDestination.name}`;\n throw WemapMultiRoutingError.notFound(mapWithDestination.name || \"\", customError(details))\n }\n\n const newRouterRequest: RouterRequest = {\n ...routerRequest,\n origin,\n destination: ioMapRoute.start,\n waypoints: []\n };\n try {\n remoteRouterItineraries = await RemoteRouterManager.getItinerariesWithFallback(newRouterRequest, fallbackStrategy);\n } catch (e) {\n if (e instanceof RemoteRoutingError) {\n e.message = customError(e.message);\n }\n throw e;\n }\n\n // Concat the remote router response (for each itinerary) with the IO map itinerary\n ioMapItinerary = Itinerary.fromGraphRoute(ioMapRoute);\n return remoteRouterItineraries.map(\n remoteRouterItinerary => Itinerary.fromItineraries(remoteRouterItinerary, ioMapItinerary)\n );\n }\n\n /**\n * Case 5\n *\n * If maps have been found for the \"origin\" and the \"destination\" but they are different, so:\n * - A first itinerary (ioMapItinerary1) is calculated from \"origin\" to an \"entrypoint\" of\n * the mapWithOrigin using the wemap router.\n * - A second itinerary (remoteRouterResponse) is calculated from an \"entrypoint\" of the\n * mapWithOrigin to an \"entrypoint\" of the destinationWithMap using remote routers.\n * - A third itinerary (ioMapItinerary2) is calculated from an \"entrypoint\" of the mapWithDestination\n * to the \"destination\" using the wemap router.\n * Itinerary returned is the concatenation of the three itineraries.\n */\n if (mapWithOrigin && mapWithDestination) {\n\n if (!mapWithOrigin.entryPoints.length) {\n throw WemapMultiRoutingError.notFound(mapWithOrigin.name || '',\n `One map including the \"origin\" (${mapWithOrigin.name}) and another \n including the \"destination\" (${mapWithDestination.name}) has been found, however, no \"entrypoints\" have \n been found to go out of the origin map`\n );\n }\n\n if (!mapWithDestination.entryPoints.length) {\n throw WemapMultiRoutingError.notFound(mapWithDestination.name || '',\n `One map including the \"origin\" (${mapWithOrigin.name}) and another \n including the \"destination\" (${mapWithDestination.name}) has been found, however, no \"entrypoints\" have \n been found to go in the second map`\n );\n }\n\n const customError = (details: string) => 'Tried to calculate an itinerary from \"origin\" to \"entrypoints1\" '\n + `using wemap router on local map \"${mapWithOrigin.name}\", an itinerary from `\n + '\"entrypoints1\" to \"entrypoints2\" using remote routers '\n + `(${fallbackStrategy.map(r => r.name).join(', ')}) and an itinerary from \"entrypoints2\" `\n + `to \"destination\" using wemap router on local map \"${mapWithDestination.name}\", but failed. `\n + `Details: ${details}.`;\n\n\n const ioMapRoute1 = mapWithOrigin.getBestRouteFromOriginToEntryPoints(origin, destination, routerOptions);\n if (!ioMapRoute1) {\n const details = `No route found from ${origin.toString()} to entry points in map: ${mapWithOrigin.name}`;\n throw WemapMultiRoutingError.notFound(mapWithOrigin.name || \"\", customError(details))\n }\n\n const ioMapRoute2 = mapWithDestination.getBestRouteFromEntryPointsToDestination(origin, destination, routerOptions);\n if (!ioMapRoute2) {\n const details = `No route found from entry points to ${destination.toString()} in map: ${mapWithDestination.name}`;\n throw WemapMultiRoutingError.notFound(mapWithDestination.name || \"\", customError(details))\n }\n\n const newRouterRequest: RouterRequest = {\n ...routerRequest,\n origin: ioMapRoute1.end,\n destination: ioMapRoute2.start,\n waypoints: []\n };\n try {\n remoteRouterItineraries = await RemoteRouterManager.getItinerariesWithFallback(newRouterRequest, fallbackStrategy);\n } catch (e) {\n if (e instanceof RemoteRoutingError) {\n e.message = customError(e.message);\n }\n throw e;\n }\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 return remoteRouterItineraries.map(remoteRouterItinerary =>\n Itinerary.fromItineraries(\n Itinerary.fromGraphRoute(ioMapRoute1),\n remoteRouterItinerary,\n Itinerary.fromGraphRoute(ioMapRoute2)\n )\n );\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, Level } from '@wemap/geo';\nimport { OsmNode, OsmParser } from '@wemap/osm';\n\nimport Graph from '../graph/Graph.js';\nimport GraphRouter from '../graph/GraphRouter.js';\nimport { GraphRouterOptions } from '../graph/GraphRouterOptions.js';\nimport Vertex from '../graph/Vertex.js';\nimport OsmGraphUtils from '../wemap-osm/OsmGraphUtils.js';\n\n\nexport type ParsingErrors = {\n routingIoNotFound: OsmNode[],\n routingBoundsNotFound: boolean\n}\n\n\nclass CustomNetworkMap {\n\n name: string | null;\n graph: Graph;\n router: GraphRouter;\n bounds: MultiPolygon;\n entryPoints: Vertex[];\n\n constructor(\n graph: Graph,\n entryPoints: Vertex[],\n bounds: MultiPolygon | null = null,\n name: string | null = null) {\n\n this.name = name;\n this.graph = graph;\n this.router = new GraphRouter(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 graph \"${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 graph \"${name}\"`);\n }\n this.bounds = {\n type: 'MultiPolygon',\n coordinates: [convexHull.geometry.coordinates]\n };\n }\n }\n\n static fromOsmXml(\n osmXmlString: string,\n name: string | null = null,\n callbackErrors?: (errors: ParsingErrors) => void\n ) {\n const errors: ParsingErrors = {\n routingIoNotFound: [],\n routingBoundsNotFound: false\n };\n\n const osmModel = OsmParser.parseOsmXmlString(osmXmlString);\n let verticesMapping: [nodeId: number, vertex: Vertex][] = []\n const graph = OsmGraphUtils.createGraphFromOsmModel(osmModel, OsmGraphUtils.DEFAULT_WAY_SELECTOR, vm => (verticesMapping = vm));\n\n const entryPointsOsmNodes = osmModel.nodes.filter(node => node.tags['wemap:routing-io']);\n const entryPointsToCheck = entryPointsOsmNodes.map(node => {\n const vertex = verticesMapping.find(v => v[0] === node.id)?.[1]\n if (!vertex) { errors.routingIoNotFound.push(node); }\n return vertex || null;\n });\n const entryPoints = entryPointsToCheck.filter(it => it !== null) as Vertex[];\n entryPoints.forEach(v => graph.exitVertices.add(v));\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 errors.routingBoundsNotFound = true;\n }\n callbackErrors?.(errors);\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 getBestRouteFromEntryPointsToDestination(start: Coordinates, end: Coordinates, options: GraphRouterOptions) {\n // TODO: use multiple-destinations algorithm\n const sortedEntryPoints = this.getOrderedEntryPointsSortedByDistance(start, end);\n for (const entryPoint of sortedEntryPoints) {\n const route = this.router.calculateShortestPath(entryPoint.coords, end, options).route();\n if (route.hasRoute) {\n return route;\n }\n // no route found\n }\n return null;\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 getBestRouteFromOriginToEntryPoints(start: Coordinates, end: Coordinates, options: GraphRouterOptions) {\n // TODO: use multiple-destinations algorithm\n const sortedEntryPoints = this.getOrderedEntryPointsSortedByDistance(start, end);\n for (const entryPoint of sortedEntryPoints) {\n const route = this.router.calculateShortestPath(start, entryPoint.coords, options).route();\n if (route.hasRoute) {\n return route;\n }\n // no route found\n }\n return null;\n }\n\n getRouteInsideMap(start: Coordinates, end: Coordinates, options: GraphRouterOptions) {\n // Call the Wemap router to get the shortest path\n return this.router.calculateShortestPath(start, end, options).route();\n }\n\n getTripInsideMap(waypoints: Coordinates[], options: GraphRouterOptions) {\n // Call the Wemap router to get the shortest trip itinerary\n return this.router.getShortestTrip(waypoints, options);\n }\n\n getRoutesMultipleDestinationsInsideMap(start: Coordinates, ends: Coordinates[], options: GraphRouterOptions) {\n // Call the Wemap router to get the shortest path for all the input destinations\n return this.router.calculateShortestPathToMultipleDestinations(start, ends, options);\n }\n\n}\n\nexport default CustomNetworkMap;\n","import { Coordinates } from '@wemap/geo';\n\nimport Itinerary from './model/Itinerary.js';\nimport Leg from './model/Leg.js';\nimport { Step } from './model/Step.js';\nimport Graph from './graph/Graph.js';\nimport GraphProjection from './graph/GraphProjection.js';\nimport Vertex from './graph/Vertex.js';\nimport Edge from './graph/Edge.js';\n\nexport type ItineraryInfo<U extends Coordinates = Coordinates> = {\n nextStep: Step | null;\n previousStep: Step | null;\n projection: GraphProjection<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 _graph: Graph | 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 this._graph = itinerary.toGraph();\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._graph) {\n return null;\n }\n\n const projection = this._graph.getProjection(position);\n if (!projection) {\n return null;\n }\n\n let itineraryInfo: ItineraryInfo<U> | null = null;\n\n if (projection.nearestElement instanceof Vertex) {\n const idx = this._itinerary.coords.findIndex(\n coords => (projection.nearestElement as Vertex).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 Edge) {\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":["Level","Coordinates","BoundingBox","UserPosition","diffAngleLines","GeoConstants","deg2rad","diffAngle","GeoUtils","last","OsmNode","StatusCode","jsonToCoordinates","inputModeCorrespondance","transitModeCorrespondance","positiveMod","rad2deg","CitywayRemoteRouter","DeutscheBahnRemoteRouter","IdfmRemoteRouter","OsrmRemoteRouter","OtpRemoteRouter","WemapMultiRemoteRouter","RemoteRouterManager","OsmParser"],"mappings":"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"}