@@ -450,6 +450,7 @@ st_minimum_rotated_rectangle.sf = function(x, dTolerance, ...) {
450450# ' @name geos_unary
451451# ' @export
452452# ' @param envelope object of class \code{sfc} or \code{sfg} containing a \code{POLYGON} with the envelope for a voronoi diagram; this only takes effect when it is larger than the default envelope, chosen when \code{envelope} is an empty polygon
453+ # ' @param point_order logical; preserve point order if TRUE and GEOS version >= 3.12; overrides bOnlyEdges
453454# ' @details \code{st_voronoi} creates voronoi tesselation. \code{st_voronoi} requires GEOS version 3.5 or above
454455# ' @examples
455456# ' set.seed(1)
@@ -470,33 +471,48 @@ st_minimum_rotated_rectangle.sf = function(x, dTolerance, ...) {
470471# ' # compute Voronoi polygons:
471472# ' pols = st_collection_extract(st_voronoi(do.call(c, st_geometry(pts))))
472473# ' # match them to points:
473- # ' pts$pols = pols[unlist(st_intersects(pts, pols))]
474+ # ' pts_pol = st_intersects(pts, pols)
475+ # ' pts$pols = pols[unlist(pts_pol)] # re-order
476+ # ' if (isTRUE(try(compareVersion(sf_extSoftVersion()["GEOS"], "3.12.0") > -1,
477+ # ' silent = TRUE))) {
478+ # ' pols_po = st_collection_extract(st_voronoi(do.call(c, st_geometry(pts)),
479+ # ' point_order = TRUE)) # GEOS >= 3.12 can preserve order of inputs
480+ # ' pts_pol_po = st_intersects(pts, pols_po)
481+ # ' print(all(unlist(pts_pol_po) == 1:(n/2)))
482+ # ' }
474483# ' plot(pts["id"], pch = 16) # ID is color
475484# ' plot(st_set_geometry(pts, "pols")["id"], xlim = c(0,1), ylim = c(0,1), reset = FALSE)
476485# ' plot(st_geometry(pts), add = TRUE)
477486# ' layout(matrix(1)) # reset plot layout
478487# ' }
479- st_voronoi = function (x , envelope , dTolerance = 0.0 , bOnlyEdges = FALSE )
488+ st_voronoi = function (x , envelope , dTolerance = 0.0 , bOnlyEdges = FALSE , point_order = FALSE )
480489 UseMethod(" st_voronoi" )
481490
482491# ' @export
483- st_voronoi.sfg = function (x , envelope = st_polygon(), dTolerance = 0.0 , bOnlyEdges = FALSE )
484- get_first_sfg(st_voronoi(st_sfc(x ), st_sfc(envelope ), dTolerance , bOnlyEdges = bOnlyEdges ))
492+ st_voronoi.sfg = function (x , envelope = st_polygon(), dTolerance = 0.0 , bOnlyEdges = FALSE , point_order = FALSE )
493+ get_first_sfg(st_voronoi(st_sfc(x ), st_sfc(envelope ), dTolerance , bOnlyEdges = bOnlyEdges , point_order = point_order ))
485494
486495# ' @export
487- st_voronoi.sfc = function (x , envelope = st_polygon(), dTolerance = 0.0 , bOnlyEdges = FALSE ) {
496+ st_voronoi.sfc = function (x , envelope = st_polygon(), dTolerance = 0.0 , bOnlyEdges = FALSE , point_order = FALSE ) {
488497 if (compareVersion(CPL_geos_version(), " 3.5.0" ) > - 1 ) {
489498 if (isTRUE(st_is_longlat(x )))
490499 warning(" st_voronoi does not correctly triangulate longitude/latitude data" )
500+ if (compareVersion(CPL_geos_version(), " 3.12.0" ) > - 1 ) {
501+ bOnlyEdges = as.integer(bOnlyEdges )
502+ if (point_order ) bOnlyEdges = 2L # GEOS enum GEOS_VORONOI_PRESERVE_ORDER
503+ } else {
504+ if (point_order )
505+ warning(" Point order retention not supported for GEOS " , CPL_geos_version())
506+ }
491507 st_sfc(CPL_geos_voronoi(x , st_sfc(envelope ), dTolerance = dTolerance ,
492508 bOnlyEdges = as.integer(bOnlyEdges )))
493509 } else
494510 stop(" for voronoi, GEOS version 3.5.0 or higher is required" )
495511}
496512
497513# ' @export
498- st_voronoi.sf = function (x , envelope = st_polygon(), dTolerance = 0.0 , bOnlyEdges = FALSE ) {
499- st_set_geometry(x , st_voronoi(st_geometry(x ), st_sfc(envelope ), dTolerance , bOnlyEdges ))
514+ st_voronoi.sf = function (x , envelope = st_polygon(), dTolerance = 0.0 , bOnlyEdges = FALSE , point_order = FALSE ) {
515+ st_set_geometry(x , st_voronoi(st_geometry(x ), st_sfc(envelope ), dTolerance , bOnlyEdges = bOnlyEdges , point_order = point_order ))
500516}
501517
502518# ' @name geos_unary
0 commit comments