Inspiration

Anyone who lives near a canal or a blocked drain knows where the mosquitoes come from. What you can't know is which bit of water is the problem, or which nights are going to be bad. I read about OneAquaHealth's work on urban streams, and one of their field methods is trapping adult mosquitoes right next to those streams. That got me thinking: if still water is what breeds them, why can't I just look at a map and see which water, and when?

What it does

You search a town (or zoom in on one) and every ditch, drain, pond and stream gets coloured by how likely it is to be breeding biting mosquitoes tonight, on a 0 to 100 scale. Tap one and it tells you the score, why it got that score in normal words, and what someone living nearby or whoever looks after that water could actually do about it.

The score comes from four things multiplied together: how far the larvae have grown (it depends on the warmth), how long since heavy rain last flushed them out, what kind of water it is (a stormwater basin is very different from a flowing river), and how many people live close by. It works out which mosquitoes live in each place: Culex pipiens, Culex quinquefasciatus, Aedes aegypti and Aedes albopictus, using GBIF records and whether the local winter lets them survive. There's a chart of the whole year, week by week, including the 16-day forecast and the rain. People can report whether they got bitten at a spot, and the app keeps track of how often the model got it right. Every forecast can be exported as FHIR R4, the format health systems use. It's an estimate from a model, not a measurement

How we built it

There's no machine learning in it. The core is a degree-day model based on published lab studies: Loetti et al. (2011) for Culex pipiens (it starts developing above 5.5 °C and needs 199.5 degree-days to go from larva to adult), and Shocket et al. (2020) and Mordecai et al. (2017) for the other three species.

Backend: Python and FastAPI, with numpy, pandas, shapely and rasterio. Water and neighbourhoods: OpenStreetMap through the Overpass API, JRC Global Surface Water satellite data for ponds and seasonal pools nobody has mapped, and Meta's population map to count the people nearby. Weather: Open-Meteo, with NASA POWER and MET Norway as backups. Frontend: plain JavaScript with MapLibre and OpenFreeMap tiles. It works on phones too. Hosting: Render runs the app, bite reports are saved in a Neon Postgres database, and a GitHub Action updates the weather every day and adds more cities.

Challenges we ran into

Free services blocking my server. Render's free servers share their internet address with lots of other apps, so the weather API started refusing my requests and the main OpenStreetMap servers wouldn't connect at all. At first a new town would just hang for minutes. I added time limits and backup data sources, and made the app show satellite water while the full map loads. A new town now opens in about 5 to 8 seconds, though the full street map can still take a minute or two when the public servers are busy. Some towns are barely mapped. In a few places OpenStreetMap has almost no water or houses at all, which is why I added the satellite data. Keeping the numbers honest. I wrote down every factor, threshold and assumption along with where it came from, and listed the limits in the README.

Accomplishments that we're proud of

It works pretty much anywhere. Around 150 cities open straight away, and any other town loads the first time someone searches for it. The seasons look like real ones. When I compared the model with real mosquito records from GBIF near each place, month by month, it matched with an average correlation of 0.72. Oslo's season comes out weeks later and much weaker than Coimbra's, which is what you'd expect. Every score can be explained in one sentence and traced back to a paper or a dataset.

What we learned

Mosquito species are really different from each other. The dengue and tiger mosquitoes breed in buckets and tyres around houses, not in ditches, so they needed their own version of the model. FHIR can describe a place, not just a patient: an Observation can be about a Location. There's no official code for mosquito breeding risk, so I used a clearly labelled custom one. Free public data is amazing, but it breaks, so every source needs a backup plan.

What's next for BiteCast

Adding wetlands from ESA WorldCover and satellite rainfall for tropical countries. Testing the model against real mosquito trap counts and dengue case numbers.

Built With

Share this project:

Updates

Submission history