I want to generate point data within a polygon where I provide a starting point and generate n points, where each point is generated within a maximum radius of the previous point. This is based on the assumption that an object that I'm tracking can only travel a maximum distance between two ping intervals.
The spatstat::rSSI function does something similar but it specifies a minimum distance between points whereas I want a maximum distance and for it to be from the previous point not all points. https://gis.stackexchange.com/questions/163287/randomly-sampling-points-in-r-with-minimum-distance-constraint
here is a first approach
#set start point
start <- matrix( data = c( 5, 52), ncol = 2, dimnames = list( "", c("lon", "lat") ) )
# lon lat
# 5 52
n = 10 #how many points from startpoint?
max_dist = 100 #maximum distance to previous point in metres
#pre-allocate
L <- vector( mode = "list", length = 1+n )
#and initialise startpoint
L[[1]] <- start
library( geosphere )
set.seed(123) #for reproduction only, remove in production!
for ( i in 2:(n+1) ) {
L[[i]] <- geosphere::destPoint( p = L[[i-1]], #start = previous point
b = runif(1, 0, 360), #random bearing bewteen 0 and 360 degrees
d = runif(1, 0, max_dist ) #random distanxe between 0 and max_dist
)
}
#transform to a data.table
library( data.table )
ans <- data.table::rbindlist( lapply( L, as.data.table ), use.names = TRUE, fill = TRUE)
# lon lat
# 1: 5.000000 52.00000
# 2: 5.000336 51.99966
# 3: 5.000835 51.99979
# 4: 5.000546 52.00016
# 5: 5.000907 51.99989
# 6: 5.001065 51.99983
# 7: 5.000414 52.00002
# 8: 5.001240 52.00046
# 9: 5.001055 52.00062
#10: 5.000992 52.00113
#11: 5.000553 52.00109
#visual confirmation
library(sf)
library(leaflet)
leaflet( data = ans) %>% addTiles() %>%
addCircleMarkers( lng = ~lon, lat = ~lat ) %>%
addPolylines( lng = ~lon, lat = ~lat )
not implemented: polygon boundaries, since no sample data is provided and I'm a lazy boy ;-) You could include a test inside the for loop to see if the new coordinates are within boundaries of the polygon, and if not; recalculate.