Implement filtering of shuttles by proximity to the closest route polyline coordinate

This commit is contained in:
2025-09-26 15:40:58 -07:00
parent 9268ad5181
commit 7ed780a459
2 changed files with 50 additions and 6 deletions

View File

@@ -1,7 +1,7 @@
import { ShuttleGetterSetterRepository } from "../../repositories/shuttle/ShuttleGetterSetterRepository";
import { IEta, IRoute, IShuttle, IStop } from "../../entities/ShuttleRepositoryEntities";
import { ShuttleRepositoryLoader } from "./ShuttleRepositoryLoader";
import { IEntityWithId } from "../../entities/SharedEntities";
import { ICoordinates, IEntityWithId } from "../../entities/SharedEntities";
import { ApiResponseError } from "../ApiResponseError";
/**
@@ -10,12 +10,13 @@ import { ApiResponseError } from "../ApiResponseError";
* which inherit from `IEntityWithId`.
*/
export class ApiBasedShuttleRepositoryLoader implements ShuttleRepositoryLoader {
baseUrl = "https://passiogo.com/mapGetData.php";
readonly baseUrl = "https://passiogo.com/mapGetData.php";
constructor(
public passioSystemId: string,
public systemIdForConstructedData: string,
public repository: ShuttleGetterSetterRepository,
readonly shuttleToRouteCoordinateMaximumDistanceMiles = 10,
) {
}
@@ -31,7 +32,7 @@ export class ApiBasedShuttleRepositoryLoader implements ShuttleRepositoryLoader
public async updateAll() {
await this.updateRouteDataForSystem();
await this.updateStopAndPolylineDataForRoutesInSystem();
await this.updateShuttleDataForSystem();
await this.updateShuttleDataForSystemBasedOnProximityToRoutes();
// Because ETA method doesn't support pruning yet,
// add a call to the clear method here
@@ -155,11 +156,12 @@ export class ApiBasedShuttleRepositoryLoader implements ShuttleRepositoryLoader
return await response.json();
}
public async updateShuttleDataForSystem() {
public async updateShuttleDataForSystemBasedOnProximityToRoutes() {
try {
const json = await this.fetchShuttleDataJson();
const shuttles = this.constructShuttlesFromJson(json);
let shuttles = this.constructShuttlesFromJson(json);
if (shuttles !== null) {
shuttles = await this.filterShuttlesByDistanceFromCorrespondingRoute(shuttles);
await this.updateShuttleDataInRepository(shuttles);
} else {
console.warn(`Shuttle update failed for the following JSON: ${JSON.stringify(json)}`)
@@ -391,4 +393,46 @@ export class ApiBasedShuttleRepositoryLoader implements ShuttleRepositoryLoader
}
}
private filterShuttlesByDistanceFromCorrespondingRoute = async (shuttles: IShuttle[]) => {
let filteredShuttles: IShuttle[] = [];
await Promise.all(shuttles.map(async (shuttle) => {
const route = await this.repository.getRouteById(shuttle.routeId);
if (route != null) {
let closestDistanceMiles = Number.MAX_VALUE;
route.polylineCoordinates.forEach((coordinate) => {
const calculatedDistance = ApiBasedShuttleRepositoryLoader.convertDistanceBetweenCoordinatesToMiles(coordinate, shuttle.coordinates)
if (closestDistanceMiles > calculatedDistance) {
closestDistanceMiles = calculatedDistance;
}
});
if (closestDistanceMiles <= this.shuttleToRouteCoordinateMaximumDistanceMiles) {
filteredShuttles.push(shuttle);
}
} else {
console.warn(`No corresponding route found for ID ${shuttle.routeId} of shuttle ${shuttle.id}`)
}
}));
return filteredShuttles;
};
public static convertDistanceBetweenCoordinatesToMiles = (fromCoordinate: ICoordinates, toCoordinate: ICoordinates): number => {
const earthRadiusMiles = 3959;
const lat1Rad = fromCoordinate.latitude * Math.PI / 180;
const lat2Rad = toCoordinate.latitude * Math.PI / 180;
const deltaLatRad = (toCoordinate.latitude - fromCoordinate.latitude) * Math.PI / 180;
const deltaLonRad = (toCoordinate.longitude - fromCoordinate.longitude) * Math.PI / 180;
const a = Math.sin(deltaLatRad / 2) * Math.sin(deltaLatRad / 2) +
Math.cos(lat1Rad) * Math.cos(lat2Rad) *
Math.sin(deltaLonRad / 2) * Math.sin(deltaLonRad / 2);
const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
return earthRadiusMiles * c;
};
}

View File

@@ -3,7 +3,7 @@ import { RepositoryLoader } from "../RepositoryLoader";
export interface ShuttleRepositoryLoader extends RepositoryLoader {
updateRouteDataForSystem(): Promise<void>;
updateStopAndPolylineDataForRoutesInSystem(): Promise<void>;
updateShuttleDataForSystem(): Promise<void>;
updateShuttleDataForSystemBasedOnProximityToRoutes(): Promise<void>;
updateEtaDataForExistingStopsForSystem(): Promise<void>;
updateEtaDataForStopId(stopId: string): Promise<void>;
}