Atlas Map

I’ve never been a good sleeper. What helps most is the sun: getting light at the right time of day is the closest thing I have to a reset button for my body clock.

That gets complicated when you travel constantly. Every trip means a new sunrise, a new sunset and a new set of hours to fight my way into. Before I land somewhere, I want to know what’s going to hit me: when the light comes up, how long the day is, and what the weather will be when I’m out hiking.

So I built Atlas Map, a world clock for iPhone that shows the time, the light and the weather for every city you care about, and lets you move all of them through time at once.

More than a time zone.

A world clock tells you it’s 6:12 PM in New York. It doesn’t tell you the sun sets in fifteen minutes, that tomorrow will be about two minutes shorter, or that it’s 63° and clear.

That was the information I actually needed. Not just what time is it there, but what is it like there: how high is the sun, how much daylight is left, how warm will it be. And not only now, but the evening I land, or the week I’m planning to be on a trail.

Every screen in Atlas Map answers that question in its own way.

Move every city through time.

At the bottom of every screen sits Time Travel, a single slider that moves every city, every screen and every chart together. Drag it forward six hours and every card, the globe and the clock move with it. Tap the date and a calendar opens, with shortcuts to the next solstices and equinoxes. You can travel a century in either direction.

The detail I’m proudest of is how the skies move. Jump from 4 PM to 8 PM and the colors don’t just fade from blue to dark. They pass through everything in between, the late-afternoon gold, the sunset orange and the dusk purple, as if you’d watched those four hours go by.

Every city, lit by its own sky.

The List is where I start. Each city gets a card with its time, a strip showing its whole day from midnight to midnight, the next sunrise or sunset, and the weather. Around every card glows that city’s sky right now: blue at noon, amber at sunset, deep navy at night.

The top card is your home base. It glows a little brighter, every time difference is measured from it, and the Map and Clock follow it. Press and hold any card to drag it into a new order. If you don’t share your location, the top card simply takes its place.

A real Earth, at any hour.

The Map is a satellite globe you can spin with your finger. The night side follows Time Travel, city lights come on as it gets dark, and the stars behind the Earth turn with the real sky. The satellite images even change with the seasons, so snow creeps south in winter.

Each city’s label is filled with its own sky, shaded from the side the sun is on. Tap one to open a miniature daylight chart and its next twelve hours of weather. A time zone layer shows every zone and its local time. By default north stays up. Unlock the globe and you can spin it any way you like, or twist it with two fingers.

Every clock on one face.

The Time tab puts every city on a single clock face, one hand each, so you can see at a glance who’s awake.

Underneath, a ruler places each city by the sun instead of the clock: midnight, sunrise, noon, sunset. Two cities can share a time zone and still sit apart, because the sun reaches one well before the other. That difference is exactly what I care about when I’m trying to reset my body clock.

Follow the sun.

Tap any city for its details. The Daylight chart shows the sun’s path across the day. Put your finger on the line and drag the sun to see the light at any hour, with the sunset colors spreading across the sky as it goes down.

Below that is the weather: the next 24 hours and the next eight days, in one card.

A year that rolls.

Then comes This Year: the year’s daylight curve with the temperature laid over it, and markers on the warmest and coldest days so far. Touch the curve and drag toward either edge, and the year starts to roll. The months slide past, last year comes in from one side and the years ahead from the other, faster the closer your thumb is to the edge.

Home Screen and Lock Screen widgets keep your cities one glance away.

Unnoticed details.

The things I hope nobody notices, because everything just feels right:

Under the hood.

Atlas Map is built in SwiftUI. I’m a designer, not an engineer, so here’s what each problem was in plain terms. The code underneath is for anyone who’d like to see how it works.

An Earth I could rewind.

My first plan was to use Apple’s own 3D map. It’s beautiful, but it always shows the real time of day. There’s no way to ask it what the Earth looks like at sunrise tomorrow, and that broke the whole idea of Time Travel.

So I made my own globe. For every point on the Earth, the app works out how high the sun is at the moment you’re looking at. High sun is bright day. Low sun dims and warms toward sunset. Below the horizon it fades to night, and once it’s properly dark, the city lights come on.

// For each spot on the globe: how high is the sun here, in degrees?
float alt = asin(dot(ground, sunDirection)) * 180 / pi;

// Day: dimmer as the sun gets low, warmer where it's setting.
float3 color = day * mix(horizonLight, 1.0, smoothstep(0.0, dayFullAltitude, alt));
color *= mix(float3(1), sunsetTint, sunsetStrength * sunset);

// Night: city lights only come on once it's properly dark.
float lights = smoothstep(lightsStart, lightsEnd, alt);
color = mix(color, nightColor, smoothstep(nightStart, nightEnd, alt));

Because the globe is drawn this way, it doesn’t care what time it is. Give it any moment and it shows that moment.

The lag the Map didn’t have.

With five or six cities, the List and the Clock started to stutter when I scrubbed through time quickly. The strange part was the Map. It had the most going on, and it never lagged at all.

That was the clue. The Map is drawn by the phone’s graphics chip, which is built to paint pictures quickly. The List was asking the main processor to repaint every card’s soft, blurry glow on every frame. And the Clock was looking up each city’s population in a list of 34,000 cities, every frame, to decide which dots to show, even though a city’s population never changes.

So the glows went to the graphics chip, like the Map, and each population is looked up once and remembered.

// The glow is handed to the graphics chip, drawn in one pass,
// instead of being repainted by the main processor every frame.
SkyGlowFrame(shape: shape, altitude: altitude)
    .drawingGroup()

// A city's population never changes: look it up once, then remember it.
if let known = cache[key] { return known }
let population = lookUp(name: name, latitude: latitude, longitude: longitude)
cache[key] = population

Move the clock, not the color.

Time Travel moves in steps of an hour, so each step should ease the skies to their new colors. But a fade only knows where it starts and where it ends. Going from 4 PM to 8 PM, it blended blue straight into navy, and every sunset in between was lost.

The fix was to move the clock instead of the color. Each sky now travels through the moments between the two times and works out the real color at each one, so the sunset is there because the sun really did set along the way.

That fix caused one bug of its own. On the Clock, the city dots on the ruler started leaving dark copies of themselves behind. The animation was moving each dot’s position as well as its color, and the dot’s dark ring wasn’t keeping up. One line told it to animate only the sky, never where it sits.

// The moment being shown is what animates, so a jump from 4 PM to 8 PM
// passes through every sky in between, sunset included.
var animatableData: Double {
    get { time }
    set { time = newValue }
}

// Only the moment moves, never where the sky sits or how big it is.
SkyMomentFrame(time: time, content: content)
    .geometryGroup()

Get Atlas Map.

Coming soon to iPhone. No accounts, no ads and no tracking.