The Map Generator

I think it’s time to explain the map generator design. This may shed light on the reasons for taken decisions and can explain the appearance of obtained results. Finally, I hope that the criticism of the approach will help to identify ways to improve the project.

First, the project is almost entirely written in Haskell. At the moment there are about 30,000 lines of Haskell code. The choice of language was due to the fact that it allows you to produce a productive compiled code, and the functional approach ensures a good structuring of this rather complex project.

(Earlier I had dealt with some hypostases of the functional programming, and therefore it was not so difficult for me to master the Haskell at a sufficient level.)

The whole process of planet map generating can be divided into two main stages: generating of planetary relief, and then, obtaining data and drawing the map over the existing terrain. Now we list these stages and their main divisions.

  1. Generation of the initial base relief grid by various methods (fractional brownian motion, generalization of the midpoint displacement method, and functional approach). The resulting grid is then further subjected to the further transformations.
  2. The values of the grid are taken modulo and scaled. Then the sea level value is determined from the given ocean/all planet surface ratio (usually it is around 0.7).
  3. The positions of land mass areas are determined.
  4. In the land areas there are points of local minima (pits) and a significant number of them are eliminated by raising the values of the grid to the level of surrounding points. The remaining pits will serve as a places for possible lakes.
  5. Here, we make the distribution of the height values of the land relief similar to what is observed on the Earth (see Mathematical modelling of mountain height distribution on the Earth’s surface).
  6. We build river-lines relying on the base grid height values, so that each next point of the river-line is not higher than the previous one. As a result, the set of tree like structures of the river-lines is obtained, in which a river-line is the bunch of separate pieces belonging to different rhombuses.
  7. Further, using a special procedure separately in each rhombus we build a relief based on the nearest values of the heights on the river-lines.
  8. At this stage, the values of the heights of the base grid may not coincide with the new values at these points. Therefore we correct the base grid.
  9. Here, the generation of maps begins. First, we create DEM files (Digital Elevation Model Data). Then we generate Geotiff raster tiles for one or more resolutions.
  10. We turn the river-lines into full rivers by giving them a width and smoothing their banks.
  11. The shores of the lakes are determined.
  12. We determine the outlines of land areas and inland waters (these are lakes with a height of the surface at the ocean level; named as lowlakes).
  13. The resulting data is recorded to the spatial database store (PostGIS).
  14. Then we validate all obtained map features and make their correction (with PostGIS tools) if necessary.
  15. Currently we use mapnik with the defined style to generate PNG tiles.

Finally, for visual display we can use one of the web libraries (LeafLet, OpenLayers, etc.)

Next is a few comments on the mentioned stages.

  • At the stage when the base grid of heights is build, the rhombuses is formed on the surface of the cones. In each rhombus we introduce a local grid as mentioned in one of the past posts. And then, ignoring the distortions, we consider a rhombus as a square, and the local grid becomes very similar to the usual grid in the Cartesian coordinate system (although not completely similar; we must take into account the valid proximity of the points to each other). Further we are dealing only with this simplified system of base and local grids.
  • Currentlly,  we avoid situations where planet poles are contaned in land masses. Alse, we avoid land masses laying on the time line (180 degree meridian). This is due to some complexities for the relief generation process, but even more so due to use of map display in Web Mercator projection and possibility of obtaining non-valid map features which are difficult to divide into parts (in left and right hemispheres).
  • If you still intend to locate the continents at the poles, I recommend the transformation of the map data (rotation of the sphere around an arbitrary axis) with the subsequent change of the map projection.
  • In river system constructing we place only one river source in each romb. In order to get very different types of relief on a planet, it is planned to gradually change the number of sources along with the change in numerical parameters of the relief (local fractal dimention and scale).
  • Also in the map data there is no information now to which lake or river this river flows into. While constructing river-lines, this information is available, but when we put a lake on a map, some rivers become an inflow of this lake, instead of a tributary of another river. Valid information should be obtained at the PostGIS level. Which is planned to be done.
  • The resulting map vector data is a ESRI shapefiles which is the generalization of the dBase IV format.