Trích xuất các khu vực giao nhau trong R


19

Tôi có hai đa giác. Một cái chứa các trường (X, Y, Z) và cái kia chứa các loại đất (A, B, C, D). Tôi muốn biết khu vực nào của mọi lĩnh vực đều chứa loại đất nào. Tôi đã thử như sau:

nhập mô tả hình ảnh ở đây

library(rgdal)
library(rgeos)
Field<-readOGR("./","Field")
Soil<-readOGR("./","Soil")
Results<-gIntersects(Soil,Field,byid=TRUE)
rownames(Results)<-Field@data$FieldName
colnames(Results)<-Soil@data$SoilType

> Results
      A     B     C     D
Z  TRUE FALSE FALSE FALSE
Y FALSE  TRUE  TRUE FALSE
X  TRUE  TRUE  TRUE  TRUE

và đạt được kết quả tốt với nó cho tôi biết lĩnh vực nào chứa loại đất nào. Tuy nhiên, làm thế nào để tôi có được khu vực thay thế?


1
Lưu ý, st_intersection sẽ không hoạt động nếu điểm của bạn là vĩ độ và kinh độ. Bạn đã không xác định rằng bạn có tọa độ địa lý, mặc dù điều đó được gợi ý vì bạn đang nói về các loại đất.
Fourier

Câu trả lời:


24

Phương pháp này sử dụng intersect()chức năng từ rastergói. Dữ liệu mẫu mà tôi đã sử dụng không lý tưởng (đối với một điều họ đang ở tọa độ chưa được cung cấp), nhưng tôi nghĩ rằng nó có ý tưởng xuyên suốt.

library(sp)
library(raster)
library(rgdal)
library(rgeos)
library(maptools)

# Example data from raster package
p1 <- shapefile(system.file("external/lux.shp", package="raster"))
# Remove attribute data
p1 <- as(p1, 'SpatialPolygons')
# Add in some fake soil type data
soil <- SpatialPolygonsDataFrame(p1, data.frame(soil=LETTERS[1:12]), match.ID=F)

# Field polygons
p2 <- union(as(extent(6, 6.4, 49.75, 50), 'SpatialPolygons'),
             as(extent(5.8, 6.2, 49.5, 49.7), 'SpatialPolygons'))
field <- SpatialPolygonsDataFrame(p2, data.frame(field=c('x','y')), match.ID=F)
projection(field) <- projection(soil)

# intersect from raster package
pi <- intersect(soil, field)
plot(soil, axes=T); plot(field, add=T); plot(pi, add=T, col='red')

# Extract areas from polygon objects then attach as attribute
pi$area <- area(pi) / 1000000

# For each field, get area per soil type
aggregate(area~field + soil, data=pi, FUN=sum)

Imgur

Các kết quả:

    field soil         area
1      x    A 2.457226e+01
2      x    B 2.095659e+02
3      x    C 5.714943e+00
4      y    C 5.311882e-03
5      x    D 7.620041e+01
6      x    E 3.101547e+01
7      x    F 1.019455e+02
8      x    H 7.106824e-03
9      y    H 2.973232e+00
10     y    I 1.752702e+02
11     y    J 1.886562e+02
12     y    K 1.538229e+02
13     x    L 1.321748e+02
14     y    L 1.182670e+01

2
Để làm rõ: Tôi thích raster::intersecthơn rgeos::gIntersectionbởi vì cái trước tham gia dữ liệu thuộc tính từ hai SpatialPolgonsDataFrameđối tượng, trong khi cái sau dường như bỏ dữ liệu thuộc tính.
Matt SM

Cảm ơn cho nhiều chi tiết và câu trả lời chính xác. Bạn đã giúp tôi rất nhiều!!!
user2386786

4
Nếu bạn sử dụng byid = TRUE trong "gIntersection", nó sẽ trả về IDS thuộc tính có thể được sử dụng với hợp nhất để liên kết các thuộc tính. Các chức năng là khác nhau và cần lưu ý làm thế nào. Hàm "giao nhau" sử dụng các phạm vi chồng chéo trong khi đó, "gIntersection" là giao điểm rõ ràng của hình học vectơ. Cách tiếp cận giao nhau là giao điểm hình vuông / hình chữ nhật và không phải là giao điểm của đa giác thực tế. Phạm vi có thể được xác định lại bằng cách sử dụng phạm vi và bbox. Có những lợi thế cho cả hai phương pháp.
Jeffrey Evans

1
@JeffreyEvans Điểm tốt lại gIntersection; tuy nhiên, ID tính năng đầu vào không được cung cấp trực tiếp, chúng được nối và lưu trữ trong ID tính năng của đầu ra. Điều này có nghĩa là các bước bổ sung để phân tích ID, sau đó tham gia vào các thuộc tính. Tôi muốn raster::intersectbao gồm các ID đầu vào này như các thuộc tính bổ sung trong đầu ra.
Matt SM

1
Cảm ơn bạn đã chỉ ra rằng, tôi hoàn toàn bỏ lỡ giao lộ. Thật thú vị, nó sử dụng gIntersects. Cắt ngắn đẹp nếu bạn muốn các thuộc tính tham gia.
Jeffrey Evans

23

Đây là một cách tiếp cận thay thế bằng cách sử dụng sfgói mới , có nghĩa là để thay thế sp. Mọi thứ sạch sẽ hơn, và thân thiện với đường ống:

library(sf)
library(tidyverse)

# example data from raster package
soil <- st_read(system.file("external/lux.shp", package="raster")) %>% 
  # add in some fake soil type data
  mutate(soil = LETTERS[c(1:6,1:6)]) %>% 
  select(soil)

# field polygons
field <- c("POLYGON((6 49.75,6 50,6.4 50,6.4 49.75,6 49.75))",
        "POLYGON((5.8 49.5,5.8 49.7,6.2 49.7,6.2 49.5,5.8 49.5))") %>% 
  st_as_sfc(crs = st_crs(soil)) %>% 
  st_sf(field = c('x','y'), geoms = ., stringsAsFactors = FALSE)

# intersect - note that sf is intelligent with attribute data!
pi <- st_intersection(soil, field)
plot(soil$geometry, axes = TRUE)
plot(field$geoms, add = TRUE)
plot(pi$geometry, add = TRUE, col = 'red')

# add in areas in m2
attArea <- pi %>% 
  mutate(area = st_area(.) %>% as.numeric())

# for each field, get area per soil type
attArea %>% 
  as_tibble() %>% 
  group_by(field, soil) %>% 
  summarize(area = sum(area))

nhập mô tả hình ảnh ở đây

   field  soil      area
   <chr> <chr>     <dbl>
1      x     A  24572264
2      x     B 209573036
3      x     C   5714943
4      x     D  76200409
5      x     E  31015469
6      x     F 234120314
7      y     B   2973232
8      y     C 175275520
9      y     D 188656204
10     y     E 153822938
11     y     F  11826698
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.