| Title: | Viewscape Analysis |
|---|---|
| Description: | Provides tools for viewscape analysis from one or multiple viewpoints using a digital surface or elevation model. Core functionality includes computing viewsheds, quantifying visual magnitude, calculating a suite of viewscape configuration metrics (extent, depth, relief, Sky View Factor, skyline variation, and patch-based landscape structure), Shannon Diversity Index and land cover feature proportions within the visible area, pairwise intervisibility networks, panoramic view generation, and visualizing results as rasters or polygons. Viewscape configuration metrics follow the methods of Tabrizian et al. (2020) <doi:10.1016/j.landurbplan.2019.103704>. The viewshed algorithm is based on Franklin & Ray (1994) <https://citeseerx.ist.psu.edu/document?repid=rep1&type=pdf&doi=555780f6f5d7e537eb1edb28862c86d1519af2be> and Wang et al. (2000) <doi:10.14358/PERS.66.1.87>. Visual magnitude is derived from Chamberlain & Meitner (2013) <doi:10.1016/j.landurbplan.2013.01.003>. Sky View Factor is computed following Oke (1981) <doi:10.1002/joc.3370010304> as implemented in the 'shadow' package (Dorman et al. 2019) <doi:10.32614/RJ-2019-024>. |
| Authors: | Xiaohao Yang [aut, cre, cph], Nathan Fox [aut], Derek Van Berkel [aut], Mark Lindquist [aut] |
| Maintainer: | Xiaohao Yang <[email protected]> |
| License: | GPL-3 |
| Version: | 3.0.0 |
| Built: | 2026-06-28 09:02:47 UTC |
| Source: | https://github.com/billbillbilly/viewscape |
The calculate_diversity function is designed to calculate landscape diversity metrics within a viewshed. It takes as input a land cover raster, a viewshed object representing the observer's line of sight, and an optional parameter to compute class proportions.
calculate_diversity(viewshed, land, proportion = FALSE)calculate_diversity(viewshed, land, proportion = FALSE)
viewshed |
Viewshed object. |
land |
Raster. The raster of land use/land cover representing different land use/cover classes. |
proportion |
logical (Optional), indicating whether to return class proportions along with the Shannon Diversity Index (SDI). (default is FALSE). |
List. a list containing the Shannon Diversity Index (SDI) and, if the proportion parameter is set to TRUE, a table of class proportions within the viewshed.
library(viewscape) # Load a viewpoint test_viewpoint <- sf::read_sf(system.file("test_viewpoint.shp", package = "viewscape")) # load dsm raster dsm <- terra::rast(system.file("test_dsm.tif", package ="viewscape")) #Compute viewshed output <- viewscape::compute_viewshed(dsm = dsm, viewpoints = test_viewpoint, offset_viewpoint = 6, r = 1600) # load landuse raster test_landuse <- terra::rast(system.file("test_landuse.tif", package ="viewscape")) diversity <- viewscape::calculate_diversity(output, test_landuse)library(viewscape) # Load a viewpoint test_viewpoint <- sf::read_sf(system.file("test_viewpoint.shp", package = "viewscape")) # load dsm raster dsm <- terra::rast(system.file("test_dsm.tif", package ="viewscape")) #Compute viewshed output <- viewscape::compute_viewshed(dsm = dsm, viewpoints = test_viewpoint, offset_viewpoint = 6, r = 1600) # load landuse raster test_landuse <- terra::rast(system.file("test_landuse.tif", package ="viewscape")) diversity <- viewscape::calculate_diversity(output, test_landuse)
The calculate_feature function is designed to extract specific feature-related information within a viewshed. It allows you to compute the proportion of the feature that is present in the viewshed.
calculate_feature(viewshed, feature, type, exclude_value)calculate_feature(viewshed, feature, type, exclude_value)
viewshed |
Viewshed object. |
feature |
Raster. Land cover or land use |
type |
Numeric. The input type of land cover raster. type=1: percentage raster (that represents the percentage of area in each cell). type=2: binary raster (that only uses two values to represent whether the feature exists in each cell). |
exclude_value |
Numeric. the value of those cells need to be excluded in the analysis. If type = 2, exclude_value is reqired. |
Numeric. The canopy area in the viewshed.
library(viewscape) # Load a viewpoint test_viewpoint <- sf::read_sf(system.file("test_viewpoint.shp", package = "viewscape")) # load dsm raster dsm <- terra::rast(system.file("test_dsm.tif", package ="viewscape")) #Compute viewshed viewshed <- viewscape::compute_viewshed(dsm = dsm, viewpoints = test_viewpoint, offset_viewpoint = 6) # load canopy raster test_canopy <- terra::rast(system.file("test_canopy.tif", package ="viewscape")) # calculate the percentage of canopy coverage test_canopy_proportion <- viewscape::calculate_feature(viewshed = viewshed, feature = test_canopy, type = 2, exclude_value = 0)library(viewscape) # Load a viewpoint test_viewpoint <- sf::read_sf(system.file("test_viewpoint.shp", package = "viewscape")) # load dsm raster dsm <- terra::rast(system.file("test_dsm.tif", package ="viewscape")) #Compute viewshed viewshed <- viewscape::compute_viewshed(dsm = dsm, viewpoints = test_viewpoint, offset_viewpoint = 6) # load canopy raster test_canopy <- terra::rast(system.file("test_canopy.tif", package ="viewscape")) # calculate the percentage of canopy coverage test_canopy_proportion <- viewscape::calculate_feature(viewshed = viewshed, feature = test_canopy, type = 2, exclude_value = 0)
The calculate_viewmetrics function is designed to compute a set of configuration metrics based on a given viewshed object and optionally, digital surface models (DSM) and digital terrain models (DTM) for terrain analysis. The function calculates various metrics that describe the visibility characteristics of a landscape from a specific viewpoint.The metrics include:
Extent: The total area of the viewshed, calculated as the number of visible grid cells multiplied by the grid resolution
Depth: The furthest visible distance within the viewshed from the viewpoint
Vdepth: The standard deviation of distances to visible points, providing a measure of the variation in visible distances
Horizontal: The total visible horizontal or terrestrial area within the viewshed
Relief: The standard deviation of elevations of the visible ground surface
Skyline: The standard deviation of the vertical viewscape, including visible canopy and buildings, when specified
Number of patches: Visible fragmentation measured by total visible patches with the viewscape
Mean shape index: Visible patchiness based on average perimeter-to-area ratio for all viewscape patches (vegetation and building)
Edge density: A measure of visible complexity based on the length of patch edges per unit area
Patch size: Total average size of a patches over the entire viewscape area
Patch density: Visible landscape granularity based on measuring patch density
Shannon diversity index: The abundance and evenness of land cover/use in a viewshed
Proportion of object: Proportion of a single type of land use or cover in a viewshed
calculate_viewmetrics(viewshed, dsm, dtm, masks = list())calculate_viewmetrics(viewshed, dsm, dtm, masks = list())
viewshed |
Viewshed object. |
dsm |
Raster, Digital Surface Model for the calculation of |
dtm |
Raster, Digital Terrain Model |
masks |
List, a list including rasters of canopy and building footprints. For example of canopy raster, the value for cells without canopy should be 0 and the value for cells with canopy can be any number. |
List
Tabrizian, P., Baran, P.K., Berkel, D.B., Mitásová, H., & Meentemeyer, R.K. (2020). Modeling restorative potential of urban environments by coupling viewscape analysis of lidar data with experiments in immersive virtual environments. Landscape and Urban Planning, 195, 103704.
# Load in DSM test_dsm <- terra::rast(system.file("test_dsm.tif", package ="viewscape")) # Load DTM test_dtm <- terra::rast(system.file("test_dtm.tif", package ="viewscape")) # Load canopy raster test_canopy <- terra::rast(system.file("test_canopy.tif", package ="viewscape")) # Load building footprints raster test_building <- terra::rast(system.file("test_building.tif", package ="viewscape")) # Load in the viewpoint test_viewpoint <- sf::read_sf(system.file("test_viewpoint.shp", package = "viewscape")) # Compute viewshed output <- viewscape::compute_viewshed(dsm = test_dsm, viewpoints = test_viewpoint, offset_viewpoint = 6, r = 1600) # calculate metrics given the viewshed, canopy, and building footprints test_metrics <- viewscape::calculate_viewmetrics(output, test_dsm, test_dtm, list(test_canopy, test_building))# Load in DSM test_dsm <- terra::rast(system.file("test_dsm.tif", package ="viewscape")) # Load DTM test_dtm <- terra::rast(system.file("test_dtm.tif", package ="viewscape")) # Load canopy raster test_canopy <- terra::rast(system.file("test_canopy.tif", package ="viewscape")) # Load building footprints raster test_building <- terra::rast(system.file("test_building.tif", package ="viewscape")) # Load in the viewpoint test_viewpoint <- sf::read_sf(system.file("test_viewpoint.shp", package = "viewscape")) # Compute viewshed output <- viewscape::compute_viewshed(dsm = test_dsm, viewpoints = test_viewpoint, offset_viewpoint = 6, r = 1600) # calculate metrics given the viewshed, canopy, and building footprints test_metrics <- viewscape::calculate_viewmetrics(output, test_dsm, test_dtm, list(test_canopy, test_building))
The compute_viewshed function is designed for computing viewsheds, which are areas visible from specific viewpoints, based on a Digital Surface Model (DSM). It provides flexibility for single or multi-viewpoint analyses and allows options for parallel processing, raster output, and plotting.
compute_viewshed( dsm, viewpoints, offset_viewpoint = 1.7, offset_height = 0, r = NULL, refraction_factor = 0.13, method = "plane", parallel = FALSE, workers = 1, raster = FALSE, plot = FALSE )compute_viewshed( dsm, viewpoints, offset_viewpoint = 1.7, offset_height = 0, r = NULL, refraction_factor = 0.13, method = "plane", parallel = FALSE, workers = 1, raster = FALSE, plot = FALSE )
dsm |
Raster, the digital surface model/digital elevation model |
viewpoints |
sf point(s) or vector including x,y coordinates of a viewpoint or a matrix including several viewpoints with x,y coordinates |
offset_viewpoint |
numeric, setting the height of the viewpoint. (default is 1.7 meters). |
offset_height |
numeric, setting the height of positions that a given viewpoint will look at. (defaut is 0) |
r |
Numeric (optional), setting the radius for viewshed analysis. (The default is 1000m/3281ft) |
refraction_factor |
Number, indicating the refraction factor. The refraction factor adjusts the effect of atmospheric refraction on the apparent curvature of the Earth. In most standard applications, a refraction factor of 0.13 is used, and so does this function. However, the appropriate refraction factor may vary depending on environmental conditions. |
method |
Character, The algorithm for computing a viewshed: "plane" and "los" (see details). "plane" is used as default. |
parallel |
Logical, (default is FALSE) indicating if parallel computing should be used to compute viewsheds of multiview points. When it is TRUE, arguements 'raster' and 'plot' are ignored |
workers |
Numeric, indicating the number of CPU cores that will be used for parallel computing. It is required if 'parallel' is 'TRUE'. |
raster |
Logical, (default is FALSE) if it is TRUE, the raster of viewshed will be returned. The default is FALSE |
plot |
Logical, (default is FALSE) if it is TRUE, the raster of viewshed will be displayed |
For method, "plane" is the reference plane algorithm introduced by Wang et al. (2000) and "los" is the line of sight algorithm (Franklin & Ray, 1994). The reference plane algorithm can be more time-efficient than the line of sight algorithm, whereas the accuracy of the line of sight is better.
Raster or list. For single-viewpoint analysis, the function returns either a raster (raster is TRUE) or a viewshed object. Value 1 means visible while value 0 means invisible. For multi-viewpoint analysis, a list of viewsheds is returned.
Franklin, W. R., & Ray, C. (1994, May). Higher isn’t necessarily better: Visibility algorithms and experiments. In Advances in GIS research: sixth international symposium on spatial data handling (Vol. 2, pp. 751-770). Edinburgh: Taylor & Francis.
Wang, J., Robinson, G. J., & White, K. (2000). Generating viewsheds without using sightlines. Photogrammetric engineering and remote sensing, 66(1), 87-90.
# Load a viewpoint test_viewpoint <- sf::read_sf(system.file("test_viewpoint.shp", package = "viewscape")) # load dsm raster dsm <- terra::rast(system.file("test_dsm.tif", package ="viewscape")) #Compute viewshed output <- viewscape::compute_viewshed(dsm = dsm, viewpoints = test_viewpoint, offset_viewpoint = 6, r = 1600)# Load a viewpoint test_viewpoint <- sf::read_sf(system.file("test_viewpoint.shp", package = "viewscape")) # load dsm raster dsm <- terra::rast(system.file("test_dsm.tif", package ="viewscape")) #Compute viewshed output <- viewscape::compute_viewshed(dsm = dsm, viewpoints = test_viewpoint, offset_viewpoint = 6, r = 1600)
The fov_mask function is designed to subset a viewshed based on its viewpoint and the field of view
fov_mask(viewshed, fov)fov_mask(viewshed, fov)
viewshed |
viewshed object, generated by compute_viewshed() |
fov |
Vector, specifying the field of view with two angles in degree (e.g. c(10,100)) for masking a viewshed based on its viewpoints. See details. |
For defining the field of view ('fov'), angles range from 0 to 360 degrees, with 0 inclusive and 360 exclusive. The initial angle must be smaller than the terminal angle in the sequence c(a,b) (a < b). To capture the northeast quadrant of a viewshed, one would use c(0,90), while the eastern quadrant would be delineated by c(45,315) as shown below:
| 135 | 90 | 45 |
| 180 | v | 0 |
| 225 | 270 | 315 |
Here, 'v' represents the viewpoint, with angles measured counterclockwise from due north.
viewshed object
# Load a viewpoint test_viewpoint <- sf::read_sf(system.file("test_viewpoint.shp", package = "viewscape")) # load dsm raster dsm <- terra::rast(system.file("test_dsm.tif", package ="viewscape")) # Compute viewshed viewshed <- viewscape::compute_viewshed(dsm, viewpoints = test_viewpoint, offset_viewpoint = 6) # subset viewshed using the field of view out <- viewscape::fov_mask(viewshed, c(40,160))# Load a viewpoint test_viewpoint <- sf::read_sf(system.file("test_viewpoint.shp", package = "viewscape")) # load dsm raster dsm <- terra::rast(system.file("test_dsm.tif", package ="viewscape")) # Compute viewshed viewshed <- viewscape::compute_viewshed(dsm, viewpoints = test_viewpoint, offset_viewpoint = 6) # subset viewshed using the field of view out <- viewscape::fov_mask(viewshed, c(40,160))
Generate an equirectangular or cylindrical panoramic view from a DSM.
For method = "equirectangular":
No semantic: automatically downloads ESRI WorldImagery tiles via greenSD and projects the satellite RGB colours onto the panoramic rays, producing a 3-band colour panorama (R, G, B, 0–255).
With semantic: projects the supplied land-use / land-cover raster onto the panoramic rays, returning a 2-layer SpatRaster (depth + land-cover codes).
For method = "cylindrical" the function always returns a single-layer
distance panorama (with an optional second semantic layer).
pano_view( dsm = NULL, vpt = NULL, h = 6, semantic = NULL, method = "equirectangular", sky_threshold = 3, step_size = 0.5, max_dist = 500, pano_dim = c(256, 512), ares = 0.0174533, heading = 0, color_source = NULL, sky_color = c(135, 206, 235), satellite_zoom = 17L, plot = FALSE, legend = TRUE, axes = TRUE )pano_view( dsm = NULL, vpt = NULL, h = 6, semantic = NULL, method = "equirectangular", sky_threshold = 3, step_size = 0.5, max_dist = 500, pano_dim = c(256, 512), ares = 0.0174533, heading = 0, color_source = NULL, sky_color = c(135, 206, 235), satellite_zoom = 17L, plot = FALSE, legend = TRUE, axes = TRUE )
dsm |
A SpatRaster object (single layer) of surface elevation. |
vpt |
A POINT sf object or numeric coordinate pair representing the viewpoint (in projected coordinates). |
h |
Numeric. Height of the viewpoint above the ground surface (in metres). Default: 6. |
semantic |
A SpatRaster object (single layer) of land-use / land-cover
class values. When supplied with |
method |
Character. |
sky_threshold |
Numeric. Elevation buffer (metres) below the ray position that is still treated as terrain (default: 3.0). |
step_size |
Numeric. Ray marching step size in DSM coordinate units (default: 0.5). |
max_dist |
Numeric. Maximum ray distance (default: 500). |
pano_dim |
Integer vector of length 2: panorama height and width in
pixels (default: |
ares |
Numeric. Cylindrical vertical angular resolution in radians per
pixel. Ignored when |
heading |
Numeric. Camera heading in degrees (default: 0 = north). See Details. |
color_source |
Optional SpatRaster with exactly 3 bands (R, G, B,
values 0–255). Overrides the automatic greenSD satellite download when
|
sky_color |
Numeric vector of length 3 (R, G, B, 0–255). Colour
painted on sky pixels in the colour panorama. Default: sky blue
|
satellite_zoom |
Integer. Tile zoom level passed to
|
plot |
Logical. Whether to plot the result (default: |
legend |
Logical. Whether to display a legend when plotting
(default: |
axes |
Logical. Whether to display axes when plotting (default: |
For heading:
heading = 0 → facing north (default)
heading = 90 → facing east
heading = 180 → facing south
heading = 270 → facing west
The equirectangular colour panorama requires the greenSD package
(install with devtools::install_github("billbillbilly/greenSD")).
It calls greenSD::get_tile_green(bbox, zoom, provider = "esri") and
uses the raw RGB tile ([[2]]) as the colour source.
method = "equirectangular", no semantic: 3-band SpatRaster
(R, G, B, 0–255). Plot with terra::plotRGB().
method = "equirectangular", with semantic: 2-layer SpatRaster
(depth in metres, land-cover code).
method = "cylindrical", no semantic: single-layer distance
SpatRaster (NA = sky).
method = "cylindrical", with semantic: 2-layer SpatRaster
(depth, semantic class).
Lu, X., Li, Z., Cui, Z., Oswald, M. R., Pollefeys, M., & Qin, R. (2020). Geometry-aware satellite-to-ground image synthesis for urban areas. In Proceedings of the IEEE/CVF Conference on Computer Vision and Pattern Recognition (pp. 859-867).
dsm <- terra::rast(system.file("test_dsm.tif", package = "viewscape")) vpt <- sf::read_sf(system.file("test_viewpoint.shp", package = "viewscape")) # cylindrical distance panorama (no internet needed) result <- viewscape::pano_view(dsm, vpt, h = 6, method = "cylindrical")dsm <- terra::rast(system.file("test_dsm.tif", package = "viewscape")) vpt <- sf::read_sf(system.file("test_viewpoint.shp", package = "viewscape")) # cylindrical distance panorama (no internet needed) result <- viewscape::pano_view(dsm, vpt, h = 6, method = "cylindrical")
A viewshed object contains a 'matrix' of visible and invisible area,
resolution, extent, and crs
visiblematrix
resolutionvector
extentnumeric
crscharacter
Visual Magnitude quantifies the extent of a visible region as perceived by an observer. It is derived from the surface's slope and angle features, alongside the observer's relative distance from the area (Chamberlain & Meitner).
visual_magnitude(viewshed, dsm)visual_magnitude(viewshed, dsm)
viewshed |
Viewshed object. |
dsm |
SpatRaster. A digital surface / elevation model |
SpatRaster
Chamberlain, B. C., & Meitner, M. J. (2013). A route-based visibility analysis for landscape management. Landscape and Urban Planning, 111, 13-24.
# Load a viewpoint test_viewpoint <- sf::read_sf(system.file("test_viewpoint.shp", package = "viewscape")) # load dsm raster dsm <- terra::rast(system.file("test_dsm.tif", package ="viewscape")) # Compute viewshed viewshed <- viewscape::compute_viewshed(dsm = dsm, viewpoints = test_viewpoint, offset_viewpoint = 6) # Compute visual magnitude vm <- viewscape::visual_magnitude(viewshed, dsm)# Load a viewpoint test_viewpoint <- sf::read_sf(system.file("test_viewpoint.shp", package = "viewscape")) # load dsm raster dsm <- terra::rast(system.file("test_dsm.tif", package ="viewscape")) # Compute viewshed viewshed <- viewscape::compute_viewshed(dsm = dsm, viewpoints = test_viewpoint, offset_viewpoint = 6) # Compute visual magnitude vm <- viewscape::visual_magnitude(viewshed, dsm)
The visualize_viewshed function is designed for the visualization of a viewshed analysis, providing users with various options for visualizing the results. The function works with a viewshed object and offers multiple plotting and output types.
visualize_viewshed(viewshed, plottype = "", outputtype = "")visualize_viewshed(viewshed, plottype = "", outputtype = "")
viewshed |
Viewshed object |
plottype |
Character, specifying the type of visualization ("polygon" or "raster"). |
outputtype |
Character, specifying the type of output object ("raster" or "polygon"). |
Visualized viewshed as either a raster or polygon object, depending on the outputtype specified.
# Load a viewpoint test_viewpoint <- sf::read_sf(system.file("test_viewpoint.shp", package = "viewscape")) # load dsm raster dsm <- terra::rast(system.file("test_dsm.tif", package ="viewscape")) #Compute viewshed viewshed <- compute_viewshed(dsm = dsm, viewpoints = test_viewpoint, offset_viewpoint = 6) # Visualize the viewshed as polygons visualize_viewshed(viewshed, plottype = "polygon") # Visualize the viewshed as a raster visualize_viewshed(viewshed, plottype = "raster") # Get the visualized viewshed as a polygon object polygon_viewshed <- visualize_viewshed(viewshed, plottype = "polygon", outputtype = "polygon")# Load a viewpoint test_viewpoint <- sf::read_sf(system.file("test_viewpoint.shp", package = "viewscape")) # load dsm raster dsm <- terra::rast(system.file("test_dsm.tif", package ="viewscape")) #Compute viewshed viewshed <- compute_viewshed(dsm = dsm, viewpoints = test_viewpoint, offset_viewpoint = 6) # Visualize the viewshed as polygons visualize_viewshed(viewshed, plottype = "polygon") # Visualize the viewshed as a raster visualize_viewshed(viewshed, plottype = "raster") # Get the visualized viewshed as a polygon object polygon_viewshed <- visualize_viewshed(viewshed, plottype = "polygon", outputtype = "polygon")