-
Notifications
You must be signed in to change notification settings - Fork 4
/
types.castGeopoint.R
105 lines (71 loc) · 3.36 KB
/
types.castGeopoint.R
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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
#' @title Cast geographic point
#' @description Cast geographic point
#' @param format available options are "default", "array" and "object", where
#' \describe{
#' \item{\code{default }}{A string of the pattern "lon, lat", where \code{lon} is the longitude
#' and \code{lat} is the latitude (note the space is optional after the \code{,}). E.g. \code{"90, 45"}.}
#' \item{\code{array }}{A JSON array, or a string parsable as a JSON array, of exactly two items,
#' where each item is a number, and the first item is \code{lon} and the second item is \code{lat} e.g. \code{[90, 45]}.}
#' \item{\code{object }}{A JSON object with exactly two keys, \code{lat} and \code{lon} and each value is a number e.g. \code{{"lon": 90, "lat": 45}}.}
#' }
#' @param value geopoint to cast
#' @rdname types.castGeopoint
#' @export
#'
#' @seealso \href{https://specs.frictionlessdata.io//table-schema/#geopoint}{Types and formats specifications}
#'
#' @examples
#'
#' types.castGeopoint(format = "default", value = list(180, 90))
#'
#' types.castGeopoint(format = "default", value = '180,90')
#'
#' types.castGeopoint(format = "default", value = '180, -90')
#'
#' types.castGeopoint(format = "array", value = list(180, 90))
#'
#' types.castGeopoint(format = "array", value = '[180, -90]')
#'
#' types.castGeopoint(format = "object", value = list(lon = 180, lat = 90))
#'
#' types.castGeopoint(format = "object", value = '{"lon": 180, "lat": 90}')
#'
types.castGeopoint <- function(format, value) {
tryCatch({
lon_lat <- list()
if (format == 'default') {
if (is.character(value)) {
lon_lat <- as.list(unlist(strsplit(value, ",")))
lon_lat[[1]] <- trimws(lon_lat[[1]], which = "both")
lon_lat[[2]] <- trimws(lon_lat[[2]], which = "both")
} else if (is.array(value) | is.list(value)) {
lon_lat <- value
} else return(config::get("ERROR", file = system.file("config/config.yml", package = "tableschema.r")))
} else if (format == 'array' | format == 'list') {
if (is.character(value)) {
value <- jsonlite::fromJSON(value, simplifyVector = FALSE)
}
lon_lat <- value
} else if (format == 'object') {
if (is.character(value)) {
value <- jsonlite::fromJSON(value)
}
lon_lat[[1]] <- value[[1]]
lon_lat[[2]] <- value[[2]]
}
lon_lat[[1]] <- as.numeric(lon_lat[[1]])
lon_lat[[2]] <- as.numeric(lon_lat[[2]])
},
error = function(e) {
return(config::get("ERROR", file = system.file("config/config.yml", package = "tableschema.r")))
})
if (is_empty(lon_lat) | is.null(lon_lat) | !is.null(names(lon_lat)) ) return(config::get("ERROR", file = system.file("config/config.yml", package = "tableschema.r")))
if (length(lon_lat) != 2) return(config::get("ERROR", file = system.file("config/config.yml", package = "tableschema.r")))
if (is.nan(lon_lat[[1]]) | lon_lat[[1]] > 180 | lon_lat[[1]] < -180) {
return(config::get("ERROR", file = system.file("config/config.yml", package = "tableschema.r")))
}
if (is.nan(lon_lat[[2]]) | lon_lat[[2]] > 90 | lon_lat[[2]] < -90) {
return(config::get("ERROR", file = system.file("config/config.yml", package = "tableschema.r")))
}
return(lon_lat)
}