Skip to content

Commit

Permalink
#170: Using HTTPError instead of returning null in services
Browse files Browse the repository at this point in the history
  • Loading branch information
Kevin Ebsen committed Sep 15, 2023
1 parent 0aaf3be commit 07a355d
Show file tree
Hide file tree
Showing 3 changed files with 107 additions and 223 deletions.
99 changes: 28 additions & 71 deletions Server/src/services/poi.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export default class POIService {
* @param track `Track` the new POI belongs to, if no track is given, the closest will be chosen
* @param description optional description of the new POI
* @param isTurningPoint is the new POI a point, where one can turn around their vehicle (optional)
* @returns created `POI` if successful, `null` otherwise
* @returns created `POI` if successful
*/
public static async createPOI(
position: GeoJSON.Feature<GeoJSON.Point>,
Expand All @@ -25,24 +25,18 @@ export default class POIService {
track?: Track,
description?: string,
isTurningPoint?: boolean
): Promise<POI | null> {
): Promise<POI> {
// TODO: check if poi is anywhere near the track
// get closest track if none is given
if (track == null) {
const tempTrack = await TrackService.getClosestTrack(position)
if (tempTrack == null) {
logger.error(`No closest track was found for position ${JSON.stringify(position)}.`)
return null
}
track = tempTrack
track = await TrackService.getClosestTrack(position)
}

// add kilometer value
const enrichedPoint = await this.enrichPOIPosition(position, track)
if (enrichedPoint == null) {
logger.error(`The position ${JSON.stringify(position)} could not be enriched.`)
return null
}
const enrichedPoint = await this.enrichPOIPosition(
position,
track ?? (await TrackService.getClosestTrack(position))
)

// Note: geopos is from type GeoJSON.Feature and can't be parsed directly into Prisma.InputJsonValue
// Therefore we cast it into unknown first.
Expand All @@ -60,103 +54,66 @@ export default class POIService {
* Add value of track kilometer to properties for a given point
* @param point position of POI to enrich
* @param track optional `TracK`, which is used to compute the track kilometer, if none is given the closest will be used
* @returns point with added track kilometer, `null` if not successful
* @returns point with added track kilometer
*/
public static async enrichPOIPosition(
point: GeoJSON.Feature<GeoJSON.Point>,
track?: Track
): Promise<GeoJSON.Feature<GeoJSON.Point> | null> {
): Promise<GeoJSON.Feature<GeoJSON.Point>> {
// initialize track if none is given
if (track == null) {
const tempTrack = await TrackService.getClosestTrack(point)
if (tempTrack == null) {
logger.error(`No closest track was found for position ${JSON.stringify(point)}.`)
return null
}
track = tempTrack
track = await TrackService.getClosestTrack(point)
}

// calculate and set track kilometer
const trackKm = await TrackService.getPointTrackKm(point, track)
if (trackKm == null) {
logger.error(`Could not get track distance for position ${JSON.stringify(point)} on track with id ${track.uid}.`)
return null
}
const trackKm = TrackService.getPointTrackKm(point, track)
GeoJSONUtils.setTrackKm(point, trackKm)
return point
}

/**
* Wrapper to get distance of poi in kilometers along the assigned track
* @param poi `POI` to get the distance for
* @returns track kilometer of `poi`, `null` if computation was not possible
* @returns track kilometer of `poi`
*/
public static async getPOITrackDistanceKm(poi: POI): Promise<number | null> {
public static async getPOITrackDistanceKm(poi: POI): Promise<number> {
// get closest track if none is given
const poiPos = GeoJSONUtils.parseGeoJSONFeaturePoint(poi.position)
if (poiPos == null) {
logger.error(`Position ${JSON.stringify(poi.position)} could not be parsed.`)
return null
}

// get track distance in kilometers
let poiTrackKm = GeoJSONUtils.getTrackKm(poiPos)
if (poiTrackKm == null) {
if (poiTrackKm == null) {
logger.info(`Position of POI with ID ${poi.uid} is not enriched yet.`)
// the poi position is not "enriched" yet.
// Therefore, obtain and typecast the position
const poiPos = GeoJSONUtils.parseGeoJSONFeaturePoint(poi.position)
if (poiPos == null) {
logger.error(`Position ${JSON.stringify(poi.position)} could not be parsed.`)
return null
}
logger.info(`Position of POI with ID ${poi.uid} is not enriched yet.`)
// the poi position is not "enriched" yet.
// Therefore, obtain and typecast the position
const poiPos = GeoJSONUtils.parseGeoJSONFeaturePoint(poi.position)

// get track of POI to enrich it
const track = await database.tracks.getById(poi.trackId)
// get track of POI to enrich it
const track = await database.tracks.getById(poi.trackId)

// then enrich it with the given track
const enrichedPos = await this.enrichPOIPosition(poiPos, track)
if (enrichedPos == null) {
logger.error(`Could not enrich position of POI with ID ${poi.uid}.`)
return null
}
// try to update the poi in the database, now that we have enriched it
await database.pois.update(poi.uid, { position: enrichedPos as unknown as Prisma.InputJsonValue })
// then enrich it with the given track
const enrichedPos = await this.enrichPOIPosition(poiPos, track)
// try to update the poi in the database, now that we have enriched it
await database.pois.update(poi.uid, { position: enrichedPos as unknown as Prisma.InputJsonValue })

// and re-calculate poiTrackKm (we do not care that much at this point if the update was successful)
poiTrackKm = GeoJSONUtils.getTrackKm(enrichedPos)
if (poiTrackKm == null) {
logger.error(`Could not get track kilometer of POI position ${JSON.stringify(enrichedPos)}.`)
return null
}
}
// and re-calculate poiTrackKm (we do not care that much at this point if the update was successful)
poiTrackKm = GeoJSONUtils.getTrackKm(enrichedPos)
}
return poiTrackKm
}

/**
* Compute distance of given POI as percentage along the assigned track
* @param poi `POI` to compute distance for
* @returns percentage of track distance of `poi`, `null` if computation was not possible
* @returns percentage of track distance of `poi`
*/
public static async getPOITrackDistancePercentage(poi: POI): Promise<number | null> {
public static async getPOITrackDistancePercentage(poi: POI): Promise<number> {
// get track length
const track = await database.tracks.getById(poi.trackId)

const trackLength = TrackService.getTrackLength(track)
if (trackLength == null) {
logger.error(`Length of track with id ${track.uid} could not be calculated.`)
return null
}

const poiDistKm = await this.getPOITrackDistanceKm(poi)
if (poiDistKm == null) {
logger.error(`Could not get track kilometer of POI with ID ${poi.uid}.`)
return null
}

// compute percentage
const poiDistKm = await this.getPOITrackDistanceKm(poi)
return (poiDistKm / trackLength) * 100
}

Expand Down
Loading

0 comments on commit 07a355d

Please sign in to comment.