-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
✨ Add function to split linestring by points
- Loading branch information
Showing
4 changed files
with
143 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
#' Split a linestring into multiple segments | ||
#' | ||
#' @param linestring A linestring object. | ||
#' @param split_points A `sfc` object containing points to split the | ||
#' linestring. | ||
#' @param tolerance A numeric value representing the maximum distance | ||
#' allowed between the linestring and the split points. If the distance | ||
#' between a split point and the linestring exceeds this value, the point | ||
#' will not be used to split the linestring. | ||
#' @return A `sfc` object containing the split linestrings. | ||
#' @export | ||
#' @examples | ||
#' library(sf) | ||
#' | ||
#' # Create a linestring | ||
#' linestring <- create_linestring(0, -1, 0, 1, 2, 1, 2, 0, 0, 0) | ||
#' | ||
#' # Create a set of split points | ||
#' split_points <- st_sfc( | ||
#' st_point(c(0, 0)), | ||
#' st_point(c(1, 1)), | ||
#' st_point(c(2, 0)) | ||
#' ) | ||
#' | ||
#' # Plot the linestring and split points | ||
#' plot(linestring) | ||
#' plot(split_points, add = TRUE) | ||
#' | ||
#' # Split the linestring | ||
#' segments <- split_linestring(linestring, split_points) | ||
#' | ||
#' # Plot the split linestrings | ||
#' plot(segments, col = c("#E69F00", "#56B4E9", "#009E73", "#F0E442"), lwd = 2) | ||
split_linestring <- function(linestring, split_points, tolerance = 0.01) { | ||
UseMethod("split_linestring") | ||
} | ||
|
||
#' @export | ||
split_linestring.LINESTRING <- function(linestring, | ||
split_points, | ||
tolerance = 0.01) { | ||
# Decompose the linestring into a list of line segments | ||
line_segments <- decompose_linestring(linestring) | ||
|
||
# Identify split points on the line segments, remove those | ||
# near the endpoints, and add the start point of each line | ||
points_on_lines <- lapply(line_segments, function(line_segment) { | ||
valid_points <- filter_points_within_tolerance( | ||
split_points, | ||
line_segment, | ||
tolerance | ||
) | ||
valid_points <- remove_points_near_endpoints( | ||
valid_points, | ||
line_segment, | ||
tolerance | ||
) | ||
c(st_startpoint(line_segment), valid_points) | ||
}) | ||
|
||
# Combine all split points and add the end point of the linestring | ||
all_points <- st_sfc(c( | ||
unlist(points_on_lines, recursive = FALSE), | ||
st_endpoint(linestring) | ||
)) | ||
|
||
# Determine which points belong to each segment by calculating | ||
# the segment index | ||
is_split_point <- rep(FALSE, length(all_points)) | ||
is_split_point[unlist(st_contains(split_points, all_points))] <- TRUE | ||
is_split_point[c(1, length(all_points))] <- FALSE | ||
segment_index <- cumsum(is_split_point) | ||
|
||
# Split the list of points into sub-lists based on the segment index | ||
segment_points_list <- split(all_points, segment_index) | ||
segment_points_list[-length(segment_points_list)] <- mapply( | ||
c, | ||
segment_points_list[-length(segment_points_list)], | ||
lapply(all_points[is_split_point], st_sfc) | ||
) | ||
|
||
# Create linestring objects for each linestring segment | ||
segments <- st_sfc(lapply(segment_points_list, function(segment_points) { | ||
st_linestring(st_coordinates(segment_points)) | ||
})) | ||
|
||
return(segments) | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.