Khởi tạo đa giác không gian mà không sử dụng shapefile trong R


22

Vì vậy, cách thông thường chúng ta đọc một shapefile trong R là thông qua gói maptools, như thế này:

sfdata <- readShapeSpatial("/path/to/my/shapefile.shp", proj4string=CRS("+proj=longlat"))

Tuy nhiên, tôi có một trường hợp sử dụng theo đó tôi không có shapefile.shp mà thay vào đó tôi có một loạt các tọa độ đa giác

16.484375 59.736328125,17.4951171875 55.1220703125,24.74609375 55.0341796875,22.5927734375 61.142578125,16.484375 59.736328125

và hình chiếu tương ứng của nó

coord. ref. : +proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0 

Làm cách nào để tôi "khởi tạo" sfdata (sẽ là "đối tượng đa giác") trực tiếp từ dữ liệu này? (không đi theo đường vòng để tạo một shapefile với các dữ liệu này và sau đó đọc từ shapefile mới được tạo)

Câu trả lời:


35

Đầu tiên lấy tọa độ thành ma trận 2 cột:

> xym
         [,1]     [,2]
[1,] 16.48438 59.73633
[2,] 17.49512 55.12207
[3,] 24.74609 55.03418
[4,] 22.59277 61.14258
[5,] 16.48438 59.73633

Sau đó tạo một Đa giác, bọc nó vào một đối tượng Đa giác, sau đó bọc nó thành một đối tượng SpatialPolygons:

> library(sp)
> p = Polygon(xym)
> ps = Polygons(list(p),1)
> sps = SpatialPolygons(list(ps))

Lý do cho mức độ phức tạp này là vì Đa giác là một vòng đơn giản, đối tượng Đa giác có thể là một số vòng có ID (ở đây được đặt thành 1) (giống như một tính năng duy nhất trong GIS) và SpatialPolygons có thể có CRS . Ồ, có lẽ tôi nên đặt nó:

> proj4string(sps) = CRS("+proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0")

Nếu bạn muốn biến nó thành SpatialPolygonsDataFrame (đó là những gì xuất hiện của readShapeSpatial khi shapefile là đa giác) thì hãy làm:

> data = data.frame(f=99.9)
> spdf = SpatialPolygonsDataFrame(sps,data)
> spdf

đưa ra điều này:

> summary(spdf)
Object of class SpatialPolygonsDataFrame
Coordinates:
       min      max
x 16.48438 24.74609
y 55.03418 61.14258
Is projected: FALSE 
proj4string :
[+proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0]
Data attributes:
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
   99.9    99.9    99.9    99.9    99.9    99.9 

+1 Rất đẹp, giải thích rõ ràng. Thật tuyệt khi thấy mã được chia nhỏ bằng các giải thích thay vì được cung cấp dưới dạng một khối nguyên khối!
whuber

Tuyệt vời ... thật tuyệt khi thấy những vật thể này được ghép lại với nhau như thế nào! Cần xem thêm các trang trợ giúp R ​​được viết rõ ràng như thế này.
Simbamangu

Đó là điều tôi phải tự dạy lại mỗi lần tôi muốn làm điều đó, vì vậy tôi tận dụng mọi cơ hội để dạy người khác!
Spacesman

1
tuyệt vời ... làm thế nào tôi có thể thêm nhiều đa giác id (f) duy nhất vào khung dữ liệu?
mga

2
Để câu trả lời này có giá trị chung hơn, bạn có thể chỉ ra cách thực hiện trong trường hợp có nhiều đa giác? Đây là một chút khó khăn.
Tomas

2

Để hoàn thành câu trả lời xuất sắc của Spacesman cho trường hợp dữ liệu của bạn sẽ chứa nhiều đa giác, đây là một số mã sử dụng dplyr:

library(dplyr)
library(ggplot2)
library(sp)
## use data from ggplot2:::geom_polygon example:
positions <- data.frame(id = rep(factor(c("1.1", "2.1", "1.2", "2.2", "1.3", "2.3")), each = 4),
                    x = c(2, 1, 1.1, 2.2, 1, 0, 0.3, 1.1, 2.2, 1.1, 1.2, 2.5, 1.1, 0.3,
                          0.5, 1.2, 2.5, 1.2, 1.3, 2.7, 1.2, 0.5, 0.6, 1.3),
                    y = c(-0.5, 0, 1, 0.5, 0, 0.5, 1.5, 1, 0.5, 1, 2.1, 1.7, 1, 1.5,
                          2.2, 2.1, 1.7, 2.1, 3.2, 2.8, 2.1, 2.2, 3.3, 3.2)) %>% as.tbl


df_to_spp <- positions %>%
  group_by(id) %>%
  do(poly=select(., x, y) %>%Polygon()) %>%
  rowwise() %>%
  do(polys=Polygons(list(.$poly),.$id)) %>%
  {SpatialPolygons(.$polys)}

## plot it
plot(df_to_spp)

Để giải trí, bạn có thể so sánh với âm mưu thu được bằng ggplot2cách sử dụng khung dữ liệu ban đầu:

ggplot(positions) + 
  geom_polygon(aes(x=x, y=y, group=id), colour="black", fill=NA)

Lưu ý rằng mã ở trên giả định rằng bạn chỉ có một polyogn cho mỗi id. Nếu một số id có các đa giác rời rạc, tôi đoán người ta nên thêm một cột khác trong tập dữ liệu, đầu tiên group_bylà id phụ, sau đó sử dụng group_by(upper-id)thay vìrowwise

Cùng mã sử dụng purrr::maphàm:

df_to_spp <- positions %>%
  nest(-id) %>%
  mutate(Poly=purrr::map(data, ~select(., x, y)  %>% Polygon()),
         polys=map2(Poly, id, ~Polygons(list(.x),.y))) %>%
  {SpatialPolygons(.$polys)}
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.