Calenhad is GIS and terrain creation for imaginary worlds.
I identified some requirements relating to imaginary worlds that are not well catered for by traditional real-world Geographical Information Systems offerings such as QGIS, for all their comprehensiveness and pedigree.

If we are creating a world ourselves instead of describing the one God made, we are generating procedurally or by hand data which in real-world GIS is typically downloaded or produced by some other system. We need tools to generate topographic and other data to describe the world the user is imagining. I think that in general we will want to guide the high-level structure of a planet (say where there will be continents and oceans, what rough shape they will be, where there will be mountain ranges, and so forth) and overlay low-level detail (place specific features, sculpt particular pieces of topography, arrange the landscape to suit his story or game scenario) but let the computer generate realistic and appropriate landscapes for levels of detail between the satellite view and the street-level view.

Calenhad uses noise generation (a port of libnoise to a GLSL implementation on the GPU) and potentially sculpting tools and a tectonics simulator to generate topography.real-world GIS raster data is arranged on a latitude – longitude grid in an equirectangular (or Mercator or similar cylindrical) projection and reprojected into any of some thousands of projections to provide the view a user wants. If we generate raster data in two dimensions and show it on a a globe or similar, we will see obvious pinching towards the poles because we have the same number of pixels at any given latitude, but the distance covered by those pixels decreases with the cosine of the latitude. This is OK on the Earth becaue most applications are not interested in high latitudes and those that are are generally interested only in high latitudes. Our application needs to consider the whole planet where our user may regard polar regions as important and indeed may need a view that covers polar and temperate regions together (suppose we want to depict Helcaraxë from Tolkein’s Silmarillion).

We want a structure for “raster” data which provides and even distribution of data points over the planet, which will allow us to compose maps across all latitudes without pinching in high latitudes. We need this to perform structured grid computation over the whole globe, which is necessary for simulating processes such as plate tectonics and erosion. For Calenhad, we select an icosphere model created by recursively subdividing the triangular faces of an icosahedron to progressively approximate a sphere. The points (vertices) are constructed in a natural heirarchy so that we can select different levels of detail by selecting only points at a particular level in the heirarchy, corresponding to the iteration which created them: the first iteration has 80 points, the second 320, the third 1,280, and so on.

We obtain not only the points but also the edges that link them and the triangles those edges form. That means it is easy to walk over the icosphere to quickly find the vertex nearest a given geolocation and at a given level of detail, so we don’t need to index points or features using a quadtree or similar. We can also easily export a triangle mesh for the purposes of rendering in a 3D pipeline.

When we change the landscape we want pretty quick feedback to see the resulting geography. In real-world GIS it would be OK for the system to take some time to compose maps using a new raster file uploaded because we are not working with rasterised data interactively. Pipeline-based terrain generators such as WorldMachine do this for 2D terrain heightfields. Calenhad at the moment uses a GLSL shader to produce and manipualte various kinds of fractal noise in a similar fashion to the venerable libnoise library, but in parallel on the GPU instead of serially on the CPU.

Earth-based GIS has some difficulty dealing with planets whose astronomical data is different from Earth although it is possible to use geoids that represent the Moon, Mars, etc. On the other hand we do not need to be at all pendantic about the finer points: we don’t need geolocations and altitudes down to the nanometre and we don’t need a precisely calibrated triaxial geoid with bumps and dents in the right places; indeed it would be quite confusing and complicated to try to. For now at least approximating the planet as a sphere should be fine. Of course an author might want a flat world, or a funny-shaped world, but GIS wouldn’t help us there anyway.

The solution at the moment provides the following.

  • Pipeline editing for combinations of libnoise-style modules
  • Rendering of the output and interactive visualisation using GLSL compute shader providing a parallelised equivalent to libnoise on the GPU
  • Serialisation of a pipeline to and from XML
  • Calculation of module parameters from entered mathematical expressions using variables
Architecture is C++, GLSL and Qt5.12 with no QML. I use a handful of libraries:
  • GeographicLib: for calculating distances and azimuths on the sphere when building and traversing the icosphere)
  • exprtk: parsing and calculating mathematical formulae entered as text)
  • QWT: some of the widgets, such as the compass / navigator that appears on the map

It also stands on the shoulders of the following giants:

  • Icosphere classes were ported from the C# implementation by Andreas Kahler (http://blog.andreaskahler.com/2009/06/creating-icosphere-mesh-in-code.html) to C++. These aren’t being used in anger yet but they will support tectonic and erosion simulation. They provide a structured grid for algorithms which operate across a number of data points in one pass.
  • Legend editor: this allows the colour scheme of the map to be editied and managed and is adapted from one by Richard Steffen (https://store.kde.org/p/1132126/)
  • FlowLayout is one of the examples that comes with Qt5. It works like the FlowLayout in the old Java AWT.
  • TextEdit, which allows the code completion popup for mathematical expressions, is one of the examples that comes with Qt5.
  • The pipeline editor is adapted from code by Stansialw Adaszewski (http://adared.ch/qnodeseditor-qt-nodesports-based-data-processing-flow-editor/).
  • CalenhadGlobe (the interactive map viewer) includes some code by James Chappell (https://www.storage-b.com/c/16) to write lat/long coordinates out in degrees and minutes and seconds of arc.

The classic libnoise library (http://libnoise.sourceforge.net/) has been ported (with some approximation) to a compute shader written in GLSL to perform its operations in parallel. This is very fast indeed. One adaptation that would be useful would be to allow a pattern to be rotated on the sphere (i.e. around an arbitrary pole) instead of around the axes in 3D space which do not align with the surface.