feat(transport_helper): add route building functionality

This commit is contained in:
fbachus
2026-07-11 22:02:29 +02:00
parent 761870bd33
commit 08e6d36dbe
+88 -3
View File
@@ -48,18 +48,22 @@ class DbHelper {
class Route { class Route {
// TODO: add last_viewed, last_modified and such // TODO: add last_viewed, last_modified and such
int? id; int? id;
String? startStation;
String? endStation;
List<Segment> segments = List.empty(); List<Segment> segments = List.empty();
Duration duration = Duration(minutes: 0); Duration duration = Duration(minutes: 0);
Route({ Route({
this.id, this.id,
this.startStation,
this.endStation,
required this.segments, required this.segments,
required this.duration, required this.duration,
}); });
/// toMap for Route but it's just route ids for now /// toMap for Route but it's just route ids for now
Map<String, Object?> toMapRoute() { Map<String, Object?> toMapRoute() {
return {"id": id}; return {"id": id, "startstation": startStation, "endstation": endStation};
} }
/// toMap for routesegments relational table /// toMap for routesegments relational table
@@ -76,12 +80,22 @@ class Route {
return tmp; return tmp;
} }
factory Route.empty(Station start) {
return Route(
startStation: start.name,
segments: List.empty(),
duration: Duration(minutes: 0),
);
}
factory Route.fromMap( factory Route.fromMap(
Map<String, Object?> routeMaps, Map<String, Object?> routeMaps,
List<Segment> segmentMaps, List<Segment> segmentMaps,
) { ) {
return Route( return Route(
id: routeMaps["id"] as int, id: routeMaps["id"] as int,
startStation: routeMaps["startstation"] as String?,
endStation: routeMaps["endstation"] as String?,
segments: segmentMaps, segments: segmentMaps,
duration: Duration(minutes: 0), duration: Duration(minutes: 0),
); );
@@ -100,10 +114,57 @@ class Route {
return newRoute; return newRoute;
} }
/// recalculate some technically redundant data for fast and easy access
void sync() async {
if (segments.isNotEmpty) {
startStation = segments.first.startPoint.name;
endStation = segments.last.endPoint.name;
duration = segments.first.startTime.difference(segments.last.endTime);
} else {
// if the route has no segments yet, at least the startStation should remain,
// otherwise delete the thing
// having a startStation makes the first step faster at least
// no need to put a mostly empty route into the db though
endStation = null;
duration = Duration(minutes: 0);
}
}
void addSegment(Segment newSeg) {
segments.add(newSeg);
dbInsertLastRouteSegment();
}
void removeLastSegment() {
dbDeleteLastRouteSegment();
segments.removeLast();
}
void _removeSegment(int idx) {
segments.removeAt(idx);
}
void replaceSegment(int idx, Segment replacement) {
if ((idx < segments.length - 1 &&
replacement.fitsBetween(segments[idx - 1], segments[idx + 1])) ||
replacement.startTime.isAfter(segments[idx - 1].endTime)) {
segments[idx] = replacement;
dbUpdateRouteSegments();
} else if (idx >= segments.length) {
addSegment(replacement);
} else {
throw "startTime for Segment does not fit"; //TODO: can do this better and maybe we should allow this
}
}
static void initRouteTable() async { static void initRouteTable() async {
Database database = DbHelper.db; Database database = DbHelper.db;
database.execute("""CREATE TABLE IF NOT EXISTS route( database.execute("""CREATE TABLE IF NOT EXISTS route(
id INTEGER PRIMARY KEY AUTOINCREMENT, id INTEGER PRIMARY KEY AUTOINCREMENT,
startstation TEXT,
endstation TEXT,
FOREIGN KEY (startstation) REFERENCES station(name)
FOREIGN KEY (endstation) REFERENCES station(name)
); );
"""); """);
} }
@@ -157,13 +218,19 @@ class Route {
); );
} }
void dbInsertLastRouteSegment() async {
Database database = DbHelper.db;
var lastRouteSegment = toMapRouteSegments().last;
database.insert("routesegments", lastRouteSegment);
}
void dbInsertRouteSegments() async { void dbInsertRouteSegments() async {
Database database = DbHelper.db; Database database = DbHelper.db;
var routeSegments = toMapRouteSegments(); var routeSegments = toMapRouteSegments();
for (var i = 0; i < routeSegments.length; i++) { for (var i = 0; i < routeSegments.length; i++) {
database.insert( database.insert(
"routesegments", "routesegments",
routeSegments[i], routeSegments[i], //TODO: does this work?
); );
} }
} }
@@ -202,6 +269,15 @@ class Route {
assert(result == 0); assert(result == 0);
} }
void dbDeleteRouteSegment(int idx) {
Database database = DbHelper.db;
database.delete(
"routesegments",
where: "route = ? AND segmentorder = ?",
whereArgs: [id, idx], // TODO: test the index
);
}
void dbDeleteLastRouteSegment() { void dbDeleteLastRouteSegment() {
Database database = DbHelper.db; Database database = DbHelper.db;
database.delete( database.delete(
@@ -277,6 +353,14 @@ class Segment {
return tmp; return tmp;
} }
bool fitsBetween(Segment prev, Segment next) {
return startTime.isAfter(prev.endTime) && endTime.isBefore(next.startTime);
}
bool sameEndpoints(Segment other) {
return startPoint == other.startPoint && endPoint == other.endPoint;
}
static void initSegmentTable() async { static void initSegmentTable() async {
Database database = DbHelper.db; Database database = DbHelper.db;
String station = Station.tableName; String station = Station.tableName;
@@ -360,6 +444,7 @@ class Station {
.toList(); .toList();
} }
//TODO: usage
factory Station.fromMap( factory Station.fromMap(
Map<String, Object?> map, { Map<String, Object?> map, {
List<Line>? stationLines, List<Line>? stationLines,
@@ -790,4 +875,4 @@ enum VehicleType {
subway, subway,
regionalTrain, regionalTrain,
PLACEHOLDER, PLACEHOLDER,
} }