UNPKG

ojp-sdk

Version:

OJP (Open Journey Planner) Javascript SDK

296 lines (295 loc) 15 kB
import { OJPBaseRequest } from '../base-request'; import { EMPTY_API_CONFIG } from '../../types/stage-config'; import { TripRequestParser } from './trip-request-parser'; import { TripLocationPoint } from '../../trip'; import { Location } from '../../location/location'; import { OJP_Helpers } from "../../helpers/ojp-helpers"; export class TripRequest extends OJPBaseRequest { constructor(stageConfig, language, fromTripLocation, toTripLocation, departureDate = new Date(), tripRequestBoardingType = 'Dep', numberOfResults = null, numberOfResultsBefore = null, numberOfResultsAfter = null, publicTransportModes = []) { super(stageConfig, language); 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.modeType = "monomodal"; this.transportMode = "public_transport"; this.includeLegProjection = true; this.viaLocations = []; this.enableExtensions = true; this.response = null; } static Empty() { const emptyTripLocationPoint = TripLocationPoint.Empty(); const request = new TripRequest(EMPTY_API_CONFIG, 'en', emptyTripLocationPoint, emptyTripLocationPoint, new Date(), 'Dep'); return request; } static initWithResponseMock(mockText) { const request = TripRequest.Empty(); request.mockResponseXML = mockText; return request; } static initWithRequestMock(mockText, stageConfig = EMPTY_API_CONFIG) { const request = TripRequest.Empty(); request.mockRequestXML = mockText; request.requestInfo.requestXML = mockText; return request; } static initWithStopRefs(stageConfig, language, fromStopRef, toStopRef, departureDate = new Date(), tripRequestBoardingType = 'Dep') { const fromLocation = Location.initWithStopPlaceRef(fromStopRef); const toLocation = Location.initWithStopPlaceRef(toStopRef); const fromTripLocationPoint = new TripLocationPoint(fromLocation); const toTripLocationPoint = new TripLocationPoint(toLocation); const request = new TripRequest(stageConfig, language, fromTripLocationPoint, toTripLocationPoint, departureDate, tripRequestBoardingType); return request; } static initWithLocationsAndDate(stageConfig, language, fromLocation, toLocation, departureDate, tripRequestBoardingType = 'Dep') { const fromTripLocationPoint = new TripLocationPoint(fromLocation); const toTripLocationPoint = new TripLocationPoint(toLocation); const request = new TripRequest(stageConfig, language, fromTripLocationPoint, toTripLocationPoint, departureDate, tripRequestBoardingType); return request; } static initWithTripLocationsAndDate(stageConfig, language, fromTripLocation, toTripLocation, departureDate, tripRequestBoardingType = 'Dep', includeLegProjection = false, modeType = 'monomodal', transportMode = 'public_transport', viaTripLocations = [], numberOfResults = null, numberOfResultsBefore = null, numberOfResultsAfter = null, publicTransportModes = []) { 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, fromTripLocation, toTripLocation, departureDate, tripRequestBoardingType, numberOfResults, numberOfResultsBefore, numberOfResultsAfter, publicTransportModes); request.includeLegProjection = includeLegProjection; request.modeType = modeType; request.transportMode = transportMode; request.viaLocations = viaTripLocations; return request; } buildRequestNode() { super.buildRequestNode(); const now = new Date(); const dateF = now.toISOString(); this.serviceRequestNode.ele("RequestTimestamp", dateF); this.serviceRequestNode.ele("RequestorRef", OJP_Helpers.buildRequestorRef()); const tripRequestNode = this.serviceRequestNode.ele("ojp:OJPTripRequest"); tripRequestNode.ele("RequestTimestamp", dateF); const modeType = this.modeType; const isMonomodal = modeType === "monomodal"; const transportMode = this.transportMode; 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; let tagName = isFrom ? "ojp:Origin" : "ojp:Destination"; const endPointNode = tripRequestNode.ele(tagName); const placeRefNode = endPointNode.ele("ojp: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("ojp:StopPlaceRef", stopPlaceRef); placeRefNode.ele("ojp:LocationName").ele("ojp:Text", locationName); } else { if (location.geoPosition) { const geoPositionNode = placeRefNode.ele("ojp:GeoPosition"); geoPositionNode.ele("Longitude", location.geoPosition.longitude); geoPositionNode.ele("Latitude", location.geoPosition.latitude); const locationName = location.geoPosition.asLatLngString(); placeRefNode.ele("ojp:LocationName").ele("ojp:Text", locationName); } } const dateF = this.departureDate.toISOString(); if (isFrom) { if (this.tripRequestBoardingType === 'Dep') { endPointNode.ele("ojp:DepArrTime", dateF); } } else { if (this.tripRequestBoardingType === 'Arr') { endPointNode.ele("ojp:DepArrTime", dateF); } } if (!isMonomodal) { // 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; } const itNode = endPointNode.ele('ojp:IndividualTransportOptions'); this.addAdditionalRestrictions(itNode, tripLocation); })(); } } }); this.viaLocations.forEach(viaLocation => { var _a, _b, _c; const viaNode = tripRequestNode.ele('ojp:Via'); const viaPointNode = viaNode.ele('ojp:ViaPoint'); const stopPlace = viaLocation.location.stopPlace; if (stopPlace === null) { const geoPosition = viaLocation.location.geoPosition; if (geoPosition !== null) { const geoPositionNode = viaPointNode.ele('ojp:GeoPosition'); geoPositionNode.ele('Longitude', geoPosition.longitude); geoPositionNode.ele('Latitude', geoPosition.latitude); viaPointNode.ele('ojp:Name').ele('ojp:Text', (_a = viaLocation.location.computeLocationName()) !== null && _a !== void 0 ? _a : 'n/a'); } } else { viaPointNode.ele('ojp:StopPlaceRef', stopPlace.stopPlaceRef); viaPointNode.ele('ojp:LocationName').ele('ojp: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('ojp:DwellTime', 'PT' + viaLocation.dwellTimeMinutes.toString() + 'M'); } }); const paramsNode = tripRequestNode.ele("ojp:Params"); if (this.transportMode === 'public_transport' && (this.publicTransportModes.length > 0)) { // https://opentransportdata.swiss/en/cookbook/ojptriprequest/#Params const modeContainerNode = paramsNode.ele('PtModeFilter'); modeContainerNode.ele('ojp:Exclude', 'false'); this.publicTransportModes.forEach(publicTransportMode => { modeContainerNode.ele('ojp:PtMode', publicTransportMode); }); } if (this.enableExtensions) { paramsNode.ele('ojp:PrivateModeFilter').ele('ojp:Exclude', 'false'); } if (this.numberOfResults !== null) { paramsNode.ele('ojp:NumberOfResults', this.numberOfResults); } if (this.numberOfResultsBefore !== null) { paramsNode.ele('ojp:NumberOfResultsBefore', this.numberOfResultsBefore); } if (this.numberOfResultsAfter !== null) { paramsNode.ele('ojp:NumberOfResultsAfter', this.numberOfResultsAfter); } paramsNode.ele("ojp:IncludeTrackSections", true); paramsNode.ele("ojp:IncludeLegProjection", this.includeLegProjection); paramsNode.ele("ojp:IncludeTurnDescription", true); const isPublicTransport = this.transportMode === 'public_transport'; if (isPublicTransport) { paramsNode.ele("ojp:IncludeIntermediateStops", true); } const sharingModes = [ "bicycle_rental", "car_sharing", "escooter_rental", ]; const isSharingMode = sharingModes.indexOf(transportMode) !== -1; if (isMonomodal) { const standardModes = [ "foot", "walk", "self-drive-car", "cycle", "taxi", "others-drive-car", ]; if (standardModes.indexOf(transportMode) !== -1) { paramsNode.ele("ojp:ItModesToCover", transportMode); } // https://opentransportdata.swiss/en/cookbook/ojptriprequest/#Parameters_for_Configuration_of_the_TripRequest // - monomodal // - sharing transport modes // => Params/Extension/ItModesToCover=transportMode if (isSharingMode) { const paramsExtensionNode = paramsNode.ele("ojp:Extension"); paramsExtensionNode.ele("ojp:ItModesToCover", transportMode); } } else { // https://opentransportdata.swiss/en/cookbook/ojptriprequest/#Parameters_for_Configuration_of_the_TripRequest // - non-monomodal // - sharing transport modes // => Params/Extension/Origin/Mode=transportMode if (isSharingMode) { const paramsExtensionNode = paramsNode.ele("ojp: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 ? 'ojp:Origin' : 'ojp:Destination'; const endPointNode = paramsExtensionNode.ele(tagName); this.addAdditionalRestrictions(endPointNode, tripLocation); }); } } paramsNode.ele("ojp:UseRealtimeData", 'explanatory'); } addAdditionalRestrictions(nodeEl, tripLocation) { const hasAdditionalRestrictions = (tripLocation.minDuration !== null) || (tripLocation.maxDuration !== null) || (tripLocation.minDistance !== null) || (tripLocation.maxDistance !== null); if (!hasAdditionalRestrictions) { return; } if (tripLocation.customTransportMode) { nodeEl.ele('ojp:Mode', tripLocation.customTransportMode); } if (tripLocation.minDuration !== null) { nodeEl.ele('ojp:MinDuration', 'PT' + tripLocation.minDuration + 'M'); } if (tripLocation.maxDuration !== null) { nodeEl.ele('ojp:MaxDuration', 'PT' + tripLocation.maxDuration + 'M'); } if (tripLocation.minDistance !== null) { nodeEl.ele('ojp:MinDistance', tripLocation.minDistance); } if (tripLocation.maxDistance !== null) { nodeEl.ele('ojp: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(); 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); } }