add support for network calculation from the calculator
All checks were successful
Release / meta (push) Successful in 1m39s
Release / linux-build (push) Successful in 1m55s
Release / web-build (push) Successful in 3m12s
Release / android-build (push) Successful in 6m48s
Release / release-master (push) Successful in 22s
Release / release-dev (push) Successful in 28s

This commit is contained in:
2026-01-27 00:41:27 +00:00
parent 94adf06726
commit 45bd872b23
12 changed files with 299 additions and 55 deletions

View File

@@ -517,6 +517,7 @@ class StatsAbout {
final mileageByYear = <int, double>{};
final classByYear = <int, List<StatsClassMileage>>{};
final networkByYear = <int, List<StatsNetworkMileage>>{};
final countryByYear = <int, List<StatsCountryMileage>>{};
final stationByYear = <int, List<StatsStationVisits>>{};
final winnersByYear = <int, int>{};
final winnerTypeCountsByYear = <int, Map<String, int>>{};
@@ -577,6 +578,17 @@ class StatsAbout {
return const [];
}
List<StatsCountryMileage> parseCountryList(dynamic value) {
if (value is List) {
return value
.whereType<Map>()
.map((e) => StatsCountryMileage.fromJson(
e.map((key, value) => MapEntry(key.toString(), value))))
.toList();
}
return const [];
}
void parseYearMap<T>(
dynamic source,
Map<int, T> target,
@@ -611,6 +623,11 @@ class StatsAbout {
networkByYear,
parseNetworkList,
);
parseYearMap<List<StatsCountryMileage>>(
json['top_countries'],
countryByYear,
parseCountryList,
);
parseYearMap<List<StatsStationVisits>>(
json['top_stations'],
stationByYear,
@@ -643,6 +660,7 @@ class StatsAbout {
...mileageByYear.keys,
...classByYear.keys,
...networkByYear.keys,
...countryByYear.keys,
...stationByYear.keys,
...winnersByYear.keys,
...winnerTypeCountsByYear.keys,
@@ -656,6 +674,7 @@ class StatsAbout {
mileage: mileageByYear[year] ?? 0,
topClasses: classByYear[year] ?? const [],
topNetworks: networkByYear[year] ?? const [],
topCountries: countryByYear[year] ?? const [],
topStations: stationByYear[year] ?? const [],
winnerCount: winnersByYear[year] ?? 0,
winnerTypeCounts: winnerTypeCountsByYear[year] ?? const {},
@@ -678,6 +697,7 @@ class StatsYear {
final double mileage;
final List<StatsClassMileage> topClasses;
final List<StatsNetworkMileage> topNetworks;
final List<StatsCountryMileage> topCountries;
final List<StatsStationVisits> topStations;
final int winnerCount;
final Map<String, int> winnerTypeCounts;
@@ -688,6 +708,7 @@ class StatsYear {
required this.mileage,
required this.topClasses,
required this.topNetworks,
required this.topCountries,
required this.topStations,
required this.winnerCount,
required this.winnerTypeCounts,
@@ -727,6 +748,22 @@ class StatsNetworkMileage {
);
}
class StatsCountryMileage {
final String country;
final double mileage;
StatsCountryMileage({
required this.country,
required this.mileage,
});
factory StatsCountryMileage.fromJson(Map<String, dynamic> json) =>
StatsCountryMileage(
country: _asString(json['country'], 'Unknown'),
mileage: _asDouble(json['mileage']),
);
}
class StatsStationVisits {
final String station;
final int visits;
@@ -1205,6 +1242,8 @@ class Leg {
final String start, end, network, notes, headcode, user;
final String origin, destination;
final List<String> route;
final List<NetworkMileage> networkMileage;
final List<CountryMileage> countryMileage;
final String? legShareId;
final LegShareMeta? sharedFrom;
final List<LegShareMeta> sharedTo;
@@ -1231,6 +1270,8 @@ class Leg {
required this.driving,
required this.user,
required this.locos,
this.networkMileage = const [],
this.countryMileage = const [],
this.endTime,
this.originTime,
this.destinationTime,
@@ -1300,6 +1341,14 @@ class Leg {
: _asInt(json['leg_end_delay']),
origin: _asString(json['leg_origin']),
destination: _asString(json['leg_destination']),
networkMileage: (json['network_mileage'] as List? ?? const [])
.whereType<Map>()
.map((e) => NetworkMileage.fromJson(Map<String, dynamic>.from(e)))
.toList(),
countryMileage: (json['country_mileage'] as List? ?? const [])
.whereType<Map>()
.map((e) => CountryMileage.fromJson(Map<String, dynamic>.from(e)))
.toList(),
legShareId: _asString(json['leg_share_id']),
sharedFrom: sharedFrom,
sharedTo: sharedTo,
@@ -1470,12 +1519,16 @@ class RouteResult {
final List<String> calculatedRoute;
final List<double> costs;
final double distance;
final List<NetworkMileage> networkMileage;
final List<CountryMileage> countryMileage;
RouteResult({
required this.inputRoute,
required this.calculatedRoute,
required this.costs,
required this.distance,
this.networkMileage = const [],
this.countryMileage = const [],
});
factory RouteResult.fromJson(Map<String, dynamic> json) {
@@ -1484,10 +1537,50 @@ class RouteResult {
calculatedRoute: List<String>.from(json['calculated_route']),
costs: (json['costs'] as List).map((e) => (e as num).toDouble()).toList(),
distance: (json['distance'] as num).toDouble(),
networkMileage: (json['network_mileage'] as List? ?? const [])
.whereType<Map>()
.map((e) => NetworkMileage.fromJson(Map<String, dynamic>.from(e)))
.toList(),
countryMileage: (json['country_mileage'] as List? ?? const [])
.whereType<Map>()
.map((e) => CountryMileage.fromJson(Map<String, dynamic>.from(e)))
.toList(),
);
}
}
class NetworkMileage {
final String network;
final double miles;
NetworkMileage({
required this.network,
required this.miles,
});
factory NetworkMileage.fromJson(Map<String, dynamic> json) =>
NetworkMileage(
network: _asString(json['network']),
miles: _asDouble(json['miles']),
);
}
class CountryMileage {
final String country;
final double miles;
CountryMileage({
required this.country,
required this.miles,
});
factory CountryMileage.fromJson(Map<String, dynamic> json) =>
CountryMileage(
country: _asString(json['country']),
miles: _asDouble(json['miles']),
);
}
class Station {
final int id;
final String name;