我有一个alphahull::ashape()
结果,我需要使用spatstat::owin()
转换后续空间分析。有一个优雅的解决方案如何从凹形船体订购点并将形状转换为owin
对象或任何Spatial*
对象?对于假设矩阵coords
中的有序点,多边形定义为:
geo.owin=try(owin(poly=list(x=coords[,1],y=coords[,2])),silent=T)
if(class(geo.owin)=="try-error") geo.owin=owin(poly=list(x=rev(coords[,1]),y=rev(coords[,2])))
这是不可能的。 ashape()$edges
矩阵包含可以绘制为看起来像多边形的点的坐标,并且此处提供矩阵。但是,这些点没有按照不同的绘图颜色和箭头方向进行排序。
# data
okraj = matrix(c(23.8808, 18.0106, 23.8808, 1.8265, 1.8266, 1.8265, 18.0106, 39.5352, 39.5352, 39.5352, 13.5519, 27.9675, 3.8102, 4.8269, 8.8236, 52.7248, 45.3385, 52.7248, 50.9600, 50.9600, 50.9600, 45.3385, 39.9042, 39.9042, 39.9042, 49.1204, 41.8421, 47.1450, 44.9423, 46.0246, 13.5519, 27.9675, 32.1116, 1.8266, 4.5644, 3.8102, 17.5557, 39.5840, 32.1116, 29.2158, 4.5644, 29.2158, 4.8269, 8.8236, 17.5557, 49.1204, 41.8421, 41.3710, 50.9600, 49.8638, 47.1450, 45.5063, 39.8987, 41.3710, 40.0750, 49.8638), ncol=4, dimnames=list(NULL,c("x1","y1","x2","y2")))
# draw polygon from arrows
farby=colorRampPalette(c("lightblue","black"))(nrow(okraj))
plot(0,type="n",xlim=range(okraj[,c(1,3)]),ylim=range(okraj[,c(2,4)]),xlab="",ylab="")
for(i in 1:nrow(okraj)){
arrows(okraj[i,"x1"],okraj[i,"y1"],okraj[i,"x2"],okraj[i,"y2"],col=farby[i],length=.1,lwd=2)
}
通过其他问题搜索,返回ordered points,convex not concave shapes,C,python和Lua种语言解决方案的解决方案。我当前的代码搜索矩阵中的连接点,并在解释alpha形状边缘坐标时遇到的每个问题使用if()
条件(原谅天真编码)。
# function finding a row, which contains the connecting data
find.connection=function(bod, temp){
# test whether a connection exists in the first set of point coordinates
riadok1=ifelse(length(which(temp[,1]==bod[1]))==0,NA,which(temp[,1]==bod[1]))
riadok2=ifelse(length(which(temp[,2]==bod[2]))==0,NA,which(temp[,2]==bod[2]))
# test for a connection in the second set of coordinates
if(is.na(riadok1)){
riadok1=ifelse(length(which(temp[,3]==bod[1]))==0,NA,which(temp[,3]==bod[1]))
riadok2=ifelse(length(which(temp[,4]==bod[2]))==0,NA,which(temp[,4]==bod[2]))
}
# check multiple values in x or y coordinates and select a row where both occur
if(riadok1==riadok2){
riadok=riadok1
} else {
riadky1=ifelse(length(which(temp[,3]==bod[1]))==0,NA,which(temp[,3]==bod[1]))
riadky2=ifelse(length(which(temp[,4]==bod[2]))==0,NA,which(temp[,4]==bod[2]))
riadok=intersect(riadky1,riadky2)
}
return(riadok)
}
# setting up the variable with ordered points
coords=c(okraj[1,c("x2","y2")])
coords=rbind(coords,c(okraj[1,c("x1","y1")]))
# current working point and a matrix subset, in which to search for a connection
bod=okraj[1,1:2]
temp=okraj[-1,]
# consecutively search for connecting points
for(j in 1:nrow(okraj)){
if(any(is.na(match(bod,temp)))){
message(paste("Problem with: ", bod,", row: ",j ))
next
}
bod2=NA # next ordered point
smer=0 # controls the set of coordinates to use for a connection
for(x in 1:2){
riadok=find.connection(bod=bod,temp=temp)
# my solution to the current crash point can be implemented here
if(is.na(riadok)) bod2=NA
# select correct value for the connecting point from the two sets of coordinates
else bod2=temp[riadok,c(x+smer,x+smer+1)]
if(all(bod==bod2)) bod2=temp[riadok,c(x+2,x+3)]
if(any(is.na(bod2))){
smer=1
next
} else { break }
}
# store the connecting point and move to the next
coords=rbind(coords,bod2)
bod=bod2
# caveats for the last row in the matrix
if(!is.null(dim(temp))) temp = temp[-riadok,]
if(is.null(dim(temp))){
if(all(coords[1,]==coords[nrow(coords),])){
break
}
if(which(temp==bod[1])==1){
coords=rbind(coords,temp[3:4])
break
} else {
coords=rbind(coords,temp[1:2])
break
}
}
}
适用于某些数据集。这里,样本数据集包含一个端点okraj[8,3:4]
,它不连接到矩阵中的任何其他内容,代码崩溃。我的解决方案是跳过该行,然后再次尝试。
if(is.na(riadok)){
bod2=NA
temp=temp[-riadok,]
bod=coords[nrow(coords),]
next
}
但是,该解决方案需要删除一行数据,这是错误的。您对将alpha形状转换为映射对象的系统解决方案的帮助将非常感激。
关于removing holes from polygons的问题从@Spacedman使用rgeos
例程得到了答案。如何用这里的例子中的无序点来解决我的问题呢?