@opentripplanner/core-utils 14.0.0-alpha.2 → 14.0.1
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/README.md +0 -4
- package/esm/itinerary.js +70 -32
- package/esm/itinerary.js.map +1 -1
- package/esm/otpSchema.json +7321 -5821
- package/esm/planQuery.graphql +12 -0
- package/esm/profile.js +1 -1
- package/esm/profile.js.map +1 -1
- package/esm/query-gen.js +2 -2
- package/esm/query-gen.js.map +1 -1
- package/esm/query-params.js +2 -2
- package/esm/query-params.js.map +1 -1
- package/esm/query.js +2 -5
- package/esm/query.js.map +1 -1
- package/esm/storage.js +2 -6
- package/esm/storage.js.map +1 -1
- package/esm/time.js +1 -2
- package/esm/time.js.map +1 -1
- package/lib/index.js +50 -35
- package/lib/index.js.map +1 -1
- package/lib/itinerary.d.ts +25 -8
- package/lib/itinerary.d.ts.map +1 -1
- package/lib/itinerary.js +524 -495
- package/lib/itinerary.js.map +1 -1
- package/lib/map.js +40 -39
- package/lib/map.js.map +1 -1
- package/lib/otpSchema.json +7321 -5821
- package/lib/planQuery.graphql +12 -0
- package/lib/profile.js +1 -1
- package/lib/profile.js.map +1 -1
- package/lib/query-gen.js +134 -138
- package/lib/query-gen.js.map +1 -1
- package/lib/query-params.js +2 -2
- package/lib/query-params.js.map +1 -1
- package/lib/query.js +3 -6
- package/lib/query.js.map +1 -1
- package/lib/route.js +230 -248
- package/lib/route.js.map +1 -1
- package/lib/storage.d.ts.map +1 -1
- package/lib/storage.js +22 -28
- package/lib/storage.js.map +1 -1
- package/lib/suspense.js +28 -16
- package/lib/suspense.js.map +1 -1
- package/lib/time.js +36 -49
- package/lib/time.js.map +1 -1
- package/lib/ui.js +33 -36
- package/lib/ui.js.map +1 -1
- package/package.json +3 -3
- package/src/__tests__/__snapshots__/query-params.ts.snap +203 -203
- package/src/__tests__/__snapshots__/query.js.snap +28 -28
- package/src/__tests__/__snapshots__/route.js.snap +76 -76
- package/src/__tests__/__snapshots__/time.js.snap +2 -2
- package/src/__tests__/itinerary.ts +108 -23
- package/src/__tests__/query.js +1 -1
- package/src/__tests__/route.js +1 -1
- package/src/core-utils.story.tsx +34 -23
- package/src/itinerary.ts +85 -37
- package/src/otpSchema.json +7321 -5821
- package/src/planQuery.graphql +12 -0
- package/src/profile.js +1 -1
- package/src/query-gen.ts +1 -1
- package/src/query-params.jsx +2 -2
- package/src/query.js +2 -5
- package/src/storage.ts +5 -9
- package/tsconfig.tsbuildinfo +1 -1
package/lib/route.js
CHANGED
|
@@ -1,22 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
exports.getMostReadableTextColor = getMostReadableTextColor;
|
|
9
|
-
exports.getRouteSortOrderValue = getRouteSortOrderValue;
|
|
10
|
-
exports.getTransitOperatorFromFeedIdAndAgencyId = getTransitOperatorFromFeedIdAndAgencyId;
|
|
11
|
-
exports.getTransitOperatorFromLeg = getTransitOperatorFromLeg;
|
|
12
|
-
exports.getTransitOperatorFromOtpRoute = getTransitOperatorFromOtpRoute;
|
|
13
|
-
exports.makeMultiCriteriaSort = makeMultiCriteriaSort;
|
|
14
|
-
exports.makeNumericValueComparator = makeNumericValueComparator;
|
|
15
|
-
exports.makeRouteComparator = makeRouteComparator;
|
|
16
|
-
exports.makeStringValueComparator = makeStringValueComparator;
|
|
17
|
-
exports.makeTransitOperatorComparator = makeTransitOperatorComparator;
|
|
18
|
-
exports.routeTypeComparator = routeTypeComparator;
|
|
19
|
-
var _chromaJs = _interopRequireDefault(require("chroma-js"));
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.getMostReadableTextColor = exports.makeRouteComparator = exports.makeMultiCriteriaSort = exports.getRouteSortOrderValue = exports.makeStringValueComparator = exports.makeNumericValueComparator = exports.alphabeticShortNameComparator = exports.routeTypeComparator = exports.makeTransitOperatorComparator = exports.getTransitOperatorFromOtpRoute = exports.getTransitOperatorFromLeg = exports.getTransitOperatorFromFeedIdAndAgencyId = void 0;
|
|
7
|
+
const chroma_js_1 = __importDefault(require("chroma-js"));
|
|
20
8
|
/**
|
|
21
9
|
* Returns the transit operator (if an exact match is found) from the transit
|
|
22
10
|
* operators config value. It is critical to use both the feedId and agencyId in
|
|
@@ -30,9 +18,10 @@ var _chromaJs = _interopRequireDefault(require("chroma-js"));
|
|
|
30
18
|
* was found
|
|
31
19
|
*/
|
|
32
20
|
function getTransitOperatorFromFeedIdAndAgencyId(feedId, agencyId, transitOperators) {
|
|
33
|
-
|
|
21
|
+
return (transitOperators.find(transitOperator => transitOperator.feedId === feedId &&
|
|
22
|
+
transitOperator.agencyId === agencyId) || null);
|
|
34
23
|
}
|
|
35
|
-
|
|
24
|
+
exports.getTransitOperatorFromFeedIdAndAgencyId = getTransitOperatorFromFeedIdAndAgencyId;
|
|
36
25
|
/**
|
|
37
26
|
* Looks up an operator from the provided leg.
|
|
38
27
|
*
|
|
@@ -42,11 +31,12 @@ function getTransitOperatorFromFeedIdAndAgencyId(feedId, agencyId, transitOperat
|
|
|
42
31
|
* @return {object} the operator if one was found or null if no match was found
|
|
43
32
|
*/
|
|
44
33
|
function getTransitOperatorFromLeg(leg, transitOperators) {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
34
|
+
if (!leg.routeId || !leg.agencyId)
|
|
35
|
+
return null;
|
|
36
|
+
const feedId = leg.routeId.split(":")[0];
|
|
37
|
+
return getTransitOperatorFromFeedIdAndAgencyId(feedId, leg.agencyId, transitOperators);
|
|
48
38
|
}
|
|
49
|
-
|
|
39
|
+
exports.getTransitOperatorFromLeg = getTransitOperatorFromLeg;
|
|
50
40
|
/**
|
|
51
41
|
* Looks up an operator from the provided configuration given an OTP route.
|
|
52
42
|
* NOTE: this assumes the use of the OTP Route model or a modified OTP
|
|
@@ -58,33 +48,34 @@ function getTransitOperatorFromLeg(leg, transitOperators) {
|
|
|
58
48
|
* @return {object} the operator if one was found or null if no match was found
|
|
59
49
|
*/
|
|
60
50
|
function getTransitOperatorFromOtpRoute(route, transitOperators) {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
51
|
+
if (!route.id)
|
|
52
|
+
return null;
|
|
53
|
+
const feedId = route.id.split(":")[0];
|
|
54
|
+
let agencyId;
|
|
55
|
+
if (route.agency) {
|
|
56
|
+
// This is returned in OTP2
|
|
57
|
+
agencyId = route.agency.id;
|
|
58
|
+
}
|
|
59
|
+
else if (route.agencyId) {
|
|
60
|
+
// This is returned in OTP1
|
|
61
|
+
agencyId = route.agencyId;
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
66
|
+
return getTransitOperatorFromFeedIdAndAgencyId(feedId, agencyId, transitOperators);
|
|
74
67
|
}
|
|
75
|
-
|
|
68
|
+
exports.getTransitOperatorFromOtpRoute = getTransitOperatorFromOtpRoute;
|
|
76
69
|
// The functions below are for enhanced route sorting functions for the route
|
|
77
70
|
// viewer on OTP-react-redux.
|
|
78
71
|
// They address route ordering issues discussed in
|
|
79
72
|
// https://github.com/opentripplanner/otp-react-redux/pull/123 and
|
|
80
73
|
// https://github.com/opentripplanner/otp-react-redux/pull/124.
|
|
81
|
-
|
|
82
74
|
/**
|
|
83
75
|
* A large comparator value that can safely be used in mathematical sort
|
|
84
76
|
* comparisons to place things at the end of lists
|
|
85
77
|
*/
|
|
86
78
|
const END_OF_LIST_COMPARATOR_VALUE = 999999999999;
|
|
87
|
-
|
|
88
79
|
/**
|
|
89
80
|
* Returns a transit operator comparator value given a route and an optional
|
|
90
81
|
* transitOperators config value. This function will do its best to handle all
|
|
@@ -99,180 +90,172 @@ const END_OF_LIST_COMPARATOR_VALUE = 999999999999;
|
|
|
99
90
|
* returned.
|
|
100
91
|
*/
|
|
101
92
|
function getTransitOperatorComparatorValue(route, transitOperators) {
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
93
|
+
// if the transitOperators is undefined or has zero length, use the route's
|
|
94
|
+
// agency name as the comparator value
|
|
95
|
+
if (!transitOperators || transitOperators.length === 0) {
|
|
96
|
+
// OTP2 Route
|
|
97
|
+
if (route.agency)
|
|
98
|
+
return route.agency.name;
|
|
99
|
+
// OTP1 Route
|
|
100
|
+
if (route.agencyName)
|
|
101
|
+
return route.agencyName;
|
|
102
|
+
// shouldn't happen as agency names will be defined
|
|
103
|
+
return "zzz";
|
|
104
|
+
}
|
|
105
|
+
// find operator associated with route
|
|
106
|
+
const transitOperator = getTransitOperatorFromOtpRoute(route, transitOperators);
|
|
107
|
+
// if transit operator not found, return infinity
|
|
108
|
+
if (!transitOperator)
|
|
109
|
+
return END_OF_LIST_COMPARATOR_VALUE;
|
|
110
|
+
// return the transit operator's sort value or END_OF_LIST_COMPARATOR_VALUE if
|
|
111
|
+
// the sort value is not a number
|
|
112
|
+
return typeof transitOperator.order === "number"
|
|
113
|
+
? transitOperator.order
|
|
114
|
+
: END_OF_LIST_COMPARATOR_VALUE;
|
|
122
115
|
}
|
|
123
|
-
|
|
124
116
|
/**
|
|
125
117
|
* Calculates the sort comparator value given two routes based off of the
|
|
126
118
|
* route's agency and provided transitOperators config data.
|
|
127
119
|
*/
|
|
128
120
|
function makeTransitOperatorComparator(transitOperators) {
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
121
|
+
return (a, b) => {
|
|
122
|
+
const aVal = getTransitOperatorComparatorValue(a, transitOperators);
|
|
123
|
+
const bVal = getTransitOperatorComparatorValue(b, transitOperators);
|
|
124
|
+
if (typeof aVal === "string") {
|
|
125
|
+
// happens when transitOperators is undefined. Both aVal are guaranteed to
|
|
126
|
+
// be strings. Make a string comparison.
|
|
127
|
+
if (aVal < bVal)
|
|
128
|
+
return -1;
|
|
129
|
+
if (aVal > bVal)
|
|
130
|
+
return 1;
|
|
131
|
+
return 0;
|
|
132
|
+
}
|
|
133
|
+
// @ts-expect-error transitOperators are defined and therefore a numeric value is guaranteed
|
|
134
|
+
// to be returned
|
|
135
|
+
return aVal - bVal;
|
|
136
|
+
};
|
|
143
137
|
}
|
|
144
|
-
|
|
138
|
+
exports.makeTransitOperatorComparator = makeTransitOperatorComparator;
|
|
145
139
|
/**
|
|
146
140
|
* Gets the desired sort values according to an optional getter function. If the
|
|
147
141
|
* getter function is not defined, the original sort values are returned.
|
|
148
142
|
*/
|
|
149
143
|
function getSortValues(getterFn, a, b) {
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
aVal,
|
|
161
|
-
bVal
|
|
162
|
-
};
|
|
144
|
+
let aVal;
|
|
145
|
+
let bVal;
|
|
146
|
+
if (typeof getterFn === "function") {
|
|
147
|
+
aVal = getterFn(a);
|
|
148
|
+
bVal = getterFn(b);
|
|
149
|
+
}
|
|
150
|
+
else {
|
|
151
|
+
aVal = a;
|
|
152
|
+
bVal = b;
|
|
153
|
+
}
|
|
154
|
+
return { aVal, bVal };
|
|
163
155
|
}
|
|
164
|
-
|
|
165
156
|
// Lookup for the sort values associated with various OTP modes.
|
|
166
157
|
// Note: JSDoc format not used to avoid bug in documentationjs.
|
|
167
158
|
// https://github.com/documentationjs/documentation/issues/372
|
|
168
159
|
const modeComparatorValue = {
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
160
|
+
SUBWAY: 1,
|
|
161
|
+
TRAM: 2,
|
|
162
|
+
TROLLEYBUS: 9,
|
|
163
|
+
RAIL: 3,
|
|
164
|
+
GONDOLA: 4,
|
|
165
|
+
FERRY: 5,
|
|
166
|
+
CABLE_CAR: 6,
|
|
167
|
+
FUNICULAR: 7,
|
|
168
|
+
BUS: 8
|
|
178
169
|
};
|
|
179
|
-
|
|
180
170
|
// Lookup that maps route types to the OTP mode sort values.
|
|
181
171
|
// Note: JSDoc format not used to avoid bug in documentationjs.
|
|
182
172
|
// https://github.com/documentationjs/documentation/issues/372
|
|
183
173
|
const routeTypeComparatorValue = {
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
// - Gondola, etc.
|
|
198
|
-
7: modeComparatorValue.FUNICULAR,
|
|
199
|
-
// - Funicular.
|
|
200
|
-
// TODO: 11 and 12 are not a part of OTP as of 2019-02-14, but for now just
|
|
201
|
-
// associate them with bus/rail.
|
|
202
|
-
11: modeComparatorValue.BUS,
|
|
203
|
-
// - Trolleybus.
|
|
204
|
-
12: modeComparatorValue.RAIL,
|
|
205
|
-
// - Monorail.
|
|
206
|
-
13: modeComparatorValue.TROLLEYBUS
|
|
174
|
+
0: modeComparatorValue.TRAM,
|
|
175
|
+
1: modeComparatorValue.SUBWAY,
|
|
176
|
+
2: modeComparatorValue.RAIL,
|
|
177
|
+
3: modeComparatorValue.BUS,
|
|
178
|
+
4: modeComparatorValue.FERRY,
|
|
179
|
+
5: modeComparatorValue.CABLE_CAR,
|
|
180
|
+
6: modeComparatorValue.GONDOLA,
|
|
181
|
+
7: modeComparatorValue.FUNICULAR,
|
|
182
|
+
// TODO: 11 and 12 are not a part of OTP as of 2019-02-14, but for now just
|
|
183
|
+
// associate them with bus/rail.
|
|
184
|
+
11: modeComparatorValue.BUS,
|
|
185
|
+
12: modeComparatorValue.RAIL,
|
|
186
|
+
13: modeComparatorValue.TROLLEYBUS
|
|
207
187
|
};
|
|
208
|
-
|
|
209
188
|
// Gets a comparator value for a given route's type (OTP mode).
|
|
210
189
|
// Note: JSDoc format not used to avoid bug in documentationjs.
|
|
211
190
|
// ttps://github.com/documentationjs/documentation/issues/372
|
|
212
191
|
function getRouteTypeComparatorValue(route) {
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
192
|
+
// For some strange reason, the short route response in OTP returns the
|
|
193
|
+
// string-based modes, but the long route response returns the
|
|
194
|
+
// integer route type. This attempts to account for both of those cases.
|
|
195
|
+
if (!route)
|
|
196
|
+
throw new Error(`Route is undefined. ${route}`);
|
|
197
|
+
if (typeof modeComparatorValue[route.mode] !== "undefined") {
|
|
198
|
+
return modeComparatorValue[route.mode];
|
|
199
|
+
}
|
|
200
|
+
if (typeof routeTypeComparatorValue[route.type] !== "undefined") {
|
|
201
|
+
return routeTypeComparatorValue[route.type];
|
|
202
|
+
}
|
|
203
|
+
// Default the comparator value to a large number (placing the route at the
|
|
204
|
+
// end of the list).
|
|
205
|
+
// eslint-disable-next-line no-console
|
|
206
|
+
console.warn("no mode/route type found for route", route);
|
|
207
|
+
return END_OF_LIST_COMPARATOR_VALUE;
|
|
228
208
|
}
|
|
229
|
-
|
|
230
209
|
/**
|
|
231
210
|
* Calculates the sort comparator value given two routes based off of route type
|
|
232
211
|
* (OTP mode).
|
|
233
212
|
*/
|
|
234
213
|
function routeTypeComparator(a, b) {
|
|
235
|
-
|
|
214
|
+
return getRouteTypeComparatorValue(a) - getRouteTypeComparatorValue(b);
|
|
236
215
|
}
|
|
237
|
-
|
|
216
|
+
exports.routeTypeComparator = routeTypeComparator;
|
|
238
217
|
/**
|
|
239
218
|
* Determines whether a value is a string that starts with an alphabetic
|
|
240
219
|
* ascii character.
|
|
241
220
|
*/
|
|
242
221
|
function startsWithAlphabeticCharacter(val) {
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
222
|
+
if (typeof val === "string" && val.length > 0) {
|
|
223
|
+
const firstCharCode = val.charCodeAt(0);
|
|
224
|
+
return ((firstCharCode >= 65 && firstCharCode <= 90) ||
|
|
225
|
+
(firstCharCode >= 97 && firstCharCode <= 122));
|
|
226
|
+
}
|
|
227
|
+
return false;
|
|
248
228
|
}
|
|
249
|
-
|
|
250
229
|
/**
|
|
251
230
|
* Sorts routes based off of whether the shortName begins with an alphabetic
|
|
252
231
|
* character. Routes with shortn that do start with an alphabetic character will
|
|
253
232
|
* be prioritized over those that don't.
|
|
254
233
|
*/
|
|
255
234
|
function alphabeticShortNameComparator(a, b) {
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
235
|
+
const aStartsWithAlphabeticCharacter = startsWithAlphabeticCharacter(a.shortName);
|
|
236
|
+
const bStartsWithAlphabeticCharacter = startsWithAlphabeticCharacter(b.shortName);
|
|
237
|
+
if (aStartsWithAlphabeticCharacter && bStartsWithAlphabeticCharacter) {
|
|
238
|
+
// both start with an alphabetic character, return equivalence
|
|
239
|
+
return 0;
|
|
240
|
+
}
|
|
241
|
+
// a does start with an alphabetic character, but b does not. Prioritize a
|
|
242
|
+
if (aStartsWithAlphabeticCharacter)
|
|
243
|
+
return -1;
|
|
244
|
+
// b does start with an alphabetic character, but a does not. Prioritize b
|
|
245
|
+
if (bStartsWithAlphabeticCharacter)
|
|
246
|
+
return 1;
|
|
247
|
+
// neither route has a shortName that starts with an alphabetic character.
|
|
248
|
+
// Return equivalence
|
|
260
249
|
return 0;
|
|
261
|
-
}
|
|
262
|
-
// a does start with an alphabetic character, but b does not. Prioritize a
|
|
263
|
-
if (aStartsWithAlphabeticCharacter) return -1;
|
|
264
|
-
// b does start with an alphabetic character, but a does not. Prioritize b
|
|
265
|
-
if (bStartsWithAlphabeticCharacter) return 1;
|
|
266
|
-
// neither route has a shortName that starts with an alphabetic character.
|
|
267
|
-
// Return equivalence
|
|
268
|
-
return 0;
|
|
269
250
|
}
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
251
|
+
exports.alphabeticShortNameComparator = alphabeticShortNameComparator;
|
|
252
|
+
const isNullOrNaN = (val) => {
|
|
253
|
+
// isNaN(null) returns false so we have to check for null explicitly.
|
|
254
|
+
// Note: Using the global version of isNaN (the Number version behaves differently.
|
|
255
|
+
// eslint-disable-next-line no-restricted-globals
|
|
256
|
+
if (typeof val === null || isNaN(val))
|
|
257
|
+
return true;
|
|
258
|
+
return typeof val !== "number";
|
|
276
259
|
};
|
|
277
260
|
/**
|
|
278
261
|
* Checks whether an appropriate comparison of numeric values can be made for
|
|
@@ -294,28 +277,24 @@ const isNullOrNaN = val => {
|
|
|
294
277
|
* comparison value from the comparator function arguments
|
|
295
278
|
*/
|
|
296
279
|
function makeNumericValueComparator(objGetterFn) {
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
// a and b are valid numbers, return the sort value
|
|
314
|
-
// @ts-expect-error We know from the checks above that both aVal and bVal are valid numbers.
|
|
315
|
-
return aVal - bVal;
|
|
316
|
-
};
|
|
280
|
+
return (a, b) => {
|
|
281
|
+
const { aVal, bVal } = getSortValues(objGetterFn, a, b);
|
|
282
|
+
// if both values aren't valid numbers, use the next sort criteria
|
|
283
|
+
if (isNullOrNaN(aVal) && isNullOrNaN(bVal)) {
|
|
284
|
+
return 0;
|
|
285
|
+
}
|
|
286
|
+
// b is a valid number, b gets priority
|
|
287
|
+
if (isNullOrNaN(aVal))
|
|
288
|
+
return 1;
|
|
289
|
+
// a is a valid number, a gets priority
|
|
290
|
+
if (isNullOrNaN(bVal))
|
|
291
|
+
return -1;
|
|
292
|
+
// a and b are valid numbers, return the sort value
|
|
293
|
+
// @ts-expect-error We know from the checks above that both aVal and bVal are valid numbers.
|
|
294
|
+
return aVal - bVal;
|
|
295
|
+
};
|
|
317
296
|
}
|
|
318
|
-
|
|
297
|
+
exports.makeNumericValueComparator = makeNumericValueComparator;
|
|
319
298
|
/**
|
|
320
299
|
* Create a comparator function that compares string values. The comparison
|
|
321
300
|
* values feed to the sort comparator function are assumed to be objects that
|
|
@@ -327,24 +306,26 @@ function makeNumericValueComparator(objGetterFn) {
|
|
|
327
306
|
* comparison value from the comparator function arguments
|
|
328
307
|
*/
|
|
329
308
|
function makeStringValueComparator(objGetterFn) {
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
309
|
+
return (a, b) => {
|
|
310
|
+
const { aVal, bVal } = getSortValues(objGetterFn, a, b);
|
|
311
|
+
// both a and b are uncomparable strings, return equivalent value
|
|
312
|
+
if (!aVal && !bVal)
|
|
313
|
+
return 0;
|
|
314
|
+
// a is not a comparable string, b gets priority
|
|
315
|
+
if (!aVal)
|
|
316
|
+
return 1;
|
|
317
|
+
// b is not a comparable string, a gets priority
|
|
318
|
+
if (!bVal)
|
|
319
|
+
return -1;
|
|
320
|
+
// a and b are comparable strings, return the sort value
|
|
321
|
+
if (aVal < bVal)
|
|
322
|
+
return -1;
|
|
323
|
+
if (aVal > bVal)
|
|
324
|
+
return 1;
|
|
325
|
+
return 0;
|
|
326
|
+
};
|
|
346
327
|
}
|
|
347
|
-
|
|
328
|
+
exports.makeStringValueComparator = makeStringValueComparator;
|
|
348
329
|
/**
|
|
349
330
|
* OTP1 sets the routeSortOrder to -999 by default. If we're encountering that value in OTP1,
|
|
350
331
|
* assume that it actually means that the route sortOrder is not set in the GTFS. If we encounter
|
|
@@ -355,16 +336,14 @@ function makeStringValueComparator(objGetterFn) {
|
|
|
355
336
|
* This was updated in OTP2 TO be empty by default. https://docs.opentripplanner.org/en/v2.3.0/OTP2-MigrationGuide/#:~:text=the%20Alerts-,Changes%20to%20the%20Index%20API,-Error%20handling%20is
|
|
356
337
|
*/
|
|
357
338
|
function getRouteSortOrderValue(route) {
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
sortOrder
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
return
|
|
364
|
-
}
|
|
365
|
-
return sortOrder;
|
|
339
|
+
const isOTP1 = !!route.agencyId;
|
|
340
|
+
const { sortOrder } = route;
|
|
341
|
+
if ((isOTP1 && sortOrder === -999) || sortOrder === undefined) {
|
|
342
|
+
return null;
|
|
343
|
+
}
|
|
344
|
+
return sortOrder;
|
|
366
345
|
}
|
|
367
|
-
|
|
346
|
+
exports.getRouteSortOrderValue = getRouteSortOrderValue;
|
|
368
347
|
/**
|
|
369
348
|
* Create a multi-criteria sort comparator function composed of other sort
|
|
370
349
|
* comparator functions. Each comparator function will be ran in the order given
|
|
@@ -373,19 +352,19 @@ function getRouteSortOrderValue(route) {
|
|
|
373
352
|
* are assumed to be equivalent.
|
|
374
353
|
*/
|
|
375
354
|
function makeMultiCriteriaSort(...criteria) {
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
355
|
+
return (a, b) => {
|
|
356
|
+
for (let i = 0; i < criteria.length; i++) {
|
|
357
|
+
const curCriteriaComparatorValue = criteria[i](a, b);
|
|
358
|
+
// if the comparison objects are not equivalent, return the value obtained
|
|
359
|
+
// in this current criteria comparison
|
|
360
|
+
if (curCriteriaComparatorValue !== 0) {
|
|
361
|
+
return curCriteriaComparatorValue;
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
return 0;
|
|
365
|
+
};
|
|
387
366
|
}
|
|
388
|
-
|
|
367
|
+
exports.makeMultiCriteriaSort = makeMultiCriteriaSort;
|
|
389
368
|
/**
|
|
390
369
|
* Creates a sort comparator function to compares routes for the purposes of
|
|
391
370
|
* sorting and displaying in a user interface. This takes in a single optional
|
|
@@ -418,9 +397,9 @@ function makeMultiCriteriaSort(...criteria) {
|
|
|
418
397
|
* 7. longName as string.
|
|
419
398
|
*/
|
|
420
399
|
function makeRouteComparator(transitOperators) {
|
|
421
|
-
|
|
400
|
+
return makeMultiCriteriaSort(makeTransitOperatorComparator(transitOperators), makeNumericValueComparator(obj => getRouteSortOrderValue(obj)), routeTypeComparator, alphabeticShortNameComparator, makeNumericValueComparator(obj => parseInt(obj.shortName, 10)), makeStringValueComparator(obj => obj.shortName), makeStringValueComparator(obj => obj.longName));
|
|
422
401
|
}
|
|
423
|
-
|
|
402
|
+
exports.makeRouteComparator = makeRouteComparator;
|
|
424
403
|
/**
|
|
425
404
|
* Tests if a pair of colors is readable. If it is, that readable color is returned.
|
|
426
405
|
* If it is not, a more appropriate alternative is returned.
|
|
@@ -435,26 +414,29 @@ function makeRouteComparator(transitOperators) {
|
|
|
435
414
|
* @param proposedTextColor A hex string, usually the "routeTextColor"
|
|
436
415
|
*/
|
|
437
416
|
function getMostReadableTextColor(backgroundColor, proposedTextColor) {
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
417
|
+
// Sometimes input will defy the method signature. Therefore we need extra fallbacks
|
|
418
|
+
if (!backgroundColor)
|
|
419
|
+
backgroundColor = "#333333";
|
|
420
|
+
if (!proposedTextColor)
|
|
421
|
+
proposedTextColor = "#ffffff";
|
|
422
|
+
if (!backgroundColor.startsWith("#")) {
|
|
423
|
+
backgroundColor = `#${backgroundColor}`;
|
|
424
|
+
}
|
|
425
|
+
if (!proposedTextColor.startsWith("#")) {
|
|
426
|
+
proposedTextColor = `#${proposedTextColor}`;
|
|
427
|
+
}
|
|
428
|
+
// Check if proposed color is readable
|
|
429
|
+
// Luminance thresholds have been selected based on actual transit agency colors
|
|
430
|
+
const fgLuminance = (0, chroma_js_1.default)(proposedTextColor).luminance();
|
|
431
|
+
const bgLuminance = (0, chroma_js_1.default)(backgroundColor).luminance();
|
|
432
|
+
if (bgLuminance + fgLuminance < 1.41 &&
|
|
433
|
+
bgLuminance + fgLuminance > 0.25 &&
|
|
434
|
+
Math.abs(bgLuminance - fgLuminance) > 0.2) {
|
|
435
|
+
return proposedTextColor;
|
|
436
|
+
}
|
|
437
|
+
// Return black or white based on luminance of background color
|
|
438
|
+
// When generating colors, white is preferred.
|
|
439
|
+
return (0, chroma_js_1.default)(backgroundColor).luminance() < 0.4 ? "#ffffff" : "#000000";
|
|
459
440
|
}
|
|
441
|
+
exports.getMostReadableTextColor = getMostReadableTextColor;
|
|
460
442
|
//# sourceMappingURL=route.js.map
|