Skip to content

Commit

Permalink
fix direct routing for non-walk (#634)
Browse files Browse the repository at this point in the history
* fix direct routing for non-walk

* wip

* wip

* wip

* wip

* wip
  • Loading branch information
felixguendling authored Oct 31, 2024
1 parent a9d98d2 commit 48ff42a
Show file tree
Hide file tree
Showing 11 changed files with 83 additions and 46 deletions.
2 changes: 1 addition & 1 deletion .pkg
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
[osr]
[email protected]:motis-project/osr.git
branch=master
commit=dc598c38804701eb1508124cd41220aad1ab3e68
commit=d7aacbe419824dcac29d3e9b016385c05d08bb91
[utl]
[email protected]:motis-project/utl.git
branch=master
Expand Down
4 changes: 2 additions & 2 deletions .pkg.lock
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
11705277383573408595
14838580964254850101
cista 5b6808fd7d7a7c1c7e4cb152b563dbf71e3efba4
zlib-ng 68ab3e2d80253ec5dc3c83691d9ff70477b32cd3
boost 73549ebca677fe6214202a1ab580362b4f80e653
Expand Down Expand Up @@ -39,7 +39,7 @@ sol2 40c7cbc7c5cfed1e8c7f1bbe6fcbe23d7a67fc75
variant 5aa73631dc969087c77433a5cdef246303051f69
tiles 6b6dc45bc904966640c7207ab91950848a8b3f6c
rtree.c 6ed73a7dc4f1184f2b5b2acd8ac1c2b28a273057
osr dc598c38804701eb1508124cd41220aad1ab3e68
osr d7aacbe419824dcac29d3e9b016385c05d08bb91
yaml-cpp 1d8ca1f35eb3a9c9142462b28282a848e5d29a91
reflect-cpp c54fe66de4650b60c23aadd4a06d9db4ffeda22f
FTXUI dd6a5d371fd7a3e2937bb579955003c54b727233
Expand Down
2 changes: 2 additions & 0 deletions include/motis/mode_to_profile.h
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
#pragma once

#include "osr/routing/mode.h"
#include "osr/routing/profile.h"

#include "motis-api/motis-api.h"

namespace motis {

api::ModeEnum to_mode(osr::mode);
osr::search_profile to_profile(api::ModeEnum, bool wheelchair);

} // namespace motis
27 changes: 22 additions & 5 deletions openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,8 @@ paths:
responses:
200:
description: |
A list of distance + duration pairs.
If no path was found, the object doesn't contain distance and duration.
A list of durations.
If no path was found, the object is empty.
content:
application/json:
schema:
Expand Down Expand Up @@ -306,20 +306,26 @@ paths:
optimal (e.g. the least transfers) journeys not being found.
If this value is too low to reach the destination at all,
it can lead to slow routing performance.
TODO: pass parameter to nigiri
schema:
type: number

- name: minTransferTime
in: query
required: false
description: Minimum transfer time for each transfer.
description: |
Minimum transfer time for each transfer.
TODO: pass parameter to nigiri
schema:
type: integer

- name: transferTimeFactor
in: query
required: false
description: Factor to multiply transfer times with.
description: |
Factor to multiply transfer times with.
TODO: pass parameter to nigiri
schema:
type: integer
default: 1
Expand Down Expand Up @@ -420,7 +426,7 @@ paths:
schema:
type: integer
default: 7200
minimum: 0
minium: 0

- name: maxPreTransitTime
in: query
Expand All @@ -443,6 +449,17 @@ paths:
type: integer
default: 900
minimum: 0

- name: maxDirectTime
in: query
required: false
description: |
Optional. Default is 30min which is `1800`.
Maximum time in seconds for direct connections.
schema:
type: integer
default: 1800
minimum: 0
responses:
'200':
description: routing result
Expand Down
11 changes: 2 additions & 9 deletions src/endpoints/routing.cc
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,6 @@ std::vector<n::routing::offset> routing::get_offsets(
}

auto offsets = std::vector<n::routing::offset>{};
auto rental_providers = 0U;
auto ignore_walk = false;

auto const handle_mode = [&](api::ModeEnum const m) {
Expand Down Expand Up @@ -170,7 +169,7 @@ std::vector<n::routing::offset> routing::get_offsets(
osr::route(*w_, *l_, profile, pos, near_stop_locations,
static_cast<osr::cost_t>(max.count()), dir,
kMaxMatchingDistance, nullptr, &sharing);
++rental_providers;
ignore_walk = true;
for (auto const [p, l] : utl::zip(paths, near_stops)) {
if (p.has_value()) {
offsets.emplace_back(
Expand All @@ -195,12 +194,7 @@ std::vector<n::routing::offset> routing::get_offsets(
};

if (utl::find(modes, api::ModeEnum::BIKE_RENTAL) != end(modes)) {
// bike rental search also finds walk paths - if at least
// one provider is found, we can ignore the walk profile
handle_mode(api::ModeEnum::BIKE_RENTAL);
if (rental_providers > 0) {
ignore_walk = true;
}
}

for (auto const m : modes) {
Expand Down Expand Up @@ -395,8 +389,7 @@ api::plan_response routing::operator()(boost::urls::url_view const& url) const {
holds_alternative<osr::location>(to) && t.has_value())
? route_direct(e, gbfs.get(), from_p, to_p, from_modes, *t,
query.wheelchair_,
std::chrono::seconds{query.maxPreTransitTime_ +
query.maxPostTransitTime_})
std::chrono::seconds{query.maxDirectTime_})
: std::pair{std::vector<api::Itinerary>{}, kInfinityDuration};

if (utl::find(modes, api::ModeEnum::TRANSIT) != end(modes) &&
Expand Down
10 changes: 10 additions & 0 deletions src/mode_to_profile.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,16 @@

namespace motis {

api::ModeEnum to_mode(osr::mode const m) {
switch (m) {
case osr::mode::kFoot: [[fallthrough]];
case osr::mode::kWheelchair: return api::ModeEnum::WALK;
case osr::mode::kBike: return api::ModeEnum::BIKE;
case osr::mode::kCar: return api::ModeEnum::CAR;
}
std::unreachable();
}

osr::search_profile to_profile(api::ModeEnum const m, bool const wheelchair) {
switch (m) {
case api::ModeEnum::WALK:
Expand Down
27 changes: 16 additions & 11 deletions src/street_routing.cc
Original file line number Diff line number Diff line change
Expand Up @@ -250,15 +250,18 @@ api::Itinerary route(osr::ways const& w,
auto const to_node = range.back().to_;
auto const to_pos = get_node_pos(to_node);
auto const next_place =
is_last_leg
? to
// All modes except sharing mobility have only one leg.
// -> This is not the last leg = it has to be sharing mobility.
: api::Place{
.name_ = sharing_data.value().provider_.sys_info_.name_,
.lat_ = to_pos.lat_,
.lon_ = to_pos.lng_,
.vertexType_ = api::VertexTypeEnum::BIKESHARE};
is_last_leg ? to
// All modes except sharing mobility have only one leg.
// -> This is not the last leg = it has to be sharing mobility.
: profile == osr::search_profile::kBikeSharing
? api::Place{.name_ =
sharing_data.value().provider_.sys_info_.name_,
.lat_ = to_pos.lat_,
.lon_ = to_pos.lng_,
.vertexType_ = api::VertexTypeEnum::BIKESHARE}
: api::Place{.lat_ = to_pos.lat_,
.lon_ = to_pos.lng_,
.vertexType_ = api::VertexTypeEnum::NORMAL};

auto concat = geo::polyline{};
auto dist = 0.0;
Expand All @@ -271,8 +274,10 @@ api::Itinerary route(osr::ways const& w,
}

auto& leg = itinerary.legs_.emplace_back(api::Leg{
.mode_ = lb->mode_ == osr::mode::kBike ? api::ModeEnum::BIKE_RENTAL
: api::ModeEnum::WALK,
.mode_ = (lb->mode_ == osr::mode::kBike &&
profile == osr::search_profile::kBikeSharing)
? api::ModeEnum::BIKE_RENTAL
: to_mode(lb->mode_),
.from_ = pred_place,
.to_ = next_place,
.duration_ = std::chrono::duration_cast<std::chrono::seconds>(
Expand Down
20 changes: 12 additions & 8 deletions ui/src/lib/formatDuration.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
export const formatDurationSec = (t: number) => {
export const formatDurationSec = (t: number): string => {
const hours = Math.floor(t / 3600);
const minutes = Math.floor((t - hours * 3600) / 60);
const seconds = t % 60;
const str = [
hours !== 0 ? hours + ' h' : '',
minutes !== 0 ? minutes + ' min' : '',
seconds !== 0 ? seconds + ' s' : ''
]
const minutes = Math.ceil((t - hours * 3600) / 60);
const str = [hours !== 0 ? hours + ' h' : '', minutes !== 0 ? minutes + ' min' : '']
.join(' ')
.trim();
return str;
};

export const formatDistanceMeters = (m: number): string => {
const kilometers = Math.floor(m / 1000);
const meters = kilometers > 5 ? 0 : Math.ceil(m - kilometers * 1000);
const str = [kilometers !== 0 ? kilometers + ' km' : '', meters !== 0 ? meters + ' m' : '']
.join(' ')
.trim();
return str;
Expand Down
11 changes: 6 additions & 5 deletions ui/src/routes/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -130,11 +130,12 @@
addEventListener('paste', (event) => {
const paste = event.clipboardData!.getData('text');
const json = JSON.parse(paste);
routingResponses = [
new Promise((resolve, _) => {
resolve(json);
})
];
console.log('paste: ', json);
const response = new Promise<PlanResponse>((resolve, _) => {
resolve(json as PlanResponse);
});
baseResponse = response;
routingResponses = [response];
});
}
Expand Down
5 changes: 3 additions & 2 deletions ui/src/routes/ConnectionDetail.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import type { Itinerary, Leg } from '$lib/openapi';
import Time from '../lib/Time.svelte';
import { routeBorderColor, routeColor } from '$lib/modeStyle';
import { formatDurationSec } from '$lib/formatDuration';
import { formatDurationSec, formatDistanceMeters } from '$lib/formatDuration';
import { Button } from '$lib/components/ui/button';
import Route from '$lib/Route.svelte';
import { getModeName } from '$lib/getModeName';
Expand Down Expand Up @@ -49,7 +49,8 @@
<div class="py-12 pl-8 flex flex-col text-muted-foreground">
<span class="ml-6">
{formatDurationSec(l.duration)}
{getModeName(l.mode)} ({Math.round(l.distance)} m)
{getModeName(l.mode)}
{formatDistanceMeters(Math.round(l.distance))}
</span>
{#if l.rental && l.rental.systemName}
<span class="ml-6">
Expand Down
10 changes: 7 additions & 3 deletions ui/src/routes/ItineraryGeoJSON.svelte
Original file line number Diff line number Diff line change
@@ -1,20 +1,24 @@
<script lang="ts">
import Layer from '$lib/map/Layer.svelte';
import GeoJSON from '$lib/map/GeoJSON.svelte';
import type { Itinerary } from '$lib/openapi';
import type { Itinerary, Mode } from '$lib/openapi';
import { getColor } from '$lib/modeStyle';
import polyline from 'polyline';
import { colord } from 'colord';
const PRECISION = 7;
function isIndividualTransport(m: Mode): boolean {
return m == 'WALK' || m == 'BIKE' || m == 'CAR';
}
function itineraryToGeoJSON(i: Itinerary): GeoJSON.GeoJSON {
return {
type: 'FeatureCollection',
features: i.legs.flatMap((l) => {
if (l.steps) {
const color = l.mode == 'WALK' ? '#42a5f5' : `${getColor(l)[0]}`;
const outlineColor = l.mode == 'WALK' ? '#1966a4' : colord(color).darken(0.2).toHex();
const color = isIndividualTransport(l.mode) ? '#42a5f5' : `${getColor(l)[0]}`;
const outlineColor = colord(color).darken(0.2).toHex();
return l.steps.map((p) => {
return {
type: 'Feature',
Expand Down

0 comments on commit 48ff42a

Please sign in to comment.