@opentripplanner/core-utils 7.0.0-alpha.4 → 7.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/esm/itinerary.js +93 -63
- package/esm/itinerary.js.map +1 -1
- package/esm/query.js +2 -4
- package/esm/query.js.map +1 -1
- package/esm/time.js +4 -7
- package/esm/time.js.map +1 -1
- package/lib/itinerary.d.ts +7 -0
- package/lib/itinerary.d.ts.map +1 -1
- package/lib/itinerary.js +86 -63
- package/lib/itinerary.js.map +1 -1
- package/lib/query.js +1 -4
- package/lib/query.js.map +1 -1
- package/lib/time.d.ts +1 -2
- package/lib/time.d.ts.map +1 -1
- package/lib/time.js +5 -9
- package/lib/time.js.map +1 -1
- package/package.json +3 -3
- package/src/__tests__/itinerary.js +42 -32
- package/src/itinerary.ts +90 -56
- package/src/query.js +3 -7
- package/src/time.ts +4 -10
- package/tsconfig.json +1 -6
- package/tsconfig.tsbuildinfo +1 -5013
|
@@ -7,47 +7,57 @@ import {
|
|
|
7
7
|
|
|
8
8
|
const bikeRentalItinerary = require("./__mocks__/bike-rental-itinerary.json");
|
|
9
9
|
const tncItinerary = require("./__mocks__/tnc-itinerary.json");
|
|
10
|
-
// const multiCurrencyItinerary = require("./__mocks__/multi-currency-itinerary.json");
|
|
11
10
|
|
|
12
11
|
describe("util > itinerary", () => {
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
describe("isTransit", () => {
|
|
13
|
+
it("should work", () => {
|
|
14
|
+
expect(isTransit("CAR")).toBeFalsy();
|
|
15
|
+
expect(isTransit("BUS")).toBeTruthy();
|
|
16
|
+
});
|
|
15
17
|
});
|
|
16
18
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
describe("getCompanyFromLeg", () => {
|
|
20
|
+
it("should return company for bike rental leg", () => {
|
|
21
|
+
const company = getCompanyFromLeg(bikeRentalItinerary.legs[1]);
|
|
22
|
+
expect(company).toEqual("GBFS");
|
|
23
|
+
});
|
|
21
24
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
+
it("should return company for TNC leg", () => {
|
|
26
|
+
const company = getCompanyFromLeg(tncItinerary.legs[0]);
|
|
27
|
+
expect(company).toEqual("UBER");
|
|
28
|
+
});
|
|
25
29
|
});
|
|
26
30
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
31
|
+
describe("getTransitFare", () => {
|
|
32
|
+
it("should return defaults with missing fare", () => {
|
|
33
|
+
const { transitFare } = getTransitFare(null);
|
|
34
|
+
// transit fare value should be zero
|
|
35
|
+
expect(transitFare).toMatchSnapshot();
|
|
36
|
+
});
|
|
32
37
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
38
|
+
it("should work with valid fare component", () => {
|
|
39
|
+
const fareComponent = {
|
|
40
|
+
currency: {
|
|
41
|
+
currency: "USD",
|
|
42
|
+
defaultFractionDigits: 2,
|
|
43
|
+
currencyCode: "USD",
|
|
44
|
+
symbol: "$"
|
|
45
|
+
},
|
|
46
|
+
cents: 575
|
|
47
|
+
};
|
|
48
|
+
const { currencyCode, transitFare } = getTransitFare(fareComponent);
|
|
49
|
+
expect(currencyCode).toEqual(fareComponent.currency.currencyCode);
|
|
50
|
+
// Snapshot tests
|
|
51
|
+
expect(transitFare).toMatchSnapshot();
|
|
52
|
+
});
|
|
47
53
|
});
|
|
48
54
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
55
|
+
describe("calculateTncFares", () => {
|
|
56
|
+
it("should return the correct amounts and currency for an itinerary with TNC", () => {
|
|
57
|
+
const fareResult = calculateTncFares(tncItinerary, true);
|
|
58
|
+
expect(fareResult.currencyCode).toEqual("USD");
|
|
59
|
+
expect(fareResult.maxTNCFare).toEqual(19);
|
|
60
|
+
expect(fareResult.minTNCFare).toEqual(17);
|
|
61
|
+
});
|
|
52
62
|
});
|
|
53
63
|
});
|
package/src/itinerary.ts
CHANGED
|
@@ -13,32 +13,6 @@ import {
|
|
|
13
13
|
} from "@opentripplanner/types";
|
|
14
14
|
import turfAlong from "@turf/along";
|
|
15
15
|
|
|
16
|
-
/*
|
|
17
|
-
import {
|
|
18
|
-
// calculateFares,
|
|
19
|
-
// getLegModeLabel,
|
|
20
|
-
// getModeForPlace,
|
|
21
|
-
// getPlaceName,
|
|
22
|
-
// getStepDirection,
|
|
23
|
-
// getStepInstructions,
|
|
24
|
-
// getStepStreetName,
|
|
25
|
-
// getTimeZoneOffset,
|
|
26
|
-
// getTransitFare
|
|
27
|
-
} from "./deprecated";
|
|
28
|
-
|
|
29
|
-
export {
|
|
30
|
-
// calculateFares,
|
|
31
|
-
// getLegModeLabel,
|
|
32
|
-
// getModeForPlace,
|
|
33
|
-
// getPlaceName,
|
|
34
|
-
// getStepDirection,
|
|
35
|
-
// getStepInstructions,
|
|
36
|
-
// getStepStreetName,
|
|
37
|
-
// getTimeZoneOffset,
|
|
38
|
-
// getTransitFare
|
|
39
|
-
};
|
|
40
|
-
*/
|
|
41
|
-
|
|
42
16
|
// All OTP transit modes
|
|
43
17
|
export const transitModes = [
|
|
44
18
|
"TRAM",
|
|
@@ -455,24 +429,24 @@ export function calculatePhysicalActivity(
|
|
|
455
429
|
* It is assumed that the same currency is used for all TNC legs.
|
|
456
430
|
*/
|
|
457
431
|
export function calculateTncFares(itinerary: Itinerary): TncFare {
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
432
|
+
return itinerary.legs
|
|
433
|
+
.filter(leg => leg.mode === "CAR" && leg.hailedCar && leg.tncData)
|
|
434
|
+
.reduce(
|
|
435
|
+
({ maxTNCFare, minTNCFare }, { tncData }) => {
|
|
436
|
+
const { currency, maxCost, minCost } = tncData;
|
|
437
|
+
return {
|
|
438
|
+
// Assumes a single currency for entire itinerary.
|
|
439
|
+
currencyCode: currency,
|
|
440
|
+
maxTNCFare: maxTNCFare + maxCost,
|
|
441
|
+
minTNCFare: minTNCFare + minCost
|
|
442
|
+
};
|
|
443
|
+
},
|
|
444
|
+
{
|
|
445
|
+
currencyCode: null,
|
|
446
|
+
maxTNCFare: 0,
|
|
447
|
+
minTNCFare: 0
|
|
448
|
+
}
|
|
449
|
+
);
|
|
476
450
|
}
|
|
477
451
|
|
|
478
452
|
/**
|
|
@@ -485,17 +459,77 @@ export function getTransitFare(
|
|
|
485
459
|
currencyCode: string;
|
|
486
460
|
transitFare: number;
|
|
487
461
|
} {
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
462
|
+
return fareComponent
|
|
463
|
+
? {
|
|
464
|
+
currencyCode: fareComponent.currency.currencyCode,
|
|
465
|
+
transitFare: fareComponent.cents
|
|
466
|
+
}
|
|
467
|
+
: {
|
|
468
|
+
currencyCode: "USD",
|
|
469
|
+
transitFare: 0
|
|
470
|
+
};
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
/**
|
|
474
|
+
* Sources:
|
|
475
|
+
* - https://www.itf-oecd.org/sites/default/files/docs/environmental-performance-new-mobility.pdf
|
|
476
|
+
* - https://www.thrustcarbon.com/insights/how-to-calculate-emissions-from-a-ferry-journey
|
|
477
|
+
* - https://www.itf-oecd.org/sites/default/files/life-cycle-assessment-calculations-2020.xlsx
|
|
478
|
+
* Other values extrapolated.
|
|
479
|
+
*/
|
|
480
|
+
const CARBON_INTENSITY_DEFAULTS = {
|
|
481
|
+
walk: 0.026,
|
|
482
|
+
bicycle: 0.017,
|
|
483
|
+
car: 0.162,
|
|
484
|
+
tram: 0.066,
|
|
485
|
+
subway: 0.066,
|
|
486
|
+
rail: 0.066,
|
|
487
|
+
bus: 0.09,
|
|
488
|
+
ferry: 0.082,
|
|
489
|
+
cable_car: 0.021,
|
|
490
|
+
gondola: 0.021,
|
|
491
|
+
funicular: 0.066,
|
|
492
|
+
transit: 0.066,
|
|
493
|
+
leg_switch: 0,
|
|
494
|
+
airplane: 0.382,
|
|
495
|
+
micromobility: 0.095
|
|
496
|
+
};
|
|
497
|
+
|
|
498
|
+
/**
|
|
499
|
+
* @param {itinerary} itinerary OTP trip itinierary
|
|
500
|
+
* @param {carbonIntensity} carbonIntensity carbon intensity by mode in grams/meter
|
|
501
|
+
* @param {units} units units to be used in return value
|
|
502
|
+
* @return Amount of carbon in chosen unit
|
|
503
|
+
*/
|
|
504
|
+
export function calculateEmissions(
|
|
505
|
+
itinerary: Itinerary,
|
|
506
|
+
carbonIntensity: Record<string, number> = {},
|
|
507
|
+
units?: string
|
|
508
|
+
): number {
|
|
509
|
+
// Apply defaults for any values that we don't have.
|
|
510
|
+
const carbonIntensityWithDefaults = {
|
|
511
|
+
...CARBON_INTENSITY_DEFAULTS,
|
|
512
|
+
...carbonIntensity
|
|
500
513
|
};
|
|
514
|
+
|
|
515
|
+
// Distance is in meters, totalCarbon is in grams
|
|
516
|
+
const totalCarbon =
|
|
517
|
+
itinerary?.legs?.reduce((total, leg) => {
|
|
518
|
+
return (
|
|
519
|
+
(leg.distance * carbonIntensityWithDefaults[leg.mode.toLowerCase()] ||
|
|
520
|
+
0) + total
|
|
521
|
+
);
|
|
522
|
+
}, 0) || 0;
|
|
523
|
+
|
|
524
|
+
switch (units) {
|
|
525
|
+
case "ounce":
|
|
526
|
+
return totalCarbon / 28.35;
|
|
527
|
+
case "kilogram":
|
|
528
|
+
return totalCarbon / 1000;
|
|
529
|
+
case "pound":
|
|
530
|
+
return totalCarbon / 454;
|
|
531
|
+
case "gram":
|
|
532
|
+
default:
|
|
533
|
+
return totalCarbon;
|
|
534
|
+
}
|
|
501
535
|
}
|
package/src/query.js
CHANGED
|
@@ -8,14 +8,10 @@ import queryParams from "./query-params";
|
|
|
8
8
|
import {
|
|
9
9
|
getCurrentTime,
|
|
10
10
|
getCurrentDate,
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
OTP_API_DATE_FORMAT,
|
|
12
|
+
OTP_API_TIME_FORMAT
|
|
13
13
|
} from "./time";
|
|
14
14
|
|
|
15
|
-
// import { coordsToString, summarizeQuery } from "./deprecated";
|
|
16
|
-
|
|
17
|
-
// export { summarizeQuery };
|
|
18
|
-
|
|
19
15
|
/* The list of default parameters considered in the settings panel */
|
|
20
16
|
|
|
21
17
|
export const defaultParams = [
|
|
@@ -427,7 +423,7 @@ export function getRoutingParams(config, currentQuery, ignoreRealtimeUpdates) {
|
|
|
427
423
|
}
|
|
428
424
|
|
|
429
425
|
// check date/time validity; ignore both if either is invalid
|
|
430
|
-
const dateValid = isMatch(params.date,
|
|
426
|
+
const dateValid = isMatch(params.date, OTP_API_DATE_FORMAT);
|
|
431
427
|
const timeValid = isMatch(params.time, OTP_API_TIME_FORMAT);
|
|
432
428
|
|
|
433
429
|
if (!dateValid || !timeValid) {
|
package/src/time.ts
CHANGED
|
@@ -2,12 +2,9 @@ import { Config } from "@opentripplanner/types";
|
|
|
2
2
|
import { startOfDay, add, format } from "date-fns";
|
|
3
3
|
import { utcToZonedTime } from "date-fns-tz";
|
|
4
4
|
|
|
5
|
-
//
|
|
6
|
-
//
|
|
7
|
-
export const OTP_API_DATE_FORMAT = "
|
|
8
|
-
// Date-Fns uses a different string format than moment.js
|
|
9
|
-
// see https://github.com/date-fns/date-fns/blob/master/docs/unicodeTokens.md
|
|
10
|
-
export const OTP_API_DATE_FORMAT_DATE_FNS = "yyyy-MM-dd";
|
|
5
|
+
// Date/time formats (per date-fns) when sending/receiving date from OTP
|
|
6
|
+
// regardless of whatever the user has configured as the display format.
|
|
7
|
+
export const OTP_API_DATE_FORMAT = "yyyy-MM-dd";
|
|
11
8
|
export const OTP_API_TIME_FORMAT = "HH:mm";
|
|
12
9
|
|
|
13
10
|
/**
|
|
@@ -89,8 +86,5 @@ export function getCurrentTime(timezone = getUserTimezone()): string {
|
|
|
89
86
|
* The conversion to the user's timezone is needed for testing purposes.
|
|
90
87
|
*/
|
|
91
88
|
export function getCurrentDate(timezone = getUserTimezone()): string {
|
|
92
|
-
return format(
|
|
93
|
-
utcToZonedTime(Date.now(), timezone),
|
|
94
|
-
OTP_API_DATE_FORMAT_DATE_FNS
|
|
95
|
-
);
|
|
89
|
+
return format(utcToZonedTime(Date.now(), timezone), OTP_API_DATE_FORMAT);
|
|
96
90
|
}
|