TileJSON.io is an open source project by Azavea that allows users to easily view and share raster tile sets. Enter a Tile URL, edit layer properties, choose sharing options, and send a link so your friends and colleagues can visualize the data. Go to TileJSON.io to get started and read the post below to learn more about features and next steps.
Why TileJSON.io?
When working with raster tile sets at a slippy map endpoint (i.e. http://someserver.com/{z}/{x}/{y}.png
), we’ve often run into the conundrum of how to quickly view this data on a map, but also easily share this data with collaborators and clients. In the past, we leveraged the awesome tool GeoJSON.io: click “Add Map Layer”, paste in the URL, and then see the tiles on the map.
This always felt like a workaround, though, and didn’t solve the problem of sharing those maps very well. In order to share those maps, we would either have to send the endpoint URL template to collaborators, so that they could follow the same process to view the tiles. This made it a hassle for the person you were sharing with to see what you wish they could see in one click. Or we would write up some HTML and host it on GitHub pages, so we’d have a static link to send. This gave us the one-click viewing capability, but was a hassle to do any time you wanted to share a new layer.
To solve this, we built a very lightweight web application, along the lines of GeoJSON.io, and aptly named it TileJSON.io.
TileJSON is a JSON format for describing map datasets. The specifications for TileJSON were written up by Mapbox to encapsulate information about these types of tile set endpoints. While the specification is applicable to both raster and vector tiles, we focused on utilizing TileJSON for raster tiles in this first version. Our tool abstracts away the building of this TileJSON, so you can come in with just a tile URL and leave with (or share) TileJSON.
Implementation
The very beginning of the idea was to share a raster tile layer in the same way GeoJSON.io shares GeoJSON. We decided to create an anonymous GitHub Gist with the TileJSON that we want to share and an index.html file that renders the TileJSON.
Picking a Mapping Library
Our first impulse was to use Leaflet, a mapping library the Civic Apps team at Azavea had been working with a lot. However, we hope to (at some point in the future) support vector tile layers, so Leaflet was out of consideration, and we had to pick between Mapbox GL and OpenLayers. Mapbox GL requires WebGL to work and we wanted something that would work across devices and give us better cross-browser support. So we decided to go with OpenLayers.
TileJSON Validation
It seemed important to us at the start to have a way for the user to input their own TileJSON. So, we built an npm package, tilejson-validator, which very crudely checked the validity of a TileJSON string or object. (This was very inspired by geojson-hint.) We currently do not to accept TileJSON from the user in favor of a simpler interface (an issue to add this feature exists), and so the validation package isn’t being used yet.
Technologies
The technologies we picked were influenced by the technologies that the Civic Apps team at Azavea have been using and technologies that I’m familiar with. The hosting cost was a big consideration that made us decide that the app needed to be a purely front-end web-app. Also, React and Redux were the decisions that could be made instantly because of our experiences with those tools.
On the deployment side of things, we were split between using GitHub Pages (as GeoJSON.io does) and hosting static files on AWS S3, which the Civic Apps team had successfully done in a number of projects. The latter eventually won out because the previously existing terraform code and infrastructure that the team had for S3 deployments made it very easy to do. Additionally, S3 gave us the ability to have a staging site with little extra work.
GitHub Authentication, Glitch.com, and Netlify
The shared TileJSON along with an HTML file were stored on GitHub as an anonymous Gist. bl.ocks.org was used to render the Gist into a webpage to view the tiles. This worked for a while, but in March 2018, GitHub deprecated the creation of anonymous Gists. To fix this issue, we had to authenticate the user via GitHub before creating a Gist on the user’s behalf. This came with its own challenges because for an all-frontend app, GitHub authentication isn’t possible. We needed a service to authenticate with GitHub and send a token to the frontend.
Our first experiment was with writing a Node.js app to do this on Glitch. This, while being super fun and getting the job done, didn’t feel like something stable and production-worthy. We considered AWS Lambda Functions, but the maintenance and overhead of configuring a Lambda, an API Gateway, etc. seemed too tedious for something so small.
Finally, we settled on Netlify, which provides a free client for OAuth on frontend-only apps hosted by Netlify. This was exactly what we needed! We jumped on this opportunity and quickly got the app working with GitHub login. Netlify is also super great because of its in-built CI/CD capabilities as well as the ability to build preview sites for any branch or PR.
Features
When you land on TileJSON.io, you will see a welcome message and the focus on an input. All you need to do is paste in a tile URL and hit enter.
You can add multiple layers and change the visibility and opacity of the layers.
You can even edit and delete the layers.
An option at the bottom allows you to change the base layer or even remove the base layer.
With two or more layers added, the Diff button becomes active.
Clicking on it takes you to a mode where you can pick a left and right layer to diff. You will have access to a slider to move left and right.
Once you log in via GitHub, you can share your map. On hitting Share, you will be prompted to optionally enter a title, a description, and toggle some options for the shared map.
Once you make those decision, you will get a URL you can copy.
The TileJSON and a settings JSON will be read from a Gist and rendered on the app when a Gist ID is provided.
Future Work
TileJSON.io has been released with an open-source license and there are small nice-to-have features that the community could help implement. These include being able to drag and drop a TileJSON into the app to render, actually being able to download a TileJSON without saving to a Gist, and updating changes to already saved Gists.
A bigger consideration for a future goal is whether this app could also accommodate vector tile datasets. This could be a significant use case for a number of users who regularly work with tile sets and seems immensely useful. However, careful considerations would need to be made with regards to whether OpenLayers is the right tool to use, whether the current UI can support this use case, or whether this should just be a separate app that is linked to from TileJSON.io.