Skip to content

Commit

Permalink
Merge pull request #48 from jakobdanel/feat/distance-n-neighbours
Browse files Browse the repository at this point in the history
Feat/distance n neighbours
  • Loading branch information
jakobdanel authored Jan 15, 2024
2 parents 5a04c58 + 65750b0 commit 8c130bc
Show file tree
Hide file tree
Showing 13 changed files with 376 additions and 0 deletions.
7 changes: 7 additions & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -6,26 +6,33 @@ export(get_tiles_path)
export(is_tile_existing)
export(lfa_capitalize_first_char)
export(lfa_check_flag)
export(lfa_combine_sf_obj)
export(lfa_create_stacked_distributions_plot)
export(lfa_create_stacked_histogram)
export(lfa_create_tile_location_objects)
export(lfa_detection)
export(lfa_download)
export(lfa_download_areas)
export(lfa_find_n_nearest_trees)
export(lfa_get_all_areas)
export(lfa_get_detection_area)
export(lfa_get_detections)
export(lfa_get_detections_species)
export(lfa_get_flag_path)
export(lfa_get_neighbor_paths)
export(lfa_get_species)
export(lfa_ground_correction)
export(lfa_init)
export(lfa_init_data_structure)
export(lfa_intersect_areas)
export(lfa_load_ctg_if_not_present)
export(lfa_map_tile_locations)
export(lfa_merge_and_save)
export(lfa_modify_gpkg)
export(lfa_rd_to_qmd)
export(lfa_rd_to_results)
export(lfa_read_area_as_catalog)
export(lfa_save_all_neighbours)
export(lfa_segmentation)
export(lfa_set_flag)
export(read_catalog)
Expand Down
31 changes: 31 additions & 0 deletions R/combine_sf_obj.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#' Combine Spatial Feature Objects from Multiple GeoPackage Files
#'
#' This function reads spatial feature objects (sf) from multiple GeoPackage files and combines them into a single sf object.
#' Each GeoPackage file is assumed to contain neighbor information for a specific detection area, and the resulting sf object
#' includes additional columns indicating the corresponding area and species information.
#'
#' @param paths A character vector containing file paths to GeoPackage files with neighbor information.
#' @param area_infos A data frame or list containing information about the corresponding detection areas, including "area" and "specie" columns.
#' @return A combined sf object with additional columns for area and specie information.
#' @export
#'
#' @examples
#' # Assuming paths and area_infos are defined
#' combined_sf <- lfa_combine_sf_obj(paths, area_infos)
#'
#' # Print the combined sf object
#' print(combined_sf)
#'
#'@export
lfa_combine_sf_obj <- function(paths, area_infos) {
sf_obj <- sf::st_read(paths[1])
sf_obj$area = area_infos$area[1]
sf_obj$specie = area_infos$specie[1]
for (i in 2:length(paths)) {
extend <- sf::st_read(paths[i])
extend$area = area_infos$area[i]
extend$specie = area_infos$specie[i]
sf_obj <- dplyr::bind_rows(sf_obj, extend)
}
return(sf_obj)
}
48 changes: 48 additions & 0 deletions R/find_n_nearest_trees.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#' Find n Nearest Trees
#'
#' This function calculates the distances to the n nearest trees for each tree in the input dataset.
#'
#' @param trees A sf object containing tree coordinates.
#' @param n The number of nearest trees to find for each tree (default is 100).
#' @return A data frame with additional columns representing the distances to the n nearest trees.
#'
#' @examples
#' # Load tree data using lfa_get_detections() (not provided)
#' tree_data <- lfa_get_detections()
#'
#' # Filter tree data for a specific species and area
#' tree_data = tree_data[tree_data$specie == "pine" & tree_data$area == "greffen", ]
#'
#' # Find the 100 nearest trees for each tree in the filtered dataset
#' tree_data <- lfa_find_n_nearest_trees(tree_data)
#'
#'@export
lfa_find_n_nearest_trees <- function(trees, n = 100) {
coordinates <- sf::st_coordinates(trees)

distances_matrix <- matrix(NA, nrow = nrow(coordinates), ncol = n)

cat("Calculate ", nrow(coordinates), "entries")
for (i in seq_len(nrow(coordinates))) {
query_point <- coordinates[i,]
neighbors <-
spdep::knn2nb(spdep::knearneigh(coordinates, k = n))

# Extract the coordinates of neighbors and create an sf object
neighbor_indices <- unlist(neighbors[[i]])
neighbors_sf <- trees[neighbor_indices,]

# Set CRS for query point
query_point_sf <-
sf::st_sfc(sf::st_point(c(query_point[1], query_point[2])), crs = sf::st_crs(trees))

distances <- sf::st_distance(query_point_sf, neighbors_sf)
distances <- distances[order(distances)]
distances_matrix[i, ] <- distances
cat(i, "/", nrow(coordinates), "\n")
}
distances_matrix <- distances_matrix |> data.frame()
colnames(distances_matrix) <- paste0("Neighbor_", 1:n)
trees <- dplyr::bind_cols(trees, distances_matrix)
return(trees)
}
43 changes: 43 additions & 0 deletions R/get_detections.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#' Retrieve aggregated detection data for multiple species.
#'
#' This function obtains aggregated detection data for multiple species by iterating
#' through the list of species obtained from \code{\link{lfa_get_species}}. For each
#' species, it calls \code{\link{lfa_get_detections_species}} to retrieve the
#' corresponding detection data and aggregates the results into a single data frame.
#' The resulting data frame includes columns for the species, tree detection data,
#' and the area in which the detections occurred.
#'
#' @return A data frame containing aggregated detection data for multiple species.
#'
#' @export
#' @seealso
#' \code{\link{lfa_get_species}}, \code{\link{lfa_get_detections_species}}
#'
#' @examples
#' lfa_get_detections()
#'
#' @keywords data manipulation aggregation
#'
#' @family data retrieval functions
#'
#' @examples
#' # Retrieve aggregated detection data for multiple species
#' detections_data <- lfa_get_detections()
#'
#' @export
lfa_get_detections <- function() {
species <- lfa_get_species()
results <- NULL
for(specie in species){
trees <- lfa_get_detections_species(specie)
trees$specie <- specie
if(is.null(results)){
results <- trees
} else {
results <- dplyr::bind_rows(results, trees)
}
}
results$area <- as.factor(results$area)
results$specie <- as.factor(results$specie)
return(results)
}
25 changes: 25 additions & 0 deletions R/get_neighbor_paths.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#' Get Paths to Neighbor GeoPackage Files
#'
#' This function retrieves the file paths to GeoPackage files containing neighbor information for each detection area.
#' The GeoPackage files are assumed to be named "neighbours.gpkg" and organized in a directory structure under the "data" folder.
#'
#' @return A character vector containing file paths to GeoPackage files for each detection area's neighbors.
#' @export
#'
#' @examples
#' # Get paths to neighbor GeoPackage files for all areas
#' paths <- lfa_get_neighbor_paths()
#'
#' # Print the obtained file paths
#' print(paths)
#'@export
lfa_get_neighbor_paths <- function() {
all_areas <- lfa::lfa_get_all_areas()
return(file.path(
getwd(),
"data",
all_areas$specie,
all_areas$area,
"neighbours.gpkg"
))
}
25 changes: 25 additions & 0 deletions R/get_species.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#' Get a list of species from the data directory.
#'
#' This function retrieves a list of species by scanning the "data" directory
#' located in the current working directory.
#'
#' @return A character vector containing the names of species found in the "data" directory.
#'
#' @seealso
#' \code{\link{list.dirs}}
#'
#' @references
#' This function relies on the \code{\link{list.dirs}} function for directory listing.
#'
#' @keywords data manipulation file system
#'
#' @family data retrieval functions
#'
#' @examples
#' # Retrieve the list of species
#' species_list <- lfa_get_species()
#'
#' @export
lfa_get_species <- function() {
return(file.path(getwd(), "data") |> list.dirs(full.names = FALSE, recursive = FALSE))
}
24 changes: 24 additions & 0 deletions R/save_all_neighbours.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#' Save Neighbors for All Areas
#'
#' This function iterates through all detection areas, finds the n nearest trees for each tree,
#' and saves the result to a GeoPackage file for each area.
#'
#' @param n The number of nearest trees to find for each tree (default is 100).
#' @export
#'
#' @examples
#' # Save neighbors for all areas with default value (n=100)
#' lfa_save_all_neighbours()
#'
#' # Save neighbors for all areas with a specific value of n (e.g., n=50)
#' lfa_save_all_neighbours(n = 50)
#' @export
lfa_save_all_neighbours <- function (n = 100) {
all_areas <- lfa::lfa_get_all_areas()
for (i in 1:nrow(all_areas)) {
cat("Find neighbours for", all_areas[i, 1], ",", all_areas[i, 2], "\n")
out_path <-
file.path(getwd(), "data", all_areas[i, 1], all_areas[i, 2], "neighbours.gpkg")
lfa::lfa_get_detection_area(all_areas[i, 1], all_areas[i, 2]) |> lfa::lfa_find_n_nearest_trees(n) |> sf::st_write(out_path, append = F)
}
}
29 changes: 29 additions & 0 deletions man/lfa_combine_sf_obj.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

30 changes: 30 additions & 0 deletions man/lfa_find_n_nearest_trees.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

36 changes: 36 additions & 0 deletions man/lfa_get_detections.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

22 changes: 22 additions & 0 deletions man/lfa_get_neighbor_paths.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

34 changes: 34 additions & 0 deletions man/lfa_get_species.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 8c130bc

Please sign in to comment.