Browsing the SFO Museum Aviation Collection Through Real Time Flight Data

This is a blog post by aaron cope that was published on March 23, 2023 . It was tagged whosonfirst, flightdata, golang, webassembly and wasm.

We are excited to announce a new interface for browsing the SFO Museum Aviation Collection: Real time (-ish) flights to and from SFO. You can try it out on the Mills Field website at:

https://millsfield.sfomuseum.org/flights/realtime/

I like to say that there is no part of a passenger’s time at SFO that shouldn’t have a straight line back to the SFO Museum Aviation Collection. Whether it’s the gate they are flying out of, the boarding area or terminal they are waiting for a flight in, the airline and aircraft they are flying on, or even the airport they are traveling to, there should be at least one related object from our collection for them to investigate.

With this in mind we’ve created a map-based interface to display real time (or more specifically real time -ish because there is a delay) flights as they are traveling to and from SFO, inside North America. For each of those flights we know the airline servicing the flight as well as its origin and destination airport. As a flight’s position is updated we plot its location on a map and display a popup with a random object for each flight-related facet from the SFO Museum Aviation Collection. When you click on an object its dedicated web page on the collection.sfomuseum.org website will be opened in a new tab.

You can click on any flight to see its popup but as a practical matter popups are only opened automatically when the size of map displayed is less than 1000 miles (a little more than the distance between San Francisco and Denver). If automatic popups are displayed on larger maps and it happens to be a particularly busy moment for travel to and from San Franciso the interface goes a little mad and behaves like this:

Sometimes there is enough flight traffic that there isn’t time to see all the objects associated with a flight before a new popup, for another flight, appears. To account for this there is also a carousel of recently seen objects displayed beneath the map. Newer objects are added to the left-hand side of the carousel with older objects being removed as necessary. Each of these objects links to its dedicated web page on the collection.sfomuseum.org website.

Popups will only be opened automatically for flights that are within the map’s current viewport. For example, if you have the map centered on the San Francisco Bay Area then you won’t see popups for a flight departing Boston’s Logan Airport. You can disable automatic popups by clicking anywhere on an open popup or by clicking on a different flight to open its popup. Automatic popups will resume once the currently-open popup is closed.

Sometimes we may not be able to derive objects for a given airline or airport, as you can see in the screenshot, above, of a Breeze Airways flight from San Bernadino to SFO. That might be because we haven’t collected anything for that subject yet (Breeze only just started flying in and out of SFO in 2022) or because those objects haven’t been published to the SFO Museum Aviation Collection website yet. We do have lots of objects about SFO, though, so every popup will have a least one object to explore further.

The map itself has controls for displaying historical aerial maps of SFO so you can see how contemporary flight patterns compare relative to the shape and size of SFO throughout the years. Objects in the aviation collection have associations with the “airfield” related concepts they represent (airline, aircraft, airport) but they also have associations with the place(s) those objects depict or are from. A logical next step for this interface is to ask what region a given flight is passing through and then to include a random object from that place alongside all the other objects. There is, after all, a whole country’s worth of objects in the SFO Museum Aviation Collection to explore.

Until then here’s a screenshot of some early work demonstrating resolving ICAO airline and airport identifiers to their SFO Museum equivalents and a reminder that all of this data, from objects and airlines and airports to individual flights, is published under a liberal use license and available from the sfomuseum-data GitHub repository.

The rest of this blog post is about some of the technical underpinnings of the real time flight map. If you’re not interested in that you can stop reading now and start investigating the real time flight map itself here: https://millsfield.sfomuseum.org/flights/realtime/

Under the hood

The real time map fetches collection objects for the airline and airports associated with a flight using an OEmbed endpoint for random objects. You can use the endpoint to return a random object from the entire SFO Museum Aviation Collection or a random object for a specific airline or airport, using the ?airline_id= or ?airport_id= query parameters respectively. For example:

$> curl -s 'https://collection.sfomuseum.org/random/oembed?airport_id=102527513' | jq

{
  "version": "1.0",
  "type": "photo",
  "width": 973,
  "height": 767,
  "title": "negative: San Francisco International Airport (SFO), fire department",
  "url": "https://static.sfomuseum.org/media/152/782/407/3/1527824073_dkpiNzWKGuzD8phDsTdlW07z8sDwr1C5_b.jpg",
  "author_name": "SFO Museum",
  "author_url": "https://collection.sfomuseum.org/objects/1511945391/",
  "provider_name": "SFO Museum",
  "provider_url": "https://collection.sfomuseum.org/",
  "sfomuseum:accession_number": "2011.032.0959"
}

By the time a flight has been relayed to the real time map its airline and airport IDs have already been derived from their ICAO equivalents. For example, KSFO becomes 102527513 and DAL (the ICAO airline code for Delta Airlines) becomes 1159284261 and so on. We perform these lookups, internally, using the sfomuseum/go-sfomuseum-airfield package, written in Go. In the spirit of investigation and generousity we are releasing a go-sfomuseum-airfield-wasm package which makes that same lookup functionality available as a WebAssembly binary that exposes JavaScript methods for looking up SFO Museum-specific identifiers matching IATA and ICAO codes. For example:

sfomuseum_lookup_airport("KSFO")
    .then((data) => { ... });

In this example, the airport code KSFO returns the following response, as a JSON-encoded string:

[
 {
  "wof:id": 102527513,
  "wof:name": "San Francisco International Airport",
  "sfomuseum:airport_id": 121,
  "iata:code": "SFO",
  "icao:code": "KSFO",
  "wd:id": "Q8688",
  "mz:is_current": 1
 }
]

Here’s a screenshot from the example website included with the package, which allows you to query airlines, airports and aircraft (that are associated with the SFO Museum Aviation Collection). See the way multiple different airlines all have the same IATA and ICAO airline codes? Yeah, that… but fortunately they all have unique, stable and permanent Who’s On First identifiers.

The WASM binary that is produced by the go-sfomuseum-airfield-wasm package is very large, like 11MB large, which means it may be prohibitive for any kind of production, internet-facing use. This is particularly true considering that it is possible to compile a static lookup table and query it directly in JavaScript at a fraction of the size of the WASM binary. These are all “known knowns” but WebAssembly continue to be exciting and useful for a variety of reasons we’ve talked about in past blog posts so it’s worth seeing what it makes possible now and because, eventually, some day the binaries won’t be so big. Onwards!