R'de bir shapefile kullanmadan uzaysal poligonu oluşturma


22

Böylece, R'de bir shapefile okuduğumuzun genel yolu, maptools paketi aracılığıyla şöyle olur:

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

Bununla birlikte, bir shapefile.shp dosyasının olmadığı bir kullanım durumum var, bunun yerine bir dizi çokgen koordinatım var

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

ve karşılık gelen projeksiyon

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

Sfdata'yı (bir "çokgen nesne" olacak) doğrudan bu verilerden nasıl başlatırım? (bu verilerle şekil dosyası oluşturma ve sonra yeni oluşturulan şekil dosyasından okuma yapma yolunda gitmeden)

Yanıtlar:


35

İlk önce koordinatları 2 sütunlu bir matrise alın:

> 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

Sonra bir Çokgen oluşturun, bunu Çokgenler nesnesine sarın, sonra onu bir SpatialPolygons nesnesine sarın:

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

Bu karmaşıklık seviyesinin nedeni bir Poligonun basit bir halka olması, bir Poligon nesnesi bir ID'ye sahip birkaç halka olabilir (burada 1'e ayarlanmıştır) (yani bir CBS'deki tek bir özellik gibidir) ve bir SpatialPolygons bir CRS'ye sahip olabilir. . Ooh, muhtemelen ayarlamalıyım:

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

SpatialPolygonsDataFrame'e dönüştürmek istiyorsanız (bu, shapefile çokgen olduğunda bizim readShapeSpatial'ımız olan şeydir):

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

bunu vererek:

> 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 Çok güzel, net bir açıklama. Kodun, monolitik bir blok olarak sunulmak yerine açıklamalardan ayrıldığını görmek harika!
whuber

Mükemmel ... bu nesnelerin nasıl bir araya getirildiğini görmek harika! Bunun gibi açıkça yazılmış R yardım sayfalarının daha fazlasını görmeniz gerekir.
Simbamangu

Bu, her yapmak istediğimde kendime yeniden öğretmem gereken bir şey, bu yüzden diğer insanlara öğretmek için herhangi bir fırsatı değerlendiriyorum!
Spacedman

1
mükemmel ... veri çerçevesine birden fazla benzersiz kimlik (f) çokgen eklemeye ne dersim?
mga

2
Bu cevabın daha genel bir geçerliliği olması için, çoklu poligon durumunda nasıl yapılacağını gösterebilir misiniz? Bu biraz zor.
Tomas

2

Spacedman'ın verilerinizin birden fazla çokgen içerdiği durum için mükemmel cevabını tamamlamak için işte bazı kodlar 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)

Sadece eğlence için, ggplot2ilk veri çerçevesini kullanarak elde edilen arsa ile karşılaştırabilirsiniz :

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

Yukarıdaki kodun, kimlik başına yalnızca bir polyognunuz olduğunu varsaydığını unutmayın. Bazı kimliklerin ayrık çokgenleri varsa, birinin veri kümesine, önce group_byalt kimliği daha sonra bir sütun eklemesi gerekir , sonra group_by(upper-id)yerine kullanması gerekir .rowwise

purrr::mapFonksiyonu kullanarak aynı kod :

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)}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.