Geotagging at SFO Museum, Part 5 – Images

This is a blog post by aaron cope that was published on April 29, 2020 . It was tagged sfo, collection, geotagging, oembed and iiif.

model aircraft instruction book: Metalcraft Corporation. Paper, ink. Gift of the Captain John B. Russell Family, SFO Museum Collection. 2012.149.0814.

This is the fifth of an 11-part blog post about geotagging photos in the SFO Museum collection. At the end of the last post I wrote:

By now, you might be wondering: If go-www-geotag is a tool to geotag photos then… where are the photos?

If the go-www-geotag application is designed to be agnotic to the details of any one user’s data sources how does it know where to find and load the images it’s meant to geotag? Isn’t this exactly the problem I described in the first post in this series, a scenario where the go-www-geotag application is required to know about an infinite number of image sources?

Developing an abstraction layer for the retrieval and publishing of cultural heritage materials that attempts to integrate and interface directly with an institution’s technical scaffolding is going to be a challenge at best and a fool’s errand at worst.

Rather than trying to support a potentially infinite list of image sources we’ve decided to require the use of the oEmbed standard as the means by which images are identified and loaded in to the application. oEmbed describes itself as:

…a format for allowing an embedded representation of a URL on third party sites. The simple API allows a website to display embedded content (such as photos or videos) when a user posts a link to that resource…

Essentially, it’s a lightweight API that doesn’t require authentication or credentials which, when given a URL, returns just enough information to display an image and suitable accreditation.

For example, if I call the Mills Field oEmbed endpoint with the URL for this photo of planes taxiing at SFO, at the top of this post, the response looks like this:

curl -s '' | jq
  "version": "1.0",
  "type": "photo",
  "width": "593",
  "height": "600",
  "title": "negative: San Francisco International Airport (SFO), aerial",
  "url": "",
  "author_name": "SFO Museum",
  "author_url": "",
  "provider_name": "SFO Museum",
  "provider_url": "",
  "geotag:geojson_url": "",
  "geotag:uri": "151/194/820/7/1511948207.geojson"

The response contains a url parameter which is a pointer to an image that the go-www-geotag application can use to display above the map. Pretty simple, right?

What I like about this approach is that the only thing we need to ask (museum) staff to do is copy and paste a URL for an object on the Mills Field website in order to get started geotagging photos.

The go-www-geotag also has support for passing along an optional ?oembed-url={URL} query parameter when opening the application in a web browser. If the query parameter is present the application will automatically retrieve and display the image associated with {URL} so staff won’t even need to copy and paste anything to start geotagging photos.

To enable support for oEmbed you’d start the application like this:

./bin/server \
	-nextzen-apikey {NEXTZEN_API_KEY} \
	-enable-placeholder \
	-placeholder-endpoint {PLACEHOLDER_API_ENDPOINT} \
	-enable-oembed \
	-oembed-endpoints '{url}&format=json'

2020/04/15 08:58:22 Listening on http://localhost:8080

The -oembed-endpoints is a comma-separated list of URI Templates (RFC 6570) strings that are used to validate and restrict URLs and endpoints the go-www-geotag application can query.

When you open the application in your web browser you’ll see an input field at the top of the page (above the geocoder search box) where you can enter a URL to derive an image from.

For example, if I enter the URL I’ll see this:

oEmbed is not the only way to retrieve image and descriptive metadata information for a “resource” (for example, a collection object) on the web. There’s a similar concept in the IIIF Presentation API that talks about “manifest” files. The IIIF documentation states that:

The manifest response contains sufficient information for the client to initialize itself and begin to display something quickly to the user. The manifest resource represents a single object and any intellectual work or works embodied within that object. In particular it includes the descriptive, rights and linking information for the object. It then embeds the sequence(s) of canvases that should be rendered to the user.

Which sounds a lot like oEmbed, doesn’t it? The reason we chose to start with oEmbed rather than IIIF is that while neither is especially complicated the former was simply faster and easier to set up and deploy. This echoes the rationale we talked about in the last blog post about the lack of polish, in the short-term, for the geocoding functionality in the go-www-geotag application:

We have a basic interaction model and we understand how to account for its shortcomings while we continue to develop the rest of the application.

We plan to add support for IIIF manifests (there’s an open ticket if you’d like to help out) but it was important to start with something very simple that could be implemented by as many institutions as possible with as little overhead as possible. It’s not so much that IIIF is harder as it is that oEmbed is easier, if that makes sense.

And here’s how it all comes together in the go-www-geotag application:

Does the field of view in this image really end at the edge of the airport campus or should it stretch all the way up the Bay to the city of San Francisco? It’s a rhetorical question, containing many possible answers. It’s also a convenient device to describe some additional features of the go-www-geotag application.

In the first post of this series, hinting at the work to come and posting a screenshot of a geotagged photograph of the 1950s terminal building under construction, I wrote:

As you can see the field of view for this photo is a bit short. It should extend all the way to Sweeney Ridge to the West of the airport but insteads stop at the Terminal Building.

The point being: What if we want or need to correct geotagging information in a photo and what happens if the go-www-geotag application loads an image that’s already been geotagged?

To account for these things we’ve updated the SFO Museum oEmbed endpoint to include some additional non-standard properties for images that have already been geotagged. When the go-www-geotag application sees these properties in a response it will use them to set the default camera view on the map.

For example here’s the oEmbed response, with the custom properties highlighted in blue, for that photo of the main terminal building under construction:

curl -s '' | jq
  "version": "1.0",
  "type": "photo",
  "width": "784",
  "height": "600",
  "title": "negative: San Francisco Airport, Terminal Building construction",
  "url": "",
  "author_name": "SFO Museum",
  "author_url": "",
  "provider_name": "SFO Museum",
  "provider_url": "",
  "geotag:camera_latitude": "37.6198063664",
  "geotag:camera_longitude": "-122.376408577",
  "geotag:target_latitude": "37.6163534265",
  "geotag:target_longitude": "-122.383475679",
  "geotag:angle": "41.9659437436",
  "geotag:uri": "151/194/393/5/1511943935.geojson"

Loading the URL for that object in go-www-geotag causes the application to render the map, and the initial camera view, like this:

And here is a screenshot with the field of view, and updated geometry information, extending all the way to Sweeney Ridge:

Have you noticed the Save button in some of the screenshots above? We’ll talk about that in the next blog post.