个人感觉R语言最有趣的就是各种各样的制图包,今天就来学习一个!
下面附上原作者Github链接https://github.com/tylermorganwall/rayshader
关于各种包的函数文档可以https://cran.r-project.org/web/packages/available_packages_by_name.html这里找到。
这里先说一些其他的东西,之前一直看到“->”但不知道和“=”有啥区别,后来学习了一下,两者大多数环境下没有区别,但这里举个例子,func(x=1)与func(x<-1,前者调用完后变量x不会被保留,而后者会在工作区里保留变量x=1。
管道(%>%)调用函数,其作用是将前一步的结果直接传参给下一步的函数,从而省略了中间的赋值步骤,可以大量减少内存中的对象,节省内存。x %>% f(y) 等同于 f(x, y),y %>% f(x, ., z) 等同于 f(x, y, z )。
install.packages("rgdal")
install.packages("devtools")
devtools::install_github("tylermorganwall/rayshader")
之前安装过rgdal包和devtools包就不用安装了。
loadzip = tempfile()
download.file("https://tylermw.com/data/dem_01.tif.zip", loadzip)
localtif = raster::raster(unzip(loadzip, "dem_01.tif"))
unlink(loadzip)
#And convert it to a matrix:
elmat = matrix(raster::extract(localtif, raster::extent(localtif), buffer = 1000),
nrow = ncol(localtif), ncol = nrow(localtif))
#We use another one of rayshader's built-in textures:
elmat %>%
sphere_shade(texture = "desert") %>%
plot_map()
此代码是先下载示例的30m分辨率的dem数据(可以改成自己的数据),之后将dem转成matrix矩阵,这里用到raster包里的extrac取值函数,中间用到缓冲buffer参数,但是这个参数一般用于点的缓冲,在这里可能是用于面的缓冲,有没有似乎对结果没有什么影响。sphere_shade为纹理映射函数,其中参数texture为映射的纹理特征,有“imhof1”, “imhof2”, “imhof3”, imhof4“,”desert“,”bw“,”unicorn"这几个选项。下图为不同texture的效果。
elmat %>%
sphere_shade(sunangle = 45, texture = "desert") %>%
plot_map()
elmat %>%
sphere_shade(texture = "desert") %>%
add_water(detect_water(elmat), color = "desert") %>%
plot_map()
detect_water函数是利用泛洪填充算法来侦测水体, add_water是获取前者得到的水体并添加到地形图上。color函数设置水体的颜色,可以为“imhof1”, “imhof2”, “imhof3”, imhof4“,”desert“,”bw“,”unicorn",前五个是各种明暗的蓝色,bw是白色,unicorn是彩虹色。
raymat = ray_shade(elmat)
#And we can add a raytraced layer from that sun direction as well:
elmat %>%
sphere_shade(texture = "desert") %>%
add_water(detect_water(elmat), color = "desert") %>%
add_shadow(raymat) %>%
plot_map()
注:sphere_shade只能调整山体的明暗效果,ray_shade可以根据方向生成阴影,当方向参数未设置时,会依据平均光线方向和曲面法向的点来缩放每个像元的灯光强度。控制方向参数的默认值为anglebreaks=seq(40,50,1), sunangle=315,具体两者有何联系和不同,我还真不知道555555,add_shadow是添加之前得到的阴影。
具体的我也不懂,大致就是前者计算了全局光照ambient_shade函数是计算间接光照,即物体之间因为反射、折射而导致的光线、阴影变化。使其看起来更真实。
ambmat = ambient_shade(elmat)
elmat %>%
sphere_shade(texture = "desert") %>%
add_water(detect_water(elmat), color = "desert") %>%
add_shadow(raymat) %>%
add_shadow(ambmat) %>%
plot_map()
这一块是我最喜欢的了,感觉非常的炫酷!ray_shade函数中zscale函数为X和Y间距(假定相等)与Z轴之间的比率(个人感觉dem分辨率30m,zscale应该是30,但是或许设置小一点的值让山变得陡峭可以获得很好的视觉效果,所以plot_3d和ray_shade中的值稍微小一点),其中maxsearch为射线检查的最大距离。add_shadow中max_darken参数为0.5表示图像变暗的限度为50%。
elmat %>%
sphere_shade(texture = "desert") %>%
add_water(detect_water(elmat), color = "desert") %>%
add_shadow(ray_shade(elmat, zscale = 3, maxsearch = 300), 0.5) %>%
add_shadow(ambmat, 0.5) %>%
plot_3d(elmat, zscale = 10, fov = 0, theta = 135, zoom = 0.75, phi = 45, windowsize = c(1000, 800))
render_snapshot()
elmat %>%
sphere_shade(texture = "desert") %>%
add_water(detect_water(elmat), color = "desert") %>%
add_shadow(raymat, 0.5) %>%
add_shadow(ambmat, 0.5) %>%
plot_3d(elmat, zscale = 10, fov = 30, theta = -225, phi = 25, windowsize = c(1000, 800), zoom = 0.3)
render_depth(focus = 0.6, focallength = 200, clear = TRUE)
montshadow = ray_shade(montereybay, zscale = 50, lambert = FALSE)
montamb = ambient_shade(montereybay, zscale = 50)
montereybay %>%
sphere_shade(zscale = 10, texture = "imhof1") %>%
add_shadow(montshadow, 0.5) %>%
add_shadow(montamb) %>%
plot_3d(montereybay, zscale = 50, fov = 0, theta = -45, phi = 45, windowsize = c(1000, 800), zoom = 0.75,
water = TRUE, waterdepth = 0, wateralpha = 0.5, watercolor = "lightblue",
waterlinecolor = "white", waterlinealpha = 0.5)
render_snapshot(clear = TRUE)
这里的montereybay加利福尼亚州蒙特雷湾水深数据是它自带的。fov视角角度。 theta绕Z轴旋转角度。wateralpha水的透明度,waterdepth 海平面高度。
par(mfrow = c(1, 2))
montereybay %>%
sphere_shade(zscale = 10, texture = "imhof1") %>%
add_shadow(montshadow, 0.5) %>%
add_shadow(montamb) %>%
plot_3d(montereybay, zscale = 50, fov = 0, theta = -45, phi = 45, windowsize = c(1000, 800), zoom = 0.6,
water = TRUE, waterdepth = 0, wateralpha = 0.5, watercolor = "lightblue",
waterlinecolor = "white", waterlinealpha = 0.5, baseshape = "circle")
render_snapshot(clear = TRUE)
montereybay %>%
sphere_shade(zscale = 10, texture = "imhof1") %>%
add_shadow(montshadow, 0.5) %>%
add_shadow(montamb) %>%
plot_3d(montereybay, zscale = 50, fov = 0, theta = -45, phi = 45, windowsize = c(1000, 800), zoom = 0.6,
water = TRUE, waterdepth = 0, wateralpha = 0.5, watercolor = "lightblue",
waterlinecolor = "white", waterlinealpha = 0.5, baseshape = "hex")
render_snapshot(clear = TRUE)
plot_3d函数中waterlinecolor为水图层的边界颜色,waterlinealpha为相应的透明度,baseshape为底座的形状,有"rectangle",“circle”,"hex"三种。
montereybay %>%
sphere_shade(zscale = 10, texture = "imhof1") %>%
add_shadow(montshadow, 0.5) %>%
add_shadow(montamb) %>%
plot_3d(montereybay, zscale = 50, fov = 0, theta = -100, phi = 30, windowsize = c(1000, 800), zoom = 0.6,
water = TRUE, waterdepth = 0, waterlinecolor = "white", waterlinealpha = 0.5,
wateralpha = 0.5, watercolor = "lightblue")
render_label(montereybay, x = 350, y = 240, z = 4000, zscale = 50,
text = "Moss Landing", textsize = 2, linewidth = 5)
render_label(montereybay, x = 220, y = 330, z = 6000, zscale = 50,
text = "Santa Cruz", color = "darkred", textcolor = "darkred", textsize = 2, linewidth = 5)
render_label(montereybay, x = 300, y = 130, z = 4000, zscale = 50,
text = "Monterey", dashed = TRUE, textsize = 2, linewidth = 5)
render_label(montereybay, x = 50, y = 130, z = 1000, zscale = 50,
text = "Monterey Canyon", relativez = FALSE, textsize = 2, linewidth = 5)
render_snapshot(clear = TRUE)
render_label用法一看便知,不必介绍。但是作者原代码我直接运行会报错:
这里报错原因是我没安装freetype矢量字体,一种解决方法是每个render_label加上 freetype = "false”,且textsize 改为1,这种方法是改用栅格字体,但是字体大小只能为1,看起来会比较小。
另一只解决方法是下载安装freetype字体,字体网站的链接是[http://freetype.sourceforge.net/index2.html]
(http://freetype.sourceforge.net/index2.html),具体安装方法自己百度,似乎挺麻烦的。。。我就先搁置了
1.http://www.imooc.com/wenda/detail/451927