1
#' HERE Geocoder API: Geocode
2
#'
3
#' Geocodes addresses using the HERE 'Geocoder' API.
4
#'
5
#' @references
6
#' \href{https://developer.here.com/documentation/geocoding-search-api/dev_guide/topics/endpoint-geocode-brief.html}{HERE Geocoder API: Geocode}
7
#'
8
#' @param address character, addresses to geocode.
9
#' @param sf boolean, return an \code{sf} object (\code{default = TRUE}) or a
10
#'   \code{data.frame}?
11
#' @param url_only boolean, only return the generated URLs (\code{default =
12
#'   FALSE})?
13
#' @param addresses character, addresses to geocode (deprecated).
14
#'
15
#' @return
16
#' If \code{sf = TRUE}, an \code{sf} object, containing the position coordinates
17
#' geocoded addresses as geometry list column and the access coordinates as
18
#' well-known text (WKT).
19
#' If \code{sf = FALSE}, a \code{data.frame} containing the coordinates of the
20
#' geocoded addresses as \code{lng}, \code{lat} columns.
21
#' @export
22
#'
23
#' @examples
24
#' # Provide an API Key for a HERE project
25
#' set_key("<YOUR API KEY>")
26
#'
27
#' locs <- geocode(address = poi$city, url_only = TRUE)
28
geocode <- function(address, sf = TRUE, url_only = FALSE, addresses) {
29

30 1
  if (!missing("addresses")) {
31 1
    warning("'addresses' is deprecated, use 'address' instead.")
32 1
    address <- addresses
33
  }
34

35
  # Input checks
36 1
  .check_addresses(address)
37 1
  .check_boolean(sf)
38 1
  .check_boolean(url_only)
39

40
  # Add API key
41 1
  url <- .add_key(
42 1
    url = "https://geocode.search.hereapi.com/v1/geocode?"
43
  )
44

45
  # Add addresses
46 1
  url = paste0(
47 1
    url,
48 1
    "&q=",
49 1
    address
50
  )
51

52
  # Return urls if chosen
53 1
  if (url_only) return(url)
54

55
  # Request and get content
56 1
  data <- .get_content(
57 1
    url = url
58
  )
59 0
  if (length(data) == 0) return(NULL)
60

61
  # Extract information
62 1
  geocoded <- .extract_geocoded(data, address)
63

64
  # Create sf object
65 1
  if (nrow(geocoded) > 0) {
66 1
    rownames(geocoded) <- NULL
67
    # Return sf object if chosen
68 1
    if (sf) {
69
      # Parse access coordinates to WKT
70 1
      geocoded$access <- .wkt_from_point_df(geocoded, "lng_access", "lat_access")
71 1
      geocoded[, c("lng_access", "lat_access") := NULL]
72
      # Parse position coordinates and set as default geometry
73 1
      return(
74 1
        sf::st_set_crs(
75 1
          sf::st_as_sf(
76 1
            as.data.frame(geocoded),
77 1
            coords = c("lng_position", "lat_position"),
78 1
            sf_column_name = "geometry"
79 1
          ), value = 4326
80
        )
81
      )
82
    } else {
83 1
      return(as.data.frame(geocoded))
84
    }
85
  } else {
86 0
    return(NULL)
87
  }
88
}
89

90
.extract_geocoded <- function(data, address) {
91 1
  template <- data.table::data.table(
92 1
    id = numeric(),
93 1
    address = character(),
94 1
    type = character(),
95 1
    street = character(),
96 1
    house_number = character(),
97 1
    postal_code = character(),
98 1
    district = character(),
99 1
    city = character(),
100 1
    county = character(),
101 1
    state = character(),
102 1
    country = character(),
103 1
    lng_access = numeric(),
104 1
    lat_access = numeric(),
105 1
    lng_position = numeric(),
106 1
    lat_position = numeric()
107
  )
108 1
  ids <- .get_ids(data)
109 1
  count <- 0
110 1
  geocode_failed <- character(0)
111 1
  geocoded <- data.table::rbindlist(
112 1
    append(list(template),
113 1
           lapply(data, function(con) {
114 1
             count <<- count + 1
115 1
             df <- jsonlite::fromJSON(con)
116 1
             if (length(df$items) == 0) {
117 0
               geocode_failed <<- c(geocode_failed, address[count])
118 0
               return(NULL)
119
             }
120 1
             result <- data.table::data.table(
121 1
               id = ids[count],
122 1
               address = df$items$address$label,
123 1
               type = df$items$resultType,
124 1
               street = df$items$address$street,
125 1
               house_number = df$items$address$houseNumber,
126 1
               postal_code = df$items$address$postalCode,
127 1
               district = df$items$address$district,
128 1
               city = df$items$address$city,
129 1
               county = df$items$address$county,
130 1
               state = df$items$address$state,
131 1
               country = df$items$address$countryName,
132 1
               lng_access = if (is.null(df$items$access[[1]]$lng)) NA else df$items$access[[1]]$lng,
133 1
               lat_access = if (is.null(df$items$access[[1]]$lat)) NA else df$items$access[[1]]$lat,
134 1
               lng_position = df$items$position$lng,
135 1
               lat_position = df$items$position$lat
136
             )
137 1
             result[1, ]
138
           })
139 1
    ), fill = TRUE
140
  )
141 1
  if (length(geocode_failed) > 0) {
142 0
    message(
143 0
      sprintf(
144 0
        "Address(es) '%s' not found.",
145 0
        paste(geocode_failed, collapse = "', '")
146
      )
147
    )
148
  }
149 1
  return(geocoded)
150
}

Read our documentation on viewing source code .

Loading