Voronoi图多边形包含在地理边界内

时间:2014-06-16 04:31:40

标签: r maps polygons voronoi spatstat

我正在尝试在固定的地理区域内为一组点创建Voronoi多边形(也称为Dirichlet曲面细分或Thiessen多边形)。但是,我在R中找到一个方法会遇到地图边界内的多边形。我的主要目标是获得准确的面积计算(不仅仅是生成视觉图)。例如,以下内容直观地传达了我想要实现的目标:

library(maps)
library(deldir)
data(countyMapEnv)
counties <- map('county', c('maryland,carroll','maryland,frederick', 'maryland,montgomery', 'maryland,howard'), interior=FALSE)
x <- c(-77.208703, -77.456582, -77.090600,  -77.035668, -77.197144)
y <- c(39.188603, 39.347019, 39.672818, 39.501898, 39.389203)
points(x,y)
vt <- deldir(x, y, rw=counties$range)
plot(vt, wlines="tess", lty="solid", add=TRUE)

产生以下内容:

Voronoi polygons for the 5 locations

从概念上讲,我希望将countiesvt相交,这应该提供一组由县边界限定的多边形,并为每个多边形进行准确的面积计算。现在,vt$summary为每个多边形提供了面积计算,但除了一个内部多边形外,它们显然被夸大了,deldir()似乎只接受其rw参数的矩形包围。我是R的地理位置能力的新手,所以我对其他方法持开放态度。

2 个答案:

答案 0 :(得分:11)

您应该可以使用spatstat函数dirichlet来实现此目的。

第一项任务是将县转换为类owin的spatstat观察窗口(代码部分基于@jbaums的答案):

library(maps)
library(maptools)
library(spatstat)
library(rgeos)

counties <- map('county', c('maryland,carroll', 'maryland,frederick', 
                            'maryland,montgomery', 'maryland,howard'), 
                fill=TRUE, plot=FALSE)
# fill=TRUE is necessary for converting this map object to SpatialPolygons
countries <- gUnaryUnion(map2SpatialPolygons(counties, IDs=counties$names,
                                 proj4string=CRS("+proj=longlat +datum=WGS84")))
W <- as(countries, "owin")

然后你只需要将{5}点放在ppp格式中,制作Dirichlet tesslation并制作区域:

X <- ppp(x=c(-77.208703, -77.456582, -77.090600,  -77.035668, -77.197144),
         y=c(39.188603, 39.347019, 39.672818, 39.501898, 39.389203), window = W)

y <- dirichlet(X) # Dirichlet tesselation
plot(y) # Plot tesselation
plot(X, add = TRUE) # Add points
tile.areas(y) #Areas

答案 1 :(得分:9)

一旦我们同时拥有Voronoi多边形和countiesSpatialPolygons个对象,我们就可以在gIntersection的帮助下实现这一目标。

首先,让我们加载一些必要的库并准备好您的数据。

library(maptools)
library(rgeos)

counties <- map('county', c('maryland,carroll', 'maryland,frederick', 
                            'maryland,montgomery', 'maryland,howard'), 
                fill=TRUE, plot=FALSE)
# fill=TRUE is necessary for converting this map object to SpatialPolygons

p <- data.frame(x=c(-77.208703, -77.456582, -77.090600,  -77.035668, -77.197144),
                y=c(39.188603, 39.347019, 39.672818, 39.501898, 39.389203))

现在,我们可以将counties map对象转换为SpatialPolygons map2SpatialPolygons来自maptools包。我将它包裹在rgeos::gUnaryUnion中,将四个多边形组合成一个多边形(否则我们会在轨道上绘制内部边界)。我还添加了相关的预测。

counties.sp <- gUnaryUnion(
  map2SpatialPolygons(counties, IDs=counties$names,
                      proj4string=CRS("+proj=longlat +datum=WGS84")))

为了将deldir对象转换为SpatialPolygons对象,有一个很好的功能,我提到了here(帽子提示到Carson Farmer)和哪个@Spacedman随后修改(剪辑到一定范围)并发布here

voronoipolygons <- function(x, poly) {
  require(deldir)
  if (.hasSlot(x, 'coords')) {
    crds <- x@coords  
  } else crds <- x
  bb = bbox(poly)
  rw = as.numeric(t(bbox(poly)))
  z <- deldir(crds[,1], crds[,2],rw=rw)
  w <- tile.list(z)
  polys <- vector(mode='list', length=length(w))
  require(sp)
  for (i in seq(along=polys)) {
    pcrds <- cbind(w[[i]]$x, w[[i]]$y)
    pcrds <- rbind(pcrds, pcrds[1,])
    polys[[i]] <- Polygons(list(Polygon(pcrds)), ID=as.character(i))
  }
  SP <- SpatialPolygons(polys)

  SpatialPolygonsDataFrame(
    SP, data.frame(x=crds[,1], y=crds[,2], 
                   row.names=sapply(slot(SP, 'polygons'), 
                                    function(x) slot(x, 'ID'))))  
}

现在我们可以继续使用它来创建我们的Voronoi SpatialPolygons

v <- voronoipolygons(p, counties.sp)
proj4string(v) <- proj4string(counties.sp)

现在剩下要做的就是两个几何形状相交 - rgeos的面包和黄油:

final <- gIntersection(counties.sp, v, byid=TRUE)

plot(final)
points(p, pch=20)

enter image description here