HexJSON format v1.1

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:

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.

Note: the shifts in each coordinate system are based on the absolute column/row numbers as specified in the HexJSON file, not on their relative position in a layout. Using absolute numbers ensures that a layout still renders correctly if a column or row is added later.

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.

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:

  1. 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.
  2. Drawing multiple anti-clockwise edges around the same hexagon is more straightforward.
  3. Allowing anti-clockwise edges needs fewer edges to change if you were to switch between even and odd layouts.
Note: The 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

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.