Shadow Angle and Sun Position Dating for GEOINT
How to use shadow bearings and solar elevation to date and geolocate images. Reproducible workflow using SunCalc, NOAA's calculator, and Python.
For: Enthusiasts & students, Journalists, Security professionals
Shadow Angle and Sun Position Dating for GEOINT
Shadows don’t lie, but they do require careful reading. At any given moment, the sun’s position in the sky is a deterministic function of latitude, longitude, and UTC time. That means a shadow cast by a vertical object encodes the sun’s azimuth and elevation at the moment of exposure. If you can measure those values from an image and match them against a candidate location and date, you can confirm or rule out the claimed circumstances of a photograph without touching a single piece of metadata.
No paid subscription. No proprietary dataset. Just geometry, patience, and a reliable workflow.
Bellingcat’s 2020 piece on shadow geolocation is still the clearest single introduction to this method. What follows builds on that framework, expands the toolset, and adds the error-accounting that makes the difference between a defensible finding and an overconfident one.
Why the Physics Works
The sun’s azimuth (compass bearing from north) and elevation above the horizon are fully determined by three variables: latitude, longitude, and date/time in UTC. Shadows fall directly opposite the sun’s azimuth and grow longer as elevation drops toward the horizon.
Measure a shadow’s direction and length ratio in an image, constrain the location even loosely, and you can calculate which date-time combinations produce matching solar positions. Run the problem in reverse and you can test whether a claimed date and time are consistent with what the shadows actually show.
Step 1: Extract a Shadow Bearing
Before opening any calculator, you need a measurable shadow bearing from the image itself.
What you need: A shadow cast by a vertical object on a roughly flat, horizontal surface. A pole, a standing person, a building corner, a tree trunk all work.
How to measure:
- Open the image in a tool that lets you draw and measure angles. QGIS with a georeferenced basemap works well. So does loading the image into Google Earth Pro as an image overlay and using its ruler.
- Draw a line from the base of the object along the center of the shadow to the shadow tip.
- Note the compass bearing of that line. This bearing points away from the sun. The sun’s azimuth is that bearing plus 180° (mod 360°).
If the image contains a recognizable street or building you can match to satellite imagery, overlay a compass rose from Google Earth or SunCalc.org to calibrate direction relative to known geography.
Step 2: Estimate Solar Elevation from Shadow Length
Shadow direction gives you azimuth. Shadow length gives you elevation.
The relationship is straightforward:
solar_elevation = arctan(object_height / shadow_length)
If you know the object’s real-world height (a standard EU street lamp runs roughly 6–8 m; an average adult roughly 1.7 m), measure the shadow length at the same scale in the image and calculate the ratio. If you don’t know absolute height, the ratio itself is still usable as input.
This calculation assumes a perfectly vertical object on flat ground. Slope, camera tilt, and lens distortion all introduce error. Treat your result as a range. For typical field images, ±5° of solar elevation is a reasonable working margin.
Step 3: Match Against Sun Position Tools
With an azimuth and an elevation estimate in hand, you’re looking for the date-time-location combinations that produce matching solar positions.
SunCalc.org
SunCalc.org is free, browser-based, and needs no account. Drop a pin on your candidate location and drag the time slider until the displayed azimuth and elevation match your measured values. The arc showing the sun’s path across the day makes it easy to see at a glance whether you’re in the right neighborhood.
The limitation: there’s no inverse search. You iterate manually.
NOAA Solar Calculator
NOAA’s Solar Calculator returns azimuth and elevation to two decimal places for any latitude, longitude, date, and UTC time you enter. It’s the tool most commonly cited in forensic and academic contexts because the underlying algorithm is published and auditable. Enter your candidate coordinates, date, and time, then compare the output against your measurements.
Python: astropy or ephem
For anyone comfortable scripting, Python’s astropy and the older ephem library both compute solar position from first principles. This lets you loop over every 10-minute interval across a range of dates and flag combinations where azimuth and elevation both fall within your measured tolerance. When you’re narrowing a date range rather than pinning a single moment, this approach is considerably faster than manual iteration.
Pseudo-logic:
for date in candidate_date_range:
for time_utc in range(0, 1440, 10): # every 10 minutes
az, el = get_sun_position(lat, lon, date, time_utc)
if abs(az - measured_az) < 5 and abs(el - measured_el) < 5:
print(date, time_utc, az, el)
Step 4: Cross-Check with a Second Shadow or Landmark
A single shadow measurement carries real uncertainty. Strong verification means at least two independent checks.
Two shadows in the same frame: Both must point in the same direction. If they don’t, at least one object isn’t truly vertical, the surface isn’t flat, or something has been composited. Any divergence is worth flagging.
Known landmark height: If you can identify and geolocate a building in the frame, look up its approximate height through local planning databases, Wikidata, or Google Earth’s terrain tool. Calculate the shadow it should cast at your proposed date and time and compare it to what’s visible.
Vegetation state: Bellingcat’s guide on seasonal geolocation makes the point well. Bare deciduous trees push the date toward autumn or winter; full canopy toward late spring through early summer. Pairing shadow geometry with vegetation state narrows the candidate window considerably.
Step 5: Report a Range, Not a Point
Responsible shadow analysis always outputs a range. A well-formed finding looks something like this:
Shadow azimuth measured at approximately 220°, elevation ratio consistent with ~30° solar elevation. At the candidate location (approx. 48.8°N, 2.3°E), these values are consistent with: (a) late October to mid-February between approximately 13:00–14:00 UTC, or (b) mid-October between approximately 12:30–13:00 UTC. Analysis cannot distinguish between these windows without additional corroborating evidence.
Bounded, honest output is what separates sound GEOINT from a claim that collapses under scrutiny.
A Workflow You Can Practice Right Now
Bellingcat’s December 2020 article includes a step-by-step walkthrough using imagery from Nagorno-Karabakh. Using SunCalc and compass alignment from Google Earth, the team confirmed that shadow angles were consistent with afternoon hours on specific autumn dates, corroborating other evidence in the investigation.
To build the same intuition yourself:
- Pick any geolocated, date-stamped photograph from a public source. Wikimedia Commons is a good starting point; many images carry EXIF GPS and timestamp data.
- Temporarily set aside the EXIF data.
- Measure the shadow bearing and estimate solar elevation using the method above.
- Run SunCalc and the NOAA calculator for the known location across several candidate dates.
- Check whether the returned sun position matches the shadow you measured.
- Reveal the EXIF timestamp and compare.
Do this 10–15 times with known-good images and you’ll develop a realistic feel for how much precision the method can actually deliver.
Errors Worth Watching
| Error | Why it matters | Mitigation |
|---|---|---|
| Assuming flat ground | Slope displaces the shadow tip significantly | Check terrain in Google Earth’s 3D view |
| Ignoring lens distortion | Wide-angle lenses bend apparent shadow angles | Measure from the center of frame when possible |
| Confusing local time with UTC | Sun calculators need UTC | Convert explicitly; account for DST |
| Single-shadow overconfidence | One measurement has wide uncertainty | Always seek a second shadow or independent check |
| Ignoring hemisphere | Shadows fall north in the southern hemisphere | Confirm latitude sign before interpreting azimuth |
Shadow analysis earns its place as one layer in a multi-method investigation, alongside landmark matching, metadata analysis, and contextual research. Used carefully, with documented uncertainty ranges and cross-checked measurements, it has contributed to published accountability journalism. The physics is deterministic. The skill is measuring carefully enough to let it say something.