Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/pairwise azimuth #97

Open
wants to merge 14 commits into
base: master
Choose a base branch
from
4 changes: 2 additions & 2 deletions R/RcppExports.R
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ CPL_geodetic_length <- function(sfc, semi_major, inv_flattening) {
.Call('_lwgeom_CPL_geodetic_length', PACKAGE = 'lwgeom', sfc, semi_major, inv_flattening)
}

CPL_geodetic_azimuth <- function(sfc, semi_major, inv_flattening) {
.Call('_lwgeom_CPL_geodetic_azimuth', PACKAGE = 'lwgeom', sfc, semi_major, inv_flattening)
CPL_geodetic_azimuth <- function(sfc, semi_major, inv_flattening, sfc2_ = NULL) {
.Call('_lwgeom_CPL_geodetic_azimuth', PACKAGE = 'lwgeom', sfc, semi_major, inv_flattening, sfc2_)
}

CPL_geodetic_segmentize <- function(sfc, max_seg_length) {
Expand Down
12 changes: 10 additions & 2 deletions R/bearing.R
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,24 @@
#'
#' compute azimuth between sequence of points
#' @param x object of class \code{sf}, \code{sfc} or \code{sfg}
#' @param y object of class \code{sf}, \code{sfc} or \code{sfg}, or NULL
#' @export
#' @examples
#' library(sf)
#' p = st_sfc(st_point(c(7,52)), st_point(c(8,53)), crs = 4326)
#' st_geod_azimuth(p)
st_geod_azimuth = function(x) {
st_geod_azimuth = function(x, y = NULL) {
stopifnot(st_is_longlat(x))
stopifnot(all(st_is(x, "POINT")))
p = st_crs(st_geometry(x), parameters = TRUE)
ret = CPL_geodetic_azimuth(st_geometry(x), p$SemiMajor, p$InvFlattening)
if (is.null(y)) {
ret = CPL_geodetic_azimuth(st_geometry(x), p$SemiMajor, p$InvFlattening)
} else {
ret = CPL_geodetic_azimuth(st_geometry(x),
p$SemiMajor,
p$InvFlattening,
st_geometry(y))
}
units(ret) = as_units("rad")
ret
}
4 changes: 3 additions & 1 deletion man/st_geod_azimuth.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 5 additions & 4 deletions src/RcppExports.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,16 @@ BEGIN_RCPP
END_RCPP
}
// CPL_geodetic_azimuth
Rcpp::NumericVector CPL_geodetic_azimuth(Rcpp::List sfc, double semi_major, double inv_flattening);
RcppExport SEXP _lwgeom_CPL_geodetic_azimuth(SEXP sfcSEXP, SEXP semi_majorSEXP, SEXP inv_flatteningSEXP) {
Rcpp::NumericVector CPL_geodetic_azimuth(Rcpp::List sfc, double semi_major, double inv_flattening, Nullable<Rcpp::List> sfc2_);
RcppExport SEXP _lwgeom_CPL_geodetic_azimuth(SEXP sfcSEXP, SEXP semi_majorSEXP, SEXP inv_flatteningSEXP, SEXP sfc2_SEXP) {
BEGIN_RCPP
Rcpp::RObject rcpp_result_gen;
Rcpp::RNGScope rcpp_rngScope_gen;
Rcpp::traits::input_parameter< Rcpp::List >::type sfc(sfcSEXP);
Rcpp::traits::input_parameter< double >::type semi_major(semi_majorSEXP);
Rcpp::traits::input_parameter< double >::type inv_flattening(inv_flatteningSEXP);
rcpp_result_gen = Rcpp::wrap(CPL_geodetic_azimuth(sfc, semi_major, inv_flattening));
Rcpp::traits::input_parameter< Nullable<Rcpp::List> >::type sfc2_(sfc2_SEXP);
rcpp_result_gen = Rcpp::wrap(CPL_geodetic_azimuth(sfc, semi_major, inv_flattening, sfc2_));
return rcpp_result_gen;
END_RCPP
}
Expand Down Expand Up @@ -361,7 +362,7 @@ END_RCPP
static const R_CallMethodDef CallEntries[] = {
{"_lwgeom_CPL_geodetic_area", (DL_FUNC) &_lwgeom_CPL_geodetic_area, 3},
{"_lwgeom_CPL_geodetic_length", (DL_FUNC) &_lwgeom_CPL_geodetic_length, 3},
{"_lwgeom_CPL_geodetic_azimuth", (DL_FUNC) &_lwgeom_CPL_geodetic_azimuth, 3},
{"_lwgeom_CPL_geodetic_azimuth", (DL_FUNC) &_lwgeom_CPL_geodetic_azimuth, 4},
{"_lwgeom_CPL_geodetic_segmentize", (DL_FUNC) &_lwgeom_CPL_geodetic_segmentize, 2},
{"_lwgeom_CPL_geodetic_covers", (DL_FUNC) &_lwgeom_CPL_geodetic_covers, 2},
{"_lwgeom_CPL_geodetic_distance", (DL_FUNC) &_lwgeom_CPL_geodetic_distance, 7},
Expand Down
43 changes: 30 additions & 13 deletions src/geodetic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,19 +37,36 @@ Rcpp::NumericVector CPL_geodetic_length(Rcpp::List sfc, double semi_major, doubl
}

// [[Rcpp::export]]
Rcpp::NumericVector CPL_geodetic_azimuth(Rcpp::List sfc, double semi_major, double inv_flattening) {
if (sfc.size() < 1)
stop("bearing needs at least 2 points"); // #nocov
Rcpp::NumericVector ret(sfc.size() - 1);
std::vector<LWGEOM *> lw = lwgeom_from_sfc(sfc);
SPHEROID s;
spheroid_init(&s, semi_major, semi_major * (1.0 - 1.0/inv_flattening));
for (int i = 0; i < ret.size(); i++) {
ret[i] = lwgeom_azumith_spheroid((LWPOINT*) lw[i], (LWPOINT*) lw[i+1], &s);
lwgeom_free(lw[i]);
}
lwgeom_free(lw[ret.size()]); // last
return ret;
Rcpp::NumericVector CPL_geodetic_azimuth(Rcpp::List sfc, double semi_major, double inv_flattening, Nullable<Rcpp::List> sfc2_ = R_NilValue) {
if (sfc.size() < 1)
stop("bearing needs at least 2 points"); // #nocov
std::vector<LWGEOM *> lw = lwgeom_from_sfc(sfc);
SPHEROID s;
spheroid_init(&s, semi_major, semi_major * (1.0 - 1.0/inv_flattening));

if (sfc2_.isNotNull()) {
Rcpp::NumericVector ret(sfc.size());

Rcpp::List sfc2(sfc2_);
if (sfc2.size() < 1)
stop("bearing needs at least 2 points"); // #nocov
if (sfc.size() != sfc2.size())
stop("length of x and y must match");
std::vector<LWGEOM *> lw2 = lwgeom_from_sfc(sfc2);
for (int i = 0; i < ret.size(); i++) {
ret[i] = lwgeom_azumith_spheroid((LWPOINT*) lw[i], (LWPOINT*) lw2[i], &s);
lwgeom_free(lw[i]);
}
return ret;
} else {
Rcpp::NumericVector ret(sfc.size() - 1);
for (int i = 0; i == ret.size(); i++) {
robitalec marked this conversation as resolved.
Show resolved Hide resolved
ret[i] = lwgeom_azumith_spheroid((LWPOINT*) lw[i], (LWPOINT*) lw[i+1], &s);
lwgeom_free(lw[i]);
}
lwgeom_free(lw[ret.size()]); // last
return ret;
}
}

// [[Rcpp::export]]
Expand Down
Loading