We want to make sharing hexagon-based maps - such as our UK constituency hex map - easy. We've defined a simple JSON format to achieve that. The format requires layout and hexes:
{
"layout": "odd-r",
"hexes": {
"E14000530": {"q":-3,"r":-11},
"E14000531": {"q":-3,"r":-1}
}
}
The layout property should be one of the following coordinate systems:
odd-r(pointy-topped)
odd numbered rows shift righteven-r(pointy-topped)
even numbered rows shift rightodd-q(flat-topped)
odd numbered columns shift upeven-q(flat-topped)
even numbered columns shift up
Unlike Red Blob Games, the row number, r, increases vertically. This is to match with conventions used in most cartography (the HexJSON format is inspired by GeoJSON which has -90° at the geometric south pole and +90° at the geometric north pole) and most x-y graphs but differs from conventions in computer graphics.
Adding hexes
The hexes are then defined using unique keys for each. Every hex is positioned by providing column (q) and row (r) coordinates. You don't have to start at 0,0.
You can add your own custom data fields to each hex if you want to. Just make sure you don't use the keys q and r as they will be the coordinates e.g.
{
"layout": "odd-r",
"hexes": {
"E14000530":{
"name": "Aldershot",
"q": -3,
"r": -11,
"area": "SE",
"NUTS1": "UKJ",
"electorate": 72430
},
"E14000531":{
"name": "Aldridge-Brownhills",
"q": -3,
"r": -1,
"area": "WM",
"NUTS1": "UKG",
"electorate": 60215
}
...
}
}
Adding boundaries
In version 1.1 (28th February 2024) we have added the concept of boundaries around hexagons. This lets us define, say, a border between two groups of hexagons. You can provide multiple named boundaries using the additional property boundaries. Each boundary should contain an edges array that defines an ordered series of edges to create a line (the line does not have to be continuous). Each item in the array should provide the q and r coordinates of a particular hexagon along with the edge number e. For example:
{
"layout": "odd-r",
"hexes": { ... },
"boundaries": {
"name-1": {
"edges": [
{"q":-3,"r":-11,"e":2},
{"q":-3,"r":-12,"e":4}
]
}
}
}
Edges, e, are numbered from 1 to 6 moving clockwise from the top of the hexagon. Positive numbered edges are drawn in a clockwise sense and negative numbered edges are drawn in an anti-clockwise sense. This should allow continuous lines to be created.
-
pointy-topped
positive edge numbers -
pointy-topped
negative edge numbers -
flat-topped
positive edge numbers -
flat-topped
negative edge numbers
This means that there are two ways to define the same edge moving in the same direction; using one hexagon's coordinates with a clockwise sense or the neighbouring hexagon in the anti-clockwise sense. Although this adds redundancy, it gives the following advantages:
- Allows you to use the "best" hexagon as the base. For instance, if you want to draw a border for Scotland you could make sure that all your edges were based on Scottish hexagons.
- Drawing multiple anti-clockwise edges around the same hexagon is more straightforward.
- Allowing anti-clockwise edges needs fewer edges to change if you were to switch between even and odd layouts.
edges are not required to continue on from each other. That means that a line may contain gaps. So a renderer should check where the end of the last edge finished and the current edge begins to work out if a gap should be left. A renderer may also wish to give users the option to style a specific boundary using its name or any other properties of the boundary.See edges being drawn in this example.
Changelog
- v1.1 (28 February 2024): added definition of optional
boundaries. - v1.0 (8 May 2017): initial definition of format including
layoutandhexes.
Using HexJSON
The format is JSON so should be easy to ingest by your favourite programming language. We'll add examples that people have created below.
- Building a layout: Stuart Lowe created a HexJSON builder that reads a CSV file, allows you to reposition hexes, and save the output.
- JS: Stuart Lowe has created a small standalone JS library.
- D3: Oli Hawkins has created a plugin to read HexJSON files with D3.js.
- R: Tony Hirst wrote a series of blog posts (part 1, part 2, part 3) which describe a HTMLWidget that renders HexJSON for R.
- R: Joseph Bailey has a great tool for generating hex maps from geospatial polygons.