Files
Bus-Infotainment--IBus-/lib/backend/modules/tube_info.dart
2024-07-13 19:25:15 +01:00

132 lines
3.2 KiB
Dart

import 'package:bus_infotainment/tfl_datasets.dart';
import 'package:bus_infotainment/utils/OrdinanceSurveyUtils.dart';
import 'package:bus_infotainment/utils/audio%20wrapper.dart';
import 'package:vector_math/vector_math.dart';
class TubeStations {
List<TubeStation> stations = [];
List<TubeLine> lines = [];
TubeStations.fromJson(Map<String, dynamic> json) {
/*
Example:
"Acton Town": {
"lines": [
"District",
"Piccadilly"
],
"location": {
"lat": 51.5029984,
"lng": -0.2803455
}
},
*/
for (String stationName in json.keys) {
TubeStation station = TubeStation();
station.name = stationName;
Map<String, dynamic> stationData = json[stationName];
station.latitude = stationData["location"]["lat"];
station.longitude = stationData["location"]["lng"];
for (String lineName in stationData["lines"]) {
// check if the line already exists
TubeLine line = lines.firstWhere((element) => element.name == lineName, orElse: () => TubeLine()..name = lineName);
if (!lines.contains(line)) {
lines.add(line);
}
station.lines.add(line);
}
stations.add(station);
}
}
// Get the london underground line that is a close match to a given bus route variant
TubeLine? getClosestLine(BusRouteVariant variant) {
Map<TubeLine, int> lineMatches = {};
for (TubeLine line in lines) {
lineMatches[line] = 0;
}
for (BusRouteStop stop in variant.busStops) {
for (TubeStation station in stations) {
// get the distance between the bus stop and the tube station
double distance = Vector2(stop.easting.toDouble(), stop.northing.toDouble()).distanceTo(OSGrid.toNorthingEasting(station.latitude, station.longitude));
// if the distance is less than 100m, then we can assume that the bus stop is near the tube station
if (distance < 400) {
for (TubeLine line in station.lines) {
lineMatches[line] = lineMatches[line]! + 1;
}
}
}
}
TubeLine? closestLine;
int closestMatch = 0;
for (TubeLine line in lineMatches.keys) {
if (lineMatches[line]! > closestMatch) {
closestLine = line;
closestMatch = lineMatches[line]!;
}
}
return closestLine;
}
}
class TubeStation {
late final String name;
late final double latitude;
late final double longitude;
List<TubeLine> lines = [];
}
class TubeLine {
late final String name;
AudioWrapperSource? getAudio() {
String lineName = name.toLowerCase().replaceAll(" ", "_");
lineName = lineName.replaceAll("and", "N");
lineName = lineName.toUpperCase();
return AudioWrapperAssetSource("audio/rail_replacement/$lineName.mp3");
}
// Get short name
// example: "District" -> "DIS", "London Overground" -> "LO", "TfL Rail" -> "TFL", "Waterloo and City" -> "W&C"
String getShortName() {
String shortName = name;
List<String> words = shortName.split(" ");
shortName = words.map((e) => e[0]).join("");
if (shortName.length < 3) {
shortName = name.substring(0, 3).toUpperCase();
}
return shortName;
}
}