3 min read
England is My Polluted City
JavaFX app to display historical air pollution data of the whole UK on an interactive map.

This project implements a fully functional JavaFX Application to display historical Air Pollution Data of the whole United Kingdom on an interactive map. Users are able to explore the historic pollution levels between 2018 and 2023 on a colour coded map, as well as view detailed location and pollution data at specific data points. There are many quality of life features implemented, such as a robust GUI to filter through different years and pollutants, an extensive statistics framework, as well as a “colourblind mode” to make the pollution viewer more accessible.
As a group, we actually made something great. We went over and beyond — as we head out from the very start. The project has over 8.5 thousand lines of code. And it has a lot of fascinating features: LODs, entire map, API integration, polygon culling, multithreading, and caching of many of the calculations.
Me
What I contributed to the project is the statistics framework and caching.
Statistics
As you can see from the tree structure of the statistics package, I tried making the framework as modular as possible, where it’s really easy to add an additional statistical data to the UI.
1statistics2├── back3│ ├── calculators4│ │ ├── AllPollutionsCalculator.java5│ │ ├── DistributionAnalysisCalculator.java6│ │ ├── HistogramCalculator.java7│ │ ├── PollutionExtremesCalculator.java8│ │ └── TrendsCalculator.java9│ ├── StatisticsCalculator.java10│ └── StatisticsManager.java11├── types12│ ├── AllPollutionsResult.java13│ ├── DistributionAnalysisResult.java14│ ├── DistributionYearlyMetric.java15│ ├── HistogramResult.java16│ ├── PollutionExtremesResult.java17│ ├── StatisticsResult.java18│ └── TrendsResult.java19└── ui20├── components21│ ├── DataTablePanel.java22│ ├── HistogramChartPanel.java23│ ├── LineChartPanel.java24│ └── LogarithmicAxis.java25├── panels26│ ├── AllPollutionsPanel.java27│ ├── DistributionAnalysisPanel.java28│ ├── HistogramPanel.java29│ ├── PollutionExtremesPanel.java30│ └── TrendsPanel.java31├── StatisticsPanel.java32└── StatisticsPanelFactory.java33347 directories, 25 files
After creating the Calculator, Panel, and the Result type , you can add it into the panel factory and it’s all done:
1return switch (result) {2case TrendsResult stResult -> new TrendsPanel(stResult);3case PollutionExtremesResult peResult -> new PollutionExtremesPanel(peResult);4case AllPollutionsResult apResult -> new AllPollutionsPanel(apResult);5case DistributionAnalysisResult daResult -> new DistributionAnalysisPanel(daResult);6case HistogramResult hResult -> new HistogramPanel(hResult);7default -> throw new IllegalArgumentException("Unsupported statistics result type: " + result.getClass().getName());8};
Caching
One thing I did throughout the codebase is to cache a lot of the results, including statistical, csv data, and LOD. Well, it does take up around 3GB of memory, so maybe not the best of ideas. But, it still speeds up the app considerable, especially going back and forth between the statistics and map views.
Concurrency is a lie
I tried adding some proper threading into the application, but I just couldn’t manage to do it. I tried having JavaFX on a different thread and fiddled with CompletableFuture
objects, but to no avail.
§