Some updates
To begin the 3rd devblog of the highly anticipated app set to revolutionize our times, I’d like to explain the reason for the extended hiatus since the last blog post. I was on a vacation with my family. Now that my future bosses and adoring fans have realized that I am absolutely, positively, and without a doubt NOT inconsistent, and the gap in updates was solely because I was sipping well-deserved coconut water on a beach, let’s dive headfirst into the whirlpool of progress I’ve made.
Updates to the second devblog
After implementing ETA and geolocation I decided to start working on the map itself and so this part will be only about the map and its implementation!
Great flutter_map plugin
For the basis of the bus app, I decided to go for a map as the main body, similar to other location related applications. For this job I found a great plugin flutter_map, it is well documented as well as easy to set up.
Other great feature of the plugin is a MarkersLayer. Once again - super easy to set up it only needs an list of the Marker objects. The markers themselves are widgets, which means they can be easily customized.
Vilnius bus stops.txt file
Now I had to find a way to get all of the Vilnius bus stations on the map, and thankfully transitfeeds website exists. There is plenty of information about bus transit of Vilnius such as routes, calendar, trips and stops. I simply had to download the txt file and parse it! The file looks like this:
stop_id | stop_code | stop_name | stop_desc | stop_lat | stop_lon | stop_url | location_type | parent_station |
---|---|---|---|---|---|---|---|---|
9483 | 1-asis Lentvaris | 54.64437 | 25.06552 | Link | ||||
9102 | Bijūnų st. | 54.66740 | 25.21588 | Link | ||||
16291 | Geležinio Vilko st. | 54.75762 | 25.27183 | Link |
I just had to create an marker object for every station, however original Marker class can not contain any additional information such as stop_name, so by using the power of OOP I created a custom BusMarker class which made my life much easier.
Future<List<StopInfo>> _parseStopsFromFile(String fileName) async {
List<StopInfo> stopsList = [];
try {
String data = await rootBundle.loadString(fileName);
List<List<dynamic>> csvTable =
const CsvToListConverter(eol: "\n").convert(data);
for (var row in csvTable) {
String stopName = row[2].replaceAll('"', '').trim();
double stopLat = double.parse(row[4].toString());
double stopLon = double.parse(row[5].toString());
StopInfo stopInfo = StopInfo(
stopName: stopName,
stopLat: stopLat,
stopLon: stopLon,
);
stopsList.add(stopInfo);
}
} catch (e) {
// Handle file read or parsing error here
print('Error while reading or parsing the file: $e');
}
return stopsList;
}
This is the function that parses the important information from the file. I made it write info into a seperate class StopInfo so if there were some additional information I could easily upgrade the function.
Popups
For easiest possible use of the app, I wanted to simply click on a station marker and select it as destination, and for that I needed popups. This time plugins did not make my life easier so I used GestureDetector instead. This is how the popups look like right now:
Ending note
With these implementations, it now kind of looks like an application! Thanks for my dedicated fans who read all the way through 🤓🤓🤓💪💪💪