diff --git a/Server/src/services/poi.service.ts b/Server/src/services/poi.service.ts index ba28c2d5..44d5163d 100644 --- a/Server/src/services/poi.service.ts +++ b/Server/src/services/poi.service.ts @@ -31,6 +31,7 @@ export default class POIService { 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 @@ -39,6 +40,7 @@ export default class POIService { // 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 } // typecast to any, because JSON is expected @@ -59,7 +61,7 @@ export default class POIService { if (track == null) { const tempTrack = await TrackService.getClosestTrack(point) if (tempTrack == null) { - // TODO: log this + logger.error(`No closest track was found for position ${JSON.stringify(point)}.`) return null } track = tempTrack @@ -68,7 +70,7 @@ export default class POIService { // calculate and set track kilometer const trackKm = await TrackService.getPointTrackKm(point, track) if (trackKm == null) { - // TODO: log this + logger.error(`Could not get track distance for position ${JSON.stringify(point)} on track with id ${track.uid}.`) return null } GeoJSONUtils.setTrackKm(point, trackKm) @@ -84,7 +86,7 @@ export default class POIService { // get closest track if none is given const poiPos = GeoJSONUtils.parseGeoJSONFeaturePoint(poi.position) if (poiPos == null) { - // TODO: log this + logger.error(`Position ${JSON.stringify(poi.position)} could not be parsed.`) return null } @@ -97,19 +99,21 @@ export default class POIService { // 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 } // get track of POI to enrich it const track = await database.tracks.getById(poi.trackId) if (track == null) { + logger.error(`Track with id ${poi.trackId} was not found.`) return null } // 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}`) + 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 @@ -120,7 +124,7 @@ export default class POIService { // 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 distance as percentage of POI with ID ${poi.uid}.`) + logger.error(`Could not get track kilometer of POI position ${JSON.stringify(enrichedPos)}.`) return null } } @@ -137,17 +141,19 @@ export default class POIService { // get track length const track = await database.tracks.getById(poi.trackId) if (track == null) { + logger.error(`Track with id ${poi.trackId} was not found.`) return null } 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 distance as percentage of POI with ID ${poi.uid}.`) + logger.error(`Could not get track kilometer of POI with ID ${poi.uid}.`) return null } diff --git a/Server/src/services/track.service.ts b/Server/src/services/track.service.ts index 743c1e2b..3a57c5cf 100644 --- a/Server/src/services/track.service.ts +++ b/Server/src/services/track.service.ts @@ -3,10 +3,11 @@ import database from "./database.service" import GeoJSONUtils from "../utils/geojsonUtils" import distance from "@turf/distance" -import nearestPointOnLine from "@turf/nearest-point-on-line" +import nearestPointOnLine, { NearestPointOnLine } from "@turf/nearest-point-on-line" import * as turfMeta from "@turf/meta" import * as turfHelpers from "@turf/helpers" import bearing from "@turf/bearing" +import { logger } from "../utils/logger" /** * Service for track management. This also includes handling the GeoJSON track data. @@ -84,6 +85,7 @@ export default class TrackService { // get the track kilometer value from projected point const projectedPoint = await this.getProjectedPointOnTrack(position, track) if (projectedPoint == null) { + logger.error(`Could not project position ${JSON.stringify(position)}.`) return null } return GeoJSONUtils.getTrackKm(projectedPoint) @@ -105,6 +107,7 @@ export default class TrackService { // if an error occured while trying to find the closest track, there is nothing we can do if (tempTrack == null) { + logger.error(`Could not find closest track for position ${JSON.stringify(position)}.`) return null } track = tempTrack @@ -113,18 +116,22 @@ export default class TrackService { // converting feature collection of points from track to linestring to project position onto it const trackData = GeoJSONUtils.parseGeoJSONFeatureCollectionPoints(track.data) if (trackData == null) { - // TODO: log this + logger.error(`Could not parse track data of track with id ${track.uid}.`) return null } const lineStringData: GeoJSON.Feature = turfHelpers.lineString(turfMeta.coordAll(trackData)) // projecting point on linestring of track // this also computes on which line segment this point is, the distance to position and the distance along the track - const projectedPoint = nearestPointOnLine(lineStringData, position) + const projectedPoint: NearestPointOnLine = nearestPointOnLine(lineStringData, position) // for easier access we set the property of track kilometer to the already calculated value if (projectedPoint.properties["location"] == null) { - // TODO: log this + logger.error( + `Turf error: Could not calculate nearest point on line correctly for position ${JSON.stringify( + position + )} and for linestring of track with id ${track.uid}.` + ) // this is a slight overreaction as we can still return the projected point, but the track kilometer property will not be accessible return null } @@ -144,17 +151,20 @@ export default class TrackService { // validate track kilometer value const trackLength = this.getTrackLength(track) if (trackLength == null) { - // TODO: log this + logger.error(`Length of track with id ${track.uid} could not be calculated.`) return null } if (trackKm < 0 || trackKm > trackLength) { + logger.error( + `Unexpected value for track kilometer: ${trackKm}. This needs to be more than 0 and less than ${trackLength}.` + ) return null } // get track data const trackData = GeoJSONUtils.parseGeoJSONFeatureCollectionPoints(track.data) if (trackData == null) { - // TODO: log this + logger.error(`Could not parse track data of track with id ${track.uid}.`) return null } @@ -168,7 +178,7 @@ export default class TrackService { const trackPoint = trackData.features[i] const trackPointKm = GeoJSONUtils.getTrackKm(trackPoint) if (trackPointKm == null) { - // TODO: log this, this should not happen + logger.error(`Could not access track kilometer value of track point ${i} of track with id ${track.uid}.`) return null } @@ -178,7 +188,9 @@ export default class TrackService { } } - // TODO: log this, this would be really weird as we validated the track kilometer value passed + logger.error( + `Track kilometer value ${trackKm} could not be found while iterating track points of track with id ${track.uid}.` + ) return null } @@ -191,6 +203,7 @@ export default class TrackService { const tracks = await database.tracks.getAll() // there are no tracks at all if (tracks.length == 0) { + logger.warn(`No track was found.`) return null } @@ -200,16 +213,20 @@ export default class TrackService { for (let i = 0; i < tracks.length; i++) { const trackData = GeoJSONUtils.parseGeoJSONFeatureCollectionPoints(tracks[i].data) if (trackData == null) { - // TODO: log this + logger.error(`Could not parse track data of track with id ${tracks[i].uid}.`) return null } // converting feature collection of points to linestring to measure distance const lineStringData: GeoJSON.Feature = turfHelpers.lineString(turfMeta.coordAll(trackData)) // this gives us the nearest point on the linestring including the distance to that point - const closestPoint: GeoJSON.Feature = nearestPointOnLine(lineStringData, position) - if (closestPoint.properties == null || closestPoint.properties["dist"] == null) { - // TODO: this should not happen, so maybe log this + const closestPoint: NearestPointOnLine = nearestPointOnLine(lineStringData, position) + if (closestPoint.properties["dist"] == null) { + logger.warn( + `Turf error: Could not calculate nearest point on line correctly for position ${JSON.stringify( + position + )} and for linestring of track with id ${tracks[i].uid}.` + ) continue } @@ -222,6 +239,7 @@ export default class TrackService { // check if closest track was found if (minTrack < 0) { + logger.warn(`Somehow no closest track was found even after iterating all existing tracks.`) return null } else { return tracks[minTrack] @@ -238,7 +256,7 @@ export default class TrackService { // load track data const trackData = GeoJSONUtils.parseGeoJSONFeatureCollectionPoints(track.data) if (trackData == null) { - // TODO: log this + logger.error(`Could not parse track data of track with id ${track.uid}.`) return null } @@ -246,7 +264,7 @@ export default class TrackService { const trackPointsLength = trackData.features.length const trackLength = GeoJSONUtils.getTrackKm(trackData.features[trackPointsLength - 1]) if (trackLength == null) { - // TODO: log this, track data invalid, probably check if track exists and try to get it by id + logger.error(`Could not access track kilometer value of last track point of track with id ${track.uid}.`) return null } return trackLength @@ -260,7 +278,7 @@ export default class TrackService { public static getTrackAsLineString(track: Track): GeoJSON.Feature | null { const trackData = GeoJSONUtils.parseGeoJSONFeatureCollectionPoints(track.data) if (trackData == null) { - // TODO: log this + logger.error(`Could not parse track data of track with id ${track.uid}.`) return null } return turfHelpers.lineString(turfMeta.coordAll(trackData)) diff --git a/Server/src/services/vehicle.service.ts b/Server/src/services/vehicle.service.ts index 8beb3f4b..f376cd46 100644 --- a/Server/src/services/vehicle.service.ts +++ b/Server/src/services/vehicle.service.ts @@ -39,6 +39,7 @@ export default class VehicleService { * @returns `Vehicle[]` either #`count` of nearest vehicles or all vehicles within `distance` of track-kilometers, but at most #`count`. * That is the array could be empty. `null` if an error occurs */ + // NOT ADDING LOGGING HERE, BECAUSE IT WILL BE REMOVED ANYWAY (see issue #114) public static async getNearbyVehicles( point: GeoJSON.Feature | Vehicle, track?: Track, @@ -237,7 +238,7 @@ export default class VehicleService { const lastTrackerLog = trackerLogs[0] const lastTrackerPosition = GeoJSONUtils.parseGeoJSONFeaturePoint(lastTrackerLog.position) if (lastTrackerPosition == null) { - logger.warn(`Position ${trackerLogs[0].position} is not in GeoJSON-format.`) + logger.warn(`Position ${JSON.stringify(trackerLogs[0].position)} is not in GeoJSON-format.`) continue } @@ -294,7 +295,7 @@ export default class VehicleService { // parse position from log const lastPosition = GeoJSONUtils.parseGeoJSONFeaturePoint(log.position) if (lastPosition == null) { - logger.warn(`Position ${log.position} is not in GeoJSON-format.`) + logger.warn(`Position ${JSON.stringify(log.position)} is not in GeoJSON-format.`) continue } @@ -343,7 +344,9 @@ export default class VehicleService { const lastPosition = GeoJSONUtils.parseGeoJSONFeaturePoint(appPositions[i][1].position) if (lastPosition == null) { // at this point this should not happen anymore - logger.error(`Position ${appPositions[i][1].position} is not in GeoJSON-format, but should be.`) + logger.error( + `Position ${JSON.stringify(appPositions[i][1].position)} is not in GeoJSON-format, but should be.` + ) return null } const projectedPoint = nearestPointOnLine(lineStringData, lastPosition) @@ -398,8 +401,6 @@ export default class VehicleService { * @returns the last known position of `vehicle` mapped on its track, null if an error occurs */ private static async getLastKnownVehiclePosition(vehicle: Vehicle): Promise | null> { - // TODO: this could be optimized by computing an average position from all last entries by all trackers - // get last log and track of vehicle const lastLog = await database.logs.getAll(vehicle.uid, undefined, 1) if (lastLog.length != 1) { @@ -433,14 +434,14 @@ export default class VehicleService { // get track point of vehicle const vehicleTrackPoint = await this.getVehiclePosition(vehicle) if (vehicleTrackPoint == null) { - // TODO: log this + logger.error(`Could not compute position of vehicle with id ${vehicle.uid}.`) return null } // get track kilometer for vehicle position const vehicleTrackKm = GeoJSONUtils.getTrackKm(vehicleTrackPoint) if (vehicleTrackKm == null) { - // TODO: log this + logger.error(`Could not read track kilometer value from position ${JSON.stringify(vehicleTrackPoint)}.`) return null } @@ -456,7 +457,7 @@ export default class VehicleService { // get track const track = await database.tracks.getById(vehicle.trackId) if (track == null) { - // TODO: logging + logger.error(`Track with id ${vehicle.trackId} was not found.`) return null } @@ -464,6 +465,9 @@ export default class VehicleService { const trackLength = TrackService.getTrackLength(track) const vehicleDistance = await this.getVehicleTrackDistanceKm(vehicle) if (trackLength == null || vehicleDistance == null) { + logger.error( + `Distance of track with id ${track.uid} or distance of vehicle with id ${vehicle.uid} on that track could not be computed.` + ) return null } @@ -524,7 +528,7 @@ export default class VehicleService { // get track const track = await database.tracks.getById(vehicle.trackId) if (track == null) { - // TODO: log + logger.error(`Track with id ${vehicle.trackId} was not found.`) return 0 } @@ -534,7 +538,7 @@ export default class VehicleService { // finally compute track heading const trackBearing = await TrackService.getTrackHeading(track, trackKm) if (trackBearing == null) { - // TODO: log this + logger.error(`Could not compute heading of track with id ${track.uid} at track kilometer ${trackKm}.`) return 0 } // TODO: maybe give this a buffer of uncertainty @@ -553,6 +557,7 @@ export default class VehicleService { */ public static async getVehicleSpeed(vehicle: Vehicle): Promise { // get all trackers for given vehicle + // TODO: remove necessity of trackers const trackers = await database.trackers.getByVehicleId(vehicle.uid) if (trackers.length == 0) { logger.error(`No tracker found for vehicle ${vehicle.uid}.`)