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 stations = []; List lines = []; TubeStations.fromJson(Map 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 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 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 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 words = shortName.split(" "); shortName = words.map((e) => e[0]).join(""); if (shortName.length < 3) { shortName = name.substring(0, 3).toUpperCase(); } return shortName; } }