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