Estimation de la distance plutôt que de compter sur l'instabilité de signal.eu.org/osm
This commit is contained in:
parent
99bd7a88a5
commit
11ab6f66f7
@ -0,0 +1,8 @@
|
||||
/*
|
||||
Warnings:
|
||||
|
||||
- You are about to drop the column `geometry` on the `TrainTrip` table. All the data in the column will be lost.
|
||||
|
||||
*/
|
||||
-- AlterTable
|
||||
ALTER TABLE "TrainTrip" DROP COLUMN "geometry";
|
@ -65,7 +65,6 @@ model TrainTrip {
|
||||
departureTime DateTime @db.Timestamptz(3)
|
||||
arrivalTime DateTime @db.Timestamptz(3)
|
||||
infoJson Json
|
||||
geometry String
|
||||
moneyUpdate MoneyUpdate?
|
||||
}
|
||||
|
||||
|
23
server/src/common/utils/calculus.utils.ts
Normal file
23
server/src/common/utils/calculus.utils.ts
Normal file
@ -0,0 +1,23 @@
|
||||
const EARTH_RADIUS = 6378137
|
||||
|
||||
type Coordinates = {
|
||||
latitude: number
|
||||
longitude: number
|
||||
}
|
||||
|
||||
type UseDistanceTypes = {
|
||||
from: Coordinates
|
||||
to: Coordinates
|
||||
}
|
||||
|
||||
export function toRadians(degrees: number) {
|
||||
return (degrees * Math.PI) / 180
|
||||
}
|
||||
|
||||
export function distanceCoordinates({ from, to }: UseDistanceTypes) {
|
||||
const distance = EARTH_RADIUS * Math.acos(
|
||||
Math.sin(toRadians(to.latitude)) * Math.sin(toRadians(from.latitude)) +
|
||||
Math.cos(toRadians(to.latitude)) * Math.cos(toRadians(from.latitude)) * Math.cos(toRadians(from.longitude) - toRadians(to.longitude)),
|
||||
)
|
||||
return distance
|
||||
}
|
@ -15,7 +15,7 @@ export class CreateTrainDto {
|
||||
|
||||
@IsNumber()
|
||||
@Type(() => Number)
|
||||
@ApiProperty({ description: "Distance en mètres du trajet, calculé sur https://signal.eu.org/osm/" })
|
||||
@ApiProperty({ description: "Distance estimée en mètres du trajet" })
|
||||
distance: number
|
||||
|
||||
@IsString()
|
||||
@ -39,8 +39,4 @@ export class CreateTrainDto {
|
||||
@IsJSON()
|
||||
@ApiProperty({ description: "Informations JSON supplémentaires transmises par Interrail" })
|
||||
infoJson: JsonValue
|
||||
|
||||
@IsString()
|
||||
@ApiProperty({ description: "Géométrie de la course, obtenue par https://signal.eu.org/osm/" })
|
||||
geometry: string
|
||||
}
|
||||
|
@ -1,71 +0,0 @@
|
||||
export enum DrivingSide {
|
||||
LEFT = "left",
|
||||
RIGHT = "right",
|
||||
}
|
||||
|
||||
export type OSMRLocation = number[]
|
||||
|
||||
export interface OSMRWaypoint {
|
||||
location: OSMRLocation
|
||||
distance: number
|
||||
hint: string
|
||||
name: string
|
||||
}
|
||||
|
||||
export interface OSMRIntersection {
|
||||
location: OSMRLocation
|
||||
bearings: number[]
|
||||
entry: boolean[]
|
||||
in?: number
|
||||
out?: number
|
||||
classes: string[]
|
||||
}
|
||||
|
||||
export interface OSMRManeuver {
|
||||
type: string
|
||||
location: OSMRLocation
|
||||
bearing_before: number
|
||||
bearing_after: number
|
||||
}
|
||||
|
||||
export interface OSMRLegStep {
|
||||
distance: number
|
||||
duration: number
|
||||
weight: number
|
||||
driving_side: DrivingSide
|
||||
intersections: OSMRIntersection[]
|
||||
ref: string
|
||||
name: string
|
||||
mode: string
|
||||
maneuver: OSMRManeuver
|
||||
geometry: string
|
||||
}
|
||||
|
||||
export interface OSMRLeg {
|
||||
distance: number
|
||||
steps: OSMRLegStep[]
|
||||
duration: number
|
||||
weight: number
|
||||
summary: string
|
||||
}
|
||||
|
||||
export interface OSMRRoute {
|
||||
distance: number
|
||||
weight_name: SVGStringList
|
||||
legs: OSMRLeg[]
|
||||
duration: number
|
||||
weight: number
|
||||
geometry: string
|
||||
}
|
||||
|
||||
export interface OSMRTrain {
|
||||
waypoints: OSMRWaypoint[]
|
||||
routes: OSMRRoute[]
|
||||
}
|
||||
|
||||
export interface OSMRError {
|
||||
code: string
|
||||
message: string
|
||||
}
|
||||
|
||||
export type OSMRResponse = OSMRTrain & OSMRError
|
@ -13,7 +13,7 @@ export class TrainEntity implements TrainTrip {
|
||||
@ApiProperty({ description: "Identifiant de l'utilisateur⋅rice effectuant le trajet" })
|
||||
userId: number
|
||||
|
||||
@ApiProperty({ description: "Distance en mètres du trajet, calculé sur https://signal.eu.org/osm/" })
|
||||
@ApiProperty({ description: "Distance estimée en mètres du trajet" })
|
||||
distance: number
|
||||
|
||||
@ApiProperty({ description: "Nom de la gare de départ" })
|
||||
@ -30,7 +30,4 @@ export class TrainEntity implements TrainTrip {
|
||||
|
||||
@ApiProperty({ description: "Informations JSON supplémentaires transmises par Interrail" })
|
||||
infoJson: JsonValue
|
||||
|
||||
@ApiProperty({ description: "Géométrie de la course, obtenue par https://signal.eu.org/osm/" })
|
||||
geometry: string
|
||||
}
|
||||
|
@ -7,8 +7,7 @@ import { QueryPaginationDto } from 'src/common/dto/pagination-query.dto'
|
||||
import { paginate } from 'src/common/utils/pagination.utils'
|
||||
import { ImportTrainDto } from './dto/import-train.dto'
|
||||
import { InterrailJourney, InterrailLegInfo, InterrailTravelInfo } from './dto/interrail-api.dto'
|
||||
import { JsonObject } from '@prisma/client/runtime/library'
|
||||
import { OSMRResponse } from './dto/osmr-api.dto'
|
||||
import { distanceCoordinates } from 'src/common/utils/calculus.utils'
|
||||
|
||||
@Injectable()
|
||||
export class TrainsService {
|
||||
@ -65,15 +64,14 @@ export class TrainsService {
|
||||
arrival.setDate(arrival.getDate() + travelInfoJson.arrivalTime.offset)
|
||||
|
||||
const legInfoJson: InterrailLegInfo = JSON.parse(leg.infoJson)
|
||||
const coordinatesString = legInfoJson.trainStopStations.map(trainStopStation => {
|
||||
return `${trainStopStation.coordinates.longitude},${trainStopStation.coordinates.latitude}`
|
||||
}).join(';')
|
||||
const osmrResult: OSMRResponse = await fetch(`https://signal.eu.org/osm/eu/route/v1/train/${coordinatesString}?overview=full&steps=true&exclude=highspeed`).then(result => result.json())
|
||||
if (osmrResult?.code === "NoRoute")
|
||||
throw new NotAcceptableException("Aucune route n'a été trouvée avec https://signal.eu.org/osm/")
|
||||
const route = osmrResult.routes[0]
|
||||
const distance = route.distance
|
||||
const geometry = route.geometry
|
||||
const distance = legInfoJson.trainStopStations
|
||||
.map(trainStopStation => trainStopStation.coordinates)
|
||||
.reduce((distance, coordinates, index) => {
|
||||
if (index === 0)
|
||||
return distance
|
||||
const oldCoordinates = legInfoJson.trainStopStations.at(index - 1).coordinates
|
||||
return distance + distanceCoordinates({ from: oldCoordinates, to: coordinates })
|
||||
}, 0)
|
||||
|
||||
return this.prisma.trainTrip.upsert({
|
||||
where: {
|
||||
@ -88,7 +86,6 @@ export class TrainsService {
|
||||
departureTime: departure,
|
||||
arrivalTime: arrival,
|
||||
infoJson: leg.infoJson,
|
||||
geometry: geometry,
|
||||
},
|
||||
update: {
|
||||
userId: user.id,
|
||||
@ -98,7 +95,6 @@ export class TrainsService {
|
||||
departureTime: departure,
|
||||
arrivalTime: arrival,
|
||||
infoJson: leg.infoJson,
|
||||
geometry: geometry,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user