**Update (01-15-2018)
There have been numerous changes to the resulting objects produced by the alphahull package. As such, I needed to rewrite the function. I added a convexHull function to the spatialEco package. However, due to licensing restrictions in the alphahull package this function is only available in the development version on GitHub. The development version can be installed using:
######################################################################################
# PROGRAM: ConvexHull
# USE: CREATE CONVEX HULL USING THE Pateiro-Lopez ALPHAHULL MODEL
# REQUIRES: sp, alphahull, maptools
#
# ARGUMENTS:
# x sp Points CLASS OBJECT
# alpha CONVEX HULL ALPHA VALUE (SEE ?alphahull)
# increment DEFAULT 360
# rnd DEFAULT 2
#
# VALUE:
# A sp SpatialPolygonsDataFrame OBJECT
#
# NOTES:
# THIS METHOD PROVIDES FLEXIBILITY OVER TRADITIONAL CONVEX FUNCTIONS. YOU CAN
# ADJUST THE ALPHA PARAMETER TO RELAX OR INCREASE TENSION BETWEEN EDGE-BOUNDARY
# POINTS TO CREATE MORE OF AN EXACT FIT OF THE ENVELOPE library(SEE EXAMPLEdevtools).
#
# REFERENCES:
# Pateiro-López & Rodríguez-Casal install_github(2009"jeffreyevans/spatialEco") Generalizing the Convex Hull of a Sample:
# The R Package alphahull. Journal of Statistical Software 34
Here is an example of the functions usage
library(5sp):1-28
# http://www.jstatsoft.org/v34/i05/paper
#
# EXAMPLES:
# requirelibrary(spspatialEco)
# data(meuse)
# coordinates(meuse) = ~x+y
# a <- ConvexHullconvexHull(meuse, alpha=100000)
# plot(a)
# points(meuse, pch=19)
# # TEST MULTIPLE alpha VALUES
# a=c(1000, 100000)
# par(mfcol=c
Convert the resulting SpatialLinesDataFrame to SpatialPolygonsDataFrame
library(1,2)sf)
# for (alpha in a) {
# ch <- ConvexHull(meuse, alpha=alpha)
# plot(ch)
# points(meuse, pch=19)
# }
#
# CONTACTsf:
# Jeffrey S. Evans
# Senior Landscape Ecologist
# The Nature Conservancy
# Central Science/DbyD
# Affiliate Assistant Professor
# Environment and Natural Resources
# University of Wyoming
# Laramie, WY 82070
# [email protected]
# (970) 672-6766
######################################################################################
ConvexHull <- function(x, alpha=250000, increment=360, rnd=2) {
if (!require (sp)) stop("sp PACKAGE MISSING")
if (!require (alphahull)) stop("sp PACKAGE MISSING")
if (!require(maptools)) stop("maptools PACKAGE MISSING")
if (!inherits(x, "SpatialPointsDataFrame") | !inherits(x, "SpatialPoints") )
stop(deparse(substitute(x)), " MUST BE A sp Points OBJECT")
x.coords <- coordinates(x)
ahull2sp <- function(x, increment=360, rnd=10, proj4string=CRS(as.character(NA))){
if (class(x) != "ahull")
stop("x needs to be an ahull class object")
xdf <- as.data.frame(x$arcs)
xdf <- subset(xdf,xdf$r > 0)
res <- NULL
if (nrow(xdf) > 0){
linesj <- list()
prevx<-NULL
prevy<-NULL
j<-1
for(i in 1:nrow(xdf)){
rowi <- xdf[i,]
v <- c(rowi$v.x, rowi$v.y)
theta <- rowi$theta
r <- rowi$r
cc <- c(rowi$c1, rowi$c2)
ipoints <- 2 + round(increment * (rowi$theta / 2),0)
angles <- anglesArc(v, theta)
seqang <- seqst_as_sf(angles[1], angles[2], length = ipointsa)
x <- round(cc[1] + r * cos(seqang),rnd)
ya <- round(cc[2] + r * sin(seqang),rnd)
if (is.null(prevx)){
prevx<-x
prevy<-y
} else if (x[1] == round(prevx[length(prevx)],rnd) && y[1] == round(prevy[length(prevy)],rnd)){
if (i == nrow(xdf)){
prevx<-append(prevx,x[2sf:ipoints])
prevy<-append(prevy,y[2:ipoints])
prevx[length(prevx)]<-prevx[1]
prevy[length(prevy)]<-prevy[1]
coordsj<-cbind(prevx,prevy)
colnamesst_polygonize(coordsja)<-NULL
linej <- Lineclass(coordsj)
linesj[[j]]a <- Lines(linej, ID = as.character(j))
} else {
prevx<-append(prevx,x[2:ipoints])
prevy<-append(prevy,y[2:ipoints])
}
} else {
prevx[length(prevx)]<-prevx[1]
prevy[length(prevy)]<-prevy[1]
coordsj<-cbind(prevxa,prevy)
colnames(coordsj"Spatial")<-NULL
linej <- Line(coordsj)
linesj[[j]] <- Lines(linej, ID = as.characterplot(j)a)
j<-j+1
prevx<-NULL
prevy<-NULL
}
}
lspl <- SpatialLines
Test multiple alpha values
par(linesj)
lns <- slotmfcol=c(lspl2, "lines"2)
polys <- sapply(lns, function(x) {
crds <-for slot(slot(x, "Lines")[[1]], "coords")
a in identicalc(crds[1500, ]1500, crds[nrow(crds)5000, ])
}100000)
polyssl <- lspl[polys]
list_of_Lines <- slot(polyssl, "lines")
sppolys <- SpatialPolygons(list(Polygons(lapply(list_of_Lines, function(x) {
Polygon(slot(slot(x, "Lines")[[1]], "coords")) }), ID = "1")), proj4string=proj4string)
hidch <- sapply(slotconvexHull(sppolys, "polygons")meuse, function(x)alpha slot(x,= "ID")a)
areas <- sapply(slot(sppolys, "polygons"), function(x) slotplot(x, "area")ch)
df <- data.framepoints(hidmeuse,areas)
names(df) <- c("HID","Area"pch=19)
rownamestitle(df) <- df$HID
res <- SpatialPolygonsDataFramepaste0(sppolys"alpha=", data=df)
res <- res[which(res@data$Area > 0a),]
}
return(res)
}
a <- ahull(x.coords, alpha=alpha)
return(ahull2sp(a, rnd=rnd))
}