I'm working on improved hillshading for some topographical map plots. The basic hillshade workflow documented in image()
is:
require(raster)
alt = getData('alt', country='CHE')
slope = terrain(alt, opt='slope')
aspect = terrain(alt, opt='aspect')
hill = hillShade(slope, aspect, 40, 270)
plot(hill, col=grey(0:100/100), legend=FALSE, main='Switzerland')
plot(alt, col=rainbow(25, alpha=0.35), add=TRUE)
This image shows plot(hill..)
before plot(alt..)
is applied:
The method creates a solid grey under-layer of hillshades on which other data layers (e.g. elevation shading) are plotted semi-transparently. The problem with this approach is (a) that the neutral colour for flat terrain (RBG (202,202,202), '#CACACA') severely shades the whole model, which (b) prevents multiple shade layering, such as used by the 'Swiss hillshade' approach.
I can imagine an workaround that converts rasters to matrices and applies hillshading as a numerical multiplier to the brightness of other layers, but this doesn't seem very elegant (although I may be wrong). I wonder if anyone has any ideas or (preferably) experience in this area? Thanks in advance.
No experience with this, but why not give the gray undermap an alpha value that depends on slopes? Here's my try:
# before
require(raster)
alt = getData('alt', country='CHE')
slope = terrain(alt, opt='slope')
aspect = terrain(alt, opt='aspect')
hill = hillShade(slope, aspect, 40, 270)
plot(hill, col=grey(0:100/100), legend=FALSE, main='Switzerland')
plot(alt, col=rainbow(25, alpha=0.35), add=TRUE)
As you say, very dark.
# after
grayalphas <- seq(-1,1,by=.01)^2*100
grayalphas[grayalphas==100] <- 99
plot(hill, col=paste0(grey(0:100/100),sprintf("%.2d",grayalphas)), legend=FALSE, main='Switzerland')
plot(alt, col=rainbow(25, alpha=0.35), add=TRUE)
I set the gray alphas to have a parabolic shape, with minimum where the gray value is .5 and max of 99 at gray values of 0 or 1. If you choose something like this, you'll want to tinker with levels, etc, but it is easy to implement. Plus you'll want to put more effort than I did into the alphas, as mine are strictly numeric and not hex.
[Edit] I found a nifty function for adding alphas, addTrans()
here in Sacha Epskamp's answer. This keeps the parabola, but it ranges from 0 in the middle to 255 on the extremes.
grayalphas <- seq(-1,1,length=101)^2*255
plot(hill, col=addTrans(grey(0:100/100),grayalphas), legend=FALSE, main='Switzerland')
plot(alt, col=rainbow(25, alpha=0.35), add=TRUE)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With