UNPKG

ojp-sdk-legacy

Version:

OJP (Open Journey Planner) Javascript SDK (legacy version)

397 lines (396 loc) 20.1 kB
import { OJPBaseRequest } from '../base-request'; import { EMPTY_API_CONFIG } from '../../types/stage-config'; import { TripRequestParser } from './trip-request-parser'; import { TripLocationPoint } from '../../trip'; export class TripRequest extends OJPBaseRequest { constructor(stageConfig, language, xmlConfig, requestorRef, fromTripLocation, toTripLocation, departureDate = new Date(), tripRequestBoardingType = 'Dep', numberOfResults = null, numberOfResultsBefore = null, numberOfResultsAfter = null, publicTransportModes = [], railSubmodes = []) { super(stageConfig, language, xmlConfig, requestorRef); this.fromTripLocation = fromTripLocation; this.toTripLocation = toTripLocation; this.departureDate = departureDate; this.tripRequestBoardingType = tripRequestBoardingType; this.numberOfResults = numberOfResults; this.numberOfResultsBefore = numberOfResultsBefore; this.numberOfResultsAfter = numberOfResultsAfter; this.publicTransportModes = publicTransportModes; this.railSubmodes = railSubmodes; this.modeType = "monomodal"; this.transportMode = "public_transport"; this.includeLegProjection = true; this.viaLocations = []; this.enableExtensions = true; this.useRealTimeDataType = 'explanatory'; this.optimisationMethod = null; this.walkSpeedDeviation = null; this.response = null; } static Empty(xmlConfig, requestorRef, stageConfig = EMPTY_API_CONFIG) { const emptyTripLocationPoint = TripLocationPoint.Empty(); const request = new TripRequest(stageConfig, 'en', xmlConfig, requestorRef, emptyTripLocationPoint, emptyTripLocationPoint, new Date(), 'Dep'); return request; } static initWithResponseMock(mockText, xmlConfig, requestorRef) { const request = TripRequest.Empty(xmlConfig, requestorRef); request.mockResponseXML = mockText; return request; } static initWithRequestMock(stageConfig, mockText, xmlConfig, requestorRef) { const request = TripRequest.Empty(xmlConfig, requestorRef, stageConfig); request.mockRequestXML = mockText; request.requestInfo.requestXML = mockText; return request; } static initWithTripLocationsAndDate(stageConfig, language, xmlConfig, requestorRef, fromTripLocation, toTripLocation, departureDate, tripRequestBoardingType = 'Dep', includeLegProjection = false, modeType = 'monomodal', transportMode = 'public_transport', viaTripLocations = [], numberOfResults = null, numberOfResultsBefore = null, numberOfResultsAfter = null, publicTransportModes = [], railSubmodes = []) { if ((fromTripLocation === null) || (toTripLocation === null)) { return null; } if (!((fromTripLocation.location.geoPosition || fromTripLocation.location.stopPlace) && (toTripLocation.location.geoPosition || toTripLocation.location.stopPlace))) { return null; } const request = new TripRequest(stageConfig, language, xmlConfig, requestorRef, fromTripLocation, toTripLocation, departureDate, tripRequestBoardingType, numberOfResults, numberOfResultsBefore, numberOfResultsAfter, publicTransportModes, railSubmodes); request.includeLegProjection = includeLegProjection; request.modeType = modeType; request.transportMode = transportMode; request.viaLocations = viaTripLocations; return request; } buildRequestNode() { super.buildRequestNode(); const siriPrefix = this.xmlConfig.defaultNS === 'siri' ? '' : 'siri:'; const ojpPrefix = this.xmlConfig.defaultNS === 'ojp' ? '' : 'ojp:'; const isOJPv2 = this.xmlConfig.ojpVersion === '2.0'; const tripRequestNode = this.serviceRequestNode.ele(ojpPrefix + "OJPTripRequest"); const now = new Date(); const dateF = now.toISOString(); tripRequestNode.ele(siriPrefix + "RequestTimestamp", dateF); const modeType = this.modeType; const isMonomodal = modeType === "monomodal"; const transportMode = this.transportMode; // https://vdvde.github.io/OJP/develop/documentation-tables/ojp.html#type_ojp__PersonalModesEnumeration const personalMode = (() => { if (transportMode === 'bicycle_rental') { return 'bicycle'; } if (transportMode === 'escooter_rental') { return 'scooter'; } if (transportMode === 'car_sharing') { return 'car'; } return null; })(); const sharingModes = [ "bicycle_rental", "car_sharing", "escooter_rental", ]; const isSharingMode = sharingModes.indexOf(transportMode) !== -1; const isWalking = transportMode === 'walk' || transportMode === 'foot'; const nameNodeName = isOJPv2 ? 'Name' : 'LocationName'; const tripEndpoints = ["From", "To"]; tripEndpoints.forEach((tripEndpoint) => { var _a, _b, _c, _d; const isFrom = tripEndpoint === "From"; const tripLocation = isFrom ? this.fromTripLocation : this.toTripLocation; const location = tripLocation.location; const tagName = isFrom ? "Origin" : "Destination"; const endPointNode = tripRequestNode.ele(ojpPrefix + tagName); const placeRefNode = endPointNode.ele(ojpPrefix + "PlaceRef"); if ((_a = location.stopPlace) === null || _a === void 0 ? void 0 : _a.stopPlaceRef) { const locationName = (_b = location.locationName) !== null && _b !== void 0 ? _b : "n/a"; let stopPlaceRef = (_d = (_c = location.stopPlace) === null || _c === void 0 ? void 0 : _c.stopPlaceRef) !== null && _d !== void 0 ? _d : ""; placeRefNode.ele(ojpPrefix + "StopPlaceRef", stopPlaceRef); placeRefNode.ele(ojpPrefix + nameNodeName).ele(ojpPrefix + "Text", locationName); } else { if (location.geoPosition) { const geoPositionNode = placeRefNode.ele(ojpPrefix + "GeoPosition"); geoPositionNode.ele(siriPrefix + "Longitude", location.geoPosition.longitude); geoPositionNode.ele(siriPrefix + "Latitude", location.geoPosition.latitude); const locationName = location.geoPosition.asLatLngString(); placeRefNode.ele(ojpPrefix + nameNodeName).ele(ojpPrefix + "Text", locationName); } } const dateF = this.departureDate.toISOString(); if (isFrom) { if (this.tripRequestBoardingType === 'Dep') { endPointNode.ele(ojpPrefix + "DepArrTime", dateF); } } else { if (this.tripRequestBoardingType === 'Arr') { endPointNode.ele(ojpPrefix + "DepArrTime", dateF); } } if (isMonomodal) { if (isOJPv2) { if (isWalking) { if (tripLocation.maxDuration === null) { tripLocation.maxDuration = 60; } } const transportOptionNode = endPointNode.ele(ojpPrefix + 'IndividualTransportOption'); this.addAdditionalRestrictions(transportOptionNode, tripLocation); } } else { if (isOJPv2) { if (personalMode !== null) { (() => { if (modeType === 'mode_at_start' && !isFrom) { return; } if (modeType === 'mode_at_end' && isFrom) { return; } const transportOptionNode = endPointNode.ele(ojpPrefix + 'IndividualTransportOption'); const personalModeNode = transportOptionNode.ele(ojpPrefix + 'ItModeAndModeOfOperation'); personalModeNode.ele(ojpPrefix + 'PersonalMode', personalMode); personalModeNode.ele(ojpPrefix + 'AlternativeModeOfOperation', 'sharing'); })(); } } else { // https://opentransportdata.swiss/en/cookbook/ojptriprequest/#Parameters_for_Configuration_of_the_TripRequest // non-monomodal cycle transport modes is rendered in Origin/Destination const isCycle = transportMode === 'cycle'; if (isCycle) { (() => { if (modeType === 'mode_at_start' && !isFrom) { return; } if (modeType === 'mode_at_end' && isFrom) { return; } this.addAdditionalRestrictions(endPointNode, tripLocation); })(); } } } }); this.viaLocations.forEach(viaLocation => { var _a, _b, _c; const viaNode = tripRequestNode.ele(ojpPrefix + 'Via'); const viaPointNode = viaNode.ele(ojpPrefix + 'ViaPoint'); const stopPlace = viaLocation.location.stopPlace; if (stopPlace === null) { const geoPosition = viaLocation.location.geoPosition; if (geoPosition !== null) { const geoPositionNode = viaPointNode.ele(ojpPrefix + 'GeoPosition'); geoPositionNode.ele(siriPrefix + 'Longitude', geoPosition.longitude); geoPositionNode.ele(siriPrefix + 'Latitude', geoPosition.latitude); viaPointNode.ele(ojpPrefix + nameNodeName).ele(ojpPrefix + 'Text', (_a = viaLocation.location.computeLocationName()) !== null && _a !== void 0 ? _a : 'n/a'); } } else { viaPointNode.ele(ojpPrefix + 'StopPlaceRef', stopPlace.stopPlaceRef); viaPointNode.ele(ojpPrefix + nameNodeName).ele(ojpPrefix + 'Text', (_b = stopPlace.stopPlaceName) !== null && _b !== void 0 ? _b : ((_c = viaLocation.location.computeLocationName()) !== null && _c !== void 0 ? _c : 'n/a')); } if (viaLocation.dwellTimeMinutes !== null) { viaNode.ele(ojpPrefix + 'DwellTime', 'PT' + viaLocation.dwellTimeMinutes.toString() + 'M'); } }); const paramsNode = tripRequestNode.ele(ojpPrefix + "Params"); const hasPublicTransportModesFilter = this.publicTransportModes.length > 0; if ((this.transportMode === 'public_transport') && hasPublicTransportModesFilter) { const modeContainerName = isOJPv2 ? 'ModeAndModeOfOperationFilter' : 'PtModeFilter'; const modeContainerNode = paramsNode.ele(ojpPrefix + modeContainerName); modeContainerNode.ele(ojpPrefix + 'Exclude', 'false'); const hasRailSubmodesFilter = this.railSubmodes.length > 0; if (hasRailSubmodesFilter) { // RailSubmode doesnt work with PtMode=rail, they are mutually exclusive this.railSubmodes.forEach(railSubmode => { modeContainerNode.ele(siriPrefix + 'RailSubmode', railSubmode); }); } else { this.publicTransportModes.forEach(publicTransportMode => { modeContainerNode.ele(ojpPrefix + 'PtMode', publicTransportMode); }); } } // https://opentransportdata.swiss/en/cookbook/ojptriprequest/#Parameters_for_Configuration_of_the_TripRequest // - monomodal if (isMonomodal) { if (isSharingMode) { if (isOJPv2) { const itModeToCoverNode = paramsNode.ele(ojpPrefix + 'ItModeToCover'); if (personalMode !== null) { itModeToCoverNode.ele('PersonalMode', personalMode); itModeToCoverNode.ele('AlternativeModeOfOperation', 'sharing'); } } else { // OJP1 // - sharing transport modes // => Params/Extension/ItModesToCover=transportMode const paramsExtensionNode = paramsNode.ele(ojpPrefix + 'Extension'); paramsExtensionNode.ele(ojpPrefix + 'ItModesToCover', transportMode); } } if (transportMode === 'public_transport') { if (this.numberOfResults !== null) { paramsNode.ele(ojpPrefix + 'NumberOfResults', this.numberOfResults); } if (this.numberOfResultsBefore !== null) { paramsNode.ele(ojpPrefix + 'NumberOfResultsBefore', this.numberOfResultsBefore); } if (this.numberOfResultsAfter !== null) { paramsNode.ele(ojpPrefix + 'NumberOfResultsAfter', this.numberOfResultsAfter); } } if (isOJPv2) { if (isSharingMode || isWalking) { // NumberOfResults = 0 for sharing / walking in OJP v2.0 paramsNode.ele(ojpPrefix + 'NumberOfResults', 0); } } } if (isOJPv2) { paramsNode.ele(ojpPrefix + 'IncludeAllRestrictedLines', 'true'); } else { paramsNode.ele(ojpPrefix + 'PrivateModeFilter').ele(ojpPrefix + 'Exclude', 'false'); } paramsNode.ele(ojpPrefix + "IncludeTrackSections", true); paramsNode.ele(ojpPrefix + "IncludeLegProjection", this.includeLegProjection); paramsNode.ele(ojpPrefix + "IncludeTurnDescription", true); const isPublicTransport = this.transportMode === 'public_transport'; if (isPublicTransport) { paramsNode.ele(ojpPrefix + "IncludeIntermediateStops", true); } if (isOJPv2) { if (this.walkSpeedDeviation !== null) { paramsNode.ele(ojpPrefix + 'WalkSpeed', this.walkSpeedDeviation); } } if (isMonomodal) { const standardModes = [ "foot", "walk", "self-drive-car", "cycle", "taxi", "others-drive-car", ]; if (standardModes.indexOf(transportMode) !== -1) { if (isOJPv2) { paramsNode.ele(ojpPrefix + "ItModeToCover").ele(ojpPrefix + 'PersonalMode', transportMode); } else { paramsNode.ele(ojpPrefix + "ItModesToCover", transportMode); } } if (isOJPv2) { const carTransportModes = ['car', 'car-ferry', 'car-shuttle-train', 'car_sharing', 'self-drive-car', 'others-drive-car']; if (carTransportModes.includes(transportMode)) { const modeAndModeEl = paramsNode.ele(ojpPrefix + 'ModeAndModeOfOperationFilter'); modeAndModeEl.ele(siriPrefix + 'WaterSubmode', 'localCarFerry'); modeAndModeEl.ele(siriPrefix + 'RailSubmode', 'vehicleTunnelTransportRailService'); } } } else { // https://opentransportdata.swiss/en/cookbook/ojptriprequest/#Parameters_for_Configuration_of_the_TripRequest // - non-monomodal // - sharing transport modes // => Params/Extension/Origin/Mode=transportMode const isOJPv1 = !isOJPv2; if (isSharingMode && isOJPv1) { const paramsExtensionNode = paramsNode.ele(ojpPrefix + "Extension"); tripEndpoints.forEach((tripEndpoint) => { const isFrom = tripEndpoint === "From"; if (isFrom && this.modeType === "mode_at_end") { return; } if (!isFrom && this.modeType === "mode_at_start") { return; } const tripLocation = isFrom ? this.fromTripLocation : this.toTripLocation; const tagName = isFrom ? 'Origin' : 'Destination'; const endPointNode = paramsExtensionNode.ele(ojpPrefix + tagName); this.addAdditionalRestrictions(endPointNode, tripLocation); }); } } if (isOJPv2) { paramsNode.ele(ojpPrefix + "UseRealtimeData", this.useRealTimeDataType); if (this.optimisationMethod) { paramsNode.ele(ojpPrefix + "OptimisationMethod", this.optimisationMethod); } } } addAdditionalRestrictions(wrapperNode, tripLocation) { var _a; const siriPrefix = this.xmlConfig.defaultNS === 'siri' ? '' : 'siri:'; const ojpPrefix = this.xmlConfig.defaultNS === 'ojp' ? '' : 'ojp:'; const isOJPv2 = this.xmlConfig.ojpVersion === '2.0'; const hasIndividualTransportOptions = (tripLocation.minDuration !== null) || (tripLocation.maxDuration !== null) || (tripLocation.minDistance !== null) || (tripLocation.maxDistance !== null); let customTransportMode = (_a = tripLocation.customTransportMode) !== null && _a !== void 0 ? _a : null; if (hasIndividualTransportOptions && (customTransportMode === null)) { customTransportMode = isOJPv2 ? 'foot' : 'walk'; } if (!customTransportMode) { return; } if (isOJPv2) { wrapperNode.ele(ojpPrefix + 'PersonalMode', customTransportMode); } else { wrapperNode.ele(ojpPrefix + 'Mode', customTransportMode); } if (tripLocation.minDuration !== null) { wrapperNode.ele(ojpPrefix + 'MinDuration', 'PT' + tripLocation.minDuration + 'M'); } if (tripLocation.maxDuration !== null) { wrapperNode.ele(ojpPrefix + 'MaxDuration', 'PT' + tripLocation.maxDuration + 'M'); } if (tripLocation.minDistance !== null) { wrapperNode.ele(ojpPrefix + 'MinDistance', tripLocation.minDistance); } if (tripLocation.maxDistance !== null) { wrapperNode.ele(ojpPrefix + 'MaxDistance', tripLocation.maxDistance); } } async fetchResponse() { await this.fetchOJPResponse(); const promise = new Promise((resolve) => { this.parseTripRequestResponse(resolve); }); return promise; } fetchResponseWithCallback(callback) { this.fetchOJPResponse().then((requestInfo) => { this.requestInfo = requestInfo; this.parseTripRequestResponse(callback); }); } parseTripRequestResponse(callback) { this.response = null; if (this.requestInfo.error !== null || this.requestInfo.responseXML === null) { const errorResponse = { tripsNo: 0, trips: [], message: null }; errorResponse.message = 'ERROR'; callback(errorResponse); return; } const parser = new TripRequestParser(this.xmlConfig); parser.callback = (parserResponse) => { if (parserResponse.message === 'TripRequest.Trip' && parserResponse.trips.length === 1) { this.requestInfo.parseDateTime = new Date(); } this.response = parserResponse; callback(parserResponse); }; parser.parseXML(this.requestInfo.responseXML); } }