2025-01-12 00:52:51 +08:00

156 lines
4.2 KiB
R

## ----include = FALSE----------------------------------------------------------
knitr::opts_chunk$set(collapse = TRUE, comment = "#>")
## ----setup--------------------------------------------------------------------
library(vctrs)
library(pillar)
## ----eval = FALSE-------------------------------------------------------------
# usethis::use_package("vctrs")
# usethis::use_package("pillar")
## -----------------------------------------------------------------------------
#' @export
latlon <- function(lat, lon) {
new_rcrd(list(lat = lat, lon = lon), class = "earth_latlon")
}
#' @export
format.earth_latlon <- function(x, ..., formatter = deg_min) {
x_valid <- which(!is.na(x))
lat <- field(x, "lat")[x_valid]
lon <- field(x, "lon")[x_valid]
ret <- rep(NA_character_, vec_size(x))
ret[x_valid] <- paste0(formatter(lat, "lat"), " ", formatter(lon, "lon"))
# It's important to keep NA in the vector!
ret
}
deg_min <- function(x, direction) {
pm <- if (direction == "lat") c("N", "S") else c("E", "W")
sign <- sign(x)
x <- abs(x)
deg <- trunc(x)
x <- x - deg
min <- round(x * 60)
# Ensure the columns are always the same width so they line up nicely
ret <- sprintf("%d°%.2d'%s", deg, min, ifelse(sign >= 0, pm[[1]], pm[[2]]))
format(ret, justify = "right")
}
latlon(c(32.71, 2.95), c(-117.17, 1.67))
## -----------------------------------------------------------------------------
library(tibble)
loc <- latlon(
c(28.3411783, 32.7102978, 30.2622356, 37.7859102, 28.5, NA),
c(-81.5480348, -117.1704058, -97.7403327, -122.4131357, -81.4, NA)
)
data <- tibble(venue = "rstudio::conf", year = 2017:2022, loc = loc)
data
## -----------------------------------------------------------------------------
#' @export
vec_ptype_abbr.earth_latlon <- function(x) {
"latlon"
}
data
## -----------------------------------------------------------------------------
deg_min_color <- function(x, direction) {
pm <- if (direction == "lat") c("N", "S") else c("E", "W")
sign <- sign(x)
x <- abs(x)
deg <- trunc(x)
x <- x - deg
rad <- round(x * 60)
ret <- sprintf(
"%d%s%.2d%s%s",
deg,
pillar::style_subtle("°"),
rad,
pillar::style_subtle("'"),
pm[ifelse(sign >= 0, 1, 2)]
)
format(ret, justify = "right")
}
## -----------------------------------------------------------------------------
#' @importFrom pillar pillar_shaft
#' @export
pillar_shaft.earth_latlon <- function(x, ...) {
out <- format(x, formatter = deg_min_color)
pillar::new_pillar_shaft_simple(out, align = "right")
}
## -----------------------------------------------------------------------------
data
## -----------------------------------------------------------------------------
print(data, width = 30)
## -----------------------------------------------------------------------------
#' @importFrom pillar pillar_shaft
#' @export
pillar_shaft.earth_latlon <- function(x, ...) {
out <- format(x)
pillar::new_pillar_shaft_simple(out, align = "right", min_width = 10)
}
print(data, width = 30)
## -----------------------------------------------------------------------------
deg <- function(x, direction) {
pm <- if (direction == "lat") c("N", "S") else c("E", "W")
sign <- sign(x)
x <- abs(x)
deg <- round(x)
ret <- sprintf("%d°%s", deg, pm[ifelse(sign >= 0, 1, 2)])
format(ret, justify = "right")
}
## -----------------------------------------------------------------------------
#' @importFrom pillar pillar_shaft
#' @export
pillar_shaft.earth_latlon <- function(x, ...) {
deg <- format(x, formatter = deg)
deg_min <- format(x)
pillar::new_pillar_shaft(
list(deg = deg, deg_min = deg_min),
width = pillar::get_max_extent(deg_min),
min_width = pillar::get_max_extent(deg),
class = "pillar_shaft_latlon"
)
}
## -----------------------------------------------------------------------------
#' @export
format.pillar_shaft_latlon <- function(x, width, ...) {
if (get_max_extent(x$deg_min) <= width) {
ornament <- x$deg_min
} else {
ornament <- x$deg
}
pillar::new_ornament(ornament, align = "right")
}
data
print(data, width = 30)
## ----eval = FALSE-------------------------------------------------------------
# expect_snapshot(pillar_shaft(data$loc))