Topographic maps show terrain by means of hillshading and contour lines. Features like forests, rock hachures, buildings, or roads are often superimposed. Since hillshading has a variable brightness with light colors on sunny sides of hills and dark colors on shady sides, we have the challenge that foreground elements are hard to read in certain background brightnesses.
In MapLibre-based topographic maps the colors often feel gray. The green of forests feels gray, the blue of glaciers feels gray. In swisstopo topographic maps on the other hand all colors feel colorful: wood green feels green, glacier blue feels blue, sunshine on hillshading feels warm. The main reason for this difference is blending: MapLibre can only perform normal blending while swisstopo raster maps have a wider palette of blending modes available, notably multiply blending. If you want to read more about blending see here.
Here we want to share some insights from an experiment with multiply blending using MapLibre GL JS and multiple overlapping html canvases and the css mix-blend-mode: multiply feature. For the full source code see GitHub. For an online demo see DEMO.
The basic structure is the following:
Canvas A: forest
Canvas B: hillshade
Canvas C: Contour lines with labels
Each canvas has its own maplibregl instance and the top-most MapLibre instance syncs its zoom and pan events to the other two.
Let us now have a closer look at some aspects of the resulting map.
The left image uses normal and the right image uses multiply blending. Interlaken, Switzerland. Lake / forest data from OpenStreetMap, terrain data from Mapterhorn.
With normal blending it is sometimes hard to see where we have forests as everything gets grayish. One could weaken the hillshading by making it for example more transparent. This would make the forest green stronger but the terrain effect would at the same time diminish.
With multiply blending the forest green is clearly visible and feels colorful. And it is still easy to get an intuition for the terrain.
Left image: contour lines with labels that have a white halo superimposed on hillshading and forests with normal blending. Right: same with multiply blending. Jura hills near Aarau, Switzerland. Forest data from OpenStreetMap, terrain data from Mapterhorn.
Regarding contour lines first note how the darkening effect of multiply blending helps to keep the lines visible on all background brightness levels. On the shaded sides of hills the lines adjust to a darker color while on the bright sides they are a bit warmer. This helps to keep that feeling of warm sunshine and colder shaded sides. With normal blending the line color is the same everywhere and on some backgrounds they are hard to see.
Second, note what happens to the white halos of the contour line elevation text labels. In normal blending, the white halos just paint white pixels over the lower laying forest and hillshading colors. In multiply blending however the situation is different. If you multiply a color with white this corresponds to a multiplication by 1.0, i.e., the identity and the lower laying pixel color is retained. Looks like a neat effect that could also be used for other situations maybe.
Working with multiple canvases and using the css mix-blend-mode property can give us a feeling for cartographic effects that would be possible if we had all the blend modes available in MapLibre GL JS. It is tedious of course to work with multiple canvases and the syncing lags a bit which gives a bad interactivity experience. Also it is unclear how one could go to more layers with symbols with this multi-canvas approach.
MapLibre has some open feature requests around blending modes. Probably it would be possible to get something in this direction working in the core of MapLibre GL JS. That would be really fun to play with.