-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathdms2dec
65 lines (54 loc) · 2.54 KB
/
dms2dec
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
dms2dec <- function(dms, separators = c("º", "°", "\'", "’", "\"", "\\?")) {
# separators = c("º", "°", "\'", "’", "\"", "\\?")
# separators = c("\\u00ba", "\\u00b0", "\\'", "\\u2019", "\"", "\\?", "\\\\?")
# by A. Marcia Barbosa (https://modtools.wordpress.com/)
# contributions by PaulMelloy (https://github.com/PaulMelloy)
# license: CC BY-SA 4.0 (Creative Commons)
# like R, this function is free, open-source and comes with absolutely no warranty; bug reports welcome!
# version 1.6 (27 May 2024)
# dms: a vector of latitude or longitude in degrees-minutes-seconds-hemisphere,
# e.g. 41° 34' 10.956" N (with or without spaces) or
# ddm: a vector of latitude or longitude in degrees-decimal minutes
# e.g. 41° 34.1826' N (with or without spaces)
# separators: the characters that are separating degrees, minutes and seconds in dms
# to source this function, remember to add encoding:
# source("https://raw.githubusercontent.com/AMBarbosa/unpackaged/master/dms2dec", encoding = "UTF-8")
dms <- as.character(dms)
dms <- gsub(pattern = " ", replacement = "", x = dms)
new_split_string <- "_splitHere_"
for (s in separators) dms <- gsub(pattern = s, replacement = new_split_string, x = dms, useBytes = FALSE)
dms <- gsub(paste0(new_split_string, new_split_string), new_split_string, dms, useBytes = TRUE)
splits <- strsplit(dms, split = "_splitHere_")
n <- length(dms)
deg <- min <- sec <- hem <- vector("character", n)
for (i in 1:n) {
deg[i] <- splits[[i]][1]
min[i] <- splits[[i]][2]
# Check if Degrees decimal minutes
dm <- unlist(strsplit(min[i], "[.]"))
if (length(dm) > 1) {
if (length(dm) > 2)
stop("Input minutes format is not recongnisable")
sec[i] <- as.numeric(paste0("0.", dm[2], collapse = "")) * 60
min[i] <- dm[1]
if(min[i] > 60) stop("minutes entry exceeds 60, check minutes input")
hem[i] <-
splits[[i]][splits[[i]] %in% c("N", "S", "E", "W", "n", "s", "e", "w")]
} else{
if (length(splits[[i]]) < 4) {
hem[i] <- splits[[i]][3]
} else {
sec[i] <- splits[[i]][3]
hem[i] <- splits[[i]][4]
}
}
}
dec <- colSums(rbind(as.numeric(deg), (as.numeric(min) / 60), (as.numeric(sec) / 3600)), na.rm = TRUE)
sign <- ifelse (hem %in% c("N", "E"), 1, -1)
hem_miss <- which(is.na(hem))
if (length(hem_miss) > 0) {
warning("Hemisphere not specified in position(s) ", hem_miss, ", so the sign of the resulting coordinates may be wrong.")
}
dec <- sign * dec
return(dec)
} # end dms2dec function