Обрізати об’єкт простих функцій в R


20

Чи існує функція обрізання об’єкта sf map, подібна до maptools::pruneMap(lines, xlim= c(4, 10), ylim= c(10, 15))використовуваної для SpatialPolygon або SpatialLine?

Я розглядаю, st_intersection()але може бути правильний шлях.

Відповіді:


17

st_intersectionце, мабуть, найкращий спосіб. Знайдіть будь-який спосіб, який найкраще працює, щоб змусити sfоб’єкт перетинатися з вашими даними. Ось спосіб використання зручності raster::extentта суміші старого та нового. ncстворюється example(st_read):

st_intersection(nc, st_set_crs(st_as_sf(as(raster::extent(-82, -80, 35, 36), "SpatialPolygons")), st_crs(nc)))

Я не думаю, що ви можете змусити придуматись, що st_intersectionне потрібна точна відповідність CRS, тому або встановіть їх обох на NA або переконайтесь, що вони однакові. Немає простих інструментів для bbox / масштабу afaik, тому використання растрових є хорошим способом полегшити роботу.


Дякую @mdsumner, це спрацювало як шарм. Я витрачав години, st_intersectionале не міг вирішити це сам.
Kazuhito

Тепер ви можете використовувати spex::spexдля заміни st_as_sf(as(...))дзвінка. Також tmaptools::crop_shape()може це зробити.
AF7

1
sfТепер включає st_crop, див детальну інформацію про мою відповідь
AF7

23

Оскільки сьогодні існує st_cropфункція у github-версії sf( devtools::install_github("r-spatial/sf")можливо, в CRAN найближчим часом також).

Просто видайте:

st_crop(nc, c(xmin=-82, xmax=-80, ymin=35, ymax=36))

Вектор повинен бути названий за допомогою xmin xmax ymin ymax(у будь-якому порядку).

Ви також можете використовувати будь-який об’єкт, який можна прочитати st_bboxяк обмеження обрізання, що дуже зручно.


5

Ще одне вирішення, для мене це було швидше для великих форм файлів:

library(sf)
library(raster)
library(rgeos)
library(ggplot2)

# Load National Forest shapefile
# https://data.fs.usda.gov/geodata/edw/edw_resources/shp/S_USA.AdministrativeForest.zip
nf.poly <- st_read("S_USA.AdministrativeForest"), "S_USA.AdministrativeForest")

crop_custom <- function(poly.sf) {
  poly.sp <- as(poly.sf, "Spatial")
  poly.sp.crop <- crop(poly.sp, extent(c(-82, -80, 35, 36)))
  st_as_sf(poly.sp.crop)
}

cropped <- crop_custom(nf.poly)

Спасибі. Це цікавий робочий процес, поєднання растрових :: crop () та st_as_sf () ... + 1 від мене. Я б хотів, щоб ми могли мати таку легко доступну функцію, як crop () у майбутніх версіях sf . Щодо швидкості, швидкий запуск system.time з вашою функцією повідомив користувача: 5.42, система: 0,09, минуло 5,52 , а st_intersection()підхід користувач: 1,18, система: 0,05, на вашому наборі даних пройшло 1,23 . (Напевно, моє оточення відрізняється від вашого ... не впевнений.)
Kazuhito

Це цікаво - підхід st_intersection для мене займає близько 80-х.
pbaylis

Майте на увазі, що функція raster :: crop при застосуванні до об'єктів sp геометрії діє обгорткою для функцій rgeos. Хоча, дуже зручна обгортка. API GEOS працює на WKT-об'єктах, тож незмінно буде стандартом для операцій з накладанням sf.
Джефрі Еванс

1
І це змінюється з часом, sf тепер має вбудовану "просторову індексацію" в 0,5-1 cran.r-project.org/web/packages/sf/news.html, тому зараз, ймовірно, швидше, ніж sp / rgeos.
mdsumner

1
sfТепер включає st_crop, див детальну інформацію про мою відповідь
AF7

1

@ рішення mdsumner як функція. Працює, якщо rastaце RasterBrick, масштаб, bbox тощо.

# Crop a Simple Features Data Frame to the extent of a raster
crop.sf = function(sfdf, rasta) {
  st_intersection(sfdf, st_set_crs(st_as_sf(as(extent(rasta), "SpatialPolygons")), st_crs(sfdf)))
}

Він викидає інформацію про растр crs, тому що я не знаю, як перетворити растр crs () в st_crs ()

На моїй машині та для мого зразка даних це ефективність є еквівалентною, ніж raster::cropу версії даних SpatialLinesDataFrame.

Рішення @ pbaylis приблизно в 2,5 рази повільніше:

# Slower option.
crop.sf2 = function(sfdf, rasta) {
  st_as_sf(crop(as(sfdf, "Spatial"), rasta))
}

Редагувати: коментар деяких тел пропонує spex , який виробляє SpatialPolygons з crs з раста, якщо він має crs.

Цей код використовує той самий метод, що і spex:

# Crop a Simple Features Data Frame to the extent of a raster
crop.sf3 <- function(sfdf, rasta) {
  # Get extent and crs
  ext.sp <- as(extent(rasta), "SpatialPolygons")
  crs(ext.sp) <- crs(rasta)

  # crop
  st_intersection(sfdf, st_as_sf(ext.sp))
}

sf тепер має st_cropфункцію, яку, ймовірно, варто перевірити.
cmc
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.