Skip to content

Commit

Permalink
Switching R dependency to xml2 (#18)
Browse files Browse the repository at this point in the history
* switching to xml2 dependency

* cleaning up get_trkseg_dist code

* incrementing minor version to 4.2.0
  • Loading branch information
pegeler authored Apr 16, 2024
1 parent eb1fdf1 commit 489951a
Show file tree
Hide file tree
Showing 8 changed files with 40 additions and 57 deletions.
6 changes: 3 additions & 3 deletions R/package/DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Package: eddington
Title: Compute a Cyclist's Eddington Number
Version: 4.1.3
Version: 4.2.0
Authors@R: c(
person('Paul', 'Egeler', email = 'paulegeler@gmail.com', role = c('aut','cre')),
person('Tashi', 'Reigle', role = 'ctb'))
Expand All @@ -26,12 +26,12 @@ Imports:
Rcpp,
R6,
methods,
stats,
XML
xml2
Suggests:
testthat,
knitr,
rmarkdown,
stats,
dplyr
SystemRequirements: C++17
VignetteBuilder: knitr
Expand Down
6 changes: 6 additions & 0 deletions R/package/NEWS.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
# eddington 4.2.0 (Release date: 2024-03-23)

Changes:

- Substituted `XML` package dependency for `xml2`.

# eddington 4.1.2 (Release date: 2023-12-12)

Changes:
Expand Down
2 changes: 1 addition & 1 deletion R/package/R/RcppExports.R
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
#' rides <- rgamma(15, shape = 2, scale = 10)
#'
#' # View the rides sorted in decreasing order
#' setNames(sort(rides, decreasing = TRUE), seq_along(rides))
#' stats::setNames(sort(rides, decreasing = TRUE), seq_along(rides))
#'
#' # Get the Eddington number
#' E_num(rides)
Expand Down
2 changes: 1 addition & 1 deletion R/package/R/eddington-R6.r
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
#' rides <- rgamma(15, shape = 2, scale = 10)
#'
#' # View the rides sorted in decreasing order
#' setNames(sort(rides, decreasing = TRUE), seq_along(rides))
#' stats::setNames(sort(rides, decreasing = TRUE), seq_along(rides))
#'
#' # Create the Eddington object
#' e <- Eddington$new(rides, store.cumulative = TRUE)
Expand Down
75 changes: 26 additions & 49 deletions R/package/R/gpx.r
Original file line number Diff line number Diff line change
Expand Up @@ -99,16 +99,15 @@ get_haversine_distance <- function(lat_1,
#' }
#' @export
read_gpx <- function(file, units = c("miles", "kilometers")) {
x <- XML::xmlInternalTreeParse(file)
on.exit(XML::free(x))
x <- xml2::read_xml(file)

distances <- get_trkseg_dist(x, match.arg(units))

if (!length(distances)) {
# No trkseg nodes were found. Returning an empty data frame
return(
data.frame(
date = double(0L),
date = structure(double(0L), class = "Date"),
distance = double(0L)
)
)
Expand All @@ -117,67 +116,45 @@ read_gpx <- function(file, units = c("miles", "kilometers")) {
dates <- get_dates(x)

data.frame(
# do.call preserves "Date" class
date = if (length(dates) == length(distances)) do.call(c, dates) else as.Date(NA),
date = if (length(dates) == length(distances)) dates else as.Date(NA),
distance = unlist(distances)
)
}

# XML parsing helper functions --------------------------------------------

get_dates <- function(x) {
timestamps <- XML::xpathApply(
x,
"//d:trkseg/d:trkpt[1]/d:time",
XML::xmlValue,
namespaces = NAMESPACES
)
lapply(timestamps, as.Date, TIMESTAMP_FORMAT)
x |>
xml2::xml_find_all("//d:trkseg/d:trkpt[1]/d:time", ns = NAMESPACES) |>
xml2::xml_text() |>
as.Date.character(TIMESTAMP_FORMAT)
}

get_trkseg_dist <- function(x, units = c("miles", "kilometers")) {
r <- switch(match.arg(units), miles = R_E_MI, kilometers = R_E_KM)

lapply(
XML::getNodeSet(x, "//d:trkseg", namespaces = NAMESPACES),
\(trkseg) {
trkpts <- XML::xmlChildren(trkseg)
if (length(trkpts) < 2) return(0.)
Reduce(
`+`,
apply(
cbind(trkpts[-1], trkpts[-length(trkpts)]),
1,
\(pair) .Call(`_eddington_get_haversine_distance_`,
as.double(XML::xmlGetAttr(pair[[1]], "lat")),
as.double(XML::xmlGetAttr(pair[[1]], "lon")),
as.double(XML::xmlGetAttr(pair[[2]], "lat")),
as.double(XML::xmlGetAttr(pair[[2]], "lon")),
xml2::xml_find_all(x, "//d:trkseg", ns = NAMESPACES),
\(trkseg) { # get sum of distances for a single trkseg
trkpts <- xml2::xml_children(trkseg)

if (length(trkpts) < 2L)
return(0)

sum(
vapply(
seq_along(trkpts[-1L]),
\(i) .Call(
`_eddington_get_haversine_distance_`,
as.double(xml2::xml_attr(trkpts[[i]], "lat")),
as.double(xml2::xml_attr(trkpts[[i]], "lon")),
as.double(xml2::xml_attr(trkpts[[i + 1L]], "lat")),
as.double(xml2::xml_attr(trkpts[[i + 1L]], "lon")),
r
)
),
double(1)
)
)
})
}

# Unused ------------------------------------------------------------------

get_trkseg_coords <- function(x) {
trksegs <- lapply(
XML::getNodeSet(x, "//d:trkseg", namespaces = NAMESPACES),
\(trkseg) XML::xmlApply(
trkseg,
\(trkpt) as.double(c(XML::xmlGetAttr(trkpt, "lat"),
XML::xmlGetAttr(trkpt, "lon")))
)
)
lapply(
trksegs,
\(trkseg) stats::setNames(
as.data.frame(
do.call(rbind, trkseg),
row.names = FALSE),
c("lat", "lon")
)
}
)
}
2 changes: 1 addition & 1 deletion R/package/man/E_num.Rd

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

2 changes: 1 addition & 1 deletion R/package/man/Eddington.Rd

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

2 changes: 1 addition & 1 deletion R/package/src/eddington.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
//' rides <- rgamma(15, shape = 2, scale = 10)
//'
//' # View the rides sorted in decreasing order
//' setNames(sort(rides, decreasing = TRUE), seq_along(rides))
//' stats::setNames(sort(rides, decreasing = TRUE), seq_along(rides))
//'
//' # Get the Eddington number
//' E_num(rides)
Expand Down

0 comments on commit 489951a

Please sign in to comment.