diff --git a/DESCRIPTION b/DESCRIPTION index 9b4f9a5..23d4e5e 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -42,4 +42,4 @@ Collate: clockwise.R geod.R wkt.R -RoxygenNote: 6.1.0 +RoxygenNote: 6.1.1 diff --git a/NAMESPACE b/NAMESPACE index 4c50aa9..a80a349 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -31,6 +31,7 @@ S3method(st_transform_proj,sfg) export(lwgeom_extSoftVersion) export(st_asewkt) export(st_astext) +export(st_endpoint) export(st_force_polygon_cw) export(st_geod_area) export(st_geod_azimuth) diff --git a/R/RcppExports.R b/R/RcppExports.R index 6361bc5..4be1f58 100644 --- a/R/RcppExports.R +++ b/R/RcppExports.R @@ -85,6 +85,10 @@ CPL_startpoint <- function(sfc) { .Call('_lwgeom_CPL_startpoint', PACKAGE = 'lwgeom', sfc) } +CPL_endpoint <- function(sfc) { + .Call('_lwgeom_CPL_endpoint', PACKAGE = 'lwgeom', sfc) +} + CPL_sfc_to_wkt <- function(sfc, precision) { .Call('_lwgeom_CPL_sfc_to_wkt', PACKAGE = 'lwgeom', sfc, precision) } diff --git a/R/startpoint.R b/R/startpoint.R index 1a1422e..35e838c 100644 --- a/R/startpoint.R +++ b/R/startpoint.R @@ -9,9 +9,17 @@ #' m = matrix(c(0, 1, 2, 0, 1, 4), ncol = 2) #' l = st_sfc(st_linestring(m)) #' lwgeom::st_startpoint(l) +#' lwgeom::st_endpoint(l) #' l2 = st_sfc(st_linestring(m), st_linestring(m[3:1, ])) #' lwgeom::st_startpoint(l2) +#' lwgeom::st_endpoint(l2) st_startpoint = function(x) { m <- CPL_startpoint(st_geometry(x)) st_sfc(lapply(seq_len(nrow(m)), function(i) st_point(m[i,])), crs = st_crs(x)) } +#' @rdname st_startpoint +#' @export +st_endpoint = function(x) { + m <- CPL_endpoint(st_geometry(x)) + st_sfc(lapply(seq_len(nrow(m)), function(i) st_point(m[i,])), crs = st_crs(x)) +} diff --git a/man/st_startpoint.Rd b/man/st_startpoint.Rd index 723db2b..cb645ae 100644 --- a/man/st_startpoint.Rd +++ b/man/st_startpoint.Rd @@ -2,9 +2,12 @@ % Please edit documentation in R/startpoint.R \name{st_startpoint} \alias{st_startpoint} +\alias{st_endpoint} \title{Return the start and end points from lines} \usage{ st_startpoint(x) + +st_endpoint(x) } \arguments{ \item{x}{line of class \code{sf}, \code{sfc} or \code{sfg}} @@ -23,6 +26,8 @@ library(sf) m = matrix(c(0, 1, 2, 0, 1, 4), ncol = 2) l = st_sfc(st_linestring(m)) lwgeom::st_startpoint(l) +lwgeom::st_endpoint(l) l2 = st_sfc(st_linestring(m), st_linestring(m[3:1, ])) lwgeom::st_startpoint(l2) +lwgeom::st_endpoint(l2) } diff --git a/src/RcppExports.cpp b/src/RcppExports.cpp index 1e43c05..905e576 100644 --- a/src/RcppExports.cpp +++ b/src/RcppExports.cpp @@ -257,6 +257,17 @@ BEGIN_RCPP return rcpp_result_gen; END_RCPP } +// CPL_endpoint +Rcpp::NumericMatrix CPL_endpoint(Rcpp::List sfc); +RcppExport SEXP _lwgeom_CPL_endpoint(SEXP sfcSEXP) { +BEGIN_RCPP + Rcpp::RObject rcpp_result_gen; + Rcpp::RNGScope rcpp_rngScope_gen; + Rcpp::traits::input_parameter< Rcpp::List >::type sfc(sfcSEXP); + rcpp_result_gen = Rcpp::wrap(CPL_endpoint(sfc)); + return rcpp_result_gen; +END_RCPP +} // CPL_sfc_to_wkt Rcpp::CharacterVector CPL_sfc_to_wkt(Rcpp::List sfc, Rcpp::IntegerVector precision); RcppExport SEXP _lwgeom_CPL_sfc_to_wkt(SEXP sfcSEXP, SEXP precisionSEXP) { @@ -317,6 +328,7 @@ static const R_CallMethodDef CallEntries[] = { {"_lwgeom_CPL_is_polygon_cw", (DL_FUNC) &_lwgeom_CPL_is_polygon_cw, 1}, {"_lwgeom_CPL_force_polygon_cw", (DL_FUNC) &_lwgeom_CPL_force_polygon_cw, 1}, {"_lwgeom_CPL_startpoint", (DL_FUNC) &_lwgeom_CPL_startpoint, 1}, + {"_lwgeom_CPL_endpoint", (DL_FUNC) &_lwgeom_CPL_endpoint, 1}, {"_lwgeom_CPL_sfc_to_wkt", (DL_FUNC) &_lwgeom_CPL_sfc_to_wkt, 2}, {"_lwgeom_CPL_proj_version", (DL_FUNC) &_lwgeom_CPL_proj_version, 1}, {"_lwgeom_CPL_linesubstring", (DL_FUNC) &_lwgeom_CPL_linesubstring, 4}, diff --git a/src/lwgeom.cpp b/src/lwgeom.cpp index 4089190..45e4521 100644 --- a/src/lwgeom.cpp +++ b/src/lwgeom.cpp @@ -263,6 +263,25 @@ Rcpp::NumericMatrix CPL_startpoint(Rcpp::List sfc) { // return sfc_from_lwgeom(lwgeom_cw); } +// [[Rcpp::export]] +Rcpp::NumericMatrix CPL_endpoint(Rcpp::List sfc) { + + std::vector lwgeom_cw = lwgeom_from_sfc(sfc); + Rcpp::NumericMatrix m(lwgeom_cw.size(), 2); + + // no lwgeom_endpoint so reverse in-place and use startpoint + POINT4D p; + for (size_t i = 0; i < lwgeom_cw.size(); i++) { + lwgeom_reverse_in_place(lwgeom_cw[i]); + lwgeom_startpoint(lwgeom_cw[i], &p); + m(i, 0) = p.x; + m(i, 1) = p.y; + } + + return m; +} + + // [[Rcpp::export]] Rcpp::CharacterVector CPL_sfc_to_wkt(Rcpp::List sfc, Rcpp::IntegerVector precision) {