Inspiration
In a UAE summer the air passes 45 °C and the midday sun is almost straight overhead. Students walking from a metro or tram stop, delivery riders, and people who work outdoors all make the same short walks every day. The difference between the sunny side of a street and the shady one is real, but map apps only find the shortest walk. None of them can say which way is in shade at 4:30 pm.
What it does
Shade Route answers one question: if I walk a little further, how much less sun do I get?
- Pick a date and a time. Every building casts its shadow on the map for that moment, and the 3D towers are lit from the sun's real direction.
- Drag the sun along its arc, or press Play the day. The shadows sweep across the map, and the route bends into the shade as the light moves.
- Drag the A and B pins to plan your own walk, and choose how much extra walking you accept (+10%, +25% or +50%).
- Each route shows its percent in shade, length, walking time, minutes in direct sun, and a strip that runs along the route marking the sunny stretches.
On the default walk in Dubai Marina at 4:30 pm on 21 June, the shortest route is 26% shaded. The shade route is 76% shaded, 147 m longer, and saves 5 minutes in direct sun. At 12:30 pm the sun is 87° high and buildings cast almost no shadow, and the app says so instead of inventing a shady route.
It runs entirely in the browser: no backend of its own, no account, no location tracking.
How we built it
- Sun position: the NOAA Solar Calculator equations (after Meeus), with atmospheric refraction.
- Buildings: footprints and heights from OpenStreetMap through the Overpass API (downloaded 9 Nov 2026). Height is the
heighttag if mapped, otherwisebuilding:levels× 3.2 m, otherwise 10 m. - Shadows: each building is a block on flat ground. A ground point is in shadow when the segment from it towards the sun, of length height ÷ tan(elevation), touches the footprint. A grid index keeps this fast. The drawn shadows use the same geometry, painted into one canvas layer so overlapping shadows never double in darkness.
- Walking graph: footways, pedestrian streets, steps, crossings and ordinary streets. Motorways and anything tagged foot=no are dropped. Covered walkways and tunnels always count as shade.
- Shade on every edge: every edge is checked every 1.5 m, about 136 km of walkable segments in this area.
- Routing: each edge costs metres in shade + k × metres in sun. A sweep over k (a Lagrangian relaxation heuristic) keeps the path with the least sun that stays within the detour limit. A full update (shadows, shade on every edge, both routes) takes 22–65 ms in Edge on a laptop, fast enough to update live while you drag the time.
The map is MapLibre GL with OpenFreeMap tiles. The area data ships with the site as a fixture, so the demo never depends on a live OpenStreetMap query. It's hosted as a static site on Cloudflare Pages.
Testing
- Sun position vs an independent reference: 18 points for Dubai and Abu Dhabi checked against NREL's Solar Position Algorithm (computed with pvlib). Worst error in the sun's direction: 0.026° (elevation within 0.026°; azimuth within 0.011° when the sun is below 85°, 0.053° just below the zenith).
- Shadow geometry on a synthetic 10 m box: correct strip length for sun from the south and the east, and the shaded area matches the analytic value within 1%.
- Router on a toy street grid: it takes the shaded back street when it fits the detour limit, keeps the shortest one when it doesn't, switches when the sun moves to the other side, and treats covered walkways as shade.
- End-to-end in Edge on the live site: time scrubbing, the shade route beating the shortest by over 30 points at 4:30 pm, the overhead-sun message, pin dragging, play, the detour buttons, no page errors, every update under 100 ms.
Challenges we ran into
- Drawing overlapping shadows. Translucent polygons darken where shadows overlap, so the first version looked blotchy. Painting all shadows into one canvas layer fixed it. Filling one path per building instead of one giant path cut the drawing step from about 150 ms to about 4 ms in our profiling in Edge.
- Missing heights. In Dubai Marina, 291 of 557 buildings have no height or floor count in OpenStreetMap. We chose a 10 m default: for towers it under-counts shade, though small kiosks and sheds may be over-counted. The map also draws those buildings in a darker colour so you can see which ones are guessed.
- Constrained routing. "Shadiest within +25%" is a constrained shortest-path problem. The Lagrangian sweep is fast, but it is a heuristic, and we have not measured its gap to the true optimum.
Accomplishments that we're proud of
- The moment you drag the sun and watch the route bend into the shade.
- An honest midday answer: no fake shade when the sun is overhead.
- Sun maths that matches NREL's reference to three hundredths of a degree, and the key numbers backed by tests and a browser check.
What we learned
How small the shade window is in a UAE summer. Around noon there is almost none. But by 4:30 pm on our test walk, a route 17% longer took the shaded share from 26% to 76%.
What's next for Shade Route
- Trees and shade structures from OpenStreetMap (
natural=tree,man_made=canopy,covered=*) as extra shadow casters. - More areas: university campuses, Downtown Dubai, Abu Dhabi's Corniche. The data pipeline already works for any bounding box.
- A "leave at" planner that suggests the best time in the next hour to start a walk.
Limits (stated plainly)
Trees, shade sails, arcades and bus shelters are not modelled. Building heights are often missing, and those buildings are drawn 10 m tall (too short for towers, too tall for kiosks). The model assumes flat ground and simple blocks. Shade is not the same as cool, because hot walls and ground still radiate heat.
Credits
Map data © OpenStreetMap contributors (ODbL). Base map: OpenFreeMap, OpenMapTiles. Map rendering: MapLibre GL JS. Solar equations: NOAA Global Monitoring Laboratory.
Claude was used as a coding assistant.
Built With
- canvas
- cloudflare-pages
- css3
- html5
- javascript
- maplibre-gl
- node.js
- openfreemap
- openstreetmap
- overpass-api
- playwright