Created
April 3, 2019 04:49
-
-
Save raymondben/41428babea1e6f1ae0fb1db041f37dfd to your computer and use it in GitHub Desktop.
Degrees-minutes-seconds to decimal degrees
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#' Convert degrees-minutes-seconds to decimal degrees | |
#' | |
#' This is pretty rough and not suitable as-is for public use. But for my own purposes it is more useful than e.g. sp::char2dms | |
#' | |
#' @param x character: dms representation | |
#' | |
#' @return numeric | |
#' | |
#' @export | |
dms2decdeg <- function(x) { | |
assert_that(is.character(x)) | |
degree_chars <- paste0("od",intToUtf8(c(176,186,9702))) ## 9702 is white bullet | |
min_chars <- paste0("m'\u2019",intToUtf8(c(96,180))) | |
sec_chars <- paste0("\"'\u2019",intToUtf8(c(96,180))) | |
sgn <- function(x) { | |
out <- rep(1,length(x)) | |
idx <- grepl("[nesw]",stringr::str_trim(x),ignore.case=TRUE) | |
out[idx] <-sign(grepl("[ne]",stringr::str_trim(x[idx]),ignore.case=TRUE)-0.5) ## s,w get negative signs | |
out | |
} | |
x <- gsub("\\circ",degree_chars[1],x,fixed=TRUE) | |
out <- rep(NA,length(x)) | |
## try degrees minutes seconds | |
this_re <- stringr::regex(paste0("[:space:]*([:digit:]+)[[:space:]",degree_chars,"]+([:digit:]+)[:space:]*[[:space:]",min_chars,"]+([[:digit:]\\.]+)[:space:]*[",sec_chars,"]+[:space:]*([NSEW]?)[:space:]*"),ignore_case=TRUE) | |
idx <- stringr::str_detect(x,this_re) & is.na(out) | |
if (any(idx)) { | |
temp <- stringr::str_match(x,this_re) | |
out[idx] <- sgn(temp[idx,5])*(as.numeric(temp[idx,2])+as.numeric(temp[idx,3])/60+as.numeric(temp[idx,4])/3600) | |
} | |
## try degrees decimal minutes | |
this_re <- stringr::regex(paste0("[:space:]*([:digit:]+)[[:space:]",degree_chars,"]+([[:digit:]\\.]+)[:space:]*[",min_chars,"]?[:space:]*([NSEW]?)[:space:]*$"),ignore_case=TRUE) | |
idx <- stringr::str_detect(x,this_re) & is.na(out) | |
if (any(idx)) { | |
temp <- stringr::str_match(x,this_re) | |
out[idx] <- sgn(temp[idx,4])*(as.numeric(temp[idx,2])+as.numeric(temp[idx,3])/60) | |
} | |
## try integer degrees | |
this_re <- stringr::regex(paste0("[:space:]*([:digit:]+)[:space:]*[",degree_chars,"]?[:space:]*([NSEW]?)[:space:]*$"),ignore_case=TRUE) | |
idx <- stringr::str_detect(x,this_re) & is.na(out) | |
if (any(idx)) { | |
temp <- stringr::str_match(x,this_re) | |
out[idx] <- sgn(temp[idx,3])*(as.numeric(temp[idx,2])) | |
} | |
out | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment