แยกพื้นที่สี่แยกใน R


19

ฉันมีรูปหลายเหลี่ยมสองอัน หนึ่งประกอบด้วยเขตข้อมูล (X, Y, Z) และอื่น ๆ ประกอบด้วยชนิดของดิน (A, B, C, D) ฉันต้องการที่จะรู้ว่าสิ่งที่พื้นที่ของทุกเขตข้อมูลมีชนิดของดิน ฉันพยายามต่อไปนี้:

ป้อนคำอธิบายรูปภาพที่นี่

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

และได้ผลลัพธ์ที่ดีโดยบอกว่าสนามใดมีดินประเภทใด อย่างไรก็ตามฉันจะหาพื้นที่แทนได้อย่างไร


1
หมายเหตุ st_intersection จะไม่ทำงานหากคะแนนของคุณเป็นละติจูดและลองจิจูด คุณไม่ได้ระบุว่าคุณมีพิกัดทางภูมิศาสตร์แม้ว่าจะมีคำใบ้ไว้เมื่อพูดถึงชนิดของดิน
ฟูริเย

คำตอบ:


24

วิธีนี้ใช้intersect()ฟังก์ชั่นจากrasterแพคเกจ ข้อมูลตัวอย่างที่ฉันใช้ไม่เหมาะ (สำหรับสิ่งหนึ่งที่พวกเขาอยู่ในพิกัดที่ไม่มีโครงการ) แต่ฉันคิดว่ามันทำให้เกิดความคิด

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

ผล:

    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
เพื่อชี้แจง: ฉันชอบraster::intersectมากกว่าrgeos::gIntersectionเพราะอดีตเข้าร่วมข้อมูลคุณลักษณะจากSpatialPolgonsDataFrameวัตถุสองในขณะที่หลังดูเหมือนจะลดลงข้อมูลคุณลักษณะ
แมตต์เอสเอ็ม

ขอบคุณสำหรับรายละเอียดมากมายและคำตอบที่ถูกต้อง คุณช่วยฉันมาก !!!
user2386786

4
หากคุณใช้ byid = TRUE ใน "gIntersection" จะส่งคืน IDS ของแอตทริบิวต์ซึ่งสามารถใช้กับการผสานเพื่อเชื่อมโยงแอตทริบิวต์ ฟังก์ชั่นต่าง ๆ และควรสังเกตอย่างไร ฟังก์ชัน "intersect" ใช้ขอบเขตการเหลื่อมกันในขณะที่ "gIntersection" เป็นจุดตัดที่ชัดเจนของ geometries เวกเตอร์ วิธีการตัดกันเป็นสี่แยกสี่เหลี่ยม / สี่เหลี่ยมและไม่ใช่จุดตัดของรูปหลายเหลี่ยมจริง ขอบเขตสามารถถูกกำหนดใหม่โดยใช้ขอบเขตและ bbox มีข้อดีทั้งสองวิธี
Jeffrey Evans

1
@JeffreyEvans จุดที่ดีอีกครั้งgIntersection; อย่างไรก็ตาม ID ฟีเจอร์การป้อนข้อมูลไม่ได้จัดเตรียมไว้โดยตรงพวกเขาจะต่อกันและเก็บไว้ในฟีเจอร์ ID ของเอาต์พุต นี่หมายถึงขั้นตอนพิเศษในการแยกวิเคราะห์ ID จากนั้นเข้าร่วมในแอตทริบิวต์ ฉันต้องการraster::intersectรวมรหัสอินพุตเหล่านี้เป็นแอตทริบิวต์เพิ่มเติมในผลลัพธ์
Matt SM

1
ขอบคุณที่ชี้ให้เห็นว่าฉันพลาด intersect_sp ทั้งหมด ที่น่าสนใจคือใช้ gIntersects ทางลัดดีถ้าคุณต้องการให้แอตทริบิวต์เข้าร่วม
Jeffrey Evans

23

นี่คือวิธีการสลับใช้ใหม่แพคเกจซึ่งจะหมายถึงการเปลี่ยนsf spทุกอย่างสะอาดและเป็นมิตรกับท่อ:

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

ป้อนคำอธิบายรูปภาพที่นี่

   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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.