| Type: | Package |
| Title: | Solar Potential Calculation for Point Clouds using 'VOSTOK' |
| Version: | 0.2.0 |
| Date: | 2026-02-18 |
| Description: | Calculate solar potential for LiDAR point clouds using the 'VOSTOK' (Voxel Octree Solar Toolkit) algorithm. This R program provides an interface to the original 'VOSTOK' C++ implementation by Bechtold and Hofle (2020), enabling efficient ray casting and solar position algorithms to compute solar irradiance for each point while accounting for shadowing effects. Integrates seamlessly with the 'lidR' package for LiDAR data processing workflows. The original 'VOSTOK' toolkit is available at <doi:10.11588/data/QNA02B>. |
| License: | GPL (≥ 3) |
| URL: | https://github.com/bi0m3trics/vostokR |
| BugReports: | https://github.com/bi0m3trics/vostokR/issues |
| Encoding: | UTF-8 |
| Imports: | Rcpp (≥ 1.0.11), lidR (≥ 4.0.0), data.table, terra, sf (≥ 1.0.0), methods |
| Suggests: | testthat (≥ 3.0.0) |
| LinkingTo: | Rcpp, RcppArmadillo, RcppEigen |
| Config/testthat/edition: | 3 |
| RoxygenNote: | 7.3.3 |
| SystemRequirements: | C++17 |
| NeedsCompilation: | yes |
| Packaged: | 2026-03-18 03:05:54 UTC; ajsm |
| Author: | Andrew J. Sanchez Meador [aut, cre], Sebastian Bechtold [aut] (Original VOSTOK C++ implementation), Bernhard Hofle [aut] (Original VOSTOK C++ implementation) |
| Maintainer: | Andrew J. Sanchez Meador <andrew.sanchezmeador@nau.edu> |
| Repository: | CRAN |
| Date/Publication: | 2026-03-23 09:20:02 UTC |
vostokR: Solar Potential Calculation for Point Clouds using VOSTOK
Description
This package provides an R interface to the VOSTOK (Voxel Octree Solar Toolkit) algorithm for calculating solar potential on LiDAR point clouds. It uses the original C++ implementation by Bechtold and Höfle (2020) with efficient ray casting and solar position algorithms to compute solar irradiance for each point, taking into account shadowing effects from surrounding points.
Main Functions
-
calculate_solar_potential- Main function for solar potential calculation -
add_normals- Add normal vectors to point cloud -
solar_ground_raster- Convert ground points to raster -
plot_solar_potential- Visualize results on point cloud -
set_vostokr_threads- Configure OpenMP thread count -
get_vostokr_threads- Get current thread configuration -
get_vostokr_performance_info- Check OpenMP capabilities -
clear_vostokr_caches- Clear performance caches
Citation
When using this package, please cite both the R package and the original VOSTOK toolkit:
Sánchez Meador, A.J. (2025). vostokR: Solar Potential Calculation for Point Clouds using VOSTOK. R package version 0.1.1.
Bechtold, S. and Höfle, B. (2020). VOSTOK - The Voxel Octree Solar Toolkit. heiDATA, V1. https://doi.org/10.11588/data/QNA02B
Author(s)
Maintainer: Andrew J. Sanchez Meador andrew.sanchezmeador@nau.edu
Authors:
Sebastian Bechtold (Original VOSTOK C++ implementation)
Bernhard Hofle (Original VOSTOK C++ implementation)
References
Bechtold, S. and Höfle, B. (2020). VOSTOK - The Voxel Octree Solar Toolkit. heiDATA. doi:10.11588/data/QNA02B
See Also
Useful links:
Add Normal Vectors to Point Cloud
Description
This function adds normal vectors to a LiDAR point cloud using a highly optimized C++/Eigen-based eigenvalue decomposition method with OpenMP parallelization. This implementation is 5-10x faster than pure R approaches and comparable to lasR, while providing additional geometric features useful for forestry applications.
Usage
add_normals(
las,
k = 10,
add_features = FALSE,
num_threads = 0,
verbose = FALSE
)
Arguments
las |
LAS object from lidR package |
k |
Number of neighbors to use for normal estimation (default: 10) |
add_features |
Logical, whether to add eigenvalue-based geometric features (default: FALSE) |
num_threads |
Number of OpenMP threads to use (default: 0 = auto-detect) |
verbose |
Logical. Print informational messages (default: FALSE) |
Value
LAS object with added normal vectors (nx, ny, nz) and optionally geometric features
See Also
calculate_solar_potential for solar potential calculation
Examples
library(lidR)
library(vostokR)
# Load test data
LASfile <- system.file("extdata", "test.laz", package="vostokR")
las <- readLAS(LASfile)
# Add normals using fast C++ method
las <- add_normals(las, k = 10)
names(las@data)
Calculate Solar Potential for LiDAR Point Cloud
Description
This function takes a LiDAR point cloud from the lidR package and calculates the solar potential for each point, taking into account shadowing effects from surrounding points. Location information (lat/lon/timezone) is auto-detected from the CRS when possible.
Usage
calculate_solar_potential(las, ...)
## S3 method for class 'LAS'
calculate_solar_potential(
las,
year = 2025,
day_start = NULL,
day_end = NULL,
start_date = NULL,
end_date = NULL,
day_step = 30,
minute_step = 30,
min_sun_angle = 5,
voxel_size = 1,
lat = NULL,
lon = NULL,
timezone = NULL,
n_threads = NULL,
clear_cache = FALSE,
verbose = FALSE,
...
)
## S3 method for class 'LAScatalog'
calculate_solar_potential(
las,
year = 2025,
day_start = 1,
day_end = 365,
day_step = 30,
minute_step = 30,
min_sun_angle = 5,
voxel_size = 1,
lat,
lon,
timezone,
...
)
Arguments
las |
LAS or LAScatalog object from lidR package containing point cloud data |
... |
Additional arguments passed to other methods |
year |
Numeric. Year for solar calculation (default: 2025) |
day_start |
Numeric. Start day of year (1-365). Ignored if start_date is provided. |
day_end |
Numeric. End day of year (1-365). Ignored if end_date is provided. |
start_date |
Date or character. Start date (e.g., "2025-06-01"). Overrides day_start. |
end_date |
Date or character. End date (e.g., "2025-08-31"). Overrides day_end. |
day_step |
Numeric. Step size in days for calculation (default: 30) |
minute_step |
Numeric. Time step in minutes for calculation within each day (default: 30) |
min_sun_angle |
Numeric. Minimum sun angle in degrees for calculation (default: 5) |
voxel_size |
Numeric. Size of voxels for octree shadow calculation (default: 1) |
lat |
Numeric. Latitude of the study area (auto-detected from CRS if NULL) |
lon |
Numeric. Longitude of the study area (auto-detected from CRS if NULL) |
timezone |
Numeric. Time zone offset from UTC (auto-detected from CRS if NULL) |
n_threads |
Numeric. Number of OpenMP threads to use (default: auto-detect) |
clear_cache |
Logical. Clear performance caches before calculation (default: FALSE) |
verbose |
Logical. Print informational messages (default: FALSE) |
Value
LAS object with added column for solar potential in Wh/m^2/day
Examples
library(lidR)
library(vostokR)
# Load test data
LASfile <- system.file("extdata", "test.laz", package="vostokR")
las <- readLAS(LASfile)
las <- add_normals(las, k = 10)
# Quick single-day calculation
las_solar <- calculate_solar_potential(las,
year = 2025,
day_start = 172,
day_end = 172,
day_step = 1,
minute_step = 60,
lat = 35.0,
lon = -111.0,
timezone = -7)
Clear VostokR Performance Caches
Description
Clears internal SOLPOS and shadow caches to free memory
Usage
clear_vostokr_caches(verbose = FALSE)
Arguments
verbose |
Logical. Print informational messages (default: FALSE) |
Value
No return value, called for side effects (clears internal caches).
Compute Normal Vectors Using Eigen Decomposition (C++ Implementation)
Description
Fast C++ implementation for computing normal vectors from point cloud data
using eigenvalue decomposition. This function is called internally by
add_normals and should not typically be called directly.
Usage
compute_normals_cpp(coords, neighbors, always_up = TRUE, num_threads = 0L)
Arguments
coords |
Matrix of point coordinates (n x 3: X, Y, Z) |
neighbors |
Matrix of neighbor indices (n x k) - 1-based indexing |
always_up |
Logical, ensure normals point upward (positive Z) |
num_threads |
Number of OpenMP threads to use (0 = auto-detect) |
Value
Matrix of normal vectors (n x 3)
Compute Normal Vectors and Geometric Features (C++ Implementation)
Description
Fast C++ implementation for computing normal vectors and eigenvalue-based geometric features from point cloud data. Features include linearity, planarity, sphericity, and curvature.
Usage
compute_normals_with_features_cpp(
coords,
neighbors,
always_up = TRUE,
num_threads = 0L
)
Arguments
coords |
Matrix of point coordinates (n x 3: X, Y, Z) |
neighbors |
Matrix of neighbor indices (n x k) - 1-based indexing |
always_up |
Logical, ensure normals point upward (positive Z) |
num_threads |
Number of OpenMP threads to use (0 = auto-detect) |
Value
List with normal vectors (n x 3) and features (n x 4)
Convert Date Range to Day Numbers
Description
Converts start and end dates to day of year numbers
Usage
date_to_day_numbers(start_date, end_date, year)
Arguments
start_date |
Date or character. Start date (e.g., "2025-06-01" or as.Date("2025-06-01")) |
end_date |
Date or character. End date (e.g., "2025-08-31" or as.Date("2025-08-31")) |
year |
Numeric. Year for the calculation |
Value
List with day_start and day_end
Extract Geographic Information from LAS CRS
Description
Attempts to extract latitude, longitude, and timezone from LAS coordinate reference system
Usage
extract_crs_info(las)
Arguments
las |
LAS object |
Value
List with lat, lon, timezone (or NA if cannot extract)
Get VostokR Performance Information
Description
Returns a named list containing information about OpenMP availability and thread configuration for VostokR.
Usage
get_vostokr_performance_info()
Value
A named list with the following elements:
- openmp_enabled
Logical. Whether OpenMP support is available.
- max_threads
Integer. Maximum number of threads available.
- current_threads
Integer. Number of threads currently in use.
Get Current VostokR Thread Count
Description
Returns the number of OpenMP threads currently configured for VostokR parallel computations.
Usage
get_vostokr_threads()
Value
An integer scalar indicating the current number of OpenMP threads used by VostokR.
Plot Solar Potential Point Cloud
Description
Plots solar potential values directly on the point cloud using lidR's native plotting
Usage
plot_solar_potential(las, ...)
Arguments
las |
LAS object with solar potential values |
... |
Additional arguments passed to lidR::plot() |
Value
No return value, called for side effects (produces a plot).
Examples
library(lidR)
library(vostokR)
LASfile <- system.file("extdata", "test.laz", package = "vostokR")
las <- readLAS(LASfile)
las <- add_normals(las, k = 10)
las_solar <- calculate_solar_potential(las,
year = 2025, day_start = 172, day_end = 172,
day_step = 1, minute_step = 60,
lat = 35.0, lon = -111.0, timezone = -7)
plot_solar_potential(las_solar)
Set VostokR OpenMP Thread Count
Description
Control the number of OpenMP threads used by VostokR calculations
Usage
set_vostokr_threads(n_threads = NULL, verbose = FALSE)
Arguments
n_threads |
Integer. Number of threads to use. If NULL, auto-detect based on available cores and lidR settings. |
verbose |
Logical. Print informational messages (default: FALSE) |
Value
No return value, called for side effects (sets thread count).
Convert Solar Potential Ground Points to Raster
Description
Extracts ground points from solar potential results and converts to terra SpatRaster
Usage
solar_ground_raster(
las,
res = 1,
ground_class = 2,
use_all_points = FALSE,
verbose = FALSE
)
Arguments
las |
LAS object with solar potential values |
res |
Numeric. Resolution of output raster (default: 1) |
ground_class |
Numeric. Classification code for ground points (default: 2) |
use_all_points |
Logical. If TRUE and no ground points found, use all points (default: FALSE) |
verbose |
Logical. Print informational messages (default: FALSE) |
Value
A SpatRaster object (from the terra package) containing
mean solar potential values (Wh/m^2/day) for ground points, gridded at the
specified resolution. Returns NULL if no ground points are found and
use_all_points is FALSE.
Examples
library(lidR)
library(vostokR)
LASfile <- system.file("extdata", "test.laz", package = "vostokR")
las <- readLAS(LASfile)
las <- add_normals(las, k = 10)
las_solar <- calculate_solar_potential(las,
year = 2025, day_start = 172, day_end = 172,
day_step = 1, minute_step = 60,
lat = 35.0, lon = -111.0, timezone = -7)
solar_raster <- solar_ground_raster(las_solar, res = 0.5)