@opentripplanner/core-utils 9.0.0-alpha.2 → 9.0.0-alpha.21
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/esm/graphql.d.js +2 -0
- package/esm/graphql.d.js.map +1 -0
- package/esm/index.js +2 -0
- package/esm/index.js.map +1 -1
- package/esm/itinerary.js +81 -4
- package/esm/itinerary.js.map +1 -1
- package/esm/query-gen.js +206 -0
- package/esm/query-gen.js.map +1 -0
- package/lib/core-utils.story.d.ts +22 -0
- package/lib/core-utils.story.d.ts.map +1 -0
- package/lib/core-utils.story.js +69 -0
- package/lib/core-utils.story.js.map +1 -0
- package/lib/graphql.d.js +2 -0
- package/lib/graphql.d.js.map +1 -0
- package/lib/index.d.ts +2 -0
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +3 -0
- package/lib/index.js.map +1 -1
- package/lib/itinerary.d.ts +33 -8
- package/lib/itinerary.d.ts.map +1 -1
- package/lib/itinerary.js +75 -4
- package/lib/itinerary.js.map +1 -1
- package/lib/query-gen.d.ts +75 -0
- package/lib/query-gen.d.ts.map +1 -0
- package/lib/query-gen.js +184 -0
- package/lib/query-gen.js.map +1 -0
- package/package.json +6 -4
- package/src/__tests__/query-params.ts +283 -0
- package/src/core-utils.story.tsx +1 -1
- package/src/graphql.d.ts +7 -0
- package/src/index.ts +2 -0
- package/src/itinerary.ts +86 -9
- package/src/planQuery.graphql +176 -0
- package/src/query-gen.ts +244 -0
- package/tsconfig.json +4 -1
- package/tsconfig.tsbuildinfo +1 -1
- package/src/__tests__/query-params.js +0 -93
- /package/src/__tests__/__snapshots__/{query-params.js.snap → query-params.ts.snap} +0 -0
package/src/itinerary.ts
CHANGED
|
@@ -5,8 +5,10 @@ import {
|
|
|
5
5
|
ElevationProfile,
|
|
6
6
|
FlexBookingInfo,
|
|
7
7
|
Itinerary,
|
|
8
|
+
ItineraryOnlyLegsRequired,
|
|
8
9
|
LatLngArray,
|
|
9
10
|
Leg,
|
|
11
|
+
MassUnitOption,
|
|
10
12
|
Money,
|
|
11
13
|
Place,
|
|
12
14
|
Step,
|
|
@@ -212,7 +214,9 @@ export function getCompanyFromLeg(leg: Leg): string {
|
|
|
212
214
|
return null;
|
|
213
215
|
}
|
|
214
216
|
|
|
215
|
-
export function getItineraryBounds(
|
|
217
|
+
export function getItineraryBounds(
|
|
218
|
+
itinerary: ItineraryOnlyLegsRequired
|
|
219
|
+
): LatLngArray[] {
|
|
216
220
|
let coords = [];
|
|
217
221
|
itinerary.legs.forEach(leg => {
|
|
218
222
|
const legCoords = polyline
|
|
@@ -391,10 +395,13 @@ export function getCompanyForNetwork(
|
|
|
391
395
|
* @return {string} A label for use in presentation on a website.
|
|
392
396
|
*/
|
|
393
397
|
export function getCompaniesLabelFromNetworks(
|
|
394
|
-
networks: string[],
|
|
398
|
+
networks: string | string[],
|
|
395
399
|
companies: Company[] = []
|
|
396
400
|
): string {
|
|
397
|
-
|
|
401
|
+
let networksArray = networks;
|
|
402
|
+
if (typeof networks === "string") networksArray = [networks];
|
|
403
|
+
|
|
404
|
+
return (networksArray as string[])
|
|
398
405
|
.map(network => getCompanyForNetwork(network, companies))
|
|
399
406
|
.filter(co => !!co)
|
|
400
407
|
.map(co => co.label)
|
|
@@ -407,7 +414,7 @@ export function getTNCLocation(leg: Leg, type: string): string {
|
|
|
407
414
|
}
|
|
408
415
|
|
|
409
416
|
export function calculatePhysicalActivity(
|
|
410
|
-
itinerary:
|
|
417
|
+
itinerary: ItineraryOnlyLegsRequired
|
|
411
418
|
): {
|
|
412
419
|
bikeDuration: number;
|
|
413
420
|
caloriesBurned: number;
|
|
@@ -433,7 +440,9 @@ export function calculatePhysicalActivity(
|
|
|
433
440
|
* these values and currency info.
|
|
434
441
|
* It is assumed that the same currency is used for all TNC legs.
|
|
435
442
|
*/
|
|
436
|
-
export function calculateTncFares(
|
|
443
|
+
export function calculateTncFares(
|
|
444
|
+
itinerary: ItineraryOnlyLegsRequired
|
|
445
|
+
): TncFare {
|
|
437
446
|
return itinerary.legs
|
|
438
447
|
.filter(leg => leg.mode === "CAR" && leg.hailedCar && leg.tncData)
|
|
439
448
|
.reduce(
|
|
@@ -501,15 +510,16 @@ const CARBON_INTENSITY_DEFAULTS = {
|
|
|
501
510
|
};
|
|
502
511
|
|
|
503
512
|
/**
|
|
504
|
-
* @param
|
|
505
|
-
* @param
|
|
513
|
+
* @param {itinerary} itinerary OTP trip itinierary, only legs is required.
|
|
514
|
+
* @param {carbonIntensity} carbonIntensity carbon intensity by mode in grams/meter
|
|
506
515
|
* @param {units} units units to be used in return value
|
|
507
516
|
* @return Amount of carbon in chosen unit
|
|
508
517
|
*/
|
|
509
518
|
export function calculateEmissions(
|
|
510
|
-
|
|
519
|
+
// This type makes all the properties from Itinerary optional except legs.
|
|
520
|
+
itinerary: ItineraryOnlyLegsRequired,
|
|
511
521
|
carbonIntensity: Record<string, number> = {},
|
|
512
|
-
units?:
|
|
522
|
+
units?: MassUnitOption
|
|
513
523
|
): number {
|
|
514
524
|
// Apply defaults for any values that we don't have.
|
|
515
525
|
const carbonIntensityWithDefaults = {
|
|
@@ -555,3 +565,70 @@ export function getDisplayedStopId(placeOrStop: Place | Stop): string {
|
|
|
555
565
|
}
|
|
556
566
|
return stopCode || stopId?.split(":")[1] || stopId;
|
|
557
567
|
}
|
|
568
|
+
|
|
569
|
+
/**
|
|
570
|
+
* Adds the fare product info to each leg in an itinerary, from the itinerary's fare property
|
|
571
|
+
* @param itinerary Itinerary with legProducts in fare object
|
|
572
|
+
* @returns Itinerary with legs that have fare products attached to them
|
|
573
|
+
*/
|
|
574
|
+
export function getLegsWithFares(itinerary: Itinerary): Leg[] {
|
|
575
|
+
return itinerary.legs.map((leg, i) => ({
|
|
576
|
+
...leg,
|
|
577
|
+
fareProducts: itinerary.fare?.legProducts
|
|
578
|
+
?.filter(lp => lp?.legIndices?.includes(i))
|
|
579
|
+
.flatMap(lp => lp.products)
|
|
580
|
+
}));
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
/**
|
|
584
|
+
* Extracts useful data from the fare products on a leg, such as the leg cost and transfer info.
|
|
585
|
+
* @param leg Leg with fare products (must have used getLegsWithFares)
|
|
586
|
+
* @param category Rider category
|
|
587
|
+
* @param container Fare container (cash, electronic)
|
|
588
|
+
* @returns Object containing price as well as the transfer discount amount, if a transfer was used.
|
|
589
|
+
*/
|
|
590
|
+
export function getLegCost(
|
|
591
|
+
leg: Leg,
|
|
592
|
+
category: string,
|
|
593
|
+
container: string
|
|
594
|
+
): { price?: Money; transferAmount?: number } {
|
|
595
|
+
if (!leg.fareProducts) return { price: undefined };
|
|
596
|
+
|
|
597
|
+
const relevantFareProducts = leg.fareProducts.filter(
|
|
598
|
+
fp => fp.category.name === category && fp.container.name === container
|
|
599
|
+
);
|
|
600
|
+
const totalCost = relevantFareProducts.find(fp => fp.name === "rideCost")
|
|
601
|
+
?.amount;
|
|
602
|
+
const transferFareProduct = relevantFareProducts.find(
|
|
603
|
+
fp => fp.name === "transfer"
|
|
604
|
+
);
|
|
605
|
+
|
|
606
|
+
return {
|
|
607
|
+
price: totalCost,
|
|
608
|
+
transferAmount: transferFareProduct?.amount?.cents
|
|
609
|
+
};
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
/**
|
|
613
|
+
* Returns the total itinerary cost for a given set of legs.
|
|
614
|
+
* @param legs Itinerary legs with fare products (must have used getLegsWithFares)
|
|
615
|
+
* @param category Rider category (youth, regular, senior)
|
|
616
|
+
* @param container Fare container (cash, electronic)
|
|
617
|
+
* @returns Money object for the total itinerary cost.
|
|
618
|
+
*/
|
|
619
|
+
export function getItineraryCost(
|
|
620
|
+
legs: Leg[],
|
|
621
|
+
category: string,
|
|
622
|
+
container: string
|
|
623
|
+
): Money {
|
|
624
|
+
return legs
|
|
625
|
+
.filter(leg => !!leg.fareProducts)
|
|
626
|
+
.map(leg => getLegCost(leg, category, container).price)
|
|
627
|
+
.reduce<Money>(
|
|
628
|
+
(prev, cur) => ({
|
|
629
|
+
cents: prev.cents + cur?.cents || 0,
|
|
630
|
+
currency: prev.currency ?? cur?.currency
|
|
631
|
+
}),
|
|
632
|
+
{ cents: 0, currency: null }
|
|
633
|
+
);
|
|
634
|
+
}
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
query PlanQuery(
|
|
2
|
+
$fromPlace: String!
|
|
3
|
+
$toPlace: String!
|
|
4
|
+
$modes: [TransportMode]
|
|
5
|
+
$time: String
|
|
6
|
+
$date: String
|
|
7
|
+
$wheelchair: Boolean
|
|
8
|
+
$bikeReluctance: Float
|
|
9
|
+
$carReluctance: Float
|
|
10
|
+
$walkReluctance: Float
|
|
11
|
+
$arriveBy: Boolean
|
|
12
|
+
$intermediatePlaces: [InputCoordinates]
|
|
13
|
+
$preferred: InputPreferred
|
|
14
|
+
$unpreferred: InputUnpreferred
|
|
15
|
+
$banned: InputBanned
|
|
16
|
+
$numItineraries: Int
|
|
17
|
+
) {
|
|
18
|
+
plan(
|
|
19
|
+
fromPlace: $fromPlace
|
|
20
|
+
toPlace: $toPlace
|
|
21
|
+
transportModes: $modes
|
|
22
|
+
# Currently only supporting EN locale, used for times and text
|
|
23
|
+
locale: "en"
|
|
24
|
+
time: $time
|
|
25
|
+
date: $date
|
|
26
|
+
wheelchair: $wheelchair
|
|
27
|
+
bikeReluctance: $bikeReluctance
|
|
28
|
+
carReluctance: $carReluctance
|
|
29
|
+
walkReluctance: $walkReluctance
|
|
30
|
+
arriveBy: $arriveBy
|
|
31
|
+
intermediatePlaces: $intermediatePlaces
|
|
32
|
+
preferred: $preferred
|
|
33
|
+
unpreferred: $unpreferred
|
|
34
|
+
banned: $banned
|
|
35
|
+
numItineraries: $numItineraries
|
|
36
|
+
) {
|
|
37
|
+
routingErrors {
|
|
38
|
+
code
|
|
39
|
+
inputField
|
|
40
|
+
description
|
|
41
|
+
}
|
|
42
|
+
itineraries {
|
|
43
|
+
duration
|
|
44
|
+
endTime
|
|
45
|
+
startTime
|
|
46
|
+
waitingTime
|
|
47
|
+
walkTime
|
|
48
|
+
accessibilityScore
|
|
49
|
+
legs {
|
|
50
|
+
pickupType
|
|
51
|
+
dropoffType
|
|
52
|
+
pickupBookingInfo {
|
|
53
|
+
earliestBookingTime {
|
|
54
|
+
daysPrior
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
rentedBike
|
|
58
|
+
interlineWithPreviousLeg
|
|
59
|
+
departureDelay
|
|
60
|
+
arrivalDelay
|
|
61
|
+
distance
|
|
62
|
+
duration
|
|
63
|
+
endTime
|
|
64
|
+
mode
|
|
65
|
+
realTime
|
|
66
|
+
realtimeState
|
|
67
|
+
startTime
|
|
68
|
+
transitLeg
|
|
69
|
+
accessibilityScore
|
|
70
|
+
trip {
|
|
71
|
+
id
|
|
72
|
+
gtfsId
|
|
73
|
+
tripHeadsign
|
|
74
|
+
}
|
|
75
|
+
agency {
|
|
76
|
+
name
|
|
77
|
+
id
|
|
78
|
+
timezone
|
|
79
|
+
url
|
|
80
|
+
alerts {
|
|
81
|
+
alertHeaderText
|
|
82
|
+
alertDescriptionText
|
|
83
|
+
alertUrl
|
|
84
|
+
effectiveStartDate
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
legGeometry {
|
|
88
|
+
length
|
|
89
|
+
points
|
|
90
|
+
}
|
|
91
|
+
intermediateStops {
|
|
92
|
+
lat
|
|
93
|
+
lon
|
|
94
|
+
name
|
|
95
|
+
stopCode: code
|
|
96
|
+
stopId: id
|
|
97
|
+
locationType
|
|
98
|
+
}
|
|
99
|
+
route {
|
|
100
|
+
shortName
|
|
101
|
+
longName
|
|
102
|
+
color
|
|
103
|
+
textColor
|
|
104
|
+
id
|
|
105
|
+
type
|
|
106
|
+
alerts {
|
|
107
|
+
alertHeaderText
|
|
108
|
+
alertDescriptionText
|
|
109
|
+
alertUrl
|
|
110
|
+
effectiveStartDate
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
from {
|
|
114
|
+
lat
|
|
115
|
+
lon
|
|
116
|
+
name
|
|
117
|
+
vertexType
|
|
118
|
+
rentalVehicle {
|
|
119
|
+
network
|
|
120
|
+
}
|
|
121
|
+
stop {
|
|
122
|
+
id
|
|
123
|
+
code
|
|
124
|
+
gtfsId
|
|
125
|
+
alerts {
|
|
126
|
+
alertHeaderText
|
|
127
|
+
alertDescriptionText
|
|
128
|
+
alertUrl
|
|
129
|
+
effectiveStartDate
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
to {
|
|
134
|
+
lat
|
|
135
|
+
lon
|
|
136
|
+
name
|
|
137
|
+
vertexType
|
|
138
|
+
rentalVehicle {
|
|
139
|
+
network
|
|
140
|
+
}
|
|
141
|
+
stop {
|
|
142
|
+
id
|
|
143
|
+
code
|
|
144
|
+
gtfsId
|
|
145
|
+
alerts {
|
|
146
|
+
alertHeaderText
|
|
147
|
+
alertDescriptionText
|
|
148
|
+
alertUrl
|
|
149
|
+
effectiveStartDate
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
steps {
|
|
154
|
+
distance
|
|
155
|
+
lat
|
|
156
|
+
lon
|
|
157
|
+
relativeDirection
|
|
158
|
+
absoluteDirection
|
|
159
|
+
stayOn
|
|
160
|
+
streetName
|
|
161
|
+
area
|
|
162
|
+
alerts {
|
|
163
|
+
alertHeaderText
|
|
164
|
+
alertDescriptionText
|
|
165
|
+
alertUrl
|
|
166
|
+
effectiveStartDate
|
|
167
|
+
}
|
|
168
|
+
elevationProfile {
|
|
169
|
+
distance
|
|
170
|
+
elevation
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
package/src/query-gen.ts
ADDED
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
import { LonLatOutput } from "@conveyal/lonlat";
|
|
2
|
+
import { print } from "graphql";
|
|
3
|
+
import {
|
|
4
|
+
ModeSetting,
|
|
5
|
+
ModeSettingValues,
|
|
6
|
+
TransportMode
|
|
7
|
+
} from "@opentripplanner/types";
|
|
8
|
+
|
|
9
|
+
import PlanQuery from "./planQuery.graphql";
|
|
10
|
+
|
|
11
|
+
type InputBanned = {
|
|
12
|
+
routes?: string;
|
|
13
|
+
agencies?: string;
|
|
14
|
+
trips?: string;
|
|
15
|
+
stops?: string;
|
|
16
|
+
stopsHard?: string;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
type InputPreferred = {
|
|
20
|
+
routes?: string;
|
|
21
|
+
agencies?: string;
|
|
22
|
+
unpreferredCost?: string;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
type OTPQueryParams = {
|
|
26
|
+
arriveBy: boolean;
|
|
27
|
+
date?: string;
|
|
28
|
+
from: LonLatOutput & { name?: string };
|
|
29
|
+
modes: TransportMode[];
|
|
30
|
+
modeSettings: ModeSetting[];
|
|
31
|
+
time?: string;
|
|
32
|
+
numItineraries?: number;
|
|
33
|
+
to: LonLatOutput & { name?: string };
|
|
34
|
+
banned?: InputBanned;
|
|
35
|
+
preferred?: InputPreferred;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
type GraphQLQuery = {
|
|
39
|
+
query: string;
|
|
40
|
+
variables: Record<string, unknown>;
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Mode Settings can contain additional modes to add to the query,
|
|
45
|
+
* this function extracts those additional modes from the settings
|
|
46
|
+
* and returns them in an array.
|
|
47
|
+
* @param modeSettings List of mode settings with values populated
|
|
48
|
+
* @returns Additional transport modes to add to query
|
|
49
|
+
*/
|
|
50
|
+
export function extractAdditionalModes(
|
|
51
|
+
modeSettings: ModeSetting[],
|
|
52
|
+
enabledModes: TransportMode[]
|
|
53
|
+
): TransportMode[] {
|
|
54
|
+
return modeSettings.reduce<TransportMode[]>((prev, cur) => {
|
|
55
|
+
// First, ensure that the mode associated with this setting is even enabled
|
|
56
|
+
if (!enabledModes.map(m => m.mode).includes(cur.applicableMode)) {
|
|
57
|
+
return prev;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// In checkboxes, mode must be enabled and have a transport mode in it
|
|
61
|
+
if (cur.type === "CHECKBOX" && cur.addTransportMode && cur.value) {
|
|
62
|
+
return [...prev, cur.addTransportMode];
|
|
63
|
+
}
|
|
64
|
+
if (cur.type === "DROPDOWN") {
|
|
65
|
+
const transportMode = cur.options.find(o => o.value === cur.value)
|
|
66
|
+
.addTransportMode;
|
|
67
|
+
if (transportMode) {
|
|
68
|
+
return [...prev, transportMode];
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return prev;
|
|
72
|
+
}, []);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Generates every possible mathematical subset of the input TransportModes.
|
|
77
|
+
* Uses code from:
|
|
78
|
+
* https://stackoverflow.com/questions/5752002/find-all-possible-subset-combos-in-an-array
|
|
79
|
+
* @param array Array of input transport modes
|
|
80
|
+
* @returns 2D array representing every possible subset of transport modes from input
|
|
81
|
+
*/
|
|
82
|
+
function combinations(array: TransportMode[]): TransportMode[][] {
|
|
83
|
+
if (!array) return [];
|
|
84
|
+
return (
|
|
85
|
+
// eslint-disable-next-line no-bitwise
|
|
86
|
+
new Array(1 << array.length)
|
|
87
|
+
.fill(null)
|
|
88
|
+
// eslint-disable-next-line no-bitwise
|
|
89
|
+
.map((e1, i) => array.filter((e2, j) => i & (1 << j)))
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* This constant maps all the transport mode to a broader mode type,
|
|
95
|
+
* which is used to determine the valid combinations of modes used in query generation.
|
|
96
|
+
*/
|
|
97
|
+
export const SIMPLIFICATIONS = {
|
|
98
|
+
AIRPLANE: "TRANSIT",
|
|
99
|
+
BICYCLE: "PERSONAL",
|
|
100
|
+
BUS: "TRANSIT",
|
|
101
|
+
CABLE_CAR: "TRANSIT",
|
|
102
|
+
CAR: "CAR",
|
|
103
|
+
FERRY: "TRANSIT",
|
|
104
|
+
FLEX: "SHARED", // TODO: this allows FLEX+WALK. Is this reasonable?
|
|
105
|
+
FUNICULAR: "TRANSIT",
|
|
106
|
+
GONDOLA: "TRANSIT",
|
|
107
|
+
RAIL: "TRANSIT",
|
|
108
|
+
SCOOTER: "PERSONAL",
|
|
109
|
+
SUBWAY: "TRANSIT",
|
|
110
|
+
TRAM: "TRANSIT",
|
|
111
|
+
TRANSIT: "TRANSIT",
|
|
112
|
+
WALK: "WALK"
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
// Inclusion of "TRANSIT" alone automatically implies "WALK" in OTP
|
|
116
|
+
const VALID_COMBOS = [
|
|
117
|
+
["WALK"],
|
|
118
|
+
["PERSONAL"],
|
|
119
|
+
["TRANSIT", "SHARED"],
|
|
120
|
+
["WALK", "SHARED"],
|
|
121
|
+
["TRANSIT"],
|
|
122
|
+
["TRANSIT", "PERSONAL"],
|
|
123
|
+
["TRANSIT", "CAR"]
|
|
124
|
+
];
|
|
125
|
+
|
|
126
|
+
const BANNED_TOGETHER = ["SCOOTER", "BICYCLE"];
|
|
127
|
+
|
|
128
|
+
export const TRANSIT_SUBMODES = Object.keys(SIMPLIFICATIONS).filter(
|
|
129
|
+
mode => SIMPLIFICATIONS[mode] === "TRANSIT" && mode !== "TRANSIT"
|
|
130
|
+
);
|
|
131
|
+
export const TRANSIT_SUBMODES_AND_TRANSIT = Object.keys(SIMPLIFICATIONS).filter(
|
|
132
|
+
mode => SIMPLIFICATIONS[mode] === "TRANSIT"
|
|
133
|
+
);
|
|
134
|
+
|
|
135
|
+
function isCombinationValid(
|
|
136
|
+
combo: TransportMode[],
|
|
137
|
+
queryTransitSubmodes: string[]
|
|
138
|
+
): boolean {
|
|
139
|
+
if (combo.length === 0) return false;
|
|
140
|
+
|
|
141
|
+
// All current qualifiers currently simplify to "SHARED"
|
|
142
|
+
const simplifiedModes = Array.from(
|
|
143
|
+
new Set(combo.map(c => (c.qualifier ? "SHARED" : SIMPLIFICATIONS[c.mode])))
|
|
144
|
+
);
|
|
145
|
+
|
|
146
|
+
// Ensure that if we have one transit mode, then we include ALL transit modes
|
|
147
|
+
if (simplifiedModes.includes("TRANSIT")) {
|
|
148
|
+
// Don't allow TRANSIT along with any other submodes
|
|
149
|
+
if (queryTransitSubmodes.length && combo.find(c => c.mode === "TRANSIT")) {
|
|
150
|
+
return false;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
if (
|
|
154
|
+
combo.reduce((prev, cur) => {
|
|
155
|
+
if (queryTransitSubmodes.includes(cur.mode)) {
|
|
156
|
+
return prev - 1;
|
|
157
|
+
}
|
|
158
|
+
return prev;
|
|
159
|
+
}, queryTransitSubmodes.length) !== 0
|
|
160
|
+
) {
|
|
161
|
+
return false;
|
|
162
|
+
}
|
|
163
|
+
// Continue to the other checks
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// OTP doesn't support multiple non-walk modes
|
|
167
|
+
if (BANNED_TOGETHER.every(m => combo.find(c => c.mode === m))) return false;
|
|
168
|
+
|
|
169
|
+
return !!VALID_COMBOS.find(
|
|
170
|
+
vc =>
|
|
171
|
+
simplifiedModes.every(m => vc.includes(m)) &&
|
|
172
|
+
vc.every(m => simplifiedModes.includes(m))
|
|
173
|
+
);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Generates a list of queries for OTP to get a comprehensive
|
|
178
|
+
* set of results based on the modes input.
|
|
179
|
+
* @param params OTP Query Params
|
|
180
|
+
* @returns Set of parameters to generate queries
|
|
181
|
+
*/
|
|
182
|
+
export function generateCombinations(params: OTPQueryParams): OTPQueryParams[] {
|
|
183
|
+
const completeModeList = [
|
|
184
|
+
...extractAdditionalModes(params.modeSettings, params.modes),
|
|
185
|
+
...params.modes
|
|
186
|
+
];
|
|
187
|
+
|
|
188
|
+
// List of the transit *submodes* that are included in the input params
|
|
189
|
+
const queryTransitSubmodes = completeModeList
|
|
190
|
+
.filter(mode => TRANSIT_SUBMODES.includes(mode.mode))
|
|
191
|
+
.map(mode => mode.mode);
|
|
192
|
+
|
|
193
|
+
return combinations(completeModeList)
|
|
194
|
+
.filter(combo => isCombinationValid(combo, queryTransitSubmodes))
|
|
195
|
+
.map(combo => ({ ...params, modes: combo }));
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
export function generateOtp2Query({
|
|
199
|
+
arriveBy,
|
|
200
|
+
banned,
|
|
201
|
+
date,
|
|
202
|
+
from,
|
|
203
|
+
modes,
|
|
204
|
+
modeSettings,
|
|
205
|
+
numItineraries,
|
|
206
|
+
preferred,
|
|
207
|
+
time,
|
|
208
|
+
to
|
|
209
|
+
}: OTPQueryParams): GraphQLQuery {
|
|
210
|
+
// This extracts the values from the mode settings to key value pairs
|
|
211
|
+
const modeSettingValues = modeSettings.reduce((prev, cur) => {
|
|
212
|
+
if (cur.type === "SLIDER" && cur.inverseKey) {
|
|
213
|
+
prev[cur.inverseKey] = cur.high - cur.value + cur.low;
|
|
214
|
+
}
|
|
215
|
+
prev[cur.key] = cur.value;
|
|
216
|
+
return prev;
|
|
217
|
+
}, {}) as ModeSettingValues;
|
|
218
|
+
|
|
219
|
+
const {
|
|
220
|
+
bikeReluctance,
|
|
221
|
+
carReluctance,
|
|
222
|
+
walkReluctance,
|
|
223
|
+
wheelchair
|
|
224
|
+
} = modeSettingValues;
|
|
225
|
+
|
|
226
|
+
return {
|
|
227
|
+
query: print(PlanQuery),
|
|
228
|
+
variables: {
|
|
229
|
+
arriveBy,
|
|
230
|
+
banned,
|
|
231
|
+
bikeReluctance,
|
|
232
|
+
carReluctance,
|
|
233
|
+
date,
|
|
234
|
+
fromPlace: `${from.name}::${from.lat},${from.lon}}`,
|
|
235
|
+
modes,
|
|
236
|
+
numItineraries,
|
|
237
|
+
preferred,
|
|
238
|
+
time,
|
|
239
|
+
toPlace: `${to.name}::${to.lat},${to.lon}}`,
|
|
240
|
+
walkReluctance,
|
|
241
|
+
wheelchair
|
|
242
|
+
}
|
|
243
|
+
};
|
|
244
|
+
}
|
package/tsconfig.json
CHANGED
|
@@ -2,9 +2,12 @@
|
|
|
2
2
|
"extends": "../../tsconfig.json",
|
|
3
3
|
"compilerOptions": {
|
|
4
4
|
"composite": true,
|
|
5
|
+
"target": "es2019",
|
|
5
6
|
"outDir": "./lib",
|
|
6
7
|
"rootDir": "./src",
|
|
8
|
+
"lib": ["es2019", "dom"],
|
|
7
9
|
"skipLibCheck": true
|
|
8
10
|
},
|
|
9
|
-
"include": ["src/**/*"]
|
|
11
|
+
"include": ["src/**/*"],
|
|
12
|
+
"exclude": ["src/__tests__/**/*"]
|
|
10
13
|
}
|