---
title: "Breaking Free"
url: https://www.localghost.ai/hard-truths/breaking-free
description: "Two APIs taken off the box and a map built from scratch. Prices from seven exchanges, weather from the forecast models themselves, the planet from OpenStreetMap's raw files, with a diagram of each and how you could do the same."
updated: 2026-10-12
site: LocalGhost.ai
index: https://www.localghost.ai/llms.txt
---


> HARD_TRUTHS // POST_20 // OCT 2026

# Breaking Free

[Vlad Cealicu](https://www.localghost.ai/about#vlad-cealicu) // 12 October 2026

> You don't need anyone's permission to build your own tools from public data, and once in a while yours turn out as good as the thing you were renting.

At 2am on Sunday 11 October I was still working downstairs in the lobby of the Rioca aparthotel in Neu-Ulm (Cristina was asleep and I was feeling creative) when three guys came through on their way out for the night. We got chatting, and it turned out all three of them worked in AI, one in sales and two as developers. They never did go out, and we talked until 4am.

I told them about LocalGhost, the box under my desk in London that keeps my photos, my trail and my notes and talks only to my phone, and then about the local part. When the phone wants the price of bitcoin, the streets around it or tomorrow's weather, the box works it out from the public data itself instead of asking a company that worked it out from the same data and sells it back with a key. My forecast that weekend came from the weather centres' own model files, blended on the box for the point I was standing on, and they were astonished you could do that with open data.

If three people who work in AI hadn't come across it, I suspect most people haven't either, because nobody really talks about it, so here's how I did it, in case you want to do the same with whatever you're tired of asking Google or anyone else for. It's in three parts, the prices, the map and the weather, each with a diagram.

![The LocalGhost map on my phone over Ulm and Neu-Ulm, with Sunday's trail as a green line, the photos as green dots and the stops labelled with their times.](https://www.localghost.ai/images/breaking-free-map.jpg)

*The map on my phone at 02:49 on 12 October, a night later and still in Neu-Ulm, drawn by the box from OpenStreetMap's raw files. The green line is Sunday's 8 km round Ulm and Neu-Ulm, the dots are the pictures I took, and the labels are where I stopped and when.*

## 1. Prices, from the exchanges

When I first wired prices into the box, Claude picked CoinGecko for them, and that pissed me off, because it reminded me that we'd closed the free API at CoinDesk Data. I couldn't bring myself to use the competition, so I decided to build it instead. I spent twelve years building CCCAGG ([An Index Is Not a Person](https://www.localghost.ai/hard-truths/index-not-a-person) is partly about it), so this one I knew how to do.

ghost.tallyd asks seven exchanges for their public tickers, five in dollars and Binance and OKX in USDT, which it folds into dollars at the median USDT/USD quote [1]. A quote older than fifteen minutes is dropped, and so is one more than two per cent from the median, which also gets noted. The rest is averaged by volume, and the spread between the venues is kept beside the price, so the card can say "the exchanges agree" or "they differ by 1.4%". None of those endpoints needs a key, because they're what the exchanges' own web pages read.

*Prices. Seven exchanges' public tickers go through one filter that folds USDT into dollars and drops anything stale or more than 2% from the median, then a volume-weighted average with the spread kept beside it. The ECB's daily rates turn it into pounds or euros.*

Currencies come from the European Central Bank's reference rates, published every working day at around 16:00 Frankfurt time since 1999 (funnily enough I wrote that part in Düsseldorf and Mannheim, and passed through Frankfurt as well) [2].

Against CoinGecko it's about the same for the big coins and worse for the rest, because seven venues is seven venues and a coin that trades mostly in Seoul isn't on any of them. The list of which coins count as the top fifty comes from Coinbase. The exchanges see the box asking for the same tickers every minute, which is what they'd see from a browser tab.

## 2. Maps, from the raw files

The map was the biggest job, and it didn't replace anything. I decided to build it from scratch, at first just the continents and the countries' shapes so I could put my pictures on them, and then I kept adding. It's the one I'm proudest of, because the box holds the whole planet and never tells anyone which bit of it I'm looking at.

The streets are Geofabrik's continent extracts, eight files and about 79 GB of OpenStreetMap [4], and the coastline is OpenStreetMap's land polygons [3]. Nothing in Go's standard library reads the PBF format those come in, so I wrote a reader, and it makes three passes over each file. The first marks every node a road uses, the second writes those nodes out sorted, and the third cuts every road on the tile borders and writes a routing graph beside the tiles, so the box can put the trail on real streets ([What the Box Does Now](https://www.localghost.ai/hard-truths/what-the-box-does-now) has the trail). Africa takes about four minutes and Europe takes hours.

*The map. Eight OpenStreetMap files go through three passes of a reader on the box, the last of which cuts the roads into tiles and builds a routing graph. The phone asks the box for a tile only when it zooms in over it, and the trail is drawn along the streets it walked.*

Place names come from GeoNames [5], the heights from the Copernicus 90 m elevation model, 67 GB pulled from the LocalGhost mirror [6], and the time zones from timezone-boundary-builder, rasterised on the box so "today" is my day and not UTC's [7]. The phone draws the tiles with a codec I wrote twice, once in Go and once in Kotlin.

It's still not Google Maps. There are no businesses and no reviews, no traffic and no transit, lakes and rivers draw as land, and the long things OpenStreetMap stores as relations aren't there yet. But it has the paths and the routing along them, the heights, the names and every street in the world, and for a few weeks of work I think that's quite good. It won't find you a restaurant, but it puts my pictures where I took them, which is what I started it for, and it draws every street I've walked without telling anyone where I was.

## 3. Weather, from the models

On the evening of 10 October, a few hours before the lobby, the weather card on my phone stopped saying "pulled 2 h ago", which meant the box had asked Open-Meteo, and started saying "the box's own forecast from ICON-D2 09Z, ICON-EU 06Z, IFS 06Z, GFS 06Z", the German, European, ECMWF and American models with their runs named by the hour.

Google's help page says what its forecast is made of, an internal system over the models and observations of DWD, ECMWF, NOAA, the Met Office and others, plus a radar nowcast and people's reports [8]. Most of those models are public, and anyone can download them. DWD publishes ICON as open data [9], ECMWF publishes IFS at a quarter of a degree under CC-BY-4.0 with an index that lets you fetch one field by byte range [10], and NOAA's GFS is public domain [11]. The Met Office's 2 km UK model needs an account and a key, and its free plan is a gigabyte a month [12]. I registered and got a key, which was frustrating, because it's the Met Office and we should just have the data. The first key I pasted didn't fit (it's over a thousand characters and I'd capped it at two hundred), but the box pulls that model now too.

Most of the work was the decoder. The models come as GRIB2, a World Meteorological Organization format with a dozen ways to pack the numbers [13], and ECMWF's files use CCSDS Rice compression, the codec satellites send their data down with [14]. It took about three weeks of evenings, checked against ecCodes over nineteen test files until every value matched, and a global field now decodes in 60 milliseconds.

*The weather. Four open models and the Met Office's keyed one are pulled by byte range and decoded on the box, reduced to six thousand places that are the same for every box and to the exact point I'm at, corrected for height and blended, with any model far from the others dropped. The radar nowcast is in amber because it isn't built yet.*

Every half hour tallyd looks for a newer run, pulls six fields (temperature, dew point, rain, the two wind components and cloud) out to five days, and reduces them to six thousand places that are the same for every box, so where I am doesn't change what's fetched. The temperature is moved by 6.5 °C per kilometre between the model's ground and the real one, using the box's own heights [15]. While my phone is inside ICON-D2's domain the box also keeps a window of that model's 2.2 km grid around my last fix and reads the forecast at the exact point. Then the models are blended, the German ones heaviest inside their domain and ECMWF heaviest elsewhere, after dropping any model more than four degrees from the others' median. That's the price index's rule applied to temperature, and as with prices the disagreement is kept. As I write this the card says Tuesday goes from 2 °C to 13 with some drizzle in the afternoon, and that at ten in the morning the models are 6.1 degrees apart, which the Google card has never told me. The chance of rain is the share of models that give rain in that hour, and the card says so.

I can't say yet that it's better than Google's. I've been checking it against the Google card since, from a window near Neu-Ulm, and it's as good on what I've seen, which I didn't expect. It's for the cell I'm in at the height I'm at, while Google's card is for the town. It's felt better than that, and I think part of the reason is that it's mine now rather than a service I'm renting. Google has the licensed radar over Europe, the national station networks and a million people's reports of the sky, and the box has no nowcast and no verification yet. It goes out to everyone in wisp 0.0.7.

## 4. You can do this too

Most of these data sets are published to be used without a key. The exchanges want their tickers read, the weather centres publish their models so people will use them, and OpenStreetMap exists so that nobody has to ask Google for a map. An API in front of that data is someone else reading the source for you, and it comes with a key, a quota and a terms page ([The Integration Tax](https://www.localghost.ai/hard-truths/integration-tax) is about that bill).

I don't think the APIs are villains. Open-Meteo is a good service and I'd recommend it to anyone who doesn't want to write a GRIB decoder, which is nearly everyone. But if you can read the file you can build the tool, and the tool is yours, so it keeps running when their free tier ends and it tells you where every number came from.

The map took a few weeks and 80 GB, the weather about three weeks of evenings, and the prices a few days because I'd done it before. I didn't need a team for any of it, just a Go compiler, a lot of evenings and some stubbornness (and Claude, which is how CoinGecko got in there in the first place). If there's a service you're tired of asking, look at what it reads. A lot of the time it's a file someone publishes for free, and the hard part is the format.

## 5. What's still open

The weather needs verifying. Each run starts with the model's analysis of what the weather was, so the box can score yesterday's forecasts against today's analysis with data it already holds, and after a month the weights can come from that. Observations and a radar nowcast come after. The map needs lakes and relations, and the price index needs venues outside the dollar.

And the feeling that started this, that my forecast is better than Google's, needs a month of numbers rather than two days at a window. I think it'll come out about even for the town and ahead for the point I'm standing on, but that's a guess until the numbers are in.

---

Eric Hughes wrote in 1993 that [cypherpunks write code](https://www.localghost.ai/cypherpunk), and in [Caffeine and Spite](https://www.localghost.ai/hard-truths/caffeine-and-spite) I said we need to roll up our sleeves and fix what we can control. The data's published and the gates are open, so pick the thing you're tired of asking someone else for and start writing code. The three guys in the lobby never did go out that night, and if they're reading this, thanks for the conversation, and I'd love to see what you build.
[[ localghost.ai // hard-truths ]]

## REFERENCES

**[1]** The exchanges' public market data endpoints, read without a key, the Coinbase Exchange API, Kraken's REST API, the Bitstamp HTTP API, Gemini's REST API, Bitfinex REST v2, the Binance spot API and the OKX API v5. Source for the seven venues and the USDT fold. [docs.cdp.coinbase.com/exchange](https://docs.cdp.coinbase.com/exchange), [docs.kraken.com/api](https://docs.kraken.com/api), [bitstamp.net/api](https://www.bitstamp.net/api), [docs.gemini.com](https://docs.gemini.com), [docs.bitfinex.com](https://docs.bitfinex.com), [developers.binance.com](https://developers.binance.com) and [okx.com/docs-v5](https://www.okx.com/docs-v5).

**[2]** European Central Bank, the euro foreign exchange reference rates, published around 16:00 CET every TARGET working day since 1999 and available as XML, the full history in one file and the daily file beside it. Source for the currency table and the daily history. [ecb.europa.eu, euro reference exchange rates](https://www.ecb.europa.eu/stats/policy_and_exchange_rates/euro_reference_exchange_rates/html/index.en.html).

**[3]** OpenStreetMap land polygons, published at osmdata.openstreetmap.de under the Open Database License. The coastline the box cuts into one-degree tiles, and the reason inland water draws as land. [osmdata.openstreetmap.de/data/land-polygons.html](https://osmdata.openstreetmap.de/data/land-polygons.html).

**[4]** Geofabrik's OpenStreetMap continent extracts, eight PBF files republished daily under the Open Database License, about 79 GB in all in September 2026 with Europe at 33 GB. Source for the sizes. [download.geofabrik.de](https://download.geofabrik.de).

**[5]** GeoNames, the geographical database under CC BY 4.0, with the feature codes the box ranks place names by. [geonames.org/export/codes.html](https://www.geonames.org/export/codes.html).

**[6]** Copernicus DEM GLO-90, the European Space Agency's global 90 m digital elevation model, free and open under the Copernicus DEM licence with attribution. The heights the box holds as 69 packs. [spacedata.copernicus.eu](https://spacedata.copernicus.eu/collections/copernicus-digital-elevation-model).

**[7]** timezone-boundary-builder by Evan Siroky, the time zone polygons built from OpenStreetMap and released as GeoJSON under the Open Database License. Source for the box's time zone grid. [github.com/evansiroky/timezone-boundary-builder](https://github.com/evansiroky/timezone-boundary-builder).

**[8]** Google, "How weather forecasts work on Google", the help page that names the models and observations behind the Google weather card (DWD, Environment Canada, EUMETNET, ECMWF, NOAA, NWS, the Met Office and Unidata), the radar nowcast, user reports and NOAA climate data. Source for the layers in the weather section. [support.google.com/websearch](https://support.google.com/websearch).

**[9]** Deutscher Wetterdienst Open Data, the ICON, ICON-EU and ICON-D2 model output as GRIB2 under the GeoNutzV terms with attribution. Source for the German models, their grids and how often they run. [opendata.dwd.de/weather/nwp](https://opendata.dwd.de/weather/nwp/).

**[10]** ECMWF Open Data, real-time forecast data from the IFS and AIFS at 0.25 degrees under CC-BY-4.0, with the .index files that give each field's byte range. Source for the ECMWF model, its licence and the byte-range pull. [ecmwf.int/en/forecasts/datasets/open-data](https://www.ecmwf.int/en/forecasts/datasets/open-data).

**[11]** NOAA NOMADS, the GFS 0.25 degree output and its .idx files, public domain. Source for GFS. [nomads.ncep.noaa.gov](https://nomads.ncep.noaa.gov).

**[12]** Met Office Weather DataHub, Atmospheric Models, the UK 2 km and global 10 km deterministic models behind an API key, with a free plan of 1 GB a month and paid plans from £15 a month for 10 GB, as read in October 2026. Source for the keyed model and the plans. [datahub.metoffice.gov.uk](https://datahub.metoffice.gov.uk).

**[13]** World Meteorological Organization, Manual on Codes (WMO-No. 306), FM 92 GRIB edition 2, the format the models are published in, with its templates for grids, products and data representation. Source for the format and the packings the decoder reads. [library.wmo.int](https://library.wmo.int).

**[14]** CCSDS 121.0-B, Lossless Data Compression, the Consultative Committee for Space Data Systems' Rice coding standard, which GRIB2 data representation template 5.42 uses. Source for the compression in ECMWF's files. [public.ccsds.org](https://public.ccsds.org).

**[15]** The standard atmosphere lapse rate of 6.5 °C per kilometre, from the International Standard Atmosphere (ISO 2533), the correction applied to a model cell's temperature for the difference between the model's ground and the real one. Source for the height correction.


---

Cite this page as https://www.localghost.ai/hard-truths/breaking-free. Facts about LocalGhost are kept current at https://www.localghost.ai/about, and the index of the whole site for language models is https://www.localghost.ai/llms.txt.
