Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

function to create random points given a certain NLM #84

Open
bniebuhr opened this issue Nov 30, 2021 · 0 comments
Open

function to create random points given a certain NLM #84

bniebuhr opened this issue Nov 30, 2021 · 0 comments

Comments

@bniebuhr
Copy link

Hi,

I would like to suggest a feature: the possibility to simulate points in space that use a given nlm as input for defining the weights or probabilities of simulating a point in a given location. Often it is useful to have spatial point patterns to test or create hypothesis or models, and having the flexibility of the nlm's created through NLMR as a basis for that would be great!

Here is a suggestion of implementation that I am currently using in a working package right now. It seems to work well and is simple.

#' Simulate points using input raster as weights 
#'
#' This function simulate point patterns in space using the values of
#' an input raster as weights or probabilities for selecting a point in a 
#' given location. It was designed to simulate points based on  neutral landscape 
#' models but it works with other input rasters as well.
#' 
#' The function works by first selecting random pixels in the landscape and 
#' finding their centers, then adding random variation within each pixel to
#' define the final point locations. 
#' It was based on this StackExchange super useful answer from "Spacedman":
#' https://gis.stackexchange.com/questions/224321/randomly-generate-points-using-weights-from-raster
#'
#' TO IMPROVE: implement with terra package
#'
#' @param n_features `[integer(1)=1000]` \cr Total number of features to spread in space.
#' @param base_raster `[RasterLayer]` \cr Input raster used for defining the weights.
#'
#' @returns The coordinates (x,y) of the simulated points.
#'
#' @example examples/set_points_from_raster_example.R
#'
#' @export

# function to simulate points using input raster as weights 
set_points_from_raster <- function(base_raster, n_features = 1000) {
  
  # get parameters
  res = raster::res(base_raster)
  
  # random points in the center of the cells
  ptscell <- sample(1:length(base_raster), n_features, prob = base_raster[], replace = TRUE)
  # get the centers
  center <- raster::xyFromCell(base_raster, ptscell)
  # add random values within the pixels
  pts <- center + cbind(runif(nrow(center), - res[1]/2, res[1]/2),
                        runif(nrow(center), - res[2]/2, res[2]/2))
  
  # return the points
  data.frame(pts)
}

And here are some examples of use for the function.

#-----
# minimal example

# example based on
# https://gis.stackexchange.com/questions/224321/randomly-generate-points-using-weights-from-raster
library(raster)
library(landscapetools)
library(ggplot2)

# raster
set.seed(12)
r <- raster::raster(matrix(runif(12),3,4))

# points
pts <- set_points_from_raster(r, n_features = 300)

# plot
landscapetools::show_landscape(r) +
  geom_point(aes(x, y), data = pts)

image

#-----
# using NLMR
library(NLMR)

# example NLM
set.seed(123)
nlm1 <- NLMR::nlm_mpd(100, 100, 100, roughness = .5)

# points
pts <- set_points_from_raster(nlm1, n_features = 1000)

# plot
landscapetools::show_landscape(nlm1) +
  geom_point(aes(x, y), data = pts)

image

Tell me what you think. We can build upon this implementation, I can also make a pull request if this is interesting.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant