Search code examples
rgispolygonraster

Alternative for R package concaveman to create polygons


I have a script using the R package 'concaveman', but due to issues on the ubuntu platform that I need to run the code on I cannot install this package (it has taken me three days trying to solve it). So I am looking for an alternative.

I have a random set of points ranging from 3 to 1000s of points. I want to draw a convex hull/polygon around the outer most points (step after would be to rasterize). I have been trying to do it by converting the points to a raster, then use rastertopolygons, but in rare occasions points would be in the same raster cell resulting in only two unique points. Convaveman would make this into a linear polygon (which is what I want, without using concaveman). Here is the input data that would be problematic:

x <- structure(list(x = c(166.867, 166.867, 167.117, 166.8667), y = c(-20.6333, 
-20.633, -20.833, -20.6333)), row.names = c(NA, -4L), class = c("tbl_df", 
"tbl", "data.frame"))

This is what I tried not (with the error I get):

SP_pt       <- SpatialPoints(x, proj4string=crs("+proj=longlat +ellps=WGS84 `+towgs84=0,0,0,0,0,0,0 +no_defs"))`
gridded(SP_pt) <- T
SP_pt_R     <- raster(SP_pt)
SP_poly     <- rasterToPolygons(SP_pt_R, dissolve = T)

suggested tolerance minimum: 0.333333 
Error in points2grid(points, tolerance, round) : 
  dimension 1 : coordinate intervals are not constant

Solution

  • You can use chull in base R:

    sp::Polygon(x[c(chull(x), chull(x)[1]), ])
    #> An object of class "Polygon"
    #> Slot "labpt":
    #> [1] 166.95023 -20.69977
    #> 
    #> Slot "area":
    #> [1] 6.75e-05
    #> 
    #> Slot "hole":
    #> [1] FALSE
    #> 
    #> Slot "ringDir":
    #> [1] 1
    #> 
    #> Slot "coords":
    #>             x        y
    #> [1,] 167.1170 -20.8330
    #> [2,] 166.8667 -20.6333
    #> [3,] 166.8670 -20.6330
    #> [4,] 167.1170 -20.8330
    
    

    Or if you want to use the sf package:

    sf::st_polygon(list(as.matrix(x[c(chull(x), chull(x)[1]),])))
    #> POLYGON ((167.117 -20.833, 166.8667 -20.6333, 166.867 -20.633, 167.117 -20.833))