-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathnavigationController.js
More file actions
69 lines (56 loc) · 2.27 KB
/
navigationController.js
File metadata and controls
69 lines (56 loc) · 2.27 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
/**
* Navigation Controller
* Handles route calculation between locations
* @module controllers/navigationController
*/
import buildHateoasLinks from '../utils/hateoasBuilder.js';
import { calculateDistance } from '../utils/geoUtils.js';
import R from '../utils/responseBuilder.js';
/** Supported transportation modes */
const MODES = ['WALKING', 'DRIVING', 'PUBLIC_TRANSPORT'];
/** Speed in km/h for each mode */
const SPEEDS = { WALKING: 5, DRIVING: 50, PUBLIC_TRANSPORT: 30 };
/** Validate location coordinates */
const validateLocation = (res, loc) => {
if (!loc.lat || !loc.lon) {
R.badRequest(res, 'INVALID_INPUT', `${loc.name} location required`);
return false;
}
return true;
};
/** Validate transportation mode */
const validateMode = (res, mode) => {
if (!MODES.includes(mode)) {
R.badRequest(res, 'INVALID_INPUT', `Invalid mode: ${mode}`);
return false;
}
return true;
};
/** Build route response object */
const buildRoute = (start, end, options) => ({
startPoint: { latitude: start.lat, longitude: start.lon },
endPoint: { latitude: end.lat, longitude: end.lon },
transportationMode: options.mode,
estimatedTime: Math.ceil((options.distance / SPEEDS[options.mode]) * 60),
distance: options.distance
});
/** GET /navigation - Calculate route between two points */
const getNavigation = async (req, res, next) => {
try {
const { userLatitude, userLongitude, placeLatitude, placeLongitude, transportationMode } = req.query;
const userLoc = { lat: userLatitude, lon: userLongitude, name: 'user' };
const placeLoc = { lat: placeLatitude, lon: placeLongitude, name: 'place' };
if (!validateLocation(res, userLoc)) return;
if (!validateLocation(res, placeLoc)) return;
const mode = transportationMode || 'WALKING';
if (!validateMode(res, mode)) return;
const start = { lat: parseFloat(userLatitude), lon: parseFloat(userLongitude) };
const end = { lat: parseFloat(placeLatitude), lon: parseFloat(placeLongitude) };
const distance = calculateDistance(start.lat, start.lon, end.lat, end.lon);
const route = buildRoute(start, end, { mode, distance });
return R.success(res, { route, links: buildHateoasLinks.navigation() }, 'Route calculated');
} catch (e) {
next(e);
}
};
export default { getNavigation };