Science Score: 26.0%

This score indicates how likely this project is to be science-related based on various indicators:

  • CITATION.cff file
  • codemeta.json file
    Found codemeta.json file
  • .zenodo.json file
    Found .zenodo.json file
  • DOI references
  • Academic publication links
  • Academic email domains
  • Institutional organization owner
  • JOSS paper metadata
  • Scientific vocabulary similarity
    Low similarity (16.7%) to scientific vocabulary
Last synced: 7 months ago · JSON representation

Repository

Basic Info
Statistics
  • Stars: 23
  • Watchers: 5
  • Forks: 1
  • Open Issues: 0
  • Releases: 0
Created about 3 years ago · Last pushed over 2 years ago
Metadata Files
Readme License

README.Rmd

---
output: github_document
editor_options: 
  chunk_output_type: console
---



```{r, include = FALSE}
knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>",
  fig.path = "man/figures/README-",
  out.width = "100%",
  fig.width=8,
  fig.height=8,
  cache = TRUE, 
  dpi=100)
```


  [![R-CMD-check](https://github.com/tylermorganwall/tree3d/actions/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/tylermorganwall/tree3d/actions/workflows/R-CMD-check.yaml)
  

tree3d: 3D Tree Models 
=========================================================

`tree3d` is an R package that provides highly customizable 3D tree models for data visualization and 3D scene creation. `tree3d` allows you to generate tree models as OBJ files, which can then easily be integrated into your data visualization, animation, or 3D rendering workflows.

## Features

- **Variety of tree models**: Includes both planar and solid tree models. 

- **Multiple crown types**: Provides a wide range of crown types, including: columnar, oval, palm, pyramidal, rounded, spreading, vase, and weeping. Each type offers a unique visual aesthetic to represent different types of trees.

- **Customizable dimensions and color**: Allows you to adjust the diameter, height, and color of both the tree's crown and trunk individually. This flexibility allows you to customize the tree model for your specific use case.

## Installation

`tree3d` can currently be installed from Github.

```{r, eval=FALSE}
install.packages("remotes")
remotes::install_github("tylermorganwall/tree3d")
```

## Examples

Let's load the sandbox data included in the Github repository. We will then unzip the file, and then load the shapefiles into R using {sf}.

```{r}
library(tree3d)
library(sf)
library(terra)
library(rayshader)

# Download the sample data
temp_download = tempfile(fileext = ".zip")
download.file("https://github.com/tylermorganwall/tree3d/raw/main/inst/extdata/tree3d_sandbox_data.zip", temp_download)

# Unzip and get directory
unzip(temp_download, exdir = tempdir())
zipdir = paste0(tempdir(), .Platform$file.sep, 
                "sandbox_data", .Platform$file.sep)

# Load all files
poly_boundary = sf::st_read(paste0(zipdir, "Area_Boundary_subset.shp"), quiet = TRUE)
baseline_tree = sf::st_read(paste0(zipdir, "Baseline_Trees_Z_clip.shp"), quiet = TRUE)
building_baseline = sf::st_read(paste0(zipdir, "Buildings_Baseline_2020_Z_clip.shp"), quiet = TRUE)
parcels = sf::st_read(paste0(zipdir, "Parcels_2020_clip.shp"), quiet = TRUE)

dem = terra::rast(paste0(zipdir, "DEM_2013_subset_zero.tif"))

# Inspect the tree data
head(baseline_tree)
```

Now that our data is loaded, let's generate a 3D map with rayshader. We will load in our 

```{r}
#Use rayshader to convert the DEM to a matrix and generate a 3D mesh
dem_mat = raster_to_matrix(dem)
dem_mat |>
  constant_shade("#6dbd83") |>
  add_overlay(generate_polygon_overlay(poly_boundary, extent = ext(dem),
                                       heightmap = dem_mat,
                                       palette = "#bcebc9")) |>
  add_overlay(generate_polygon_overlay(parcels, extent = ext(dem),
                                       heightmap = dem_mat,
                                       palette = "#afe0bd")) |>
  plot_3d(dem_mat, background = "lightblue", windowsize = 800)

#Render the buildings as extruded polygons
render_polygons(building_baseline, 
                extent = ext(dem), 
                data_column_top = "height_ag", 
                clear_previous = TRUE, 
                color = "white", 
                heightmap = dem_mat)
render_camera(theta = 44, phi = 36, zoom = 0.7, fov = 50, shift_vertical = -30)
render_snapshot()
```

Now that we have our 3D map generated, let's add our custom trees using rayshader's `render_trees()` function. `tree3d` provides `get_crown_file()` and `get_trunk_file()`, which allows access to the separate 3D models included in the package. Passing in each model separately gives you full control over the size, shape, and colors of the trees.

```{r}
# Render the trees, using data from `baseline_tree` to draw each tree individually
for(i in seq_len(nrow(baseline_tree))) {
  single_tree_info = baseline_tree[i,]
  tree_defaults = get_tree_data(single_tree_info$CrownType)
  latlongheight = as.matrix(st_geometry(single_tree_info)[[1]])
  render_tree(long = latlongheight[1], lat = latlongheight[2], 
              extent = ext(dem), heightmap = dem_mat, 
              tree_height = single_tree_info$Height,
              crown_width = single_tree_info$Diameter,
              trunk_height_ratio = tree_defaults$trunk_crown_ratio,
              custom_obj_crown = get_crown_file(tree = single_tree_info$CrownType),
              custom_obj_trunk = get_trunk_file())
}
render_camera(40, 23,  0.25, 90)
render_snapshot()
```

We can also generate high quality renders with our trees using rayshader:. Here, we use the solid models.

```{r hq}
render_tree(clear_previous = TRUE)
for(i in seq_len(nrow(baseline_tree))) {
  single_tree_info = baseline_tree[i,]
  tree_defaults = get_tree_data(single_tree_info$CrownType)
  latlongheight = as.matrix(st_geometry(single_tree_info)[[1]])
  render_tree(long = latlongheight[1], lat = latlongheight[2], 
              extent = ext(dem), heightmap = dem_mat, 
              tree_height = single_tree_info$Height,
              crown_width = single_tree_info$Diameter,
              trunk_height_ratio = tree_defaults$trunk_crown_ratio,
              custom_obj_crown = get_crown_file(tree = single_tree_info$CrownType,
                                                solid = TRUE),
              custom_obj_trunk = get_trunk_file())
}
render_camera(40, 23,  0.10, 90)
render_snapshot()
render_highquality(min_variance = 0,
                   sample_method = "sobol",
                   samples = 2048, 
                   lightaltitude = 30,
                   lightdirection = 45)

```

We can also extract 3D tree information from lidar data using the lidR package and use that data to generate 3D trees. Here, we'll use random trees from the package to fill in our scene.

```{r lidar}
library(lidR)
library(sf)
library(terra)

#We will use the lidR package to generate a DEM and detect the crown tops of trees, and
#then use rayshader to render 3D tree models scaled to those heights on the map.
#Load the example data from the lidR package
LASfile = system.file("extdata", "Topography.laz", package="lidR")
las = lidR::readLAS(LASfile, filter = "-inside 273450 5274350 273550 5274450")

#Convert the lidar point data to a DEM and detect the location of trees from the same data
dem = lidR::rasterize_terrain(las, algorithm = lidR::tin())
tree_top_data = lidR::locate_trees(las, lidR::lmf(ws = 5))
tree_locations = sf::st_coordinates(tree_top_data)

#Convert DEM to a matrix and extract the extent of the scene
dem_matrix = raster_to_matrix(dem)
dem_extent = terra::ext(dem)
extent_values = dem_extent@ptr$vector

#Plot the ground
dem_matrix |>
  height_shade() |>
  add_shadow(texture_shade(dem_matrix),0.2) |>
  add_shadow(lamb_shade(dem_matrix),0) |>
  plot_3d(dem_matrix, windowsize = 800, zscale = 2)
render_snapshot()

#Get tree data
tree_df = tree3d::get_tree_data()
tree_df

set.seed(1)
random_trees = tree_df[sample(1:10, nrow(tree_locations), replace=TRUE),]
random_trees$solid_available = ifelse(random_trees$solid_available, 
                                      sample(c(TRUE,FALSE),1),
                                      FALSE)
head(random_trees)

render_camera(theta=45,phi=30,zoom=0.3,fov=90, shift_vertical = -10)
for(i in seq_len(nrow(tree_locations))) {
  trunk_ratio_single = tree_df$trunk_crown_ratio[which(tree_df$name == random_trees[i,1])]
  render_tree(lat = tree_locations[i,2], long = tree_locations[i,1],
              custom_obj_crown = get_crown_file(random_trees[i,1], resolution = "high",
                                                solid = random_trees[i,2]),
              custom_obj_trunk = get_trunk_file(),
              absolute_height = TRUE, 
              tree_height = tree_locations[i,3],
              trunk_height_ratio = trunk_ratio_single,
              crown_width_ratio = 0.75 + 0.25 * runif(1),
              crown_color = random_trees[i,4],
              angle = c(0,360*runif(1),0),
              extent = dem, 
              zscale = 2, 
              heightmap = dem_matrix)
}
render_snapshot()
```

## Acknowledgements

We would like to acknowledge the following people/organizations for their contributions to the package:

elementslab (in the University of British Columbia) for supporting the development of the 3D tree models

Owner

  • Login: tylermorganwall
  • Kind: user

GitHub Events

Total
  • Watch event: 3
Last Year
  • Watch event: 3

Issues and Pull Requests

Last synced: 7 months ago

All Time
  • Total issues: 1
  • Total pull requests: 1
  • Average time to close issues: about 8 hours
  • Average time to close pull requests: about 2 months
  • Total issue authors: 1
  • Total pull request authors: 1
  • Average comments per issue: 1.0
  • Average comments per pull request: 0.0
  • Merged pull requests: 0
  • Bot issues: 0
  • Bot pull requests: 0
Past Year
  • Issues: 1
  • Pull requests: 0
  • Average time to close issues: about 8 hours
  • Average time to close pull requests: N/A
  • Issue authors: 1
  • Pull request authors: 0
  • Average comments per issue: 1.0
  • Average comments per pull request: 0
  • Merged pull requests: 0
  • Bot issues: 0
  • Bot pull requests: 0
Top Authors
Issue Authors
  • elipousson (1)
Pull Request Authors
  • aczekajlo (1)
Top Labels
Issue Labels
Pull Request Labels

Packages

  • Total packages: 1
  • Total downloads:
    • cran 163 last-month
  • Total dependent packages: 0
  • Total dependent repositories: 0
  • Total versions: 1
  • Total maintainers: 1
cran.r-project.org: tree3d

3D Tree Models

  • Versions: 1
  • Dependent Packages: 0
  • Dependent Repositories: 0
  • Downloads: 163 Last month
Rankings
Forks count: 21.8%
Dependent packages count: 29.1%
Dependent repos count: 34.9%
Stargazers count: 35.2%
Average: 42.1%
Downloads: 89.6%
Maintainers (1)
Last synced: 7 months ago