Построение линий между двумя объектами sf POINT в r - PullRequest
2 голосов
/ 29 сентября 2019

У меня есть две пространственные особенности:

library(sf)

points1 <- data.frame(foo = seq(15, 75, 15), 
                     long = c(-85, -80, -78, -75, -82), 
                     lat = c(34, 36, 37, 38, 35)) %>% 
    st_as_sf(coords = c('long', 'lat'), crs = 4326) 

points2 <- data.frame(bar = seq(15, 75, 15), 
                     long = c(85, 80, 78, 75, 82), 
                     lat = c(30, 32, 34, 36, 38)) %>% 
    st_as_sf(coords = c('long', 'lat'), crs = 4326) 

cbind(points1, points2) -> df

Это дает:

  foo bar       geometry    geometry.1
1  15  15 POINT (-85 34) POINT (85 30)
2  30  30 POINT (-80 36) POINT (80 32)
3  45  45 POINT (-78 37) POINT (78 34)
4  60  60 POINT (-75 38) POINT (75 36)
5  75  75 POINT (-82 35) POINT (82 38)

Я хотел бы нарисовать линию между парами точек в пределах df - так отТОЧКА в geometry ТОЧКА в geometry.1.Я попытался привести ТОЧКИ к ЛИНЕЙНОЙ СТРЕЛКЕ следующим образом:

df %>% summarise(do_union=F) %>% st_cast("LINESTRING") %>% plot()

, но, похоже, это не работает.Я получаю непрерывную линию, когда мне нужно пять отдельных строк.

Ответы [ 2 ]

2 голосов
/ 29 сентября 2019

Используйте mapply, чтобы создать строку строки путем объединения точек попарно из геометрических столбцов:

> st_sfc(mapply(function(a,b){st_cast(st_union(a,b),"LINESTRING")}, df$geometry, df$geometry.1, SIMPLIFY=FALSE))
Geometry set for 5 features 
geometry type:  LINESTRING
dimension:      XY
bbox:           xmin: -85 ymin: 30 xmax: 85 ymax: 38
epsg (SRID):    NA
proj4string:    NA
LINESTRING (-85 34, 85 30)
LINESTRING (-80 36, 80 32)
LINESTRING (-78 37, 78 34)
LINESTRING (-75 38, 75 36)
LINESTRING (-82 35, 82 38)

Сначала я подумал, что st_union(geom1, geom2, by_feature=TRUE) будет достаточно для выполнения большей части работы, но (так какзадокументировано) by_feature игнорируется с двумя аргументами для st_union, и вывод представляет собой объединение каждой из 25 пар функций из geom1 и geom2.

Вот более медленный, клуджирный способчерез матрицу координат:

> coords = cbind(st_coordinates(df$geometry), st_coordinates(df$geometry.1))

Построить линейные строки по строке:

> linestrings = st_sfc(
     lapply(1:nrow(coords),
           function(i){
             st_linestring(matrix(coords[i,],ncol=2,byrow=TRUE))
           }))

См .:

> plot(linestrings)

enter image description here

, если вы хотите заменить (первую) точечную геометрию в вашем фрейме данных линиями, то:

> st_geometry(df) = linestrings
1 голос
/ 29 сентября 2019

Кажется, что проще всего превратить df в длинный кадр данных sf.Таким образом, вы можете сгруппировать его и вызвать summarise, чтобы объединить точки, чтобы получить многоточечную геометрию.Затем приведите его и перезагрузите CRS.

@ Spacedman подмечает, что вам нужно убедиться, что вы храните информацию вместе по строкам, поэтому я добавил столбец идентификаторов.Чтобы проиллюстрировать, что линии все еще создаются на основе их исходной группировки, я расширил набор данных, включив в него пару точек, которые дублируют значения foo и bar.

library(dplyr)
library(sf)

points1 <- data.frame(foo = c(seq(15, 75, 15), 30), 
                      long = c(-85, -80, -78, -75, -82, -70), 
                      lat = c(34, 36, 37, 38, 35, 30)) %>% 
  st_as_sf(coords = c('long', 'lat'), crs = 4326) 

points2 <- data.frame(bar = c(seq(15, 75, 15), 30), 
                      long = c(85, 80, 78, 75, 82, 70), 
                      lat = c(30, 32, 34, 36, 38, 32)) %>% 
  st_as_sf(coords = c('long', 'lat'), crs = 4326) 

cbind(points1, points2) -> df

df_linestring <- df %>%
  mutate(id = row_number()) %>%
  tidyr::gather(key, value = geometry, -id, -foo, -bar) %>%
  group_by(id, foo, bar) %>% 
  summarise() %>%
  ungroup() %>%
  st_cast("LINESTRING") %>%
  st_set_crs(st_crs(points1))
#> Warning: attributes are not identical across measure variables;
#> they will be dropped

plot(df_linestring["id"])

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...