From e061b5b785fe92b919ab1e857ca7e77eb5d1d31a Mon Sep 17 00:00:00 2001 From: Wright Date: Tue, 9 Apr 2024 11:41:11 -0600 Subject: [PATCH 1/6] lat/long converter improvements --- DESCRIPTION | 2 +- R/geography.R | 57 +++++++++++++++++++++++++++++---------------------- 2 files changed, 33 insertions(+), 26 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index a6c8522..61d846d 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -49,7 +49,7 @@ Imports: here, tibble, tidyselect -RoxygenNote: 7.2.3 +RoxygenNote: 7.3.1 Suggests: knitr, rmarkdown, diff --git a/R/geography.R b/R/geography.R index d612f9e..9b774ff 100644 --- a/R/geography.R +++ b/R/geography.R @@ -276,36 +276,43 @@ convert_utm_to_ll <- function(df, EastingCol, NorthingCol, zone, - datum = "WGS84") { - Base <- as.data.frame(df) - Base <- dplyr::rename(Base, "b" = EastingCol, "a" = NorthingCol) - Mid <- Base[!is.na(Base$"b" & Base$"a"), ] - Mid2 <- Base[is.na(Base$"b" & Base$"a"), ] - Final <- dplyr::select(Mid, "b", "a") - Final[1:2] <- lapply(Final[1:2], FUN = function(z) { - as.numeric(z) - }) + datum = "NAD83") { + # Check for missing data + row_count <- nrow(df) + na_row_count <- nrow(dplyr::filter(df, is.na({{EastingCol}}) | is.na({{NorthingCol}}))) - Final <- cbind(Final$b, Final$a) + if (na_row_count > 0) { + df %<>% dplyr::filter(!is.na({{EastingCol}}) & !is.na({{NorthingCol}})) + warning(paste(na_row_count, "rows are missing UTM data")) + } - v <- terra::vect(Final, crs = paste0( - "+proj=utm +zone=", - zone, - " +datum=", - datum, " - +units=m" - )) + ## Set up CRS for lat/long data + latlong_CRS <- sp::CRS("+proj=longlat +datum=NAD83") # CRS for our new lat/long values - converted <- terra::project(v, "+proj=longlat +datum=WGS84") + # Loop through each datum and zone in the data + datums <- unique(df[[rlang::ensym(datum)]]) # Get vector of datums present in data + zones <- unique(df[[rlang::ensym(zone)]]) # Get vector of zones present in data + for (datum in datums) { + for (zone in zones) { + utm_CRS <- sp::CRS(paste0("+proj=utm +zone=", zone, " +datum=", datum)) # Set coordinate reference system for incoming UTM data - lonlat <- terra::geom(converted)[, c("x", "y")] + sp_utm <- sp::SpatialPoints(df %>% dplyr::filter({{zone}} == zone, {{datum}} == datum) %>% dplyr::select({{EastingCol}}, {{NorthingCol}}) %>% as.matrix(), proj4string = utm_CRS) # Convert UTM columns into a SpatialPoints object + sp_geo <- sp::spTransform(sp_utm, latlong_CRS) %>% # Transform UTM to Lat/Long + tibble::as_tibble() + + # Set data$Long and data$Lat to newly converted values, but only for the zone and datum we are currently on in our for loop + df[as.vector((df[, rlang::ensym(zone)] == zone) & (df[, rlang::ensym(datum)] == datum)), "Long"] <- sp_geo[, rlang::ensym(EastingCol)] + df[as.vector((df[, rlang::ensym(zone)] == zone) & (df[, rlang::ensym(datum)] == datum)), "Lat"] <- sp_geo[, rlang::ensym(NorthingCol)] + } + } + + # Remove UTM columns if keep_utm == FALSE + if (!keep_utm) { + df <- dplyr::select(df, -c({{EastingCol}}, {{NorthingCol}}, {{zone}}, {{datum}})) + } + + df$LatLonWKID <- lat_long_wkid # Store the wkid in the dataframe - df <- cbind(Mid, lonlat) - df <- plyr::rbind.fill(df, Mid2) - df <- dplyr::rename(df, - EastingCol = "b", NorthingCol = "a", - "decimalLongitude" = x, "decimalLatitude" = y - ) return(df) } From e0fd1ff5b485ac113221fd260765bea2934aa945 Mon Sep 17 00:00:00 2001 From: Wright Date: Tue, 16 Apr 2024 18:06:59 -0600 Subject: [PATCH 2/6] convert_utm_to_ll (Sarah's version) Accept zone and datum columns, default to NAD83, allow for tidy eval (column names can be quoted or unquoted) --- R/geography.R | 133 +++++++++++++++++++++++++-------------- man/convert_utm_to_ll.Rd | 52 ++++++++++----- 2 files changed, 121 insertions(+), 64 deletions(-) diff --git a/R/geography.R b/R/geography.R index 9b774ff..5c8be06 100644 --- a/R/geography.R +++ b/R/geography.R @@ -236,82 +236,121 @@ fuzz_location <- function(lat, #' @description `convert_utm_to_ll()` takes your dataframe with UTM coordinates #' in separate Easting and Northing columns, and adds on an additional two #' columns with the converted decimalLatitude and decimalLongitude coordinates -#' using the reference coordinate system WGS84. You may need to turn the VPN OFF -#' for this function to work properly. +#' using the reference coordinate system NAD83. Your data must also contain columns +#' specifying the zone and datum of your UTM coordinates. #' #' @details Define the name of your dataframe, the easting and northing columns #' within it, the UTM zone within which those coordinates are located, and the #' reference coordinate system (datum). UTM Northing and Easting columns must be -#' in separate columns prior to running the function. If a datum is not defined, -#' the function will default to "WGS84". If there are missing coordinates in +#' in separate columns prior to running the function. If a datum for the lat/long output +#' is not defined, the function will default to "NAD83". If there are missing coordinates in #' your dataframe they will be preserved, however they will be moved to the end #' of your dataframe. Note that some parameter names are not in snake_case but #' instead reflect DarwinCore naming conventions. #' #' @param df - The dataframe with UTM coordinates you would like to convert. #' Input the name of your dataframe. -#' @param EastingCol - The name of your Easting UTM column. Input the name in -#' quotations, ie. "EastingCol". -#' @param NorthingCol - The name of your Northing UTM column. Input the name in -#' quotations, ie. "NorthingCol". -#' @param zone - The UTM Zone. Input the zone number in quotations, ie. "17". -#' @param datum - The datum used in the coordinate reference system of your -#' coordinates. Input in quotations, ie. "WGS84" +#' @param EastingCol - The name of your Easting UTM column. You may input the name +#' with or without quotations, ie. EastingCol and "EastingCol" are both valid. +#' @param NorthingCol - The name of your Northing UTM column. You may input the name +#' with or without quotations, ie. NorthingCol and "NorthingCol" are both valid. +#' @param ZoneCol - The column containing the UTM zone, with or without quotations. +#' @param DatumCol - The column containing the datum for your UTM coordinates, +#' with or without quotations. #' #' @return The function returns your dataframe, mutated with an additional two -#' columns of decimal Longitude and decimal Latitude. +#' columns of decimal Longitude and decimal Latitude plus a column LatLong_CRS containing +#' a PROJ string that specifies the coordinate reference system for these data. #' @export #' #' @examples #' \dontrun{ +#' +#' my_dataframe %>% +#' convert_utm_to_ll( +#' EastingCol = UTM_X, +#' NorthingCol = UTM_Y, +#' ZoneCol = Zone, +#' DatumCol = Datum +#' ) +#' #' convert_utm_to_ll( #' df = mydataframe, #' EastingCol = "EastingCoords", #' NorthingCol = "NorthingCoords", -#' zone = "17", -#' datum = "WGS84" +#' ZoneCol = "zone", +#' DatumCol = "datum", +#' latlong_datum = "WGS84" #' ) #' } convert_utm_to_ll <- function(df, EastingCol, NorthingCol, - zone, - datum = "NAD83") { - # Check for missing data - row_count <- nrow(df) - na_row_count <- nrow(dplyr::filter(df, is.na({{EastingCol}}) | is.na({{NorthingCol}}))) - - if (na_row_count > 0) { - df %<>% dplyr::filter(!is.na({{EastingCol}}) & !is.na({{NorthingCol}})) - warning(paste(na_row_count, "rows are missing UTM data")) - } - - ## Set up CRS for lat/long data - latlong_CRS <- sp::CRS("+proj=longlat +datum=NAD83") # CRS for our new lat/long values - - # Loop through each datum and zone in the data - datums <- unique(df[[rlang::ensym(datum)]]) # Get vector of datums present in data - zones <- unique(df[[rlang::ensym(zone)]]) # Get vector of zones present in data - for (datum in datums) { - for (zone in zones) { - utm_CRS <- sp::CRS(paste0("+proj=utm +zone=", zone, " +datum=", datum)) # Set coordinate reference system for incoming UTM data - - sp_utm <- sp::SpatialPoints(df %>% dplyr::filter({{zone}} == zone, {{datum}} == datum) %>% dplyr::select({{EastingCol}}, {{NorthingCol}}) %>% as.matrix(), proj4string = utm_CRS) # Convert UTM columns into a SpatialPoints object - sp_geo <- sp::spTransform(sp_utm, latlong_CRS) %>% # Transform UTM to Lat/Long - tibble::as_tibble() + ZoneCol, + DatumCol, + latlong_datum = "NAD83") { + + df <- dplyr::mutate(df, `_UTMJOINCOL` = seq_len(nrow(df))) %>% # Add a temporary column for joining lat/long data back to orig. df. This is needed in case UTM data are missing and we need to remove those rows to do the conversion. + dplyr::ungroup() # Ungroup df in case it comes in with unwanted groups. + + # Separate df with just coordinates. We'll filter out any NA rows. + coord_df <- df %>% + dplyr::select(`_UTMJOINCOL`, {{EastingCol}}, {{NorthingCol}}, {{ZoneCol}}, {{DatumCol}}) + + withr::with_envvar(c("PROJ_LIB" = ""), { # This is a fix for the proj library bug in R (see pinned post "sf::st_read() of geojson not getting CRS" in IMData General Discussion). + # filter out rows that are missing UTM, zone, or datum + coord_df <- coord_df %>% + dplyr::filter(!is.na({{EastingCol}}) & + !is.na({{NorthingCol}}) & + !is.na({{ZoneCol}}) & + !is.na({{DatumCol}})) + + na_row_count <- nrow(df) - nrow(coord_df) + if (na_row_count > 0) { + warning(paste(na_row_count, "rows are missing UTM coordinates, zone, and/or datum information.")) + } - # Set data$Long and data$Lat to newly converted values, but only for the zone and datum we are currently on in our for loop - df[as.vector((df[, rlang::ensym(zone)] == zone) & (df[, rlang::ensym(datum)] == datum)), "Long"] <- sp_geo[, rlang::ensym(EastingCol)] - df[as.vector((df[, rlang::ensym(zone)] == zone) & (df[, rlang::ensym(datum)] == datum)), "Lat"] <- sp_geo[, rlang::ensym(NorthingCol)] + ## Set up CRS for lat/long data + latlong_CRS <- sp::CRS(glue::glue("+proj=longlat +datum={latlong_datum}")) # CRS for our new lat/long values + + # Loop through each datum and zone in the data + zones <- unique(dplyr::pull(coord_df, {{ZoneCol}})) # Get vector of zones present in data + datums <- unique(dplyr::pull(coord_df, {{DatumCol}})) # Get vector of datums present in data + new_coords <- tibble::tibble() + for (datum in datums) { + for (zone in zones) { + zone_num <- stringr::str_extract(zone, "\\d+") # sp::CRS wants zone number only, e.g. 11, not 11N + # Figure out if zone is in N or S hemisphere. If unspecified, assume N. If S, add "+south" to proj string. + zone_letter <- tolower(stringr::str_extract(zone, "[A-Za-z]")) + if (!is.na(zone_letter) && zone_letter == "s") { + north_south <- " +south" + } else { + north_south <- "" + } + utm_CRS <- sp::CRS(glue::glue("+proj=utm +zone={zone_num} +datum={datum}{north_south}")) # Set coordinate reference system for incoming UTM data + filtered_df <- coord_df %>% + dplyr::filter(!!rlang::ensym(ZoneCol) == zone, !!rlang::ensym(DatumCol) == datum) + sp_utm <- sp::SpatialPoints(filtered_df %>% + dplyr::select({{EastingCol}}, {{NorthingCol}}) %>% + as.matrix(), + proj4string = utm_CRS) # Convert UTM columns into a SpatialPoints object + sp_geo <- sp::spTransform(sp_utm, latlong_CRS) %>% # Transform UTM to Lat/Long + tibble::as_tibble() + + # Set data$Long and data$Lat to newly converted values, but only for the zone and datum we are currently on in our for loop + filtered_df <- filtered_df %>% dplyr::mutate(Latitude = sp_geo[[2]], + Longitude = sp_geo[[1]]) + coord_df <- dplyr::left_join(coord_df, filtered_df, by = "_UTMJOINCOL") + } } - } + }) - # Remove UTM columns if keep_utm == FALSE - if (!keep_utm) { - df <- dplyr::select(df, -c({{EastingCol}}, {{NorthingCol}}, {{zone}}, {{datum}})) - } + df <- dplyr::left_join(df, + dplyr::select(coord_df, Lat, Long, `_UTMJOINCOL`), + by = "_UTMJOINCOL") %>% + dplyr::select(-`_UTMJOINCOL`) - df$LatLonWKID <- lat_long_wkid # Store the wkid in the dataframe + df$LatLong_CRS <- latlong_CRS@projargs # Store the wkid in the dataframe return(df) } diff --git a/man/convert_utm_to_ll.Rd b/man/convert_utm_to_ll.Rd index ab73ba2..46bf252 100644 --- a/man/convert_utm_to_ll.Rd +++ b/man/convert_utm_to_ll.Rd @@ -4,7 +4,14 @@ \alias{convert_utm_to_ll} \title{Coordinate Conversion from UTM to Latitude and Longitude} \usage{ -convert_utm_to_ll(df, EastingCol, NorthingCol, zone, datum = "WGS84") +convert_utm_to_ll( + df, + EastingCol, + NorthingCol, + ZoneCol, + DatumCol, + latlong_datum = "NAD83" +) } \arguments{ \item{df}{\itemize{ @@ -13,53 +20,64 @@ Input the name of your dataframe. }} \item{EastingCol}{\itemize{ -\item The name of your Easting UTM column. Input the name in -quotations, ie. "EastingCol". +\item The name of your Easting UTM column. You may input the name +with or without quotations, ie. EastingCol and "EastingCol" are both valid. }} \item{NorthingCol}{\itemize{ -\item The name of your Northing UTM column. Input the name in -quotations, ie. "NorthingCol". +\item The name of your Northing UTM column. You may input the name +with or without quotations, ie. NorthingCol and "NorthingCol" are both valid. }} -\item{zone}{\itemize{ -\item The UTM Zone. Input the zone number in quotations, ie. "17". +\item{ZoneCol}{\itemize{ +\item The column containing the UTM zone, with or without quotations. }} -\item{datum}{\itemize{ -\item The datum used in the coordinate reference system of your -coordinates. Input in quotations, ie. "WGS84" +\item{DatumCol}{\itemize{ +\item The column containing the datum for your UTM coordinates, +with or without quotations. }} } \value{ The function returns your dataframe, mutated with an additional two -columns of decimal Longitude and decimal Latitude. +columns of decimal Longitude and decimal Latitude plus a column LatLong_CRS containing +a PROJ string that specifies the coordinate reference system for these data. } \description{ \code{convert_utm_to_ll()} takes your dataframe with UTM coordinates in separate Easting and Northing columns, and adds on an additional two columns with the converted decimalLatitude and decimalLongitude coordinates -using the reference coordinate system WGS84. You may need to turn the VPN OFF -for this function to work properly. +using the reference coordinate system NAD83. Your data must also contain columns +specifying the zone and datum of your UTM coordinates. } \details{ Define the name of your dataframe, the easting and northing columns within it, the UTM zone within which those coordinates are located, and the reference coordinate system (datum). UTM Northing and Easting columns must be -in separate columns prior to running the function. If a datum is not defined, -the function will default to "WGS84". If there are missing coordinates in +in separate columns prior to running the function. If a datum for the lat/long output +is not defined, the function will default to "NAD83". If there are missing coordinates in your dataframe they will be preserved, however they will be moved to the end of your dataframe. Note that some parameter names are not in snake_case but instead reflect DarwinCore naming conventions. } \examples{ \dontrun{ + +my_dataframe \%>\% +convert_utm_to_ll( + EastingCol = UTM_X, + NorthingCol = UTM_Y, + ZoneCol = Zone, + DatumCol = Datum +) + convert_utm_to_ll( df = mydataframe, EastingCol = "EastingCoords", NorthingCol = "NorthingCoords", - zone = "17", - datum = "WGS84" + ZoneCol = "zone", + DatumCol = "datum", + latlong_datum = "WGS84" ) } } From 3c6a7fda59064794b3ac19532a581ec303cfc6bb Mon Sep 17 00:00:00 2001 From: Wright Date: Wed, 17 Apr 2024 10:35:59 -0600 Subject: [PATCH 3/6] Change name of new utm to latlong fxn to generate_ll_from_utm. Update documentation and column names. --- NAMESPACE | 1 + R/geography.R | 106 +++++++++++++++++++++++++++++++++--- man/convert_utm_to_ll.Rd | 58 ++++++++------------ man/generate_ll_from_utm.Rd | 87 +++++++++++++++++++++++++++++ 4 files changed, 208 insertions(+), 44 deletions(-) create mode 100644 man/generate_ll_from_utm.Rd diff --git a/NAMESPACE b/NAMESPACE index 30c91f1..05a769f 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -9,6 +9,7 @@ export(convert_utm_to_ll) export(create_datastore_script) export(fix_utc_offset) export(fuzz_location) +export(generate_ll_from_utm) export(get_custom_flags) export(get_dc_flags) export(get_df_flags) diff --git a/R/geography.R b/R/geography.R index 5c8be06..5f0d962 100644 --- a/R/geography.R +++ b/R/geography.R @@ -233,11 +233,15 @@ fuzz_location <- function(lat, #' Coordinate Conversion from UTM to Latitude and Longitude #' -#' @description `convert_utm_to_ll()` takes your dataframe with UTM coordinates +#' @description `generate_ll_from_utm()` takes your dataframe with UTM coordinates #' in separate Easting and Northing columns, and adds on an additional two #' columns with the converted decimalLatitude and decimalLongitude coordinates #' using the reference coordinate system NAD83. Your data must also contain columns #' specifying the zone and datum of your UTM coordinates. +#' In contrast to `convert_utm_to_ll()` (superseded), `generate_ll_from_utm()` requires +#' zone and datum columns. It supports quoted or unquoted column names and a user-specified datum for lat/long +#' coordinates. It also adds an extra column to the output data table that documents the +#' lat/long coordinate reference system. #' #' @details Define the name of your dataframe, the easting and northing columns #' within it, the UTM zone within which those coordinates are located, and the @@ -259,7 +263,7 @@ fuzz_location <- function(lat, #' with or without quotations. #' #' @return The function returns your dataframe, mutated with an additional two -#' columns of decimal Longitude and decimal Latitude plus a column LatLong_CRS containing +#' columns of decimalLongitude and decimalLatitude plus a column LatLong_CRS containing #' a PROJ string that specifies the coordinate reference system for these data. #' @export #' @@ -267,14 +271,14 @@ fuzz_location <- function(lat, #' \dontrun{ #' #' my_dataframe %>% -#' convert_utm_to_ll( +#' generate_ll_from_utm( #' EastingCol = UTM_X, #' NorthingCol = UTM_Y, #' ZoneCol = Zone, #' DatumCol = Datum #' ) #' -#' convert_utm_to_ll( +#' generate_ll_from_utm( #' df = mydataframe, #' EastingCol = "EastingCoords", #' NorthingCol = "NorthingCoords", @@ -283,7 +287,7 @@ fuzz_location <- function(lat, #' latlong_datum = "WGS84" #' ) #' } -convert_utm_to_ll <- function(df, +generate_ll_from_utm <- function(df, EastingCol, NorthingCol, ZoneCol, @@ -338,20 +342,104 @@ convert_utm_to_ll <- function(df, tibble::as_tibble() # Set data$Long and data$Lat to newly converted values, but only for the zone and datum we are currently on in our for loop - filtered_df <- filtered_df %>% dplyr::mutate(Latitude = sp_geo[[2]], - Longitude = sp_geo[[1]]) + filtered_df <- filtered_df %>% dplyr::mutate(decimalLatitude = sp_geo[[2]], + decimalLongitude = sp_geo[[1]], + LatLong_CRS = latlong_CRS@projargs) # Store the coordinate reference system PROJ string in the dataframe coord_df <- dplyr::left_join(coord_df, filtered_df, by = "_UTMJOINCOL") } } }) df <- dplyr::left_join(df, - dplyr::select(coord_df, Lat, Long, `_UTMJOINCOL`), + dplyr::select(coord_df, decimalLatitude, decimalLongitude, LatLong_CRS, `_UTMJOINCOL`), by = "_UTMJOINCOL") %>% dplyr::select(-`_UTMJOINCOL`) - df$LatLong_CRS <- latlong_CRS@projargs # Store the wkid in the dataframe + return(df) +} +#' Coordinate Conversion from UTM to Latitude and Longitude +#' +#' @description +#' `r lifecycle::badge("superseded")` +#' `convert_utm_to_ll()` was superseded in favor of `generate_ll_from_utm()` to +#' support and encourage including zone and datum columns in datasets. `generate_ll_from_utm()` +#' also adds the ability to specify the coordinate reference system for lat/long coordinates, +#' and accepts column names either quoted or unquoted for better compatibility with +#' tidyverse piping. +#' `convert_utm_to_ll()` takes your dataframe with UTM coordinates +#' in separate Easting and Northing columns, and adds on an additional two +#' columns with the converted decimalLatitude and decimalLongitude coordinates +#' using the reference coordinate system WGS84. You may need to turn the VPN OFF +#' for this function to work properly. +#' +#' @details Define the name of your dataframe, the easting and northing columns +#' within it, the UTM zone within which those coordinates are located, and the +#' reference coordinate system (datum). UTM Northing and Easting columns must be +#' in separate columns prior to running the function. If a datum is not defined, +#' the function will default to "WGS84". If there are missing coordinates in +#' your dataframe they will be preserved, however they will be moved to the end +#' of your dataframe. Note that some parameter names are not in snake_case but +#' instead reflect DarwinCore naming conventions. +#' +#' @param df - The dataframe with UTM coordinates you would like to convert. +#' Input the name of your dataframe. +#' @param EastingCol - The name of your Easting UTM column. Input the name in +#' quotations, ie. "EastingCol". +#' @param NorthingCol - The name of your Northing UTM column. Input the name in +#' quotations, ie. "NorthingCol". +#' @param zone - The UTM Zone. Input the zone number in quotations, ie. "17". +#' @param datum - The datum used in the coordinate reference system of your +#' coordinates. Input in quotations, ie. "WGS84" +#' +#' @return The function returns your dataframe, mutated with an additional two +#' columns of decimal Longitude and decimal Latitude. +#' @export +#' +#' @examples +#' \dontrun{ +#' convert_utm_to_ll( +#' df = mydataframe, +#' EastingCol = "EastingCoords", +#' NorthingCol = "NorthingCoords", +#' zone = "17", +#' datum = "WGS84" +#' ) +#' } +convert_utm_to_ll <- function(df, + EastingCol, + NorthingCol, + zone, + datum = "WGS84") { + Base <- as.data.frame(df) + Base <- dplyr::rename(Base, "b" = EastingCol, "a" = NorthingCol) + Mid <- Base[!is.na(Base$"b" & Base$"a"), ] + Mid2 <- Base[is.na(Base$"b" & Base$"a"), ] + Final <- dplyr::select(Mid, "b", "a") + Final[1:2] <- lapply(Final[1:2], FUN = function(z) { + as.numeric(z) + }) + + Final <- cbind(Final$b, Final$a) + + v <- terra::vect(Final, crs = paste0( + "+proj=utm +zone=", + zone, + " +datum=", + datum, " + +units=m" + )) + + converted <- terra::project(v, "+proj=longlat +datum=WGS84") + + lonlat <- terra::geom(converted)[, c("x", "y")] + + df <- cbind(Mid, lonlat) + df <- plyr::rbind.fill(df, Mid2) + df <- dplyr::rename(df, + EastingCol = "b", NorthingCol = "a", + "decimalLongitude" = x, "decimalLatitude" = y + ) return(df) } diff --git a/man/convert_utm_to_ll.Rd b/man/convert_utm_to_ll.Rd index 46bf252..db2619e 100644 --- a/man/convert_utm_to_ll.Rd +++ b/man/convert_utm_to_ll.Rd @@ -4,14 +4,7 @@ \alias{convert_utm_to_ll} \title{Coordinate Conversion from UTM to Latitude and Longitude} \usage{ -convert_utm_to_ll( - df, - EastingCol, - NorthingCol, - ZoneCol, - DatumCol, - latlong_datum = "NAD83" -) +convert_utm_to_ll(df, EastingCol, NorthingCol, zone, datum = "WGS84") } \arguments{ \item{df}{\itemize{ @@ -20,64 +13,59 @@ Input the name of your dataframe. }} \item{EastingCol}{\itemize{ -\item The name of your Easting UTM column. You may input the name -with or without quotations, ie. EastingCol and "EastingCol" are both valid. +\item The name of your Easting UTM column. Input the name in +quotations, ie. "EastingCol". }} \item{NorthingCol}{\itemize{ -\item The name of your Northing UTM column. You may input the name -with or without quotations, ie. NorthingCol and "NorthingCol" are both valid. +\item The name of your Northing UTM column. Input the name in +quotations, ie. "NorthingCol". }} -\item{ZoneCol}{\itemize{ -\item The column containing the UTM zone, with or without quotations. +\item{zone}{\itemize{ +\item The UTM Zone. Input the zone number in quotations, ie. "17". }} -\item{DatumCol}{\itemize{ -\item The column containing the datum for your UTM coordinates, -with or without quotations. +\item{datum}{\itemize{ +\item The datum used in the coordinate reference system of your +coordinates. Input in quotations, ie. "WGS84" }} } \value{ The function returns your dataframe, mutated with an additional two -columns of decimal Longitude and decimal Latitude plus a column LatLong_CRS containing -a PROJ string that specifies the coordinate reference system for these data. +columns of decimal Longitude and decimal Latitude. } \description{ +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#superseded}{\figure{lifecycle-superseded.svg}{options: alt='[Superseded]'}}}{\strong{[Superseded]}} +\code{convert_utm_to_ll()} was superseded in favor of \code{generate_ll_from_utm()} to +support and encourage including zone and datum columns in datasets. \code{generate_ll_from_utm()} +also adds the ability to specify the coordinate reference system for lat/long coordinates, +and accepts column names either quoted or unquoted for better compatibility with +tidyverse piping. \code{convert_utm_to_ll()} takes your dataframe with UTM coordinates in separate Easting and Northing columns, and adds on an additional two columns with the converted decimalLatitude and decimalLongitude coordinates -using the reference coordinate system NAD83. Your data must also contain columns -specifying the zone and datum of your UTM coordinates. +using the reference coordinate system WGS84. You may need to turn the VPN OFF +for this function to work properly. } \details{ Define the name of your dataframe, the easting and northing columns within it, the UTM zone within which those coordinates are located, and the reference coordinate system (datum). UTM Northing and Easting columns must be -in separate columns prior to running the function. If a datum for the lat/long output -is not defined, the function will default to "NAD83". If there are missing coordinates in +in separate columns prior to running the function. If a datum is not defined, +the function will default to "WGS84". If there are missing coordinates in your dataframe they will be preserved, however they will be moved to the end of your dataframe. Note that some parameter names are not in snake_case but instead reflect DarwinCore naming conventions. } \examples{ \dontrun{ - -my_dataframe \%>\% -convert_utm_to_ll( - EastingCol = UTM_X, - NorthingCol = UTM_Y, - ZoneCol = Zone, - DatumCol = Datum -) - convert_utm_to_ll( df = mydataframe, EastingCol = "EastingCoords", NorthingCol = "NorthingCoords", - ZoneCol = "zone", - DatumCol = "datum", - latlong_datum = "WGS84" + zone = "17", + datum = "WGS84" ) } } diff --git a/man/generate_ll_from_utm.Rd b/man/generate_ll_from_utm.Rd new file mode 100644 index 0000000..daa6726 --- /dev/null +++ b/man/generate_ll_from_utm.Rd @@ -0,0 +1,87 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/geography.R +\name{generate_ll_from_utm} +\alias{generate_ll_from_utm} +\title{Coordinate Conversion from UTM to Latitude and Longitude} +\usage{ +generate_ll_from_utm( + df, + EastingCol, + NorthingCol, + ZoneCol, + DatumCol, + latlong_datum = "NAD83" +) +} +\arguments{ +\item{df}{\itemize{ +\item The dataframe with UTM coordinates you would like to convert. +Input the name of your dataframe. +}} + +\item{EastingCol}{\itemize{ +\item The name of your Easting UTM column. You may input the name +with or without quotations, ie. EastingCol and "EastingCol" are both valid. +}} + +\item{NorthingCol}{\itemize{ +\item The name of your Northing UTM column. You may input the name +with or without quotations, ie. NorthingCol and "NorthingCol" are both valid. +}} + +\item{ZoneCol}{\itemize{ +\item The column containing the UTM zone, with or without quotations. +}} + +\item{DatumCol}{\itemize{ +\item The column containing the datum for your UTM coordinates, +with or without quotations. +}} +} +\value{ +The function returns your dataframe, mutated with an additional two +columns of decimalLongitude and decimalLatitude plus a column LatLong_CRS containing +a PROJ string that specifies the coordinate reference system for these data. +} +\description{ +\code{generate_ll_from_utm()} takes your dataframe with UTM coordinates +in separate Easting and Northing columns, and adds on an additional two +columns with the converted decimalLatitude and decimalLongitude coordinates +using the reference coordinate system NAD83. Your data must also contain columns +specifying the zone and datum of your UTM coordinates. +In contrast to \code{convert_utm_to_ll()} (superseded), \code{generate_ll_from_utm()} requires +zone and datum columns. It supports quoted or unquoted column names and a user-specified datum for lat/long +coordinates. It also adds an extra column to the output data table that documents the +lat/long coordinate reference system. +} +\details{ +Define the name of your dataframe, the easting and northing columns +within it, the UTM zone within which those coordinates are located, and the +reference coordinate system (datum). UTM Northing and Easting columns must be +in separate columns prior to running the function. If a datum for the lat/long output +is not defined, the function will default to "NAD83". If there are missing coordinates in +your dataframe they will be preserved, however they will be moved to the end +of your dataframe. Note that some parameter names are not in snake_case but +instead reflect DarwinCore naming conventions. +} +\examples{ +\dontrun{ + +my_dataframe \%>\% +generate_ll_from_utm( + EastingCol = UTM_X, + NorthingCol = UTM_Y, + ZoneCol = Zone, + DatumCol = Datum +) + +generate_ll_from_utm( + df = mydataframe, + EastingCol = "EastingCoords", + NorthingCol = "NorthingCoords", + ZoneCol = "zone", + DatumCol = "datum", + latlong_datum = "WGS84" +) +} +} From d7da1d128e88d59d35e636b24bf59f193ee2d5c4 Mon Sep 17 00:00:00 2001 From: Wright Date: Wed, 17 Apr 2024 10:36:12 -0600 Subject: [PATCH 4/6] Unit tests for convert_utm_to_ll --- tests/testthat/test-geography.R | 75 ++++++++++++++++++++++++++++++++- 1 file changed, 74 insertions(+), 1 deletion(-) diff --git a/tests/testthat/test-geography.R b/tests/testthat/test-geography.R index ef06930..801a479 100644 --- a/tests/testthat/test-geography.R +++ b/tests/testthat/test-geography.R @@ -107,7 +107,80 @@ test_that("fuzz_location returns well known text for souther hemisphere latitude expect_equal(is.na(wk::wk_problems(wk::new_wk_wkt(x))), TRUE) }) -#### convert_utm_to_ll +#### generate_ll_from_utm +test_that("generate_ll_from_utm adds the correct columns", { + mydataframe <- tibble::tibble(EastingCol = c(-105.70421, + -105.70431, + -105.7451), + NorthingCol = c(40.70421, + 40.70431, + 40.70451), + zone = 13, + datum = "NAD83") + x <- generate_ll_from_utm(df = mydataframe, + EastingCol = EastingCol, + NorthingCol = NorthingCol, + ZoneCol = zone, + DatumCol = datum) + expect_equal(names(x), c("EastingCol", "NorthingCol", "zone", "datum", "decimalLatitude", "decimalLongitude", "LatLong_CRS")) +}) + +#### generate_ll_from_utm +test_that("generate_ll_from_utm outputs the same number of rows as the input dataframe", { + mydataframe <- tibble::tibble(EastingCol = c(-105.70421, + -105.70431, + -105.7451), + NorthingCol = c(40.70421, + 40.70431, + 40.70451), + zone = 13, + datum = "NAD83") + mydataframe_na <- mydataframe + mydataframe_na$EastingCol[1] <- NA + + x <- generate_ll_from_utm(df = mydataframe, + EastingCol = EastingCol, + NorthingCol = NorthingCol, + ZoneCol = zone, + DatumCol = datum) + y <- generate_ll_from_utm(df = mydataframe, + EastingCol = EastingCol, + NorthingCol = NorthingCol, + ZoneCol = zone, + DatumCol = datum) + + expect_equal(nrow(x), nrow(mydataframe)) + expect_equal(nrow(y), nrow(mydataframe_na)) +}) + +#### generate_ll_from_utm +test_that("generate_ll_from_utm conversion matches that of convert_utm_to_ll", { + mydataframe <- tibble::tibble(EastingCol = c(-105.70421, + -105.70431, + -105.7451), + NorthingCol = c(40.70421, + 40.70431, + 40.70451), + zone = 13, + datum = "WGS84") + + x <- generate_ll_from_utm(df = mydataframe, + EastingCol = EastingCol, + NorthingCol = NorthingCol, + ZoneCol = zone, + DatumCol = datum, + latlong_datum = "WGS84") + y <- convert_utm_to_ll(df = mydataframe, + EastingCol = EastingCol, + NorthingCol = NorthingCol, + zone = 13, + datum = "WGS84") + + expect_equal(x$decimalLatitude, y$decimalLatitude) + expect_equal(x$decimalLongitude, y$decimalLongitude) +}) + +#### convert_utm_to_ll (superseded) test_that("convert_utm_to_ll adds the correct columns", { mydataframe <- tibble::tibble(EastingCol = c(-105.70421, -105.70431, From 596048ee12684291fc983a4c07a51f4e5b989bee Mon Sep 17 00:00:00 2001 From: Wright Date: Thu, 18 Apr 2024 09:39:31 -0600 Subject: [PATCH 5/6] Fix r cmd check warnings - add imports, missing documentation --- DESCRIPTION | 5 ++++- R/geography.R | 1 + R/utils.R | 6 +++++- man/QCkit-package.Rd | 2 +- man/generate_ll_from_utm.Rd | 4 ++++ 5 files changed, 15 insertions(+), 3 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index b464bca..3322540 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -52,7 +52,10 @@ Imports: jsonlite, here, tibble, - tidyselect + tidyselect, + glue, + sp, + withr RoxygenNote: 7.3.1 Suggests: knitr, diff --git a/R/geography.R b/R/geography.R index 3e63938..767670d 100644 --- a/R/geography.R +++ b/R/geography.R @@ -362,6 +362,7 @@ fuzz_location <- function(lat, #' @param ZoneCol - The column containing the UTM zone, with or without quotations. #' @param DatumCol - The column containing the datum for your UTM coordinates, #' with or without quotations. +#' @param latlong_datum - The datum to use for lat/long coordinates. Defaults to NAD83. #' #' @return The function returns your dataframe, mutated with an additional two #' columns of decimalLongitude and decimalLatitude plus a column LatLong_CRS containing diff --git a/R/utils.R b/R/utils.R index 2ecc8c3..33660d8 100644 --- a/R/utils.R +++ b/R/utils.R @@ -35,4 +35,8 @@ globalVariables(c("any_of", "y", "capture.output", "title", - "% Accepted")) \ No newline at end of file + "% Accepted", + "_UTMJOINCOL", + "decimalLatitude", + "decimalLongitude", + "LatLong_CRS")) \ No newline at end of file diff --git a/man/QCkit-package.Rd b/man/QCkit-package.Rd index 8d4991a..67d4e4b 100644 --- a/man/QCkit-package.Rd +++ b/man/QCkit-package.Rd @@ -28,7 +28,7 @@ Authors: Other contributors: \itemize{ - \item Sarah Kelson [contributor] + \item Sarah Kelso (\href{https://orcid.org/0009-0002-8468-6945}{ORCID}) [contributor] \item Amy Sherman (\href{https://orcid.org/0000-0002-9276-0087}{ORCID}) [contributor] } diff --git a/man/generate_ll_from_utm.Rd b/man/generate_ll_from_utm.Rd index daa6726..368c3e1 100644 --- a/man/generate_ll_from_utm.Rd +++ b/man/generate_ll_from_utm.Rd @@ -37,6 +37,10 @@ with or without quotations, ie. NorthingCol and "NorthingCol" are both valid. \item The column containing the datum for your UTM coordinates, with or without quotations. }} + +\item{latlong_datum}{\itemize{ +\item The datum to use for lat/long coordinates. Defaults to NAD83. +}} } \value{ The function returns your dataframe, mutated with an additional two From 2c4636d47148fb8bf0a6e03590570a1d8bef64c6 Mon Sep 17 00:00:00 2001 From: Wright Date: Thu, 18 Apr 2024 09:59:48 -0600 Subject: [PATCH 6/6] Rebuild pkgdown site --- docs/404.html | 2 +- docs/LICENSE-text.html | 2 +- docs/LICENSE.html | 2 +- docs/articles/DRR_Purpose_and_Scope.html | 2 +- docs/articles/Starting-a-DRR.html | 2 +- docs/articles/Using-the-DRR-Template.html | 5 +- .../bsTable-3.3.7/bootstrapTable.js | 801 ------------------ .../bsTable-3.3.7/bootstrapTable.min.css | 14 - docs/articles/index.html | 2 +- docs/authors.html | 2 +- docs/index.html | 2 +- docs/news/index.html | 2 +- docs/pkgdown.yml | 4 +- docs/reference/DC_col_check.html | 2 +- docs/reference/QCkit-package.html | 4 +- docs/reference/check_dc_cols.html | 2 +- docs/reference/check_te.html | 2 +- docs/reference/convert_datetime_format.html | 9 +- docs/reference/convert_long_to_utm.html | 2 +- docs/reference/convert_utm_to_ll.html | 18 +- docs/reference/create_datastore_script.html | 2 +- docs/reference/dot-get_unit_boundary.html | 2 +- docs/reference/fix_utc_offset.html | 7 +- docs/reference/fuzz_location.html | 2 +- docs/reference/generate_ll_from_utm.html | 200 +++++ docs/reference/get_custom_flags.html | 2 +- docs/reference/get_dc_flags.html | 2 +- docs/reference/get_df_flags.html | 2 +- docs/reference/get_dp_flags.html | 2 +- docs/reference/get_elevation.html | 2 +- docs/reference/get_park_polygon.html | 2 +- docs/reference/get_taxon_rank.html | 2 +- docs/reference/get_utm_zone.html | 2 +- docs/reference/index.html | 6 +- docs/reference/long2UTM.html | 2 +- docs/reference/order_cols.html | 2 +- docs/reference/replace_blanks.html | 2 +- docs/reference/te_check.html | 2 +- docs/reference/utm_to_ll.html | 2 +- docs/reference/validate_coord.html | 2 +- docs/reference/validate_coord_list.html | 2 +- docs/sitemap.xml | 3 + 42 files changed, 267 insertions(+), 866 deletions(-) delete mode 100644 docs/articles/Using-the-DRR-Template_files/bsTable-3.3.7/bootstrapTable.js delete mode 100644 docs/articles/Using-the-DRR-Template_files/bsTable-3.3.7/bootstrapTable.min.css create mode 100644 docs/reference/generate_ll_from_utm.html diff --git a/docs/404.html b/docs/404.html index 58a25f5..bbe9a71 100644 --- a/docs/404.html +++ b/docs/404.html @@ -106,7 +106,7 @@

Page not found (404)

-

Site built with pkgdown 2.0.7.

+

Site built with pkgdown 2.0.6.

diff --git a/docs/LICENSE-text.html b/docs/LICENSE-text.html index a057989..b5eec88 100644 --- a/docs/LICENSE-text.html +++ b/docs/LICENSE-text.html @@ -103,7 +103,7 @@

License

-

Site built with pkgdown 2.0.7.

+

Site built with pkgdown 2.0.6.

diff --git a/docs/LICENSE.html b/docs/LICENSE.html index 9e83fad..940cf0b 100644 --- a/docs/LICENSE.html +++ b/docs/LICENSE.html @@ -112,7 +112,7 @@

Statement of Purpose -

Site built with pkgdown 2.0.7.

+

Site built with pkgdown 2.0.6.

diff --git a/docs/articles/DRR_Purpose_and_Scope.html b/docs/articles/DRR_Purpose_and_Scope.html index df063e3..b45398f 100644 --- a/docs/articles/DRR_Purpose_and_Scope.html +++ b/docs/articles/DRR_Purpose_and_Scope.html @@ -431,7 +431,7 @@

References

-

Site built with pkgdown 2.0.7.

+

Site built with pkgdown 2.0.6.

diff --git a/docs/articles/Starting-a-DRR.html b/docs/articles/Starting-a-DRR.html index e9bb1d5..ba7067b 100644 --- a/docs/articles/Starting-a-DRR.html +++ b/docs/articles/Starting-a-DRR.html @@ -223,7 +223,7 @@

Examples

-

Site built with pkgdown 2.0.7.

+

Site built with pkgdown 2.0.6.

diff --git a/docs/articles/Using-the-DRR-Template.html b/docs/articles/Using-the-DRR-Template.html index 39dcbb6..4ce1257 100644 --- a/docs/articles/Using-the-DRR-Template.html +++ b/docs/articles/Using-the-DRR-Template.html @@ -82,8 +82,7 @@ - -
+
diff --git a/docs/articles/Using-the-DRR-Template_files/bsTable-3.3.7/bootstrapTable.js b/docs/articles/Using-the-DRR-Template_files/bsTable-3.3.7/bootstrapTable.js deleted file mode 100644 index 0c83d3b..0000000 --- a/docs/articles/Using-the-DRR-Template_files/bsTable-3.3.7/bootstrapTable.js +++ /dev/null @@ -1,801 +0,0 @@ -/* ======================================================================== - * Bootstrap: tooltip.js v3.4.1 - * https://getbootstrap.com/docs/3.4/javascript/#tooltip - * Inspired by the original jQuery.tipsy by Jason Frame - * ======================================================================== - * Copyright 2011-2019 Twitter, Inc. - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) - * ======================================================================== */ - -+function ($) { - 'use strict'; - - var DISALLOWED_ATTRIBUTES = ['sanitize', 'whiteList', 'sanitizeFn'] - - var uriAttrs = [ - 'background', - 'cite', - 'href', - 'itemtype', - 'longdesc', - 'poster', - 'src', - 'xlink:href' - ] - - var ARIA_ATTRIBUTE_PATTERN = /^aria-[\w-]*$/i - - var DefaultWhitelist = { - // Global attributes allowed on any supplied element below. - '*': ['class', 'dir', 'id', 'lang', 'role', ARIA_ATTRIBUTE_PATTERN], - a: ['target', 'href', 'title', 'rel'], - area: [], - b: [], - br: [], - col: [], - code: [], - div: [], - em: [], - hr: [], - h1: [], - h2: [], - h3: [], - h4: [], - h5: [], - h6: [], - i: [], - img: ['src', 'alt', 'title', 'width', 'height'], - li: [], - ol: [], - p: [], - pre: [], - s: [], - small: [], - span: [], - sub: [], - sup: [], - strong: [], - u: [], - ul: [] - } - - /** - * A pattern that recognizes a commonly useful subset of URLs that are safe. - * - * Shoutout to Angular 7 https://github.com/angular/angular/blob/7.2.4/packages/core/src/sanitization/url_sanitizer.ts - */ - var SAFE_URL_PATTERN = /^(?:(?:https?|mailto|ftp|tel|file):|[^&:/?#]*(?:[/?#]|$))/gi - - /** - * A pattern that matches safe data URLs. Only matches image, video and audio types. - * - * Shoutout to Angular 7 https://github.com/angular/angular/blob/7.2.4/packages/core/src/sanitization/url_sanitizer.ts - */ - var DATA_URL_PATTERN = /^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[a-z0-9+/]+=*$/i - - function allowedAttribute(attr, allowedAttributeList) { - var attrName = attr.nodeName.toLowerCase() - - if ($.inArray(attrName, allowedAttributeList) !== -1) { - if ($.inArray(attrName, uriAttrs) !== -1) { - return Boolean(attr.nodeValue.match(SAFE_URL_PATTERN) || attr.nodeValue.match(DATA_URL_PATTERN)) - } - - return true - } - - var regExp = $(allowedAttributeList).filter(function (index, value) { - return value instanceof RegExp - }) - - // Check if a regular expression validates the attribute. - for (var i = 0, l = regExp.length; i < l; i++) { - if (attrName.match(regExp[i])) { - return true - } - } - - return false - } - - function sanitizeHtml(unsafeHtml, whiteList, sanitizeFn) { - if (unsafeHtml.length === 0) { - return unsafeHtml - } - - if (sanitizeFn && typeof sanitizeFn === 'function') { - return sanitizeFn(unsafeHtml) - } - - // IE 8 and below don't support createHTMLDocument - if (!document.implementation || !document.implementation.createHTMLDocument) { - return unsafeHtml - } - - var createdDocument = document.implementation.createHTMLDocument('sanitization') - createdDocument.body.innerHTML = unsafeHtml - - var whitelistKeys = $.map(whiteList, function (el, i) { return i }) - var elements = $(createdDocument.body).find('*') - - for (var i = 0, len = elements.length; i < len; i++) { - var el = elements[i] - var elName = el.nodeName.toLowerCase() - - if ($.inArray(elName, whitelistKeys) === -1) { - el.parentNode.removeChild(el) - - continue - } - - var attributeList = $.map(el.attributes, function (el) { return el }) - var whitelistedAttributes = [].concat(whiteList['*'] || [], whiteList[elName] || []) - - for (var j = 0, len2 = attributeList.length; j < len2; j++) { - if (!allowedAttribute(attributeList[j], whitelistedAttributes)) { - el.removeAttribute(attributeList[j].nodeName) - } - } - } - - return createdDocument.body.innerHTML - } - - // TOOLTIP PUBLIC CLASS DEFINITION - // =============================== - - var Tooltip = function (element, options) { - this.type = null - this.options = null - this.enabled = null - this.timeout = null - this.hoverState = null - this.$element = null - this.inState = null - - this.init('tooltip', element, options) - } - - Tooltip.VERSION = '3.4.1' - - Tooltip.TRANSITION_DURATION = 150 - - Tooltip.DEFAULTS = { - animation: true, - placement: 'top', - selector: false, - template: '', - trigger: 'hover focus', - title: '', - delay: 0, - html: false, - container: false, - viewport: { - selector: 'body', - padding: 0 - }, - sanitize : true, - sanitizeFn : null, - whiteList : DefaultWhitelist - } - - Tooltip.prototype.init = function (type, element, options) { - this.enabled = true - this.type = type - this.$element = $(element) - this.options = this.getOptions(options) - this.$viewport = this.options.viewport && $(document).find($.isFunction(this.options.viewport) ? this.options.viewport.call(this, this.$element) : (this.options.viewport.selector || this.options.viewport)) - this.inState = { click: false, hover: false, focus: false } - - if (this.$element[0] instanceof document.constructor && !this.options.selector) { - throw new Error('`selector` option must be specified when initializing ' + this.type + ' on the window.document object!') - } - - var triggers = this.options.trigger.split(' ') - - for (var i = triggers.length; i--;) { - var trigger = triggers[i] - - if (trigger == 'click') { - this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this)) - } else if (trigger != 'manual') { - var eventIn = trigger == 'hover' ? 'mouseenter' : 'focusin' - var eventOut = trigger == 'hover' ? 'mouseleave' : 'focusout' - - this.$element.on(eventIn + '.' + this.type, this.options.selector, $.proxy(this.enter, this)) - this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this)) - } - } - - this.options.selector ? - (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) : - this.fixTitle() - } - - Tooltip.prototype.getDefaults = function () { - return Tooltip.DEFAULTS - } - - Tooltip.prototype.getOptions = function (options) { - var dataAttributes = this.$element.data() - - for (var dataAttr in dataAttributes) { - if (dataAttributes.hasOwnProperty(dataAttr) && $.inArray(dataAttr, DISALLOWED_ATTRIBUTES) !== -1) { - delete dataAttributes[dataAttr] - } - } - - options = $.extend({}, this.getDefaults(), dataAttributes, options) - - if (options.delay && typeof options.delay == 'number') { - options.delay = { - show: options.delay, - hide: options.delay - } - } - - if (options.sanitize) { - options.template = sanitizeHtml(options.template, options.whiteList, options.sanitizeFn) - } - - return options - } - - Tooltip.prototype.getDelegateOptions = function () { - var options = {} - var defaults = this.getDefaults() - - this._options && $.each(this._options, function (key, value) { - if (defaults[key] != value) options[key] = value - }) - - return options - } - - Tooltip.prototype.enter = function (obj) { - var self = obj instanceof this.constructor ? - obj : $(obj.currentTarget).data('bs.' + this.type) - - if (!self) { - self = new this.constructor(obj.currentTarget, this.getDelegateOptions()) - $(obj.currentTarget).data('bs.' + this.type, self) - } - - if (obj instanceof $.Event) { - self.inState[obj.type == 'focusin' ? 'focus' : 'hover'] = true - } - - if (self.tip().hasClass('in') || self.hoverState == 'in') { - self.hoverState = 'in' - return - } - - clearTimeout(self.timeout) - - self.hoverState = 'in' - - if (!self.options.delay || !self.options.delay.show) return self.show() - - self.timeout = setTimeout(function () { - if (self.hoverState == 'in') self.show() - }, self.options.delay.show) - } - - Tooltip.prototype.isInStateTrue = function () { - for (var key in this.inState) { - if (this.inState[key]) return true - } - - return false - } - - Tooltip.prototype.leave = function (obj) { - var self = obj instanceof this.constructor ? - obj : $(obj.currentTarget).data('bs.' + this.type) - - if (!self) { - self = new this.constructor(obj.currentTarget, this.getDelegateOptions()) - $(obj.currentTarget).data('bs.' + this.type, self) - } - - if (obj instanceof $.Event) { - self.inState[obj.type == 'focusout' ? 'focus' : 'hover'] = false - } - - if (self.isInStateTrue()) return - - clearTimeout(self.timeout) - - self.hoverState = 'out' - - if (!self.options.delay || !self.options.delay.hide) return self.hide() - - self.timeout = setTimeout(function () { - if (self.hoverState == 'out') self.hide() - }, self.options.delay.hide) - } - - Tooltip.prototype.show = function () { - var e = $.Event('show.bs.' + this.type) - - if (this.hasContent() && this.enabled) { - this.$element.trigger(e) - - var inDom = $.contains(this.$element[0].ownerDocument.documentElement, this.$element[0]) - if (e.isDefaultPrevented() || !inDom) return - var that = this - - var $tip = this.tip() - - var tipId = this.getUID(this.type) - - this.setContent() - $tip.attr('id', tipId) - this.$element.attr('aria-describedby', tipId) - - if (this.options.animation) $tip.addClass('fade') - - var placement = typeof this.options.placement == 'function' ? - this.options.placement.call(this, $tip[0], this.$element[0]) : - this.options.placement - - var autoToken = /\s?auto?\s?/i - var autoPlace = autoToken.test(placement) - if (autoPlace) placement = placement.replace(autoToken, '') || 'top' - - $tip - .detach() - .css({ top: 0, left: 0, display: 'block' }) - .addClass(placement) - .data('bs.' + this.type, this) - - this.options.container ? $tip.appendTo($(document).find(this.options.container)) : $tip.insertAfter(this.$element) - this.$element.trigger('inserted.bs.' + this.type) - - var pos = this.getPosition() - var actualWidth = $tip[0].offsetWidth - var actualHeight = $tip[0].offsetHeight - - if (autoPlace) { - var orgPlacement = placement - var viewportDim = this.getPosition(this.$viewport) - - placement = placement == 'bottom' && pos.bottom + actualHeight > viewportDim.bottom ? 'top' : - placement == 'top' && pos.top - actualHeight < viewportDim.top ? 'bottom' : - placement == 'right' && pos.right + actualWidth > viewportDim.width ? 'left' : - placement == 'left' && pos.left - actualWidth < viewportDim.left ? 'right' : - placement - - $tip - .removeClass(orgPlacement) - .addClass(placement) - } - - var calculatedOffset = this.getCalculatedOffset(placement, pos, actualWidth, actualHeight) - - this.applyPlacement(calculatedOffset, placement) - - var complete = function () { - var prevHoverState = that.hoverState - that.$element.trigger('shown.bs.' + that.type) - that.hoverState = null - - if (prevHoverState == 'out') that.leave(that) - } - - $.support.transition && this.$tip.hasClass('fade') ? - $tip - .one('bsTransitionEnd', complete) - .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) : - complete() - } - } - - Tooltip.prototype.applyPlacement = function (offset, placement) { - var $tip = this.tip() - var width = $tip[0].offsetWidth - var height = $tip[0].offsetHeight - - // manually read margins because getBoundingClientRect includes difference - var marginTop = parseInt($tip.css('margin-top'), 10) - var marginLeft = parseInt($tip.css('margin-left'), 10) - - // we must check for NaN for ie 8/9 - if (isNaN(marginTop)) marginTop = 0 - if (isNaN(marginLeft)) marginLeft = 0 - - offset.top += marginTop - offset.left += marginLeft - - // $.fn.offset doesn't round pixel values - // so we use setOffset directly with our own function B-0 - $.offset.setOffset($tip[0], $.extend({ - using: function (props) { - $tip.css({ - top: Math.round(props.top), - left: Math.round(props.left) - }) - } - }, offset), 0) - - $tip.addClass('in') - - // check to see if placing tip in new offset caused the tip to resize itself - var actualWidth = $tip[0].offsetWidth - var actualHeight = $tip[0].offsetHeight - - if (placement == 'top' && actualHeight != height) { - offset.top = offset.top + height - actualHeight - } - - var delta = this.getViewportAdjustedDelta(placement, offset, actualWidth, actualHeight) - - if (delta.left) offset.left += delta.left - else offset.top += delta.top - - var isVertical = /top|bottom/.test(placement) - var arrowDelta = isVertical ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight - var arrowOffsetPosition = isVertical ? 'offsetWidth' : 'offsetHeight' - - $tip.offset(offset) - this.replaceArrow(arrowDelta, $tip[0][arrowOffsetPosition], isVertical) - } - - Tooltip.prototype.replaceArrow = function (delta, dimension, isVertical) { - this.arrow() - .css(isVertical ? 'left' : 'top', 50 * (1 - delta / dimension) + '%') - .css(isVertical ? 'top' : 'left', '') - } - - Tooltip.prototype.setContent = function () { - var $tip = this.tip() - var title = this.getTitle() - - if (this.options.html) { - if (this.options.sanitize) { - title = sanitizeHtml(title, this.options.whiteList, this.options.sanitizeFn) - } - - $tip.find('.tooltip-inner').html(title) - } else { - $tip.find('.tooltip-inner').text(title) - } - - $tip.removeClass('fade in top bottom left right') - } - - Tooltip.prototype.hide = function (callback) { - var that = this - var $tip = $(this.$tip) - var e = $.Event('hide.bs.' + this.type) - - function complete() { - if (that.hoverState != 'in') $tip.detach() - if (that.$element) { // TODO: Check whether guarding this code with this `if` is really necessary. - that.$element - .removeAttr('aria-describedby') - .trigger('hidden.bs.' + that.type) - } - callback && callback() - } - - this.$element.trigger(e) - - if (e.isDefaultPrevented()) return - - $tip.removeClass('in') - - $.support.transition && $tip.hasClass('fade') ? - $tip - .one('bsTransitionEnd', complete) - .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) : - complete() - - this.hoverState = null - - return this - } - - Tooltip.prototype.fixTitle = function () { - var $e = this.$element - if ($e.attr('title') || typeof $e.attr('data-original-title') != 'string') { - $e.attr('data-original-title', $e.attr('title') || '').attr('title', '') - } - } - - Tooltip.prototype.hasContent = function () { - return this.getTitle() - } - - Tooltip.prototype.getPosition = function ($element) { - $element = $element || this.$element - - var el = $element[0] - var isBody = el.tagName == 'BODY' - - var elRect = el.getBoundingClientRect() - if (elRect.width == null) { - // width and height are missing in IE8, so compute them manually; see https://github.com/twbs/bootstrap/issues/14093 - elRect = $.extend({}, elRect, { width: elRect.right - elRect.left, height: elRect.bottom - elRect.top }) - } - var isSvg = window.SVGElement && el instanceof window.SVGElement - // Avoid using $.offset() on SVGs since it gives incorrect results in jQuery 3. - // See https://github.com/twbs/bootstrap/issues/20280 - var elOffset = isBody ? { top: 0, left: 0 } : (isSvg ? null : $element.offset()) - var scroll = { scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.scrollTop() } - var outerDims = isBody ? { width: $(window).width(), height: $(window).height() } : null - - return $.extend({}, elRect, scroll, outerDims, elOffset) - } - - Tooltip.prototype.getCalculatedOffset = function (placement, pos, actualWidth, actualHeight) { - return placement == 'bottom' ? { top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2 } : - placement == 'top' ? { top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2 } : - placement == 'left' ? { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth } : - /* placement == 'right' */ { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width } - - } - - Tooltip.prototype.getViewportAdjustedDelta = function (placement, pos, actualWidth, actualHeight) { - var delta = { top: 0, left: 0 } - if (!this.$viewport) return delta - - var viewportPadding = this.options.viewport && this.options.viewport.padding || 0 - var viewportDimensions = this.getPosition(this.$viewport) - - if (/right|left/.test(placement)) { - var topEdgeOffset = pos.top - viewportPadding - viewportDimensions.scroll - var bottomEdgeOffset = pos.top + viewportPadding - viewportDimensions.scroll + actualHeight - if (topEdgeOffset < viewportDimensions.top) { // top overflow - delta.top = viewportDimensions.top - topEdgeOffset - } else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { // bottom overflow - delta.top = viewportDimensions.top + viewportDimensions.height - bottomEdgeOffset - } - } else { - var leftEdgeOffset = pos.left - viewportPadding - var rightEdgeOffset = pos.left + viewportPadding + actualWidth - if (leftEdgeOffset < viewportDimensions.left) { // left overflow - delta.left = viewportDimensions.left - leftEdgeOffset - } else if (rightEdgeOffset > viewportDimensions.right) { // right overflow - delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset - } - } - - return delta - } - - Tooltip.prototype.getTitle = function () { - var title - var $e = this.$element - var o = this.options - - title = $e.attr('data-original-title') - || (typeof o.title == 'function' ? o.title.call($e[0]) : o.title) - - return title - } - - Tooltip.prototype.getUID = function (prefix) { - do prefix += ~~(Math.random() * 1000000) - while (document.getElementById(prefix)) - return prefix - } - - Tooltip.prototype.tip = function () { - if (!this.$tip) { - this.$tip = $(this.options.template) - if (this.$tip.length != 1) { - throw new Error(this.type + ' `template` option must consist of exactly 1 top-level element!') - } - } - return this.$tip - } - - Tooltip.prototype.arrow = function () { - return (this.$arrow = this.$arrow || this.tip().find('.tooltip-arrow')) - } - - Tooltip.prototype.enable = function () { - this.enabled = true - } - - Tooltip.prototype.disable = function () { - this.enabled = false - } - - Tooltip.prototype.toggleEnabled = function () { - this.enabled = !this.enabled - } - - Tooltip.prototype.toggle = function (e) { - var self = this - if (e) { - self = $(e.currentTarget).data('bs.' + this.type) - if (!self) { - self = new this.constructor(e.currentTarget, this.getDelegateOptions()) - $(e.currentTarget).data('bs.' + this.type, self) - } - } - - if (e) { - self.inState.click = !self.inState.click - if (self.isInStateTrue()) self.enter(self) - else self.leave(self) - } else { - self.tip().hasClass('in') ? self.leave(self) : self.enter(self) - } - } - - Tooltip.prototype.destroy = function () { - var that = this - clearTimeout(this.timeout) - this.hide(function () { - that.$element.off('.' + that.type).removeData('bs.' + that.type) - if (that.$tip) { - that.$tip.detach() - } - that.$tip = null - that.$arrow = null - that.$viewport = null - that.$element = null - }) - } - - Tooltip.prototype.sanitizeHtml = function (unsafeHtml) { - return sanitizeHtml(unsafeHtml, this.options.whiteList, this.options.sanitizeFn) - } - - // TOOLTIP PLUGIN DEFINITION - // ========================= - - function Plugin(option) { - return this.each(function () { - var $this = $(this) - var data = $this.data('bs.tooltip') - var options = typeof option == 'object' && option - - if (!data && /destroy|hide/.test(option)) return - if (!data) $this.data('bs.tooltip', (data = new Tooltip(this, options))) - if (typeof option == 'string') data[option]() - }) - } - - var old = $.fn.tooltip - - $.fn.tooltip = Plugin - $.fn.tooltip.Constructor = Tooltip - - - // TOOLTIP NO CONFLICT - // =================== - - $.fn.tooltip.noConflict = function () { - $.fn.tooltip = old - return this - } - -}(jQuery); - -/* ======================================================================== - * Bootstrap: popover.js v3.4.1 - * https://getbootstrap.com/docs/3.4/javascript/#popovers - * ======================================================================== - * Copyright 2011-2019 Twitter, Inc. - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) - * ======================================================================== */ - - -+function ($) { - 'use strict'; - - // POPOVER PUBLIC CLASS DEFINITION - // =============================== - - var Popover = function (element, options) { - this.init('popover', element, options) - } - - if (!$.fn.tooltip) throw new Error('Popover requires tooltip.js') - - Popover.VERSION = '3.4.1' - - Popover.DEFAULTS = $.extend({}, $.fn.tooltip.Constructor.DEFAULTS, { - placement: 'right', - trigger: 'click', - content: '', - template: '' - }) - - - // NOTE: POPOVER EXTENDS tooltip.js - // ================================ - - Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype) - - Popover.prototype.constructor = Popover - - Popover.prototype.getDefaults = function () { - return Popover.DEFAULTS - } - - Popover.prototype.setContent = function () { - var $tip = this.tip() - var title = this.getTitle() - var content = this.getContent() - - if (this.options.html) { - var typeContent = typeof content - - if (this.options.sanitize) { - title = this.sanitizeHtml(title) - - if (typeContent === 'string') { - content = this.sanitizeHtml(content) - } - } - - $tip.find('.popover-title').html(title) - $tip.find('.popover-content').children().detach().end()[ - typeContent === 'string' ? 'html' : 'append' - ](content) - } else { - $tip.find('.popover-title').text(title) - $tip.find('.popover-content').children().detach().end().text(content) - } - - $tip.removeClass('fade top bottom left right in') - - // IE8 doesn't accept hiding via the `:empty` pseudo selector, we have to do - // this manually by checking the contents. - if (!$tip.find('.popover-title').html()) $tip.find('.popover-title').hide() - } - - Popover.prototype.hasContent = function () { - return this.getTitle() || this.getContent() - } - - Popover.prototype.getContent = function () { - var $e = this.$element - var o = this.options - - return $e.attr('data-content') - || (typeof o.content == 'function' ? - o.content.call($e[0]) : - o.content) - } - - Popover.prototype.arrow = function () { - return (this.$arrow = this.$arrow || this.tip().find('.arrow')) - } - - - // POPOVER PLUGIN DEFINITION - // ========================= - - function Plugin(option) { - return this.each(function () { - var $this = $(this) - var data = $this.data('bs.popover') - var options = typeof option == 'object' && option - - if (!data && /destroy|hide/.test(option)) return - if (!data) $this.data('bs.popover', (data = new Popover(this, options))) - if (typeof option == 'string') data[option]() - }) - } - - var old = $.fn.popover - - $.fn.popover = Plugin - $.fn.popover.Constructor = Popover - - - // POPOVER NO CONFLICT - // =================== - - $.fn.popover.noConflict = function () { - $.fn.popover = old - return this - } - -}(jQuery); diff --git a/docs/articles/Using-the-DRR-Template_files/bsTable-3.3.7/bootstrapTable.min.css b/docs/articles/Using-the-DRR-Template_files/bsTable-3.3.7/bootstrapTable.min.css deleted file mode 100644 index 7d1e81f..0000000 --- a/docs/articles/Using-the-DRR-Template_files/bsTable-3.3.7/bootstrapTable.min.css +++ /dev/null @@ -1,14 +0,0 @@ -/*! - * Bootstrap v3.3.7 (http://getbootstrap.com) - * Copyright 2011-2018 Twitter, Inc. - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) - */ - -/*! - * Generated using the Bootstrap Customizer () - * Config saved to config.json and - *//*! - * Bootstrap v3.3.7 (http://getbootstrap.com) - * Copyright 2011-2016 Twitter, Inc. - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) - *//*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */table{border-collapse:collapse;border-spacing:0}td,th{padding:0}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}*:before,*:after{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}table{background-color:transparent}caption{padding-top:8px;padding-bottom:8px;color:#777;text-align:left}th{text-align:left}.table{width:100%;max-width:100%;margin-bottom:20px}.table>thead>tr>th,.table>tbody>tr>th,.table>tfoot>tr>th,.table>thead>tr>td,.table>tbody>tr>td,.table>tfoot>tr>td{padding:8px;line-height:1.42857143;vertical-align:top;border-top:1px solid #ddd}.table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #ddd}.table>caption+thead>tr:first-child>th,.table>colgroup+thead>tr:first-child>th,.table>thead:first-child>tr:first-child>th,.table>caption+thead>tr:first-child>td,.table>colgroup+thead>tr:first-child>td,.table>thead:first-child>tr:first-child>td{border-top:0}.table>tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed>thead>tr>th,.table-condensed>tbody>tr>th,.table-condensed>tfoot>tr>th,.table-condensed>thead>tr>td,.table-condensed>tbody>tr>td,.table-condensed>tfoot>tr>td{padding:5px}.table-bordered{border:1px solid #ddd}.table-bordered>thead>tr>th,.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>td,.table-bordered>tbody>tr>td,.table-bordered>tfoot>tr>td{border:1px solid #ddd}.table-bordered>thead>tr>th,.table-bordered>thead>tr>td{border-bottom-width:2px}.table-striped>tbody>tr:nth-of-type(odd){background-color:#f9f9f9}.table-hover>tbody>tr:hover{background-color:#f5f5f5}table col[class*="col-"]{position:static;float:none;display:table-column}table td[class*="col-"],table th[class*="col-"]{position:static;float:none;display:table-cell}.table>thead>tr>td.active,.table>tbody>tr>td.active,.table>tfoot>tr>td.active,.table>thead>tr>th.active,.table>tbody>tr>th.active,.table>tfoot>tr>th.active,.table>thead>tr.active>td,.table>tbody>tr.active>td,.table>tfoot>tr.active>td,.table>thead>tr.active>th,.table>tbody>tr.active>th,.table>tfoot>tr.active>th{background-color:#f5f5f5}.table-hover>tbody>tr>td.active:hover,.table-hover>tbody>tr>th.active:hover,.table-hover>tbody>tr.active:hover>td,.table-hover>tbody>tr:hover>.active,.table-hover>tbody>tr.active:hover>th{background-color:#e8e8e8}.table>thead>tr>td.success,.table>tbody>tr>td.success,.table>tfoot>tr>td.success,.table>thead>tr>th.success,.table>tbody>tr>th.success,.table>tfoot>tr>th.success,.table>thead>tr.success>td,.table>tbody>tr.success>td,.table>tfoot>tr.success>td,.table>thead>tr.success>th,.table>tbody>tr.success>th,.table>tfoot>tr.success>th{background-color:#dff0d8}.table-hover>tbody>tr>td.success:hover,.table-hover>tbody>tr>th.success:hover,.table-hover>tbody>tr.success:hover>td,.table-hover>tbody>tr:hover>.success,.table-hover>tbody>tr.success:hover>th{background-color:#d0e9c6}.table>thead>tr>td.info,.table>tbody>tr>td.info,.table>tfoot>tr>td.info,.table>thead>tr>th.info,.table>tbody>tr>th.info,.table>tfoot>tr>th.info,.table>thead>tr.info>td,.table>tbody>tr.info>td,.table>tfoot>tr.info>td,.table>thead>tr.info>th,.table>tbody>tr.info>th,.table>tfoot>tr.info>th{background-color:#d9edf7}.table-hover>tbody>tr>td.info:hover,.table-hover>tbody>tr>th.info:hover,.table-hover>tbody>tr.info:hover>td,.table-hover>tbody>tr:hover>.info,.table-hover>tbody>tr.info:hover>th{background-color:#c4e3f3}.table>thead>tr>td.warning,.table>tbody>tr>td.warning,.table>tfoot>tr>td.warning,.table>thead>tr>th.warning,.table>tbody>tr>th.warning,.table>tfoot>tr>th.warning,.table>thead>tr.warning>td,.table>tbody>tr.warning>td,.table>tfoot>tr.warning>td,.table>thead>tr.warning>th,.table>tbody>tr.warning>th,.table>tfoot>tr.warning>th{background-color:#fcf8e3}.table-hover>tbody>tr>td.warning:hover,.table-hover>tbody>tr>th.warning:hover,.table-hover>tbody>tr.warning:hover>td,.table-hover>tbody>tr:hover>.warning,.table-hover>tbody>tr.warning:hover>th{background-color:#faf2cc}.table>thead>tr>td.danger,.table>tbody>tr>td.danger,.table>tfoot>tr>td.danger,.table>thead>tr>th.danger,.table>tbody>tr>th.danger,.table>tfoot>tr>th.danger,.table>thead>tr.danger>td,.table>tbody>tr.danger>td,.table>tfoot>tr.danger>td,.table>thead>tr.danger>th,.table>tbody>tr.danger>th,.table>tfoot>tr.danger>th{background-color:#f2dede}.table-hover>tbody>tr>td.danger:hover,.table-hover>tbody>tr>th.danger:hover,.table-hover>tbody>tr.danger:hover>td,.table-hover>tbody>tr:hover>.danger,.table-hover>tbody>tr.danger:hover>th{background-color:#ebcccc}.table-responsive{overflow-x:auto;min-height:0.01%}@media screen and (max-width:767px){.table-responsive{width:100%;margin-bottom:15px;overflow-y:hidden;-ms-overflow-style:-ms-autohiding-scrollbar;border:1px solid #ddd}.table-responsive>.table{margin-bottom:0}.table-responsive>.table>thead>tr>th,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tfoot>tr>td{white-space:nowrap}.table-responsive>.table-bordered{border:0}.table-responsive>.table-bordered>thead>tr>th:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child{border-left:0}.table-responsive>.table-bordered>thead>tr>th:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child{border-right:0}.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>th,.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>td{border-bottom:0}}.tooltip{position:absolute;z-index:1070;display:block;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-style:normal;font-weight:normal;letter-spacing:normal;line-break:auto;line-height:1.42857143;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;white-space:normal;word-break:normal;word-spacing:normal;word-wrap:normal;font-size:12px;opacity:0;filter:alpha(opacity=0)}.tooltip.in{opacity:.9;filter:alpha(opacity=90)}.tooltip.top{margin-top:-3px;padding:5px 0}.tooltip.right{margin-left:3px;padding:0 5px}.tooltip.bottom{margin-top:3px;padding:5px 0}.tooltip.left{margin-left:-3px;padding:0 5px}.tooltip-inner{max-width:200px;padding:3px 8px;color:#fff;text-align:center;background-color:#000;border-radius:4px}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-left .tooltip-arrow{bottom:0;right:5px;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-right .tooltip-arrow{bottom:0;left:5px;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#000}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#000}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-left .tooltip-arrow{top:0;right:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-right .tooltip-arrow{top:0;left:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.popover{position:absolute;top:0;left:0;z-index:1060;display:none;max-width:276px;padding:1px;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-style:normal;font-weight:normal;letter-spacing:normal;line-break:auto;line-height:1.42857143;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;white-space:normal;word-break:normal;word-spacing:normal;word-wrap:normal;font-size:14px;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.2);border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,0.2);box-shadow:0 5px 10px rgba(0,0,0,0.2)}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover-title{margin:0;padding:8px 14px;font-size:14px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-radius:5px 5px 0 0}.popover-content{padding:9px 14px}.popover>.arrow,.popover>.arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover>.arrow{border-width:11px}.popover>.arrow:after{border-width:10px;content:""}.popover.top>.arrow{left:50%;margin-left:-11px;border-bottom-width:0;border-top-color:#999;border-top-color:rgba(0,0,0,0.25);bottom:-11px}.popover.top>.arrow:after{content:" ";bottom:1px;margin-left:-10px;border-bottom-width:0;border-top-color:#fff}.popover.right>.arrow{top:50%;left:-11px;margin-top:-11px;border-left-width:0;border-right-color:#999;border-right-color:rgba(0,0,0,0.25)}.popover.right>.arrow:after{content:" ";left:1px;bottom:-10px;border-left-width:0;border-right-color:#fff}.popover.bottom>.arrow{left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,0.25);top:-11px}.popover.bottom>.arrow:after{content:" ";top:1px;margin-left:-10px;border-top-width:0;border-bottom-color:#fff}.popover.left>.arrow{top:50%;right:-11px;margin-top:-11px;border-right-width:0;border-left-color:#999;border-left-color:rgba(0,0,0,0.25)}.popover.left>.arrow:after{content:" ";right:1px;border-right-width:0;border-left-color:#fff;bottom:-10px}.clearfix:before,.clearfix:after{content:" ";display:table}.clearfix:after{clear:both}.center-block{display:block;margin-left:auto;margin-right:auto}.pull-right{float:right !important}.pull-left{float:left !important}.hide{display:none !important}.show{display:block !important}.invisible{visibility:hidden}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.hidden{display:none !important}.affix{position:fixed} diff --git a/docs/articles/index.html b/docs/articles/index.html index ff371de..dc24a3b 100644 --- a/docs/articles/index.html +++ b/docs/articles/index.html @@ -82,7 +82,7 @@

All vignettes

-

Site built with pkgdown 2.0.7.

+

Site built with pkgdown 2.0.6.

diff --git a/docs/authors.html b/docs/authors.html index d4f612a..725329b 100644 --- a/docs/authors.html +++ b/docs/authors.html @@ -120,7 +120,7 @@

Citation

-

Site built with pkgdown 2.0.7.

+

Site built with pkgdown 2.0.6.

diff --git a/docs/index.html b/docs/index.html index fd27f61..9b95b5d 100644 --- a/docs/index.html +++ b/docs/index.html @@ -166,7 +166,7 @@

Dev status

-

Site built with pkgdown 2.0.7.

+

Site built with pkgdown 2.0.6.

diff --git a/docs/news/index.html b/docs/news/index.html index 9bb61f5..1e4b4bc 100644 --- a/docs/news/index.html +++ b/docs/news/index.html @@ -158,7 +158,7 @@

Examples

-

Site built with pkgdown 2.0.7.

+

Site built with pkgdown 2.0.6.

diff --git a/docs/reference/QCkit-package.html b/docs/reference/QCkit-package.html index 8faded3..31a3fbb 100644 --- a/docs/reference/QCkit-package.html +++ b/docs/reference/QCkit-package.html @@ -81,7 +81,7 @@

Author

Authors:

Other contributors:

  • Sarah Kelson [contributor]

  • +

Other contributors:

  • Sarah Kelso (ORCID) [contributor]

  • Amy Sherman (ORCID) [contributor]

@@ -97,7 +97,7 @@

Author

-

Site built with pkgdown 2.0.7.

+

Site built with pkgdown 2.0.6.

diff --git a/docs/reference/check_dc_cols.html b/docs/reference/check_dc_cols.html index 191d85b..5dc8f2a 100644 --- a/docs/reference/check_dc_cols.html +++ b/docs/reference/check_dc_cols.html @@ -109,7 +109,7 @@

Examples

-

Site built with pkgdown 2.0.7.

+

Site built with pkgdown 2.0.6.

diff --git a/docs/reference/check_te.html b/docs/reference/check_te.html index a5fe772..3a08270 100644 --- a/docs/reference/check_te.html +++ b/docs/reference/check_te.html @@ -133,7 +133,7 @@

Examples

-

Site built with pkgdown 2.0.7.

+

Site built with pkgdown 2.0.6.

diff --git a/docs/reference/convert_datetime_format.html b/docs/reference/convert_datetime_format.html index ff5fa6b..e849325 100644 --- a/docs/reference/convert_datetime_format.html +++ b/docs/reference/convert_datetime_format.html @@ -96,12 +96,9 @@

Details

Examples

convert_datetime_format("MM/DD/YYYY")
-#> Warning: internal error -3 in R_decompress1
-#> Error in eval(expr, envir, enclos): lazy-load database 'C:/Users/rlbaker/AppData/Local/R/win-library/4.3/QCkit/R/QCkit.rdb' is corrupt
+#> [1] "%m/%d/%Y"
 convert_datetime_format(c("MM/DD/YYYY", "YY-MM-DD"))
-#> Warning: restarting interrupted promise evaluation
-#> Warning: internal error -3 in R_decompress1
-#> Error in eval(expr, envir, enclos): lazy-load database 'C:/Users/rlbaker/AppData/Local/R/win-library/4.3/QCkit/R/QCkit.rdb' is corrupt
+#> [1] "%m/%d/%Y" "%y-%m-%d"
 
 
@@ -117,7 +114,7 @@

Examples

-

Site built with pkgdown 2.0.7.

+

Site built with pkgdown 2.0.6.

diff --git a/docs/reference/convert_long_to_utm.html b/docs/reference/convert_long_to_utm.html index bc24386..7bead2c 100644 --- a/docs/reference/convert_long_to_utm.html +++ b/docs/reference/convert_long_to_utm.html @@ -111,7 +111,7 @@

Details

-

Site built with pkgdown 2.0.7.

+

Site built with pkgdown 2.0.6.

diff --git a/docs/reference/convert_utm_to_ll.html b/docs/reference/convert_utm_to_ll.html index 0d1f305..b3c7c33 100644 --- a/docs/reference/convert_utm_to_ll.html +++ b/docs/reference/convert_utm_to_ll.html @@ -1,5 +1,11 @@ -Coordinate Conversion from UTM to Latitude and Longitude — convert_utm_to_ll • QCkitCoordinate Conversion from UTM to Latitude and Longitude — convert_utm_to_ll • QCkit -

convert_utm_to_ll() takes your dataframe with UTM coordinates +

[Superseded] +convert_utm_to_ll() was superseded in favor of generate_ll_from_utm() to +support and encourage including zone and datum columns in datasets. generate_ll_from_utm() +also adds the ability to specify the coordinate reference system for lat/long coordinates, +and accepts column names either quoted or unquoted for better compatibility with +tidyverse piping. +convert_utm_to_ll() takes your dataframe with UTM coordinates in separate Easting and Northing columns, and adds on an additional two columns with the converted decimalLatitude and decimalLongitude coordinates using the reference coordinate system WGS84. You may need to turn the VPN OFF @@ -155,7 +167,7 @@

Examples

-

Site built with pkgdown 2.0.7.

+

Site built with pkgdown 2.0.6.

diff --git a/docs/reference/create_datastore_script.html b/docs/reference/create_datastore_script.html index b160f03..4eabec8 100644 --- a/docs/reference/create_datastore_script.html +++ b/docs/reference/create_datastore_script.html @@ -130,7 +130,7 @@

Examples

-

Site built with pkgdown 2.0.7.

+

Site built with pkgdown 2.0.6.

diff --git a/docs/reference/dot-get_unit_boundary.html b/docs/reference/dot-get_unit_boundary.html index 9786ce9..4433e64 100644 --- a/docs/reference/dot-get_unit_boundary.html +++ b/docs/reference/dot-get_unit_boundary.html @@ -104,7 +104,7 @@

Examples

-

Site built with pkgdown 2.0.7.

+

Site built with pkgdown 2.0.6.

diff --git a/docs/reference/fix_utc_offset.html b/docs/reference/fix_utc_offset.html index a0bcce1..8cd74fd 100644 --- a/docs/reference/fix_utc_offset.html +++ b/docs/reference/fix_utc_offset.html @@ -90,8 +90,9 @@

Examples

datetimes <- c("2023-11-16T03:32:49+07:00", "2023-11-16T03:32:49-07",
 "2023-11-16T03:32:49","2023-11-16T03:32:49Z")
 fix_utc_offset(datetimes)
-#> Warning: internal error -3 in R_decompress1
-#> Error in eval(expr, envir, enclos): lazy-load database 'C:/Users/rlbaker/AppData/Local/R/win-library/4.3/QCkit/R/QCkit.rdb' is corrupt
+#> Warning: Date strings contain missing or invalid UTC offsets
+#> [1] "2023-11-16T03:32:49+0700" "2023-11-16T03:32:49-0700"
+#> [3] "2023-11-16T03:32:49"      "2023-11-16T03:32:49+0000"
 
 
@@ -107,7 +108,7 @@

Examples

-

Site built with pkgdown 2.0.7.

+

Site built with pkgdown 2.0.6.

diff --git a/docs/reference/fuzz_location.html b/docs/reference/fuzz_location.html index ead9e63..08ec5de 100644 --- a/docs/reference/fuzz_location.html +++ b/docs/reference/fuzz_location.html @@ -134,7 +134,7 @@

Examples

-

Site built with pkgdown 2.0.7.

+

Site built with pkgdown 2.0.6.

diff --git a/docs/reference/generate_ll_from_utm.html b/docs/reference/generate_ll_from_utm.html new file mode 100644 index 0000000..bdc21ff --- /dev/null +++ b/docs/reference/generate_ll_from_utm.html @@ -0,0 +1,200 @@ + +Coordinate Conversion from UTM to Latitude and Longitude — generate_ll_from_utm • QCkit + + +
+
+ + + +
+
+ + +
+

generate_ll_from_utm() takes your dataframe with UTM coordinates +in separate Easting and Northing columns, and adds on an additional two +columns with the converted decimalLatitude and decimalLongitude coordinates +using the reference coordinate system NAD83. Your data must also contain columns +specifying the zone and datum of your UTM coordinates. +In contrast to convert_utm_to_ll() (superseded), generate_ll_from_utm() requires +zone and datum columns. It supports quoted or unquoted column names and a user-specified datum for lat/long +coordinates. It also adds an extra column to the output data table that documents the +lat/long coordinate reference system.

+
+ +
+
generate_ll_from_utm(
+  df,
+  EastingCol,
+  NorthingCol,
+  ZoneCol,
+  DatumCol,
+  latlong_datum = "NAD83"
+)
+
+ +
+

Arguments

+
df
+
  • The dataframe with UTM coordinates you would like to convert. +Input the name of your dataframe.

  • +
+ + +
EastingCol
+
  • The name of your Easting UTM column. You may input the name +with or without quotations, ie. EastingCol and "EastingCol" are both valid.

  • +
+ + +
NorthingCol
+
  • The name of your Northing UTM column. You may input the name +with or without quotations, ie. NorthingCol and "NorthingCol" are both valid.

  • +
+ + +
ZoneCol
+
  • The column containing the UTM zone, with or without quotations.

  • +
+ + +
DatumCol
+
  • The column containing the datum for your UTM coordinates, +with or without quotations.

  • +
+ + +
latlong_datum
+
  • The datum to use for lat/long coordinates. Defaults to NAD83.

  • +
+ +
+
+

Value

+ + +

The function returns your dataframe, mutated with an additional two +columns of decimalLongitude and decimalLatitude plus a column LatLong_CRS containing +a PROJ string that specifies the coordinate reference system for these data.

+
+
+

Details

+

Define the name of your dataframe, the easting and northing columns +within it, the UTM zone within which those coordinates are located, and the +reference coordinate system (datum). UTM Northing and Easting columns must be +in separate columns prior to running the function. If a datum for the lat/long output +is not defined, the function will default to "NAD83". If there are missing coordinates in +your dataframe they will be preserved, however they will be moved to the end +of your dataframe. Note that some parameter names are not in snake_case but +instead reflect DarwinCore naming conventions.

+
+ +
+

Examples

+
if (FALSE) {
+
+my_dataframe %>%
+generate_ll_from_utm(
+  EastingCol = UTM_X,
+  NorthingCol = UTM_Y,
+  ZoneCol = Zone,
+  DatumCol = Datum
+)
+
+generate_ll_from_utm(
+  df = mydataframe,
+  EastingCol = "EastingCoords",
+  NorthingCol = "NorthingCoords",
+  ZoneCol = "zone",
+  DatumCol = "datum",
+  latlong_datum = "WGS84"
+)
+}
+
+
+
+ +
+ + +
+ +
+

Site built with pkgdown 2.0.6.

+
+ +
+ + + + + + + + diff --git a/docs/reference/get_custom_flags.html b/docs/reference/get_custom_flags.html index ffeab21..ea347ac 100644 --- a/docs/reference/get_custom_flags.html +++ b/docs/reference/get_custom_flags.html @@ -169,7 +169,7 @@

Examples

-

Site built with pkgdown 2.0.7.

+

Site built with pkgdown 2.0.6.

diff --git a/docs/reference/get_dc_flags.html b/docs/reference/get_dc_flags.html index 3aeb30a..abf7674 100644 --- a/docs/reference/get_dc_flags.html +++ b/docs/reference/get_dc_flags.html @@ -136,7 +136,7 @@

Examples

-

Site built with pkgdown 2.0.7.

+

Site built with pkgdown 2.0.6.

diff --git a/docs/reference/get_df_flags.html b/docs/reference/get_df_flags.html index 54b4d79..dfc837a 100644 --- a/docs/reference/get_df_flags.html +++ b/docs/reference/get_df_flags.html @@ -133,7 +133,7 @@

Examples

-

Site built with pkgdown 2.0.7.

+

Site built with pkgdown 2.0.6.

diff --git a/docs/reference/get_dp_flags.html b/docs/reference/get_dp_flags.html index 5d1f7e8..e797cdb 100644 --- a/docs/reference/get_dp_flags.html +++ b/docs/reference/get_dp_flags.html @@ -133,7 +133,7 @@

Examples

-

Site built with pkgdown 2.0.7.

+

Site built with pkgdown 2.0.6.

diff --git a/docs/reference/get_elevation.html b/docs/reference/get_elevation.html index c81fdc3..8bf2195 100644 --- a/docs/reference/get_elevation.html +++ b/docs/reference/get_elevation.html @@ -140,7 +140,7 @@

Examples

-

Site built with pkgdown 2.0.7.

+

Site built with pkgdown 2.0.6.

diff --git a/docs/reference/get_park_polygon.html b/docs/reference/get_park_polygon.html index e62812a..ab83402 100644 --- a/docs/reference/get_park_polygon.html +++ b/docs/reference/get_park_polygon.html @@ -102,7 +102,7 @@

Examples

-

Site built with pkgdown 2.0.7.

+

Site built with pkgdown 2.0.6.

diff --git a/docs/reference/get_taxon_rank.html b/docs/reference/get_taxon_rank.html index 2b7e084..fa07f14 100644 --- a/docs/reference/get_taxon_rank.html +++ b/docs/reference/get_taxon_rank.html @@ -116,7 +116,7 @@

Examples

-

Site built with pkgdown 2.0.7.

+

Site built with pkgdown 2.0.6.

diff --git a/docs/reference/get_utm_zone.html b/docs/reference/get_utm_zone.html index 1398a61..dfe649a 100644 --- a/docs/reference/get_utm_zone.html +++ b/docs/reference/get_utm_zone.html @@ -107,7 +107,7 @@

Details

-

Site built with pkgdown 2.0.7.

+

Site built with pkgdown 2.0.6.

diff --git a/docs/reference/index.html b/docs/reference/index.html index 327f8b9..986e4c8 100644 --- a/docs/reference/index.html +++ b/docs/reference/index.html @@ -102,6 +102,10 @@

All functions fuzz_location()

Convert Coordinates Into a Polygon to Obscure Specific Location

+ +

generate_ll_from_utm()

+ +

Coordinate Conversion from UTM to Latitude and Longitude

get_custom_flags()

@@ -151,7 +155,7 @@

All functions
-

Site built with pkgdown 2.0.7.

+

Site built with pkgdown 2.0.6.

diff --git a/docs/reference/long2UTM.html b/docs/reference/long2UTM.html index 4fe2f5a..3db772f 100644 --- a/docs/reference/long2UTM.html +++ b/docs/reference/long2UTM.html @@ -113,7 +113,7 @@

Details

-

Site built with pkgdown 2.0.7.

+

Site built with pkgdown 2.0.6.

diff --git a/docs/reference/order_cols.html b/docs/reference/order_cols.html index c39b962..a649648 100644 --- a/docs/reference/order_cols.html +++ b/docs/reference/order_cols.html @@ -113,7 +113,7 @@

Examples

-

Site built with pkgdown 2.0.7.

+

Site built with pkgdown 2.0.6.

diff --git a/docs/reference/replace_blanks.html b/docs/reference/replace_blanks.html index 4a70b4b..10abf1c 100644 --- a/docs/reference/replace_blanks.html +++ b/docs/reference/replace_blanks.html @@ -117,7 +117,7 @@

Examples

-

Site built with pkgdown 2.0.7.

+

Site built with pkgdown 2.0.6.

diff --git a/docs/reference/te_check.html b/docs/reference/te_check.html index 5522f49..9558552 100644 --- a/docs/reference/te_check.html +++ b/docs/reference/te_check.html @@ -137,7 +137,7 @@

Examples

-

Site built with pkgdown 2.0.7.

+

Site built with pkgdown 2.0.6.

diff --git a/docs/reference/utm_to_ll.html b/docs/reference/utm_to_ll.html index d2f73e3..7e6a4b2 100644 --- a/docs/reference/utm_to_ll.html +++ b/docs/reference/utm_to_ll.html @@ -139,7 +139,7 @@

Examples

-

Site built with pkgdown 2.0.7.

+

Site built with pkgdown 2.0.6.

diff --git a/docs/reference/validate_coord.html b/docs/reference/validate_coord.html index 8ec4f45..17cefcd 100644 --- a/docs/reference/validate_coord.html +++ b/docs/reference/validate_coord.html @@ -110,7 +110,7 @@

Examples

-

Site built with pkgdown 2.0.7.

+

Site built with pkgdown 2.0.6.

diff --git a/docs/reference/validate_coord_list.html b/docs/reference/validate_coord_list.html index 16341d6..3b3fb73 100644 --- a/docs/reference/validate_coord_list.html +++ b/docs/reference/validate_coord_list.html @@ -126,7 +126,7 @@

Examples

-

Site built with pkgdown 2.0.7.

+

Site built with pkgdown 2.0.6.

diff --git a/docs/sitemap.xml b/docs/sitemap.xml index 178dc77..e652532 100644 --- a/docs/sitemap.xml +++ b/docs/sitemap.xml @@ -60,6 +60,9 @@ /reference/fuzz_location.html + + /reference/generate_ll_from_utm.html + /reference/get_custom_flags.html