Terrain Generalization

“Generalization” is a term used in cartography to describe reducing the complexity of data while preserving its essential characteristics in a meaningful way. It’s not just simplification, but finding and revealing the most important details. It’s a useful skill when you have more information than you need, and that’s almost always the case.

Cartographers can learn to recognize significant details in mappable data, but teaching a computer this skill is trickier.

I’m interested in this problem lately as it relates to terrain. Mountains are a hobby of mine, and depicting them has made up a significant portion of my work at Mapzen (for more on this, see Mapping Mountains). Since that post, we’ve integrated terrain data in our Walkabout and Tron house styles.

At the annual meeting of NACIS (North American Cartographic Information Society) this year, the generalization of terrain was discussed in several sessions, giving me lots of ideas to explore. Included among these was a technique described by Daniel Huffman in his blog post On Generalization Blending for Shaded Relief.

Generalization blending is a way to solve two problems at once – terrain data contains small details which aren’t necessary for understanding the size and shape of important features, but basic simplification methods such as blurring are applied everywhere indiscriminately.

blurred terrain

A displeasing, indiscriminately-blurred image.

However, if you have some knowledge of the terrain’s bumpiness, you can use it to blur small details while letting bigger features show through in all their bumpy glory.

Following Daniel’s lead, I decided to try to implement a version of this technique in a realtime Tangram shader. To detect bumpiness, I used the standard deviation, which describes the range of variation in a collection of samples. Starting with our tiled terrain normals, we can sample a small area around each pixel to test how locally smooth or bumpy that area is. This will give us a “bumpiness” map with lines along ridges – the sharper the ridge, the brighter the line.

An interactive bumpiness map of somewhere in British Columbia. Open full screen ➹

This can be used as a mask, showing the original terrain only where the mask is bright, and fading to the blurred version everywhere else:

An interactive, selectively-blurred map. Open full screen ➹

Here’s a side-by-side comparison:

unblurred terrainselectively blurred terrain

The original terrain, followed by selectively blurred terrain. I am pleased.

Here’s a live, editable version of the demo, and here’s a link to the code on github – fork away!

Further optimizations are possible – for example, here’s a version which should be faster while giving slightly different results, and here’s a version which samples in screen space to reduce artifacts at zoom levels (thanks to Patricio Gonzalez Vivo and Brett Camper for shader help). And there are lots of other kinds of blurs and manipulations to try – for instance, the current shader works best out to about z8, but this range could be expanded by linking various shading parameters to the zoom level.

In this way, I believe terrain can be made legible at all scales, and then my life’s work will be complete.