Last active
July 11, 2019 08:59
-
-
Save nicohvi/6945e6d94b13324171811265d0158a0e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// @flow | |
import { sdkService } from '@entur/journey' | |
import { first, flatten, without } from 'lodash' | |
import type { Coordinates } from '@entur/journey/flow-types' | |
import { DEFAULT_IGNORE_FIELDS } from '@entur/client-native/app/containers/WalkingDirections' | |
import { getDistanceBetweenLocations } from '@entur/client-commons/utils/location' | |
import type { BikeRentalStation, TripPattern } from '../../flow-types' | |
// N: for mange any-typer! Bruk typesystemet! | |
type BikeRentalStationPath = { | |
from: Coordinates, | |
to: Coordinates, | |
mode: string, | |
} | |
// Helper function | |
// Har denna för att enklare trekke ut lat & lon ur objekt, för att få rätt type. | |
function getLatLon(object: any): {longitude: number, latitude: number} { | |
// N: er dette kun for å filtere ut lat, long fra objektet? Da er jo noe som f.eks. R.pick(['longitude', 'latitude'], obj) bedre | |
// enn en helper-funksjon (finnes sikkert noe tilsvarende i lodash). | |
return { | |
longitude: object.longitude, | |
latitude: object.latitude, | |
} | |
} | |
// Gör ett resesök via Enturs SDK | |
function getLegsFromSDK(path: BikeRentalStationPath, walkSpeed: number) { | |
const { from, to, mode } = path | |
const legs = sdkService.getTripPatterns( | |
{ coordinates: getLatLon(from) }, | |
{ coordinates: getLatLon(to) }, | |
{ modes: [mode], walkSpeed }, | |
without(DEFAULT_IGNORE_FIELDS, 'pointsOnLink', 'rentedBike') | |
) | |
return legs | |
} | |
// Helper function | |
// summerar ihop värdet i en property i ett objekt, key finns som parameter för att göra den mer generell. | |
function getTotalValue(list: Array<any>, key: string) { // her burde any -> { [key in Keys]: number } | |
return list.reduce((totalValue, currentItem) => totalValue + currentItem[key], 0) | |
} | |
// Skapa ett TripPattern av enstaka legs | |
// Ett TripPattern borde ha en lista med legs, och totala tiden & distansen för trip:et. | |
// PS: TripPattern.legs = | |
function mergeTripPatterns(tripPatterns: Array<TripPattern>): TripPattern { | |
return { | |
...first(tripPatterns), | |
distance: getTotalValue(tripPatterns, 'distance'), | |
duration: getTotalValue(tripPatterns, 'duration'), | |
legs: tripPatterns.map(tripPattern => first(tripPattern.legs)), | |
} | |
} | |
// Hämta alla stationer nära ett stoppested och returnera den närmsta stationen | |
function getNearestStation(referencePoint: Coordinates, stations: Array<BikeRentalStation>) { | |
const distances = stations.map(station => getDistanceBetweenLocations( | |
{ geometry: { coordinates: [referencePoint.longitude, referencePoint.latitude] } }, // hvorfor bruker du ikke hjelpefunksjonen? | |
{ geometry: { coordinates: [station.longitude, station.latitude] } } | |
)) | |
return stations[distances.indexOf(Math.min(...distances))] | |
} | |
// The bread and butter function, denna är the big boss | |
// Målet är att ersätta en gånglänke mellan A och B med bysykkel!!!! | |
// | |
// Så tanken är: | |
// 1. Hämta byskkelstationer nära A och B. | |
// 2. Gör ett resesök där man åker såhär: A—> bysykkelStationA —> bysykkelStationB —> B | |
// 3. returnera detta nya resesöket (TripPattern) | |
export async function getBikeRentalStationLeg( | |
start: Coordinates, stop: Coordinates, walkSpeed: number, | |
) { | |
const [startStations, stopStations] = await Promise.all( | |
[start, stop].map(station => sdkService.getBikeRentalStationsByPosition(station, 200)) | |
) | |
// dette ser bra ut, men tror jeg ville ekstrahert det ut i en egen funksjon. | |
// typ: | |
/* | |
async function getBikeRentalStationCandidates(start: Coordinates, stop: Coordinates) { | |
const startStation = await sdkService.getBikeRentalStationsByPosition(start, 200) // antar denne returnerer tomt array | |
if(empty(startStations)) return null // ingen grunn til å fortsette | |
const stopStations = await sdkService.getBikeRentalStationsByPosition(stop, 200) | |
if(empty(stopStations)) return null // samme som over | |
return {start: getNearestStation(start, startStations), stop: getNearestStation(stop, stopStations)} | |
og i hovedfunksjonen: | |
const stations = getBikeRentalStationCandidates(start, stop) | |
if(!stations) return // ingen grunn til å forsette | |
*/ | |
const [startStation, stopStation] = [getNearestStation(start, startStations), getNearestStation(stop, stopStations)] | |
if (!startStation || !stopStation) return | |
// ingen grunn til å definere denne inne i funksjonen, burde defineres utenfor siden den er statisk. | |
const modes = ['foot', 'bicycle', 'foot'] | |
const stops = [start, startStation, stopStation, stop] | |
// denne burde også være en egen funksjon. Det er ikke tydelig fra koden at du vil gå til første stasjon, | |
// deretter ta sykkel, og så gå fra siste stasjon. | |
// Tror jeg ville gjort noe slik: | |
/* | |
function getBicyclePath(stations, start, stop) { | |
return [merge, stations.start, stations.stop, stop].map((leg, idx, arr) => { | |
if(idx === stops.length -1) return null | |
const next = arr[idx+1]; | |
return { | |
from: getLatLon(leg), | |
to: getLatLon(next), | |
mode: betweenStations(leg,next) ? 'bycicle' : 'walk' | |
} | |
}).filter(Boolean) | |
} | |
*/ | |
const paths: Array<?BikeRentalStationPath> = stops.map((station, index, arr) => { | |
if (index === stops.length - 1) return null | |
const nextStop = arr[index + 1] | |
return { | |
from: getLatLon(station), | |
to: getLatLon(nextStop), | |
mode: modes[index], // forvirrrende bruk av indekser | |
} | |
}) | |
const filteredPaths: Array<BikeRentalStationPath> = paths.filter(Boolean) | |
const patterns: Array<TripPattern> = flatten( | |
await Promise.all(filteredPaths.map(path => getLegsFromSDK(path, walkSpeed))) | |
) | |
if (!patterns) return | |
return { | |
from: startStation, | |
to: stopStation, | |
tripPattern: mergeTripPatterns(patterns), | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment