Hi everyone! I recently created and published a Flutter app called Flight CO2 Calculator.

And because sharing is caring, I decided to publish the source code, and start a mini series on how to create this app. 😉

This will make for a good example on how to use streams & blocs. And we’ll learn about Flutter search as well!

How this app works

There is a flight details card, where the user can choose the departure and arrival airports, select the flight type (one way or return) and the flight class (economy, business and first).

Once this is done, the app calculates the distance between the two airports, and the corresponding CO2 emissions.

To make this app, we need a few building blocks:

A dataset of all airports. This is a csv file from OpenFlights.org which contains about 7000 entries.

A parser, to read all this data into a list of airports.

An AirportLookup service, which takes a search term, and returns a list of airports matching that term.

service, which takes a search term, and returns a list of airports matching that term. Some code for calculating the distance and CO2 emissions.

I have structured my project as a Flutter plugin with an example app:

The plugin code contains all these building blocks.

The example app includes all the UI.

Part 1: Data and calculations

In this article, I’ll show you the steps needed to create the plugin code. As part of this we will see how to:

Parse the csv file into a list of strongly-typed Airport models.

models. Write an AirportLookup service, which will power a search screen.

service, which will power a search screen. Calculate the distance and CO2 emissions.

Ready? Let’s get started.

Parsing the list of Airports

The example app contains a file called airports.dat . The format of this file is well documented here. We’re interested in this subset of fields:

Name : Name of airport. May or may not contain the City name.

: Name of airport. May or may not contain the City name. City : Main city served by airport. May be spelled differently from Name.

: Main city served by airport. May be spelled differently from Name. Country : Country or territory where airport is located.

: Country or territory where airport is located. IATA : 3-letter IATA code. Null if not assigned/unknown.

: 3-letter IATA code. Null if not assigned/unknown. ICAO : 4-letter ICAO code.Null if not assigned.

: 4-letter ICAO code.Null if not assigned. Latitude : Decimal degrees, usually to six significant digits. Negative is South, positive is North.

: Decimal degrees, usually to six significant digits. Negative is South, positive is North. Longitude: Decimal degrees, usually to six significant digits. Negative is West, positive is East.

Here is a sample:

501,"London Biggin Hill Airport","Biggin Hill","United Kingdom","BQH","EGKB",51.33079910279999,0.0324999988079,598,0,"E","Europe/London","airport","OurAirports" 502,"London Gatwick Airport","London","United Kingdom","LGW","EGKK",51.148101806640625,-0.19027799367904663,202,0,"E","Europe/London","airport","OurAirports" 503,"London City Airport","London","United Kingdom","LCY","EGLC",51.505299,0.055278,19,0,"E","Europe/London","airport","OurAirports"

To parse the airports data, we can read the input file and split it line by line:

Each line maps to an Airport instance, which is a model class with the following fields:

The parsing of each line is done inside this factory method:

This code is similar to what we would normally write to parse JSON, with the exception that the input is a line of comma-separated values.

To parse this, we split the line into multiple components, and we use their position to identify them (as opposed to reading keys in a JSON map).

Airport Lookup

This is a service that matches a search keyword against the entire data-set of airports.

It can be implemented as follows:

This code works by filtering the full airport list with a couple of different criteria. Filtering is done with the where functional method in Dart.

A first filtering pass is done to find an exact match between the search string, and any of the “iata”, “name”, “city” or “country” properties.

If no match is found, a less strict comparison is made to see if any of the above properties contains the search string.

Distance and CO2 calculation

Given two airports, we can calculate their distance as a function of their location coordinates. In other words:

Distance = f(locationA, locationB)

This is implemented by a DistanceCalculator class, which is an adapted version of the code in this StackOverflow answer:

Given the distance, it is possible to calculate the CO2 emissions with a formula based on this paper.

CO2 = f(distance, flightClass)

The maths for this involves a lot of different parameters. I’m not including it here for simplicity, but you can take a peek at the source code if you’re interested. 😉

Wrap up

That’s it for today. In the next article I’ll show how to build the Flutter UI to create the final app.

And if you can’t wait, the full source code is already available here on GitHub:

Happy coding!

UPDATE: My Flutter & Firebase Udemy course is now available for Early Access. Use this link to enroll (discount code included):

For more articles and video tutorials, check out Code With Andrea.

I’m @biz84 on Twitter. You can also see my GitHub page. Did you like this article? Then smash that clap 👏 button! It makes me feel awesome so I can write more about Flutter. 😎