สร้างรูปหลายเหลี่ยมเชิงพื้นที่ทันทีโดยไม่ต้องใช้ shapefile ใน R


22

ดังนั้นวิธีปกติที่เราอ่าน shapefile ใน R คือผ่านแพ็คเกจ maptools เช่นนี้

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

อย่างไรก็ตามฉันมีกรณีการใช้งานโดยที่ฉันไม่มี shapefile.shp แต่ฉันมีชุดของรูปหลายเหลี่ยมพิกัด

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

และการฉายที่สอดคล้องกัน

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

ฉันจะ "สร้างอินสแตนซ์" sfdata (ซึ่งจะเป็น "รูปหลายเหลี่ยมวัตถุ") โดยตรงจากข้อมูลนี้ได้อย่างไร (โดยไม่ต้องไปในทางอ้อมของการสร้าง Shapefile ด้วยข้อมูลเหล่านี้แล้วอ่านจาก Shapefile ที่สร้างขึ้นใหม่)

คำตอบ:


35

ก่อนอื่นรับพิกัดเป็นเมทริกซ์ 2 คอลัมน์:

> 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

จากนั้นสร้างรูปหลายเหลี่ยมตัดที่เป็นวัตถุรูปหลายเหลี่ยมแล้วห่อที่เป็นวัตถุ SpatialPolygons:

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

เหตุผลของความซับซ้อนในระดับนี้คือรูปหลายเหลี่ยมเป็นวงแหวนที่เรียบง่ายวัตถุรูปหลายเหลี่ยมสามารถเป็นหลายวงที่มี ID (ที่นี่ตั้งไว้ที่ 1) (เช่นเดียวกับฟีเจอร์เดียวใน GIS) และ SpatialPolygons สามารถมี CRS . โอ้ฉันควรจะตั้งมัน:

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

ถ้าคุณต้องการเปลี่ยนให้เป็น SpatialPolygonsDataFrame (ซึ่งเป็นสิ่งที่มาจาก readShapeSpatial ของเราเมื่อ shapefile เป็นรูปหลายเหลี่ยม) ให้ทำดังนี้

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

ให้สิ่งนี้:

> 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 ดีมากการจัดแสดงที่ชัดเจน มันดีมากที่ได้เห็นโค้ดที่ถูกทำลายโดยคำอธิบายมากกว่าที่จะถูกเสนอให้เป็นบล็อกเสาหิน!
whuber

ยอดเยี่ยม ... เยี่ยมมากที่ได้เห็นว่าวัตถุเหล่านี้รวมเข้าด้วยกันได้อย่างไร! จำเป็นต้องดูหน้าความช่วยเหลือ R เพิ่มเติมที่เขียนอย่างชัดเจนเช่นนี้
Simbamangu

มันเป็นสิ่งที่ฉันต้องสอนตัวเองใหม่ทุกครั้งที่ฉันต้องการทำมันดังนั้นฉันจึงมีโอกาสที่จะสอนคนอื่น!
Spacedman

1
ยอดเยี่ยม ... ฉันจะไปเพิ่มรูปหลายเหลี่ยม id (f) ที่ไม่ซ้ำกันในกรอบข้อมูลได้อย่างไร
MGA

2
เพื่อให้คำตอบนี้มีความถูกต้องมากขึ้นคุณสามารถแสดงวิธีการในกรณีที่มีรูปหลายเหลี่ยมหลายรูปได้หรือไม่ นี่เป็นเรื่องยุ่งยากเล็กน้อย
โทมัส

2

เพื่อให้ได้คำตอบที่ยอดเยี่ยมของ Spacedman สำหรับกรณีที่ข้อมูลของคุณจะมีหลายรูปหลายเหลี่ยมนี่คือรหัสบางส่วนที่ใช้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)

เพื่อความสนุกคุณสามารถเปรียบเทียบกับพล็อตที่ได้จากการggplot2ใช้ data-frame เริ่มต้น:

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

โปรดทราบว่ารหัสข้างต้นถือว่าคุณมีโพลีโน่เดียวต่อ id เท่านั้น หากรหัสบางตัวมี disjoint polygons ฉันคิดว่าควรเพิ่มคอลัมน์อื่นในชุดข้อมูลก่อนgroup_bysub-id จากนั้นใช้group_by(upper-id)แทนrowwise

รหัสเดียวกันโดยใช้purrr::mapฟังก์ชั่น:

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