Update: In Feb 2020 I built a much better elevation API.
I wrote an announcement post, and the new API lives at opentopodata.org.
I recently finished a project that needed topological elevation data. Surprisingly there aren’t many APIs out there: the Google Maps Elevation API has restrictions on how you can use their results, and Open-Elevation doesn’t have coverage of Scandinavia and Russia.
So I put together my own API. It’s currently living at altitude.andrewnisbet.nz.
I like hosting these small projects on Google App Engine. It’s a managed service so I don’t need to worry about deployment or scaling or security patches. The downside is that there are a lot of restrictions around what you can do on the platform, and it can be tough to predict which ones will impact a given project.
One of these restrictions is that you can only use Python packages that don’t contain any C code. This means that the GDAL/OGR packages are out, which contain a lot of helpful tools for working with coordinates and geographical datasets. So instead of working with GeoTIFF files, I used a binary file. This took the whole world and split it into a grid and merged the binary values together. The values are two-byte integers. The grid runs from -180.0166666667 (the extra minute wraps around, and makes it easier to work with things like interpolation and boundaries). So I just need to convert lat and lon into row and column indices respectively, figure out how many cells that is (i.e.
row_index * n_cols + col_index), seek to that position, and read 2 bytes from the file.
I also ran into the max filesize limitation. The full dataset was about 500MB, but App Engine only allows files of 32MB. I got around that by splitting the file into ordered 30MB chunks, using the appropriate byte offset. For queries with multiple points, the file is queried in order of their byte offset to minimise seeking.