R:sf 여러 줄 POINT를 한 줄 LINSTRING으로 변환합니다.
개시하다
제목에 적힌 일을 하려고 의외로 많은 시간을 들였거나 똑똑한 방법을 찾지 못했다.구체적으로 GPS 레코더를 통해 얻은 점의 데이터를 하나의 선으로 설정하는 처리다.이 보도는 어리석은 방법을 비망록으로 남겼다.
포인트(POINT)-> 선(LINSTRING)의 코드를 먼저 씁니다.
# gps_sf_points は複数行にわたるsfオブジェクトで geometryはsfc_POINT
gps_sf_points %>%
sf::st_geometry() %>%
purrr::as_vector() %>%
matrix(ncol = 2, byrow = TRUE) %>%
sf::st_linestring() %>%
sf::st_sfc(crs = sf::st_crs(gps_sf_points)) # sfじゃなくてsfcだけどまあいいでしょう
GPS 레코더의 데이터 읽기
GPS 레코더Android 애플리케이션를 사용합니다.이 응용 프로그램은 측정 데이터를 CSV 출력으로 사용할 수 있습니다.측정 데이터는 당연히 위도경도를 포함하기 때문에 sf포장을 이용하여 마음대로 놀린다.아래와 같이 읽습니다.출력을 보면 몇 열이 있는지 알 수 있다.그 중에서
longitude
는 경도이고 latitude
는 위도이다.# 拡張子はtxtだけど中身はカンマ区切り
input <- "yyyyMMdd-hhmmss.txt"
gps_df <- readr::read_csv(input, col_names = T)
output## ─ Column specification ──────────────────────────────────
## cols(
## type = col_logical(),
## `date time` = col_datetime(format = ""),
## latitude = col_double(),
## longitude = col_double(),
## `accuracy(m)` = col_double(),
## `altitude(m)` = col_double(),
## `geoid_height(m)` = col_logical(),
## `speed(m/s)` = col_double(),
## `bearing(deg)` = col_double(),
## sat_used = col_logical(),
## sat_inview = col_double(),
## name = col_character(),
## desc = col_character()
## )
데이터 프레임에서 sf 대상으로 변환합니다.위도경도는 열지sf::st_as_sf()
로 솔직하게 만들 수 있기 때문이다.# 経度、緯度の順で指定。''でくくる必要あり
gps_sf_points <- gps_df %>%
sf::st_as_sf(coords = c('longitude', 'latitude'), crs = 4326) # EPSG4326だよね?
데이터의 수는 2943으로 다음과 같다.점->선->점이 돌아올 때 수량이 일치하는지 확인하기 위해 먼저 보냅니다.nrow(gps_sf_points)
output## [1] 2943
지도에 mapview::mapview()
로 겹치다.이동 궤적이 점으로 묘사된 것을 볼 수 있다.GPS 기록기의 데이터가 지도에 중첩되어 있다.점으로 인식되다.
점(POINT)에서 선(LINSTRING)까지
준비가 끝나면 본론으로 들어간다."서언"에서 보여준 처리를 다시 한 번 게재하다.하지만 이번에는 변수를 대입했다."함수 하나로 되는 거 아니에요?"그렇게 생각했지만 잘 안 돼서 벡터로 바뀌고 행렬을 통해...이렇게 빙빙 돌려서 처리했어요.주석에서 설명한
gps_sfc_linestring
는 sf 대상이 아니라 sfc 대상입니다.gps_sfc_linestring <- gps_sf_points %>%
sf::st_geometry() %>%
purrr::as_vector() %>%
matrix(ncol = 2, byrow = TRUE) %>% #byrowが必要
sf::st_linestring() %>%
sf::st_sfc(crs = sf::st_crs(gps_sf_points)) # sfじゃなくてsfcだけどまあいいでしょう
1 feature를 통해 알 수 있듯이 LINESTRING
gps_sfc_linestring
output## Geometry set for 1 feature
## Geometry type: LINESTRING
## Dimension: XY
## Bounding box: xmin: 137.2122 ymin: 36.70658 xmax: 137.2321 ymax: 36.72491
## Geodetic CRS: WGS 84
## LINESTRING (137.2319 36.71248, 137.2319 36.7124...
지도에 겹치면 선으로 연결되어 있음을 확실히 알 수 있다.지도상에서 중첩된 물건.선이 가지런하다
선에서 점(POINT)까지
이번에는 상반된 처리를 하다.실을 만들었으니까 반대로 점으로 돌아간 거죠?해보고 싶어요.이것도 벡터로 변환하여 행렬을 거쳐... 처리한다.출력이 정확하다
POINT
를 보면 2943줄로 되돌아오는 데이터를 알 수 있다.이 최종 결과는 sf 대상입니다.gps_sfc_linestring %>%
sf::st_cast("MULTIPOINT") %>%
purrr::as_vector() %>%
matrix(ncol = 2) %>% # byrowは不要
data.frame() %>%
sf::st_as_sf(coords = c("X1", "X2"), crs = sf::st_crs(gps_sfc_linestring))
output## Simple feature collection with 2943 features and 0 fields
## Geometry type: POINT
## Dimension: XY
## Bounding box: xmin: 137.2122 ymin: 36.70658 xmax: 137.2321 ymax: 36.72491
## Geodetic CRS: WGS 84
## First 10 features:
## geometry
## 1 POINT (137.2319 36.71248)
## 2 POINT (137.2319 36.71248)
## 3 POINT (137.2319 36.71248)
## 4 POINT (137.2319 36.71248)
## 5 POINT (137.2319 36.71248)
## 6 POINT (137.2319 36.71248)
## 7 POINT (137.2319 36.71248)
## 8 POINT (137.2319 36.71249)
## 9 POINT (137.2319 36.71249)
## 10 POINT (137.2319 36.7125)
총결산
우직한 방법이지만 여러 개
POINT
와 LINESTRING
를 서로 바꾸는 처리를 정리했다.첨부(실패 예)
솔직하게 하면 이런 느낌 아닌가요?쓴 코드는 예상한 결과에 미치지 못했다.
gps_sf_points %>%
dplyr::group_by(type) %>% # type列は全部TRUEなのでこれでグループ化
dplyr::summarise() %>%
sf::st_geometry() %>%
sf::st_cast("LINESTRING") %>%
mapview::mapview()
LINSTRING이었는데 원래 순서가 흐트러져서 경도순으로 연결이 됐어요.
Reference
이 문제에 관하여(R:sf 여러 줄 POINT를 한 줄 LINSTRING으로 변환합니다.), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://zenn.dev/re5n/articles/c6c50ca6b3b1dc텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)