Adds 3D polygons with roofs to the current scene, using latitude/longitude or coordinates in the reference system defined by the extent object.
render_buildings(
polygon,
extent,
material = "grey",
roof_material = NA,
angle = 45,
zscale = 1,
scale_data = 1,
relative_heights = TRUE,
heights_relative_to_centroid = FALSE,
roof_height = 1,
base_height = 0,
data_column_top = NULL,
data_column_bottom = NULL,
heightmap = NULL,
holes = 0,
alpha = 1,
lit = TRUE,
flat_shading = FALSE,
light_altitude = c(45, 30),
light_direction = c(315, 225),
light_intensity = 1,
light_relative = FALSE,
clear_previous = FALSE,
...
)
sf
object, "SpatialPolygon" sp
object, or xy coordinates
of polygon represented in a way that can be processed by xy.coords()
. If
xy-coordinate based polygons are open, they will be closed by adding an
edge from the last point to the first.
Either an object representing the spatial extent of the 3D scene
(either from the raster
, terra
, sf
, or sp
packages),
a length-4 numeric vector specifying c("xmin", "xmax", "ymin", "ymax")
, or the spatial object (from
the previously aforementioned packages) which will be automatically converted to an extent object.
Default "grey80"
. If a color string, this will specify the color of the sides/base of the building
Alternatively (for more customization), this can be a rayvertex::material_list()
object to specify
the full color/appearance/material options for the resulting ray_mesh
mesh.
Default NA
, defaults to the material specified in material
. If a color string, this will specify the color of the roof of the building.
Alternatively (for more customization), this can be a rayvertex::material_list()
object to specify
the full color/appearance/material options for the resulting ray_mesh
mesh.
Default 45
. Angle of the roof.
Default 1
. The ratio between the x and y spacing (which are assumed to be equal) and the z axis in the original heightmap.
Default 1
. How much to scale the top
/bottom
value when rendering. Use
zscale
to adjust the data to account for x
/y
grid spacing, and this argument to scale the data
for visualization.
Default TRUE
. Whether the heights specified in roof_height
and base_height
should
be measured relative to the underlying heightmap.
Default FALSE
. Whether the heights should be measured in absolute
terms, or relative to the centroid of the polygon.
Default 1
. Height from the base of the building to the start of the roof.
Default 0
. Height of the base of the roof.
Default NULL
. A string indicating the column in the sf
object to use
to specify the top of the extruded polygon.
Default NULL
. A string indicating the column in the sf
object to use
to specify the bottom of the extruded polygon.
Default NULL
. Automatically extracted from the rgl window–only use if auto-extraction
of matrix extent isn't working. A two-dimensional matrix, where each entry in the matrix is the elevation at that point.
All points are assumed to be evenly spaced.
Default 0
. If passing in a polygon directly, this specifies which index represents
the holes in the polygon. See the earcut
function in the decido
package for more information.
Default 1
. Transparency of the polygons.
Default TRUE
. Whether to light the polygons.
Default FALSE
. Set to TRUE
to have nicer shading on the 3D polygons. This comes
with the slight penalty of increasing the memory use of the scene due to vertex duplication. This
will not affect software or high quality renders.
Default c(45, 30)
. Degree(s) from the horizon from which to light the polygons.
Default c(315, 225)
. Degree(s) from north from which to light the polygons.
Default 1
. Intensity of the specular highlight on the polygons.
Default FALSE
. Whether the light direction should be taken relative to the camera,
or absolute.
Default FALSE
. If TRUE
, it will clear all existing polygons.
Additional arguments to pass to rgl::triangles3d()
.
if(run_documentation()) {
# Load and visualize building footprints from Open Street Map
library(osmdata)
library(sf)
library(raster)
osm_bbox = c(-121.9472, 36.6019, -121.9179, 36.6385)
#Get buildings from OpenStreetMap
opq(osm_bbox) |>
add_osm_feature("building") |>
osmdata_sf() ->
osm_data
#Get roads from OpenStreetMap
opq(osm_bbox) |>
add_osm_feature("highway") |>
osmdata_sf() ->
osm_road
#Get extent
building_polys = osm_data$osm_polygons
osm_dem = elevatr::get_elev_raster(building_polys, z = 11, clip = "bbox")
e = extent(building_polys)
# Crop DEM, but note that the cropped DEM will have an extent slightly different than what's
# specified in `e`. Save that new extent to `new_e`.
osm_dem |>
crop(e) |>
extent() ->
new_e
osm_dem |>
crop(e) |>
raster_to_matrix() ->
osm_mat
#Visualize areas less than one meter as water (approximate tidal range)
osm_mat[osm_mat <= 1] = -2
osm_mat %>%
rayimage::render_resized(mag=4) |>
sphere_shade(texture = "desert") |>
add_overlay(generate_polygon_overlay(building_polys, extent = new_e,
heightmap = osm_mat,
linewidth = 6,
resolution_multiply = 50), rescale_original = TRUE) |>
add_overlay(generate_line_overlay(osm_road$osm_lines, extent = new_e,
heightmap = osm_mat,
linewidth = 6,
resolution_multiply = 50), rescale_original = TRUE) |>
plot_3d(osm_mat, water = TRUE, windowsize = 800, watercolor = "dodgerblue",
zscale = 10,
background = "pink")
#Render buildings
render_buildings(building_polys, flat_shading = TRUE,
angle = 30 , heightmap = osm_mat,
material = "white", roof_material = "white",
extent = new_e, roof_height = 3, base_height = 0,
zscale=10)
render_camera(theta=220, phi=22, zoom=0.45, fov=0)
render_snapshot()
}
#> Data (c) OpenStreetMap contributors, ODbL 1.0. https://www.openstreetmap.org/copyright
#> Linking to GEOS 3.13.0, GDAL 3.8.5, PROJ 9.5.1; sf_use_s2() is FALSE
#> Loading required package: sp
#> Mosaicing & Projecting
#> Clipping DEM to bbox
#> Note: Elevation units are in meters.
if(run_documentation()) {
#Zoom in to show roof details and render with render_highquality()
render_camera(fov=110)
render_highquality(camera_location = c(18.22, 0.57, -50.83),
camera_lookat = c(20.88, -2.83, -38.87),
focal_distance = 13,
lightdirection = 45)
}