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)
|
departureTime DateTime @db.Timestamptz(3)
|
||||||
arrivalTime DateTime @db.Timestamptz(3)
|
arrivalTime DateTime @db.Timestamptz(3)
|
||||||
infoJson Json
|
infoJson Json
|
||||||
geometry String
|
|
||||||
moneyUpdate MoneyUpdate?
|
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()
|
@IsNumber()
|
||||||
@Type(() => Number)
|
@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
|
distance: number
|
||||||
|
|
||||||
@IsString()
|
@IsString()
|
||||||
@ -39,8 +39,4 @@ export class CreateTrainDto {
|
|||||||
@IsJSON()
|
@IsJSON()
|
||||||
@ApiProperty({ description: "Informations JSON supplémentaires transmises par Interrail" })
|
@ApiProperty({ description: "Informations JSON supplémentaires transmises par Interrail" })
|
||||||
infoJson: JsonValue
|
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" })
|
@ApiProperty({ description: "Identifiant de l'utilisateur⋅rice effectuant le trajet" })
|
||||||
userId: number
|
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
|
distance: number
|
||||||
|
|
||||||
@ApiProperty({ description: "Nom de la gare de départ" })
|
@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" })
|
@ApiProperty({ description: "Informations JSON supplémentaires transmises par Interrail" })
|
||||||
infoJson: JsonValue
|
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 { paginate } from 'src/common/utils/pagination.utils'
|
||||||
import { ImportTrainDto } from './dto/import-train.dto'
|
import { ImportTrainDto } from './dto/import-train.dto'
|
||||||
import { InterrailJourney, InterrailLegInfo, InterrailTravelInfo } from './dto/interrail-api.dto'
|
import { InterrailJourney, InterrailLegInfo, InterrailTravelInfo } from './dto/interrail-api.dto'
|
||||||
import { JsonObject } from '@prisma/client/runtime/library'
|
import { distanceCoordinates } from 'src/common/utils/calculus.utils'
|
||||||
import { OSMRResponse } from './dto/osmr-api.dto'
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class TrainsService {
|
export class TrainsService {
|
||||||
@ -65,15 +64,14 @@ export class TrainsService {
|
|||||||
arrival.setDate(arrival.getDate() + travelInfoJson.arrivalTime.offset)
|
arrival.setDate(arrival.getDate() + travelInfoJson.arrivalTime.offset)
|
||||||
|
|
||||||
const legInfoJson: InterrailLegInfo = JSON.parse(leg.infoJson)
|
const legInfoJson: InterrailLegInfo = JSON.parse(leg.infoJson)
|
||||||
const coordinatesString = legInfoJson.trainStopStations.map(trainStopStation => {
|
const distance = legInfoJson.trainStopStations
|
||||||
return `${trainStopStation.coordinates.longitude},${trainStopStation.coordinates.latitude}`
|
.map(trainStopStation => trainStopStation.coordinates)
|
||||||
}).join(';')
|
.reduce((distance, coordinates, index) => {
|
||||||
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 (index === 0)
|
||||||
if (osmrResult?.code === "NoRoute")
|
return distance
|
||||||
throw new NotAcceptableException("Aucune route n'a été trouvée avec https://signal.eu.org/osm/")
|
const oldCoordinates = legInfoJson.trainStopStations.at(index - 1).coordinates
|
||||||
const route = osmrResult.routes[0]
|
return distance + distanceCoordinates({ from: oldCoordinates, to: coordinates })
|
||||||
const distance = route.distance
|
}, 0)
|
||||||
const geometry = route.geometry
|
|
||||||
|
|
||||||
return this.prisma.trainTrip.upsert({
|
return this.prisma.trainTrip.upsert({
|
||||||
where: {
|
where: {
|
||||||
@ -88,7 +86,6 @@ export class TrainsService {
|
|||||||
departureTime: departure,
|
departureTime: departure,
|
||||||
arrivalTime: arrival,
|
arrivalTime: arrival,
|
||||||
infoJson: leg.infoJson,
|
infoJson: leg.infoJson,
|
||||||
geometry: geometry,
|
|
||||||
},
|
},
|
||||||
update: {
|
update: {
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
@ -98,7 +95,6 @@ export class TrainsService {
|
|||||||
departureTime: departure,
|
departureTime: departure,
|
||||||
arrivalTime: arrival,
|
arrivalTime: arrival,
|
||||||
infoJson: leg.infoJson,
|
infoJson: leg.infoJson,
|
||||||
geometry: geometry,
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user