28 guides · 4 topics
Guides
How to do real things with our apps, on real streets, trails and files, and the notes we keep while building them.
Plan a route, then run, ride or hike it
Draw a route that follows the running path, the bike path or the trail, and hear every turn on the way.

Routes · 6 min
Plan a 5K route around your house, then run it with the turns in your ear
Draw a 5K loop in GPX Explore with a few taps and the route follows the running paths by itself. Then run it with headphones on and the phone in your pocket, every turn spoken.

Routes · 5 min
Plan a bike ride on a national park bike path and follow it turn by turn
Draw a ride in GPX Explore with Follow Roads (Cycling) and the route keeps to the bike path beside the road. Check the climbs and the canyon in 3D, then ride it with spoken turns, a climb panel and the Lock Screen. Zion is the example.

Routes · 5 min
Plan a national park hike and follow the trail with spoken directions
Draw a hike in GPX Explore with Follow Paths (Walking) and the route keeps to the trail and its switchbacks. See the climbs and fly the trail in 3D, then hike it with the junctions spoken and the screen off. The Mist Trail in Yosemite is the example.
Tracks, workouts and walks you keep
Record a walk with your photos on the route, get your Apple Watch workouts out as GPX, and open any GPX file.

Tracks & workouts · 1 min
How to export Apple Watch workouts as GPX, with heart rate
Apple Health keeps every route your Apple Watch recorded, but not as a file. Here is how to get any workout out as a GPX file with heart rate, cadence and power, one at a time or all at once.

Tracks & workouts · 2 min
How to see heart rate and power from a GPX file
GPX files from Garmin, Strava, Wahoo, Coros, Suunto and Apple Watch carry heart rate, cadence, power and temperature on every point. Most viewers ignore them. Here is how to see them, and what the numbers mean.

Tracks & workouts · 2 min
How to open a GPX file on a Mac
Three ways to open a GPX file on a Mac, what you will see in each, and how to make one app the default for every .gpx file.
Maps, land and terrain
Build a layered KML map, choose the right map app for a file, and see what the ground data can and cannot tell you.

Maps & terrain · 8 min
Make a race-day map in KML: the course, water, medical and parking, layer by layer
How to build the map a volunteer team needs for a charity 5K, as one KML file with a folder for each kind of thing: a course that follows the streets, start and finish, water, mile markers, a medical circle, parking and closures. Drawn in KML Explore on Mac, iPhone or iPad, opened anywhere.

Maps & terrain · 12 min
One file, one job: why GPX Explore, KML Explore, Geo Measure and Geo Elevation are four apps
A developer’s look at why ObjectGraph makes separate map apps: a GPX track, a KML map, a measurement and the ground under it are four different data models with opposite rules, and one app holding all four would have to break some of them.

Maps & terrain · 5 min
Boston Harbor was 15,728 meters high
Our elevation server said a spot on the Boston waterfront stood nearly twice as high as Everest. The cause was a 2017 flaw in the open terrain data much of the web uses, plus one bug of our own. How I found every bad height on the planet and fixed them in place.

Maps & terrain · 5 min
Two terabytes of terrain on one box: the elevation API behind Geo Elevation
How elevationapi.geosq.com serves elevation profiles for the whole planet from our own server: OpenTopoData, 22,912 ASTER tiles, 65,341 Mapzen tiles, and a 100-millisecond answer.
Developer notes
Problems we hit in our own work on local models, MCP, Apple platforms and the web, and how we fixed them.
- Ollama CORS: Setting OLLAMA_ORIGINS on Mac, Windows, Linux and DockerHow to set OLLAMA_ORIGINS so web pages and browser extensions can call Ollama, and OLLAMA_HOST to reach it over the network, on macOS, Windows, Linux and DockerTested with Ollama 0.40.3 on macOS, Windows, Linux and Docker · 4 min
- Reach Your Local Ollama from a Cloud Server with Tailscale (No CORS, No Open Port)A server calling Ollama is not a browser, so OLLAMA_ORIGINS does not apply. Put the machine on a Tailscale tailnet, bind OLLAMA_HOST to its tailnet address, and point the server there. · 4 min
- Ollama think: false Not Working? Use reasoning_effort "none"Ollama's OpenAI-compatible endpoint has no think field, so Gemma 4 and other thinking models keep thinking. Send reasoning_effort: "none" there, or think: false on the native /api/chat. · 4 min
- Ollama "truncating input prompt": Why Long Prompts Lose Their InstructionsWhen a prompt is longer than the context window, Ollama keeps the first few tokens and the end and drops the middle, instruction included. Cap the input, put the instruction last, and set num_ctx or OLLAMA_CONTEXT_LENGTH. · 4 min
- OpenAI 400: "Function tools with reasoning_effort are not supported" in /v1/chat/completionsGPT-5.5 and GPT-5.6 reason at medium effort when a request sends no reasoning_effort, and Chat Completions rejects reasoning together with function tools. Send reasoning_effort "none" when you want tools without reasoning, or use /v1/responses when you want both. · 5 min
- MCP Server Returns 401 Unauthorized: Implementing OAuth in an MCP ClientWhat an MCP client does after a 401 from a remote MCP server: find the authorization server, register with RFC 7591, authorize with PKCE (S256) and the RFC 8707 resource parameter, exchange and refresh tokens. Python and httpx code from a working client. · 7 min
- MCP Inspector: the Session Token, DANGEROUSLY_OMIT_AUTH and a Local ServerRun MCP Inspector against a local FastMCP server over streamable HTTP, what the session token and DANGEROUSLY_OMIT_AUTH do, and what changed in Inspector 2. · 3 min
- Building MCP PyExec: Python Execution Server with Docker, Authentication & HTTP StreamingComplete guide to building a secure Python execution MCP server with Docker isolation, JWT authentication, session management, and HTTP streaming support · 15 min
- iOS 27 App Store product page header and search results images: sizes, design and API uploadThe header is 3840 × 1646 and the search results asset 3840 × 2560, but Search shows it at about a tenth of that. What still reads at that size, and how to upload both per localization with the App Store Connect API. · 6 min
- App Store header video and search results video: sizes, specs and API upload (iOS 27)On the iOS 27 App Store the header and search results asset can be videos: 3840 × 1646 and 3:2 up to 3840 × 2560, 5 to 30 s. Specs, a seamless loop, API upload. · 8 min
- Notification tap crashes with "Call must be made on main thread" (async UNUserNotificationCenterDelegate)On iOS 26.6 every notification tap crashed because the async didReceive bridge calls UIKit's completion off the main thread. The fix is the completion-handler delegate methods, answered on the main thread. · 5 min
- How to localize an iOS and Mac app in four languages in a dayString Catalogs generated from the compiler, the strings the compiler cannot see, screenshots per language, and localized App Store listings and screenshots uploaded from the command line. · 7 min
- Next.js 16 segment prefetch loop on Cloudflare Workers with OpenNext cache interceptionWith enableCacheInterception on and @opennextjs/aws older than 4.1.6, every Next.js 16 segment prefetch got the whole page back, and each open tab asked again about 130 times a second. Upgrade before turning interception on. On a crawled site, keeping rendered pages in the Cache API instead of R2 also cut the bill. · 6 min
- Streaming SSE through nginx and Cloudflare without bufferingServer-sent events from FastAPI arrived late and in chunks because nginx buffered the response. proxy_buffering off, or X-Accel-Buffering: no from the app, fixes nginx. Cache-Control: no-transform keeps Cloudflare from compressing the stream, and a keepalive every 15 seconds keeps quiet streams open. · 6 min
- Migrating from Static JWT Secrets to JWKS in SupabaseHow to upgrade your FastAPI authentication to use Supabase JWKS for better security and performance · 5 min
- PerfPowerServices at 190% CPU on macOS: the process-count trigger and a fix without rebootingWhy Apple's PerfPowerServices daemon can burn two CPU cores for days on macOS 27, what triggers it (more than about 2,700 processes), and how to clear it with one kill instead of a reboot. · 3 min
- Training Your Own ChatGPT on DGX Spark: Getting nanochat to Work with CUDA 13.0How I adapted Andrej Karpathy's nanochat to run on NVIDIA DGX Spark with CUDA 13.0 - complete training results included · 9 min
- Add Swap To LinuxHow to add Swap to Linux · 3 min