Skip to content

Commit

Permalink
fixed route finding bug, fixed bus icon bugs
Browse files Browse the repository at this point in the history
  • Loading branch information
unfiltered-syrup committed Nov 27, 2023
1 parent 786837b commit e04b7ae
Show file tree
Hide file tree
Showing 3 changed files with 112 additions and 115 deletions.
109 changes: 1 addition & 108 deletions back-end/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,118 +5,11 @@ require('dotenv').config();
// we will put some server logic here later...

const cors = require('cors');
const { createGraph, findOptimalRoute } = require('./getOptimizedRoute.js');
app.use(cors());

module.exports = app;

//this function creates a directed circular graph representation of of bus stops and the routes.
/*in the output graph, the key represents a bus stop, and the value represents all the bus stops that
are directly reachavble from the key bus stop.*/
function createGraph(routes) {
let graph = {};
for (let routeId in routes) {
let stops = routes[routeId];
for ( let i = 0; i < stops.length; i++) {
let currentStop = stops[i];
let nextStop = stops[(i + 1) % stops.length];
let currentKey = currentStop.toString();

if (!graph[currentKey]) {
graph[currentKey] = [];
}
graph[currentKey].push({ coordinates: nextStop, route: routeId });

}
}
return graph;
}

function getEuclideanDistance (origin, destination) {
let x1 = origin.split(',')[0];
let y1 = origin.split(',')[1];
let x2 = destination.split(',')[0];
let y2 = destination.split(',')[1];
return Math.sqrt(Math.pow((x2 - x1), 2) + Math.pow((y2 - y1), 2));
}

//find bus stops that are relatively close in term of walking distance
function findAllReachableStops(graph, origin, threshold=0.013) {
let reachableStops = [];
for (busstop in graph){
busstop = busstop.toString();
let distance = getEuclideanDistance(busstop, origin);
if (distance < threshold) {
reachableStops.push({coordinates: busstop});
}
}

return reachableStops;

}
// return walking distance from point A to point B
async function getWalkingDistance(origin, destination) {
origin = origin.split(',').join('%2C');
destination = destination.split(',').join('%2C');
let res = await fetch(`https://maps.googleapis.com/maps/api/distancematrix/json?units=imperial&origins=${origin}&destinations=${destination}&key=${process.env.EXPRESS_APP_MAP_API_KEY}`)
let data = await res.json();
res = data.rows[0].elements[0].duration.value;
return res;
}

function isOnSameRoute(stop1, stop2) {
return stop1.route === stop2.route;
}

async function findOptimalRoute(graph, origin, destination) {
let minTotalDistance = Number.MAX_VALUE;
let optimalRoute = null;

// Find all reachable stops from origin and destination
let reachableFromOrigin = findAllReachableStops(graph, origin);
let reachableFromDestination = findAllReachableStops(graph, destination);

// Calculate route distances
for (let originStop of reachableFromOrigin) {
for (let destinationStop of reachableFromDestination) {
if (isOnSameRoute(originStop, destinationStop)) {
let distanceToOriginStop = await getWalkingDistance(origin, originStop.coordinates);
let distanceFromDestinationStop = await getWalkingDistance(destinationStop.coordinates, destination);

let totalDistance = distanceToOriginStop + distanceFromDestinationStop;
console.log('fetched from Google Maps API, total distance: '+totalDistance);
console.log('----------------------------------')
// Check if this route is better than the current best
if (totalDistance < minTotalDistance) {
minTotalDistance = totalDistance;
optimalRoute = { originStop, destinationStop, route: originStop.route };
}
}
}
}
console.log('optimal route: '+optimalRoute.route);
console.log('origin stop: '+optimalRoute.originStop.coordinates);
console.log('destination stop: '+optimalRoute.destinationStop.coordinates);

return optimalRoute;
}

function findRoute (graph, origin, destination) {
const minTotalWalkingDistance = Number.MAX_VALUE;
const minRoute = null;
let closestStop = null;
let walkdist = Number.MAX_VALUE;
//find closest starting point
for (let stop in graph) {
let currentStop = stop.toString();
let currentRoute = graph[stop];
let currentDistance = getEuclideanDistance(currentStop, origin);
if (currentDistance < walkdist) {
walkdist = currentDistance;
closestStop = currentStop;
}
}
console.log('closest to starting point: '+closestStop);
}


app.get('/getRoute', (req, res) => {
Expand Down
101 changes: 101 additions & 0 deletions back-end/getOptimizedRoute.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
//this function creates a directed circular graph representation of of bus stops and the routes.
/*in the output graph, the key represents a bus stop, and the value represents all the bus stops that
are directly reachavble from the key bus stop.*/
function createGraph(routes) {
let graph = {};
for (let routeId in routes) {
let stops = routes[routeId];
for ( let i = 0; i < stops.length; i++) {
let currentStop = stops[i];
let nextStop = stops[(i + 1) % stops.length];
let currentKey = currentStop.toString();

if (!graph[currentKey]) {
graph[currentKey] = [];
}
graph[currentKey].push({ coordinates: nextStop, route: routeId });

}
}
return graph;
}

function getEuclideanDistance (origin, destination) {
let x1 = origin.split(',')[0];
let y1 = origin.split(',')[1];
let x2 = destination.split(',')[0];
let y2 = destination.split(',')[1];
return Math.sqrt(Math.pow((x2 - x1), 2) + Math.pow((y2 - y1), 2));
}

//find bus stops that are relatively close in term of walking distance
function findAllReachableStops(graph, origin, threshold=0.013) {
let reachableStops = [];
for (busstop in graph){
busstop = busstop.toString();
let distance = getEuclideanDistance(busstop, origin);
if (distance < threshold) {
console.log('reachable stop found: '+graph[busstop][0].route);
reachableStops.push({coordinates: busstop, route: graph[busstop][0].route});
}
}

return reachableStops;

}
// return walking distance from point A to point B
async function getWalkingDistance(origin, destination) {
origin = origin.split(',').join('%2C');
destination = destination.split(',').join('%2C');
let res = await fetch(`https://maps.googleapis.com/maps/api/distancematrix/json?units=imperial&origins=${origin}&destinations=${destination}&key=${process.env.EXPRESS_APP_MAP_API_KEY}`)
let data = await res.json();
res = data.rows[0].elements[0].duration.value;
return res;
}

function isOnSameRoute(stop1, stop2) {
console.log(stop1.route);
return stop1.route === stop2.route;
}

async function findOptimalRoute(graph, origin, destination) {
let minTotalDistance = Number.MAX_VALUE;
let optimalRoute = null;

// Find all reachable stops from origin and destination
let reachableFromOrigin = findAllReachableStops(graph, origin);
let reachableFromDestination = findAllReachableStops(graph, destination);

// Calculate route distances
for (let originStop of reachableFromOrigin) {
for (let destinationStop of reachableFromDestination) {
if (isOnSameRoute(originStop, destinationStop)) {
let distanceToOriginStop = await getWalkingDistance(origin, originStop.coordinates);
let distanceFromDestinationStop = await getWalkingDistance(destinationStop.coordinates, destination);

let totalDistance = distanceToOriginStop + distanceFromDestinationStop;
console.log('fetched from Google Maps API, total distance: '+totalDistance);
console.log('----------------------------------')
// Check if this route is better than the current best
if (totalDistance < minTotalDistance) {
minTotalDistance = totalDistance;
optimalRoute = { originStop, destinationStop };
}
}
}
}
console.log('optimal route: '+optimalRoute.originStop.route);
console.log('origin stop: '+optimalRoute.originStop.coordinates);
console.log('destination stop: '+optimalRoute.destinationStop.coordinates);

return optimalRoute;
}

module.exports = {
createGraph,
getEuclideanDistance,
findAllReachableStops,
getWalkingDistance,
isOnSameRoute,
findOptimalRoute
}
17 changes: 10 additions & 7 deletions front-end/src/utils/transportMarker.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export function updateTransportMarkers(transportData, markerRef, map) {
const lat = parseFloat(transportInfo.latitude);
const lng = parseFloat(transportInfo.longitude);
const newPosition = new window.google.maps.LatLng(lat, lng);
const iconUpdate = marker && marker.direction !== transportInfo.calculatedCourse;
const iconUpdate = marker && (marker.direction !== transportInfo.calculatedCourse || transportInfo.route === 'Ferry Route');

if (marker) {
// Update the position of the existing marker
Expand All @@ -29,12 +29,12 @@ export function updateTransportMarkers(transportData, markerRef, map) {

// Update the icon of the existing marker
if (iconUpdate) {
const newIcon = generateTransportMarkerIcon(transportInfo.color, transportInfo.calculatedCourse);
const newIcon = generateTransportMarkerIcon(transportInfo.color, transportInfo.calculatedCourse, transportInfo.route);
marker.setIcon(newIcon);
}
} else {
// Create a new marker
const newIcon = generateTransportMarkerIcon(transportInfo.color, transportInfo.calculatedCourse);
const newIcon = generateTransportMarkerIcon(transportInfo.color, transportInfo.calculatedCourse, transportInfo.route);
let transportMarker = createTransportMarker(newPosition, transportInfo, map, newIcon);
markerRef.current[transport] = transportMarker;
}
Expand Down Expand Up @@ -122,12 +122,15 @@ function generateTransportMarkerIcon(color, direction, route) {
</g>
</g>
</svg>`;
let iconImg;
route !== 'Ferry Route' ? (iconImg = 'data:image/svg+xml;charset=UTF-8;base64,' + btoa(svg)) : (iconImg = 'busIcons/busIcon_routeFerry_Route.png');

let iconImg = 'data:image/svg+xml;charset=UTF-8;base64,' + btoa(svg);
let scaledSize = new window.google.maps.Size(40, 40);
if (route === 'Ferry Route') {
iconImg = 'busIcons/busIcon_routeFerry_Route.png';
scaledSize= new window.google.maps.Size(30, 30);
}
const icon = {
url: iconImg,
scaledSize: new window.google.maps.Size(40, 40),
scaledSize: scaledSize,
};
return icon;
}
Expand Down

0 comments on commit e04b7ae

Please sign in to comment.