Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

139 backend remove redundant calculations and database queries #147

17 changes: 8 additions & 9 deletions Server/src/routes/track.route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -216,22 +216,21 @@ export class TrackRoute {
const ret: APIVehicle[] = await Promise.all(
vehicles.map(async (vehicle: Vehicle) => {
// get the current position of the vehicle
const geo_pos = await VehicleService.getVehiclePosition(vehicle)
const heading: number = await VehicleService.getVehicleHeading(vehicle)
const speed: number = await VehicleService.getVehicleSpeed(vehicle)
const geo_pos = await VehicleService.getVehiclePosition(vehicle, heading, speed)
const trackKm = geo_pos ? GeoJSONUtils.getTrackKm(geo_pos) : undefined
// If we know that, convert it in the API format.
const pos: Position | undefined = geo_pos
? {
lat: GeoJSONUtils.getLatitude(geo_pos),
lng: GeoJSONUtils.getLongitude(geo_pos)
}
lat: GeoJSONUtils.getLatitude(geo_pos),
lng: GeoJSONUtils.getLongitude(geo_pos)
}
: undefined
// Also acquire the percentage position. It might happen that a percentage position is known, while the position is not.
// This might not make much sense.
const percentagePosition: number | undefined = trackKm != null
? (await TrackService.getTrackKmAsPercentage(trackKm, track)) ?? undefined
: undefined
const heading: number = await VehicleService.getVehicleHeading(vehicle)
const speed: number = await VehicleService.getVehicleSpeed(vehicle)
const percentagePosition: number | undefined =
trackKm != null ? (await TrackService.getTrackKmAsPercentage(trackKm, track)) ?? undefined : undefined
return {
id: vehicle.uid,
track: vehicle.trackId,
Expand Down
21 changes: 13 additions & 8 deletions Server/src/routes/vehicle.route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,14 +112,15 @@ export class VehicleRoute {
}
}

const pos: Feature<Point> | null = await VehicleService.getVehiclePosition(userVehicle)
const heading: number = await VehicleService.getVehicleHeading(userVehicle)
const speed: number = await VehicleService.getVehicleSpeed(userVehicle)
const pos: Feature<Point> | null = await VehicleService.getVehiclePosition(userVehicle, heading, speed)
if (!pos) {
logger.error(`Could not find position of vehicle with id ${userVehicle.uid}`)
res.sendStatus(404)
return
}
const position: Position = { lat: GeoJSONUtils.getLatitude(pos), lng: GeoJSONUtils.getLongitude(pos) }
const heading: number = await VehicleService.getVehicleHeading(userVehicle)
const track: Track | null = await database.tracks.getById(userVehicle.trackId)
if (!track) {
logger.error(`Could not find track with id ${userVehicle.trackId}
Expand All @@ -136,7 +137,8 @@ export class VehicleRoute {
}
const userVehicleSimplifiedHeading: number = await VehicleService.getVehicleTrackHeading(
userVehicle,
userVehicleTrackKm
userVehicleTrackKm,
heading
)

const allVehiclesOnTrack: Vehicle[] | null = await database.vehicles.getAll(userVehicle.trackId)
Expand All @@ -148,7 +150,9 @@ export class VehicleRoute {
const appVehiclesNearUser: VehicleApp[] = (
await Promise.all(
allVehiclesOnTrack.map(async v => {
const pos = await VehicleService.getVehiclePosition(v)
const heading = await VehicleService.getVehicleHeading(v)
const speed = await VehicleService.getVehicleSpeed(v)
const pos = await VehicleService.getVehiclePosition(v, heading, speed)
const trackers = await database.trackers.getByVehicleId(v.uid)
const nearbyVehicleTrackKm: number | null = pos ? GeoJSONUtils.getTrackKm(pos) : null
if (nearbyVehicleTrackKm == null) {
Expand All @@ -162,13 +166,14 @@ export class VehicleRoute {
trackerIds: trackers.map(t => t.uid),
pos: pos ? { lat: GeoJSONUtils.getLatitude(pos), lng: GeoJSONUtils.getLongitude(pos) } : undefined,
percentagePosition: -1,
heading: await VehicleService.getVehicleHeading(v),
heading: heading,
headingTowardsUser: undefined
}
}
const nearbySimplifiedVehicleHeading: number = await VehicleService.getVehicleTrackHeading(
v,
nearbyVehicleTrackKm
nearbyVehicleTrackKm,
heading
)
return {
id: v.uid,
Expand All @@ -178,7 +183,7 @@ export class VehicleRoute {
trackerIds: trackers.map(t => t.uid),
pos: pos ? { lat: GeoJSONUtils.getLatitude(pos), lng: GeoJSONUtils.getLongitude(pos) } : undefined,
percentagePosition: (await TrackService.getTrackKmAsPercentage(nearbyVehicleTrackKm, track)) ?? -1,
heading: await VehicleService.getVehicleHeading(v),
heading: heading,
headingTowardsUser:
userVehicleSimplifiedHeading !== 0 && nearbySimplifiedVehicleHeading !== 0
? nearbySimplifiedVehicleHeading != userVehicleSimplifiedHeading
Expand All @@ -201,7 +206,7 @@ export class VehicleRoute {
pos: position,
heading: heading,
vehiclesNearUser: appVehiclesNearUser,
speed: await VehicleService.getVehicleSpeed(userVehicle),
speed: speed,
percentagePositionOnTrack: percentagePositionOnTrack,
passingPosition: undefined // TODO: Find out passingPosition
}
Expand Down
1 change: 1 addition & 0 deletions Server/src/services/db/log.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ export default class LogController {
* @param trackerId - Tracker to filter for (Optional)
* @returns Log[] - List of all logs
*/
// TODO
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you maybe elaborate a bit on this TODO with a comment after it? It might be important for Darlin as well and she might not directly know what you mean by that

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just an artefact of testing things, because I mark temporary changes like that and (normally) search and remove them before comitting. So no TODO for @Niatsuna (will be fixed in next commit).

public async getAll(vehicleId?: number, trackerId?: string, limit?: number): Promise<Log[]> {
return await this.prisma.log.findMany({
where: {
Expand Down
77 changes: 38 additions & 39 deletions Server/src/services/vehicle.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,11 @@ export default class VehicleService {
* @returns computed position of `vehicle` based on tracker data (besides the GeoJSON point there is
* also the track kilometer in the returned GeoJSON properties field), `null` if an error occurs
*/
public static async getVehiclePosition(vehicle: Vehicle): Promise<GeoJSON.Feature<GeoJSON.Point> | null> {
public static async getVehiclePosition(
vehicle: Vehicle,
vehicleHeading: number,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Those new parameters are not mentioned in the JSDoc yet. Can you add them?

vehicleSpeed: number
): Promise<GeoJSON.Feature<GeoJSON.Point> | null> {
// get track and related track data as linestring (used later)
const track = await database.tracks.getById(vehicle.trackId)
if (track == null) {
Expand Down Expand Up @@ -98,7 +102,12 @@ export default class VehicleService {
// now it is unlikely, that weights can be added to the app logs, but we could at least try it
logger.warn(`Could not add weights to tracker logs for vehicle with id ${vehicle.uid}.`)
} else {
const tempWeightedTrackKm = await this.weightedLogsToWeightedTrackKm(weightedTrackerLogs, track)
const tempWeightedTrackKm = await this.weightedLogsToWeightedTrackKm(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The if-case above seems to be impossible, as addWeightToLogs always returns a list and never null

weightedTrackerLogs,
vehicleSpeed,
vehicleHeading,
track
)
if (tempWeightedTrackKm == null) {
// (if this does not work we can still try app logs, though it is also unlikely to work)
logger.warn(
Expand All @@ -119,7 +128,12 @@ export default class VehicleService {
logger.warn(`Could not add weights to app logs for vehicle with id ${vehicle.uid}.`)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This statement will never be reached as addWeightToLogs never returns null

} else {
// try adding them to the list as well
const tempWeightedTrackKm = await this.weightedLogsToWeightedTrackKm(weightedAppLogs, track)
const tempWeightedTrackKm = await this.weightedLogsToWeightedTrackKm(
weightedAppLogs,
vehicleSpeed,
vehicleHeading,
track
)
if (tempWeightedTrackKm == null) {
logger.warn(
`Could not convert weighted app logs to weighted track kilometers for vehicle with id ${vehicle.uid}.`
Expand Down Expand Up @@ -156,6 +170,8 @@ export default class VehicleService {
*/
private static async weightedLogsToWeightedTrackKm(
weightedLogs: [Log, number][],
vehicleSpeed: number,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Those new parameters are not mentioned in the JSDoc yet

vehicleHeading: number,
track?: Track
): Promise<[number, number][] | null> {
// just need to check this for the next step
Expand All @@ -171,13 +187,6 @@ export default class VehicleService {
return null
}

// check if we need to compute vehicle speed or just use the stored speed in the logs
const vehicleSpeed = await this.getVehicleSpeed(vehicle)
if (vehicleSpeed < 0) {
logger.error(`Could not compute speed for vehicle with id ${vehicle.uid}.`)
return null
}

// predict their current position
const weightedTrackKms: [number, number][] = []
for (let i = 0; i < weightedLogs.length; i++) {
Expand All @@ -197,7 +206,7 @@ export default class VehicleService {
}

// get travelling direction
const trackHeading = await this.getVehicleTrackHeading(vehicle, lastTrackKm)
const trackHeading = await this.getVehicleTrackHeading(vehicle, lastTrackKm, vehicleHeading, track)
if (trackHeading === 0) {
logger.warn(
`Could not determine travelling direction of vehicle with id ${vehicle.uid} by log with id ${weightedLogs[i][0].uid}.`
Expand Down Expand Up @@ -351,31 +360,18 @@ export default class VehicleService {
/**
*
* @param vehicle `Vehicle` to get the last known position from
* @returns the last known position of `vehicle` mapped on its track, null if an error occurs
* @returns the last known position of `vehicle` (not mapped on track and no kilometer value set!), null if an error occurs
*/
private static async getLastKnownVehiclePosition(vehicle: Vehicle): Promise<GeoJSON.Feature<GeoJSON.Point> | null> {
// get last log and track of vehicle
// get last log of vehicle
const lastLog = await database.logs.getAll(vehicle.uid, undefined, 1)
if (lastLog.length != 1) {
logger.error(`No log entry for vehicle ${vehicle.uid} was found.`)
return null
}

const track = await database.tracks.getById(vehicle.trackId)
if (track == null) {
logger.error(`Could not find track with id ${vehicle.trackId}.`)
return null
}

// parsing to GeoJSON
const geoJSONPoint = GeoJSONUtils.parseGeoJSONFeaturePoint(lastLog[0].position)
if (geoJSONPoint == null) {
logger.error(`Could not parse the last known position of vehicle with id ${vehicle.uid}.`)
return null
}

// mapping on track
return TrackService.getProjectedPointOnTrack(geoJSONPoint, track)
return GeoJSONUtils.parseGeoJSONFeaturePoint(lastLog[0].position)
}

/**
Expand Down Expand Up @@ -425,20 +421,23 @@ export default class VehicleService {
* @param trackKm track kilometer at which the vehicle currently is (can be found with `VehicleService.getVehicleTrackDistanceKm`)
* @returns 1 or -1 if the vehicle is heading towards the end and start of the track respectively, 0 if heading is unknown
*/
public static async getVehicleTrackHeading(vehicle: Vehicle, trackKm: number): Promise<number> {
// TODO: this should be tested

// get track
const track = await database.tracks.getById(vehicle.trackId)
public static async getVehicleTrackHeading(
vehicle: Vehicle,
trackKm: number,
vehicleHeading: number,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new parameters are not mentioned in the JSDoc yet

track?: Track
): Promise<number> {
// initialize track
if (track == null) {
logger.error(`Track with id ${vehicle.trackId} was not found.`)
return 0
const tempTrack = await database.tracks.getById(vehicle.trackId)
if (tempTrack == null) {
logger.error(`Track with id ${vehicle.trackId} was not found.`)
return 0
}
track = tempTrack
}

// get (normal) heading and position of vehicle
const vehicleHeading = await this.getVehicleHeading(vehicle)

// finally compute track heading
// compute track heading
const trackBearing = await TrackService.getTrackHeading(track, trackKm)
if (trackBearing == null) {
logger.error(`Could not compute heading of track with id ${track.uid} at track kilometer ${trackKm}.`)
Expand All @@ -456,7 +455,7 @@ export default class VehicleService {
* Compute average speed of all trackers assigned to a specified vehicle.
* No speed from app will be used here due to mobility.
* @param vehicle `Vehicle` to get the speed for
* @returns average speed of `vehicle` based on tracker data, -1 if heading is unknown
* @returns average speed of `vehicle` based on tracker data, -1 if speed is unknown
*/
public static async getVehicleSpeed(vehicle: Vehicle): Promise<number> {
// get all trackers for given vehicle
Expand Down
Loading