R/mf_scale.R

Defines functions unit_conversion mf_scale

Documented in mf_scale

#' @title Plot a scale bar
#' @description Plot a scale bar.
#' @name mf_scale
#' @eval my_params(c("col"))
#' @param size size of the scale bar in units (default to km). If size is not
#' set, an automatic size is used (1/10 of the map width)
#' @param lwd width of the scale bar
#' @param cex cex of the text
#' @param pos position. It can be one of 'bottomright', 'bottomleft',
#' 'interactive'
#' or a vector of two coordinates in map units (c(x, y)).
#' @param unit units used for the scale bar. Can be "mi" for miles,
#' "m" for meters, or "km" for kilometers (default)
#' @note This scale bar does not work on unprojected (long/lat) maps.
#' @return No return value, a scale bar is displayed.
#' @export
#' @examples
#' mtq <- mf_get_mtq()
#' mf_map(mtq)
#' mf_scale()
mf_scale <- function(size, pos = "bottomright",
                     lwd = 1.5, cex = 0.6, col, unit = "km") {
  test_cur_plot()
  # default color
  if (missing(col)) {
    col <- getOption("mapsf.fg")
  }

  # get the current plot dimensions
  pu <- par("usr")
  inset <- strwidth("M", units = "user", cex = 1) / 2


  # default scale
  if (missing(size)) {
    size <- diff(pu[1:2]) / 10
    size <- unit_conversion(size = size, unit_in = "m", unit_out = unit)
    size_text <- signif(size, digits = 0)
    size <- unit_conversion(size = size_text, unit_in = unit, unit_out = "m")
  } else {
    # convert distance into meters based on dist_unit
    size_text <- as.character(size)
    size <- unit_conversion(size, unit_in = unit, unit_out = "m")
  }

  # label
  labelscale <- paste0(size_text, " ", unit)

  # xy pos
  xscale <- pu[2] - inset - size
  yscale <- pu[3] + inset

  if (!missing(pos)) {
    if (is.numeric(pos) && length(pos) == 2) {
      xscale <- pos[1]
      yscale <- pos[2]
    } else {
      if (pos == "interactive") {
        isc <- interleg(txt = c("scale bar", "Scale bar"))
        xscale <- isc[1]
        yscale <- isc[2]
      }
      if (pos == "bottomleft") {
        xscale <- pu[1] + inset
        yscale <- pu[3] + inset
      }
    }
  }

  # plot the scale bar
  segments(
    x0 = xscale,
    y0 = yscale,
    x1 = xscale + size,
    y1 = yscale,
    lwd = lwd,
    col = col, xpd = TRUE
  )
  # plot the scale bar label
  text(xscale + (size / 2), yscale,
    adj = c(0.5, -.5),
    labels = labelscale,
    cex = cex, col = col,
    xpd = TRUE
  )
}


#' Convert units
#' @param size a size
#' @param unit_in input unit
#' @param unit_out output unit
#' @noRd
unit_conversion <- function(size, unit_in, unit_out) {
  if (!unit_out %in% c("km", "m", "mi")) {
    stop("unit must be 'km', 'm', or 'mi'")
  }
  if (unit_out == "m") {
    if (unit_in == "km") size <- size * 1000
    if (unit_in == "mi") size <- size * 1609.344
  }
  if (unit_out == "km") {
    if (unit_in == "m") size <- size / 1000
  }
  if (unit_out == "mi") {
    if (unit_in == "m") size <- size / 1609.344
  }
  return(size)
}

Try the mapsf package in your browser

Any scripts or data that you put into this service are public.

mapsf documentation built on Nov. 21, 2023, 5:09 p.m.