Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Include better OTP results in walk/bike directions when available. #351

Merged
merged 3 commits into from
May 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 2 additions & 9 deletions services/frontend/www-app/src/components/SingleModeListItem.vue
Original file line number Diff line number Diff line change
@@ -1,22 +1,15 @@
<template>
<q-item-label>
{{ $t('via_$place', { place: route.viaRoadsFormatted }) }}
<q-item-label v-if="trip.viaRoadsFormatted">
{{ $t('via_$place', { place: trip.viaRoadsFormatted }) }}
</q-item-label>
</template>

<script lang="ts">
import Route from 'src/models/Route';
import { defineComponent, PropType } from 'vue';
import Trip from 'src/models/Trip';

export default defineComponent({
name: 'SingleModeListItem',
data(): { route: Route } {
// this cast is safe because we know that it's a non-transit trip
const route = this.trip.nonTransitRoute() as Route;
console.assert(route);
return { route };
},
props: {
trip: {
type: Object as PropType<Trip>,
Expand Down
25 changes: 10 additions & 15 deletions services/frontend/www-app/src/components/SingleModeSteps.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<q-item
class="maneuver"
active-class="bg-blue-1"
v-for="maneuver in route.valhallaRoute.legs[0].maneuvers"
v-for="maneuver in nonTransitLeg.maneuvers"
clickable
v-on:click="clickedManeuver(maneuver)"
v-bind:key="JSON.stringify(maneuver)"
Expand All @@ -16,7 +16,7 @@
{{ maneuver.instruction }}
</q-item-label>
<q-item-label caption>
{{ maneuver.verbal_post_transition_instruction }}
{{ maneuver.verbalPostTransitionInstruction }}
</q-item-label>
</q-item-section>
</q-item>
Expand All @@ -32,14 +32,11 @@
</style>

<script lang="ts">
import Route from 'src/models/Route';
import { defineComponent, PropType } from 'vue';
import {
ValhallaRouteLegManeuver,
valhallaTypeToIcon,
} from 'src/services/ValhallaAPI';
import { valhallaTypeToIcon } from 'src/services/ValhallaAPI';
import { getBaseMap } from './BaseMap.vue';
import Trip from 'src/models/Trip';
import { NonTransitLeg, TravelmuxManeuver } from 'src/services/TravelmuxClient';

export default defineComponent({
name: 'SingleModeSteps',
Expand All @@ -51,22 +48,20 @@ export default defineComponent({
},
data(): {
geometry: GeoJSON.LineString;
route: Route;
nonTransitLeg: NonTransitLeg;
} {
// this cast is safe because we know that the trip is a non-transit trip
const route = this.trip.nonTransitRoute() as Route;
console.assert(route);
const nonTransitLeg = this.trip.legs[0]?.raw.nonTransitLeg as NonTransitLeg;
console.assert(nonTransitLeg);
return {
route,
nonTransitLeg,
geometry: this.trip.legs[0].geometry,
};
},
methods: {
valhallaTypeToIcon,
clickedManeuver: function (maneuver: ValhallaRouteLegManeuver) {
const location = this.geometry.coordinates[maneuver.begin_shape_index];
let coord: [number, number] = [location[0], location[1]];
getBaseMap()?.flyTo(coord, { zoom: 16 });
clickedManeuver: function (maneuver: TravelmuxManeuver) {
getBaseMap()?.flyTo(maneuver.startPoint, { zoom: 16 });
},
},
});
Expand Down
24 changes: 13 additions & 11 deletions services/frontend/www-app/src/models/Trip.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { LineLayerSpecification, LngLat, LngLatBounds } from 'maplibre-gl';
import { DistanceUnits, TravelMode } from 'src/utils/models';
import { Result } from 'src/utils/Result';
import Itinerary from './Itinerary';
import Route from './Route';
import {
TravelmuxMode,
TravelmuxClient,
Expand All @@ -14,18 +13,19 @@ import {
} from 'src/services/TravelmuxClient';
import { formatDistance, formatDuration } from 'src/utils/format';
import { decodePolyline } from 'src/utils/decodePolyline';
import { i18n } from 'src/i18n/lang';

export default class Trip {
raw: TravelmuxItinerary;
inner: Route | Itinerary;
inner: Itinerary | null;
preferredDistanceUnits: DistanceUnits;
innerDistanceUnits: DistanceUnits;
legs: TripLeg[];

constructor(
raw: TravelmuxItinerary,
preferredDistanceUnits: DistanceUnits,
inner: Route | Itinerary,
inner: Itinerary | null,
innerDistanceUnits: DistanceUnits,
) {
this.raw = raw;
Expand All @@ -39,6 +39,16 @@ export default class Trip {
return formatDuration(this.raw.duration, 'shortform');
}

get viaRoadsFormatted(): string | null {
const names = this.raw.legs.flatMap((leg) => {
return leg.nonTransitLeg?.substantialStreetNames;
});
if (names.length == 0) {
return null;
}
return names.join(i18n.global.t('punctuation_list_seperator'));
}

get distanceFormatted(): string | undefined {
return formatDistance(
this.raw.distance,
Expand All @@ -62,14 +72,6 @@ export default class Trip {
return undefined;
}
}

nonTransitRoute(): Route | undefined {
if (this.mode != TravelMode.Transit) {
return this.inner as Route;
} else {
return undefined;
}
}
}

export class TripLeg {
Expand Down
72 changes: 30 additions & 42 deletions services/frontend/www-app/src/services/TravelmuxClient.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { LngLat } from 'maplibre-gl';
import { LngLat, LngLatLike } from 'maplibre-gl';
import { DistanceUnits, TravelMode } from 'src/utils/models';
import { Ok, Err, Result } from 'src/utils/Result';
import Trip, { TripFetchError } from 'src/models/Trip';
Expand All @@ -7,13 +7,8 @@ import {
OTPItinerary,
OTPItineraryLeg,
} from './OpenTripPlannerAPI';
import {
ValhallaRouteResponse,
ValhallaRoute,
ValhallaErrorCode,
} from './ValhallaAPI';
import { ValhallaRouteResponse, ValhallaErrorCode } from './ValhallaAPI';
import Itinerary from 'src/models/Itinerary';
import Route from 'src/models/Route';
import { zipWith } from 'lodash';

export interface TravelmuxPlanResponse {
Expand All @@ -32,6 +27,20 @@ export interface TravelmuxLeg {
duration: number;
geometry: string;
transitLeg?: OTPItineraryLeg;
nonTransitLeg?: NonTransitLeg;
}

export interface NonTransitLeg {
maneuvers: [TravelmuxManeuver];
substantialStreetNames?: string[];
}

export interface TravelmuxManeuver {
instruction?: string;
verbalPostTransitionInstruction?: string;
startPoint: LngLatLike;
// same as valhalla's maneuver type
type: number;
}

export interface TravelmuxItinerary {
Expand Down Expand Up @@ -120,7 +129,7 @@ export class TravelmuxClient {

const query = new URLSearchParams(params).toString();

const response = await fetch('/travelmux/v4/plan?' + query);
const response = await fetch('/travelmux/v5/plan?' + query);

if (response.ok) {
const travelmuxResponseJson: TravelmuxPlanResponse =
Expand Down Expand Up @@ -149,42 +158,21 @@ export class TravelmuxClient {
},
);
return Ok(trips);
} else if (travelmuxResponseJson._valhalla) {
const routes: ValhallaRoute[] = [];
if (travelmuxResponseJson._valhalla.trip) {
routes.push(travelmuxResponseJson._valhalla.trip);
}
for (const route of travelmuxResponseJson._valhalla.alternates || []) {
if (route.trip) {
routes.push(route.trip);
}
}
const trips = zipWith(
tmxItineraries,
routes,
(tmxItinerary: TravelmuxItinerary, valhallaRoute: ValhallaRoute) => {
console.assert(tmxItinerary, 'expected tmxItinerary to be set');
console.assert(valhallaRoute, 'expected valhallaRoute to be set');
const route = Route.fromValhalla(
valhallaRoute,
travelModeFromTravelmuxMode(modes[0]),
preferredDistanceUnits,
);
console.assert(
preferredDistanceUnits == tmxItinerary.distanceUnits,
'expected preferredDistanceUnits to match tmxItinerary.distanceUnits for valhalla requests',
);
return new Trip(
tmxItinerary,
preferredDistanceUnits,
route,
tmxItinerary.distanceUnits,
);
},
} else {
console.assert(
travelmuxResponseJson._valhalla,
'expected valhalla in non-transit response',
);
const trips = tmxItineraries.map((tmxItinerary: TravelmuxItinerary) => {
console.assert(tmxItinerary, 'expected tmxItinerary to be set');
return new Trip(
tmxItinerary,
preferredDistanceUnits,
null,
tmxItinerary.distanceUnits,
);
});
return Ok(trips);
} else {
throw Error('missing routing backend');
}
} else {
const errorBody = await response.json();
Expand Down
2 changes: 1 addition & 1 deletion services/travelmux/src/api/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@ mod app_state;
pub use app_state::AppState;

pub mod health;
pub mod v3;
pub mod v4;
pub mod v5;
1 change: 0 additions & 1 deletion services/travelmux/src/api/v3/mod.rs

This file was deleted.

Loading
Loading