← back

Pub Sun: Finding Sunny Beer Gardens with Shadow Geometry

A Python tool that finds pub gardens currently in direct sunlight by modelling real building shadows, solar position, and live cloud cover.

15 April 2026 · hoofay
pythongeospatialopenstreetmapsolarshapely

The British summer is precious. When the sun finally comes out, the last thing you want is to spend your afternoon sitting in the shade of a building you didn't notice was there. Pub Sun solves that problem: given your location, it finds pub gardens that are actually, right now, in direct sunlight.

The Problem

"Is there sun in the beer garden?" sounds like a simple question. In practice it's a geometry problem. Whether a garden is sunny depends on the solar angle, the heights and footprints of nearby buildings, whether there's cloud cover, and the exact shape of the outdoor seating area. No existing tool was putting all of that together.

How It Works

For each pub garden within a given radius, the pipeline does the following:

1. Fetch nearby buildings from OpenStreetMap (footprints + heights)
2. Compute solar azimuth + altitude for the current time and location
3. Project a shadow polygon for each building (convex hull + shadow tips)
4. Measure what fraction of the pub's garden polygon is in shadow
5. Combine shadow fraction, sun altitude, and live cloud cover into a score
6. Rank all pubs and return the sunniest ones first

The shadow geometry is handled by Shapely: each building's footprint is extruded in the direction of the shadow (opposite the sun's azimuth) by an amount proportional to the building's height and the sun's altitude angle. The result is a shadow polygon that updates in real time as the sun moves.

Data Sources

Source Used for
OpenStreetMap (Overpass)Building footprints, heights, pub locations
astral (Python library)Solar azimuth and altitude (pure maths, no API)
Open-MeteoLive cloud cover percentage
EA LIDAR tiles (optional)Better building height data where OSM tags are missing

Everything is free with no API keys required. OSM responses are cached for seven days to keep queries fast and avoid hammering the public mirrors.

Beyond Garden vs. No Garden

OSM tags aren't perfectly reliable. Not every pub with a beer garden has tagged it as beer_garden=yes. So alongside the garden score, the tool also scores eight compass directions around each pub building to identify the best pavement seating opportunities. If the south-facing footpath is wide and sunny, that gets a score too, with a small boost added to the pub's overall confidence.

London Scale

The tool runs at the local Python level for any lat/lon you provide, but it also has a batch mode that scores every pub in London. A GitHub Actions workflow re-runs this hourly and uploads the results to Cloudflare R2, where a lightweight Cloudflare Worker serves them as a JSON API. The frontend at pubsun.co.uk reads from that API and shows you the current sunny pubs on a map.

The Tricky Parts

Building heights from OSM are patchy

In Shoreditch, only about 39% of buildings have explicit height tags. The rest default to 10m, which introduces scoring error for tall buildings. LIDAR tiles from the Environment Agency can fill in the gaps: the DSM minus the DTM at each building footprint gives a real height from aerial survey data. LIDAR enrichment takes two to four minutes for a 1km radius, so it's optional but recommended for accurate results.

Excluding the pub's own building

The pub building itself would always cast a shadow over part of its own garden if you didn't handle it specially. Each garden check excludes the pub's own footprint from the shadow model, then checks only the surrounding buildings within 350m.

Overpass API reliability

The public Overpass mirrors can be slow or temporarily unreachable. The tool uses a tiered provider list with automatic failover, and will serve stale cached data rather than fail completely if all mirrors are down.

Try It

The website is at pubsun.co.uk. If you want to run the CLI yourself or look at the code, the project is on GitHub.

python demo.py                        # Shoreditch defaults
python demo.py --lat 51.465 --lon -0.039   # Brockley
python demo.py --time 14:30           # check a specific time
python demo.py --map                  # save a PNG map