Cắt đối tượng tính năng đơn giản trong R


20

Có một chức năng để cắt đối tượng bản đồ sf, tương tự như maptools::pruneMap(lines, xlim= c(4, 10), ylim= c(10, 15))được sử dụng cho SpatialPolygon hoặc SpatialLine?

Tôi đang xem xét st_intersection()nhưng có thể có cách thích hợp.

Câu trả lời:


17

st_intersectioncó lẽ là cách tốt nhất Tìm mọi cách hoạt động tốt nhất để khiến một sfđối tượng giao nhau với đầu vào của bạn. Đây là một cách sử dụng sự tiện lợi raster::extentvà pha trộn giữa cũ và mới. ncđược tạo bởi example(st_read):

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

Tôi không nghĩ rằng bạn có thể dỗ st_intersectionkhông cần CRS phù hợp chính xác, vì vậy hoặc đặt cả hai thành NA hoặc đảm bảo chúng giống nhau. Không có công cụ dễ dàng nào cho bbox / mức độ afaik, vì vậy sử dụng raster là cách tốt để khiến mọi thứ trở nên dễ dàng.


Cảm ơn rất nhiều @mdsumner, nó hoạt động như một cơ duyên. Tôi đã dành hàng giờ đồng hồ st_intersectionnhưng không thể tự giải quyết nó.
Kazuhito

Bây giờ bạn có thể sử dụng spex::spexđể thay thế st_as_sf(as(...))cuộc gọi. Ngoài ra, tmaptools::crop_shape()có thể làm điều này.
AF7

1
sfbây giờ bao gồm st_crop, xem câu trả lời của tôi để biết chi tiết.
AF7

22

Kể từ hôm nay , có một st_cropchức năng trong phiên bản github của sf( devtools::install_github("r-spatial/sf")có lẽ trên CRAN trong tương lai gần).

Chỉ cần phát hành:

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

Các vectơ phải được đặt tên với xmin xmax ymin ymax(theo thứ tự nào).

Bạn cũng có thể sử dụng bất kỳ đối tượng nào có thể được đọc bằng st_bboxgiới hạn cắt xén, rất tiện dụng.


5

Một cách giải quyết khác, đối với tôi, nó nhanh hơn đối với các shapefile lớn hơn:

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)

Cảm ơn. Đó là quy trình làm việc thú vị, sự kết hợp của raster :: crop () và st_as_sf () ... + 1 từ tôi. Tôi ước chúng ta có thể có loại hàm dễ truy cập này như crop () trong các phiên bản tương lai của sf . Về tốc độ, một lần chạy nhanh của system.time với chức năng của bạn đã báo cáo người dùng: 5,42, hệ thống: 0,09, trôi qua 5,52 , trong khi st_intersection()cách tiếp cận là người dùng: 1,18, hệ thống: 0,05, trôi qua 1,23 trên tập dữ liệu của bạn. (Có lẽ môi trường của tôi khác với bạn ... không chắc chắn.)
Kazuhito

Điều đó thật thú vị - cách tiếp cận st_intersection mất khoảng 80 năm đối với tôi.
pbaylis

Hãy nhớ rằng hàm raster :: crop, khi được áp dụng cho các đối tượng hình học sp, đóng vai trò bao bọc cho các hàm rgeos. Mặc dù, một bọc rất thuận tiện. API GEOS hoạt động trên các đối tượng WKT, do đó, sẽ luôn luôn là một tiêu chuẩn cho các hoạt động lớp phủ sf.
Jeffrey Evans

1
Và nó thay đổi theo thời gian, sf hiện có "lập chỉ mục không gian" tích hợp trong 0,5-1 cran.r-project.org/web/packages/sf/news.html vì vậy giờ đây có thể nhanh hơn sp / rgeos.
mdsumner

1
sfbây giờ bao gồm st_crop, xem câu trả lời của tôi để biết chi tiết.
AF7

1

@ mdsumner là một giải pháp. Hoạt động nếu rastalà RasterBrick, mức độ, bbox, v.v.

# 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)))
}

Nó sẽ loại bỏ thông tin crs của raster vì tôi không biết cách chuyển đổi raster crs () thành st_crs ()

Trên máy của tôi và cho mẫu dữ liệu của tôi, nó có hiệu suất tương đương raster::cropvới phiên bản dữ liệu SpatialLinesDataFrame.

Giải pháp của @ pbaylis chậm hơn khoảng 2,5 lần:

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

Chỉnh sửa: Nhận xét của Sombody gợi ý spex , nơi tạo ra SpatialPolygons với các crs từ rasta, nếu nó có crs.

Mã này sử dụng cùng một phương thức như 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))
}

Bây giờ sf có một st_cropchức năng có thể đáng để kiểm tra.
cmc
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.