class Route { List segments = List.empty(); Duration duration = Duration(minutes: 0); Route({ required this.segments, required this.duration, }); // from trip API request factory Route.fromJson(Map json) => Route( segments: json["LegList"]["Leg"].map((leg) => Segment.fromJson(leg)), duration: json["LegList"]["Leg"][-1]["Origin"]["time"] - json["LegList"]["Leg"][0]["Origin"]["time"], ); } class Segment { final Station startPoint; final Station endPoint; final DateTime startTime; final DateTime endTime; final Vehicle vehicle; Segment({ required this.startPoint, required this.endPoint, required this.startTime, required this.endTime, required this.vehicle, }); factory Segment.fromJson(Map json) => Segment( startPoint: Station.fromJson(json["Origin"]), endPoint: Station.fromJson(json["Destination"]), startTime: json["Origin"]["rtTime"], endTime: json["Destination"]["rtTime"], vehicle: Vehicle.fromJson(json["Product"]), ); } class Station { final String id; final String name; List? transportLines; List? departures; Station({ required this.id, required this.name, required this.transportLines }); factory Station.fromJson(Map json) => Station( id: json["id"] as String? ?? json["extId"] as String, name: json["name"], transportLines: json.containsKey("productAtStop") ? json["productAtStop"].map( (jsonLine) => Line.fromJson(jsonLine as Map), ) : const [], ); } class Vehicle { final String id; final Line line; Vehicle({ required this.id, required this.line, }); // we can use the "product" class from within any JSON response // (within hafas API, on the appropriate level) factory Vehicle.fromJson(Map json) => Vehicle( id: json["matchId"], line: Line.fromJson(json), ); } class Line { final String id; Station? destination; Station? direction; final VehicleType mode; final String name; Color? fgColor; Color? bgColor; Line({ required this.id, required this.name, required this.mode, this.fgColor, this.bgColor, }); // TODO: EXPLAIN!!!!!!!!!!!! static const _vehicleTypeAsCatCode = [ VehicleType.metro, VehicleType.subway, VehicleType.PLACEHOLDER, VehicleType.bus ]; factory Line.fromJson(Map json) => Line( id: json["lineId"], name: json["name"], mode: _vehicleTypeAsCatCode[int.parse(json["catCode"])], fgColor: Color.fromJson(json["foregroundColor"]) as Color? ?? Color(r: 255, g: 255, b: 255), // fallback bgColor: Color.fromJson(json["backgroundColor"]) as Color? ?? Color(r: 50, g: 50, b: 50), // fallback ); } class Departure { String? id; final Vehicle vehicle; final Station station; final DateTime departureTime; Departure({ required this.vehicle, required this.station, required this.departureTime, }); } class Color { final int r; final int g; final int b; Color({ required this.r, required this.g, required this.b, }); factory Color.fromJson(Map json) => Color( r: json["r"], g: json["g"], b: json["b"], ); } enum VehicleType { bus, tram, metro, subway, regionalTrain, PLACEHOLDER, }