mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-10-18 21:16:47 +00:00
refactor(map): build OSRM leg connectors in one place
calculateSegments and the cached legs call turned each OSRM leg into the same connector record line by line. That record now comes from osrmLegSegment; the legs call keeps adding its durationText on top, so both answers stay exactly as they were.
This commit is contained in:
@@ -17,6 +17,7 @@ import {
|
||||
routeEngineFor,
|
||||
sameRoad,
|
||||
furthestFrom,
|
||||
osrmLegSegment,
|
||||
} from './RouteCalculator'
|
||||
|
||||
// Every route now goes to the FOSSGIS per-profile hosts. The car-only project-osrm.org
|
||||
@@ -1246,3 +1247,28 @@ describe('a trip that avoids something', () => {
|
||||
expect(routes[1]).toMatchObject({ avoids: 'motorway', engine: 'valhalla', hasFerry: true })
|
||||
})
|
||||
})
|
||||
|
||||
describe('osrmLegSegment', () => {
|
||||
const waypoints = [{ lat: 48, lng: 2 }, { lat: 50, lng: 4 }, { lat: 52, lng: 6 }]
|
||||
|
||||
it('spans waypoint i to i + 1 with the label at the midpoint', () => {
|
||||
const seg = osrmLegSegment({ distance: 1500, duration: 600 }, 1, waypoints)
|
||||
expect(seg.from).toEqual([50, 4])
|
||||
expect(seg.to).toEqual([52, 6])
|
||||
expect(seg.mid).toEqual([51, 5])
|
||||
expect(seg.distance).toBe(1500)
|
||||
expect(seg.duration).toBe(600)
|
||||
})
|
||||
|
||||
it('formats driving as measured and walking at 5 km/h', () => {
|
||||
const seg = osrmLegSegment({ distance: 5000, duration: 600 }, 0, waypoints)
|
||||
expect(seg.drivingText).toBe('10 min')
|
||||
expect(seg.walkingText).toBe('1 h 0 min')
|
||||
expect(seg.durationText).toBeUndefined()
|
||||
})
|
||||
|
||||
it('writes short metric distances in metres', () => {
|
||||
useSettingsStore.setState({ settings: { ...useSettingsStore.getState().settings, distance_unit: 'metric' } })
|
||||
expect(osrmLegSegment({ distance: 420.4, duration: 60 }, 0, waypoints).distanceText).toBe('420 m')
|
||||
})
|
||||
})
|
||||
|
||||
@@ -470,20 +470,29 @@ export async function calculateSegments(
|
||||
if (data.code !== 'Ok' || !data.routes?.[0]) throw new Error('No route found')
|
||||
|
||||
const legs = data.routes[0].legs
|
||||
return legs.map((leg: { distance: number; duration: number }, i: number): RouteSegment => {
|
||||
const from: [number, number] = [waypoints[i].lat, waypoints[i].lng]
|
||||
const to: [number, number] = [waypoints[i + 1].lat, waypoints[i + 1].lng]
|
||||
const mid: [number, number] = [(from[0] + to[0]) / 2, (from[1] + to[1]) / 2]
|
||||
const walkingDuration = leg.distance / (5000 / 3600)
|
||||
return {
|
||||
mid, from, to,
|
||||
distance: leg.distance,
|
||||
duration: leg.duration,
|
||||
walkingText: formatDuration(walkingDuration),
|
||||
drivingText: formatDuration(leg.duration),
|
||||
distanceText: formatRouteDistance(leg.distance),
|
||||
}
|
||||
})
|
||||
return legs.map((leg: OsrmLeg, i: number): RouteSegment => osrmLegSegment(leg, i, waypoints))
|
||||
}
|
||||
|
||||
interface OsrmLeg { distance: number; duration: number }
|
||||
|
||||
/**
|
||||
* The connector data for OSRM leg i, which runs from waypoint i to waypoint i + 1:
|
||||
* both ends, the midpoint the label sits on, and the walking time at 5 km/h next to
|
||||
* the driving time OSRM measured.
|
||||
*/
|
||||
export function osrmLegSegment(leg: OsrmLeg, i: number, waypoints: Waypoint[]): RouteSegment {
|
||||
const from: [number, number] = [waypoints[i].lat, waypoints[i].lng]
|
||||
const to: [number, number] = [waypoints[i + 1].lat, waypoints[i + 1].lng]
|
||||
const mid: [number, number] = [(from[0] + to[0]) / 2, (from[1] + to[1]) / 2]
|
||||
const walkingDuration = leg.distance / (5000 / 3600)
|
||||
return {
|
||||
mid, from, to,
|
||||
distance: leg.distance,
|
||||
duration: leg.duration,
|
||||
walkingText: formatDuration(walkingDuration),
|
||||
drivingText: formatDuration(leg.duration),
|
||||
distanceText: formatRouteDistance(leg.distance),
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -617,22 +626,12 @@ async function osrmWithLegs(
|
||||
const coordinates: [number, number][] = route.geometry.coordinates.map(
|
||||
([lng, lat]: [number, number]) => [lat, lng]
|
||||
)
|
||||
// The day plan's connectors also show the leg's own duration line.
|
||||
const legs: RouteSegment[] = (route.legs || []).map(
|
||||
(leg: { distance: number; duration: number }, i: number): RouteSegment => {
|
||||
const from: [number, number] = [waypoints[i].lat, waypoints[i].lng]
|
||||
const to: [number, number] = [waypoints[i + 1].lat, waypoints[i + 1].lng]
|
||||
const mid: [number, number] = [(from[0] + to[0]) / 2, (from[1] + to[1]) / 2]
|
||||
const walkingDuration = leg.distance / (5000 / 3600)
|
||||
return {
|
||||
mid, from, to,
|
||||
distance: leg.distance,
|
||||
duration: leg.duration,
|
||||
walkingText: formatDuration(walkingDuration),
|
||||
drivingText: formatDuration(leg.duration),
|
||||
distanceText: formatRouteDistance(leg.distance),
|
||||
durationText: formatDuration(leg.duration),
|
||||
}
|
||||
}
|
||||
(leg: OsrmLeg, i: number): RouteSegment => ({
|
||||
...osrmLegSegment(leg, i, waypoints),
|
||||
durationText: formatDuration(leg.duration),
|
||||
})
|
||||
)
|
||||
|
||||
const snapped = readSnapped(data, waypoints)
|
||||
|
||||
Reference in New Issue
Block a user