6 Commits
7 changed files with 123 additions and 25 deletions
+64
View File
@@ -0,0 +1,64 @@
erDiagram
journey||--|{routesegments: "consists of"
routesegments||--||segment: "sorts"
segment||--|{departure: "consists of"
departure}|--|{station: "originates from"
departure}|--||vehicle: uses
vehicle||..|{line: "shared data"
segment}|--||vehicle: uses
stationlines}|..||station: "general connections"
stationlines}|..||line: groups
journey {
int id PK
string startstation
string endstation
}
routesegments {
int id PK
int journey FK
int segment FK
int segmentorder
}
segment {
int id PK
string ref
int startid FK
int endid FK
string vehicleid FK
}
departure {
int id PK
string ref
string direction
string vehicle FK
string vehiclename
string station FK
string stationname
string arrivaltime
string departuretime
}
station {
string id PK
string name
}
stationlines {
int id PK
string stationid FK
string lineid FK
}
vehicle {
string vehicleid PK
string name
string line FK
}
line {
string lineid PK
string name
string mode
string destination
string direction
string fgcolor
string bgcolor
}
+8
View File
@@ -0,0 +1,8 @@
flowchart TD
Start-->stat[Search Station]-->selstat[Select station]
selstat-->seldep["`Select departure:
vehicle, direction & time`"]
seldep-->selarr["`Select arrival station:
when & where to exit`"] --> sw{switch?} --yes-->seldep
sw--"no"-->fin([journey details])
+19
View File
@@ -0,0 +1,19 @@
sequenceDiagram
participant api@{ "type": "entity"} as public transport API
participant ah as api_handler
participant ui as UI
participant th as transport_helper
participant db@{ "type":"database"} as database
ui-->>ah: find Station
ah-->>api: GET request w/ stationname
api-->>ah: return json
ah-->>th: provide json Map
th-->>db: store object
db-->>th: return id
th-->>ah: return object
ah-->>ui: display data
+10 -10
View File
@@ -1,10 +1,10 @@
- running mobile app - [x] running mobile app
- users should be able to - [ ] users should be able to
- plan public transport in the VBB transit network - [~] plan public transport in the VBB transit network
- create and customise routes quickly and on-the-fly - [~] create and customise routes quickly and on-the-fly
- edit routes from anywhere, where respective route information can be seen - [ ] edit routes from anywhere, where respective route information can be seen
- compare routes easily, especially between different endpoints - [ ] compare routes easily, especially between different endpoints
- the app should offer up the information most relevant to current route planning - [~] the app should offer up the information most relevant to current route planning
- between route steps, there should be no more than 3 taps required, optimally even just one(1), scrolling excluded - [x] between route steps, there should be no more than 3 taps required, optimally even just one(1), scrolling excluded
- e.g. only lines that connect to a station should be shown - [x] e.g. only lines that connect to a station should be shown
- stations that a line goes through should be available as next node/ step for planning - [x] stations that a line goes through should be available as next node/ step for planning
+12 -9
View File
@@ -6,19 +6,19 @@ import 'dart:convert';
import 'transport_helper.dart'; import 'transport_helper.dart';
String timeOf(DateTime fullDT) {
// doing it this way so we always get two digits on the hour
String full = fullDT.toString();
List<String> splits = full.split(" ")[1].split(":");
String time = '${splits[0]}:${splits[1]}';
return time;
}
class ApiHandler { class ApiHandler {
// TODO: Split next line for better Error Handling // TODO: Split next line for better Error Handling
static final String baseUrl = dotenv.get("VBB_API_URL"); static final String baseUrl = dotenv.get("VBB_API_URL");
static final String accessID = dotenv.get("VBB_API_KEY"); static final String accessID = dotenv.get("VBB_API_KEY");
// TODO: function calls for the following API calls
// - [x] location.name: findStations
// - [ ] location.nearbystops
// - [ ] location.details
// - [ ] departureBoard
// - [ ] multiDepartureBoard
// - [ ] journeyDetails
//static Future<Map<String, dynamic>> findStations(String locationName) async { //static Future<Map<String, dynamic>> findStations(String locationName) async {
static Future<List<Station>> findStations( static Future<List<Station>> findStations(
String locationName, { String locationName, {
@@ -79,6 +79,7 @@ class ApiHandler {
static Future<List<Departure>> departures( static Future<List<Departure>> departures(
String stationId, { String stationId, {
int? maxDepartures = -1, int? maxDepartures = -1,
DateTime? time,
int? duration = 0, int? duration = 0,
}) async { }) async {
String urlPath = '/api/fahrinfo/latest/departureBoard'; String urlPath = '/api/fahrinfo/latest/departureBoard';
@@ -87,7 +88,9 @@ class ApiHandler {
Uri url = Uri.https(baseUrl, urlPath, { Uri url = Uri.https(baseUrl, urlPath, {
'accessId': accessID, 'accessId': accessID,
'id': stationString, 'id': stationString,
////'time': /current time //time from which departures will be shown 'time': timeOf(
time ?? DateTime.now(),
), //time from which departures will be shown
'duration': duration.toString(), //interval time in minutes 'duration': duration.toString(), //interval time in minutes
'maxJourneys': maxDepartures.toString(), 'maxJourneys': maxDepartures.toString(),
//'type': 'S', // Station/Stops only //'type': 'S', // Station/Stops only
+9 -3
View File
@@ -4,12 +4,12 @@ import 'api_handler.dart';
import 'transport_helper.dart'; import 'transport_helper.dart';
import 'dart:async'; import 'dart:async';
// import 'package:sqflite_common_ffi/sqflite_ffi.dart'; //for testing on desktop import 'package:sqflite_common_ffi/sqflite_ffi.dart'; //for testing on desktop
void main() async { void main() async {
await dotenv.load(); await dotenv.load();
const String dbName = "oeffimasterTransportDb"; const String dbName = "oeffimasterTransportDb";
// databaseFactory = databaseFactoryFfi; // for debugging and desktop test databaseFactory = databaseFactoryFfi; // for debugging and desktop test
DbHelper.initDb(dbName); DbHelper.initDb(dbName);
runApp(const MyApp()); runApp(const MyApp());
} }
@@ -273,9 +273,11 @@ class StationList extends StatelessWidget {
class ChooseDeparturePage extends StatefulWidget { class ChooseDeparturePage extends StatefulWidget {
final Station startStation; final Station startStation;
final int? journeyId; final int? journeyId;
final Departure? arrival;
const ChooseDeparturePage({ const ChooseDeparturePage({
super.key, super.key,
this.journeyId, this.journeyId,
this.arrival,
required this.startStation, required this.startStation,
}); });
@@ -288,7 +290,10 @@ class _ChooseDeparturePageState extends State<ChooseDeparturePage> {
Journey? singleJourney; Journey? singleJourney;
void loadDepartures(Station startStation) async { void loadDepartures(Station startStation) async {
departureList = await ApiHandler.departures(startStation.id); departureList = await ApiHandler.departures(
startStation.id,
time: widget.arrival?.arrivalTime ?? DateTime.now(),
);
setState(() {}); setState(() {});
} }
@@ -470,6 +475,7 @@ class _ChooseArrivalPageState extends State<ChooseArrivalPage> {
builder: (context) => ChooseDeparturePage( builder: (context) => ChooseDeparturePage(
startStation: startStation, startStation: startStation,
journeyId: journeyId, journeyId: journeyId,
arrival: arrival,
), ),
), ),
); );
+1 -3
View File
@@ -187,9 +187,7 @@ class Journey {
database.execute("""CREATE TABLE IF NOT EXISTS '$tableName'( database.execute("""CREATE TABLE IF NOT EXISTS '$tableName'(
id INTEGER PRIMARY KEY AUTOINCREMENT, id INTEGER PRIMARY KEY AUTOINCREMENT,
startstation TEXT, startstation TEXT,
endstation TEXT, endstation TEXT
FOREIGN KEY (startstation) REFERENCES station(name)
FOREIGN KEY (endstation) REFERENCES station(name)
); );
"""); """);
} }