Create Multilines from Points, Grouped by Id with Sf Package

Create Multilines from Points, grouped by ID with sf package

As Edzer explained in this issue, you have to supply the summarise function with the argument do_union = FALSE:

tst <- sfpoints %>% 
group_by(LINEID) %>%
summarise(do_union = FALSE) %>%
st_cast("LINESTRING")
plot(st_geometry(tst), col=1:2)

Sample Image

Executing sf operations on grouped objects

Not completely sure if I understood your request correctly, but I am giving it a try! So, please find below one possible solution using the st_join() function of the sf library, and then some dplyr functions to get the final result.

Reprex

  • Code
library(dplyr)
library(sf)

results <- line1 %>%
st_join(., line2, join = st_intersects) %>%
filter(., grp.x == grp.y) %>%
rename(grp = grp.x) %>%
select(-grp.y)
  • Output
results
#> Simple feature collection with 2 features and 1 field
#> Geometry type: LINESTRING
#> Dimension: XY
#> Bounding box: xmin: 1 ymin: 1 xmax: 2.5 ymax: 2.6
#> CRS: NA
#> # A tibble: 2 x 2
#> grp geometry
#> <chr> <LINESTRING>
#> 1 A (1 1, 1.5 1.5)
#> 2 B (2 2.1, 2.5 2.6)
  • Visualization
plot(results)

Sample Image


PS: In case you want to get the two intersecting lines in each group within the same sf object, you can extend the code as follows:

  • Complementary code
results2 <- results %>% 
st_union(.,line2, by_feature = TRUE) %>%
filter(., grp == grp.1) %>%
select(-grp.1)
#> Warning: attribute variables are assumed to be spatially constant throughout all
#> geometries
  • Output 2
results2
#> Simple feature collection with 2 features and 1 field
#> Geometry type: MULTILINESTRING
#> Dimension: XY
#> Bounding box: xmin: 1 ymin: 1 xmax: 2.5 ymax: 2.6
#> CRS: NA
#> # A tibble: 2 x 2
#> grp geometry
#> <chr> <MULTILINESTRING>
#> 1 A ((1 1, 1.25 1.25), (1.25 1.25, 1.5 1.5), (1.2 1, 1.25 1.25), (1.25 1.25~
#> 2 B ((2 2.1, 2.275 2.375), (2.275 2.375, 2.5 2.6), (2.2 2, 2.275 2.375), (2~
  • Visualization
plot(results2)

Sample Image

Created on 2022-01-04 by the reprex package (v2.0.1)

How to unite touching polygons with equal number of users's points in sf package

Please find below a more simple solution using only sf

Reprex

  • Code
library(sf)

Results <- polygons %>%
aggregate(.,
by = list(.$n_points),
function(x) x = floor(mean(x)),
join = st_touches)
  • Output
Results
#> Simple feature collection with 3 features and 3 fields
#> Attribute-geometry relationship: 0 constant, 2 aggregate, 1 identity
#> Geometry type: POLYGON
#> Dimension: XY
#> Bounding box: xmin: 2330 ymin: 40 xmax: 2380 ymax: 76
#> CRS: NA
#> Group.1 id n_points geometry
#> 1 1 153 1 POLYGON ((2371 55, 2371 46,...
#> 2 2 138 2 POLYGON ((2371 55, 2330 55,...
#> 3 3 144 3 POLYGON ((2380 46, 2371 46,...
  • Visualization
plot(Results["n_points"])

Sample Image

Created on 2021-12-19 by the reprex package (v2.0.1)

Split line by multiple points using sf package

Turns out there is an error in the documentation for lwgeom::st_split. It states that y is the

object split with (blade); if y contains more than one feature geometry, the geometries are st_combined

However, they are not st_combined when supplying a multi-feature sfc (as in your case).

To get your st_split to work, you'd need to combine them beforehand:

on_line_all = st_cast(nrst, "POINT")
buf_all <- st_combine(st_buffer(on_line_all,0.1))
parts_all = st_collection_extract(lwgeom::st_split(river$geometry, buf_all),"LINESTRING")

parts_all = st_as_sf(
data.frame(
id = 1:length(parts_all),
geometry = parts_all
)
)

mapview(parts_all, burst = "id")

Creating sf polygons from a dataframe

I figured out an answer based on paqmo's suggestion to look at Convert sequence of longitude and latitude to polygon via sf in R

The answer provided in that question groups all the points in the data frame as a single polygon. I've added a step to group the dataframe by the variable that identifies the polygon.

polygon <- my.df %>%
st_as_sf(coords = c("Easting", "Northing"), crs = utm18) %>%
group_by(Plot) %>%
summarise(geometry = st_combine(geometry)) %>%
st_cast("POLYGON")

Cannot plot sf linestring in R: Error in CPL_geos_is_empty(st_geometry(x))

I was having a problem just like yours and it seems that the problem is in the conversion from points to linestring. Following a solution found in the thread Create Multilines from Points, grouped by ID with sf package, you may have to use

summarise(do_union = FALSE) %>%
st_cast("LINESTRING")

before transforming your point dataset to a linestring.

I hope it helps.

extract coordinates of points in simple feature data frame

Firstly, it's worth using sf to create lines from points, which reduces the amount of code required:

library(sf)
library(dplyr)

#First create my data, I create points, and convert them into SpatialLines
lines1.df <- data.frame(
x = c(1,2,3,3,3,3,1,2,3),
y = c(1,2,2,3,4,5,4,4,4),
id = c(rep("A",6), rep("B",3))
)

lines2.df <- data.frame(
x = c(2,2,2.5,3.5,3.5,2.5,1,2),
y = c(3,4.2,4.2,4.2,3.2,3.2,2,1),
id = c(rep("A",6), rep("B",2))
)

points_to_line <- function(data, group = "id"){
data <- data %>%
group_by_at(group) %>%
summarise(do_union = FALSE) %>%
st_cast("LINESTRING") %>%
ungroup %>%
select(-do_union)
}

crs <- "+proj=utm +zone=32 +datum=WGS84"
coords <- c("x", "y")
lines1_sf <- st_as_sf(lines1.df, coords = coords, crs = crs) %>%
points_to_line()
lines2_sf <- st_as_sf(lines2.df, coords = coords, crs = crs) %>%
points_to_line()

#add attributes
lines2_sf$class <- c("A", "B")

#find intersecting points
#intersect
inters_pt <- st_intersection(lines1_sf, lines2_sf)

Here, you need to first cast to MULTIPOINT then to POINT

#extract the coordinates from the geometry column
inters_pt <- inters_pt %>%
st_cast("MULTIPOINT") %>%
st_cast("POINT")

> st_coordinates(inters_pt)
# X Y
#1 3.0 3.2
#2 3.0 4.2
#3 2.0 4.0
#4 1.5 1.5

Create a multilines Readme.txt with R

You have removed the usual new line characters from writeLines when writing to the file by changing sep. Then it looks like you want to add new lines separately but you are not writing these to the file, just the console.



Related Topics



Leave a reply



Submit