Autosuggest and geocode addresses or reverse geocode POIs using the ‘HERE Geocoding & Search’ API.
In order to geocode addresses, the function geocode()
is
used. The requests are sent asynchronously, which means that every
geocoded address is counting as one request. The addresses have to be of
type character
:
head(address, 3)
#> [1] "Luzern" "Lugano" "Lausanne"
Geocode the character vector containing the addresses:
geocoded <- geocode(address)
The return value is an sf
object containing
POINT
geometries of the addresses:
head(geocoded, 3)
#> Simple feature collection with 3 features and 16 fields
#> Geometry type: POINT
#> Dimension: XY
#> Bounding box: xmin: 6.63222 ymin: 46.00297 xmax: 8.9512 ymax: 47.04954
#> Geodetic CRS: WGS 84
#> id rank address type street house_number postal_code
#> 1 1 1 Luzern, Schweiz locality <NA> <NA> 6003
#> 2 2 1 Lugano, Ticino, Svizzera locality <NA> <NA> 6900
#> 3 3 1 Lausanne, Vaud, Suisse locality <NA> <NA> 1003
#> state_code country_code district city county state country score
#> 1 LU CHE <NA> Luzern Luzern-Stadt Luzern Schweiz 1
#> 2 TI CHE <NA> Lugano Lugano Ticino Svizzera 1
#> 3 VD CHE <NA> Lausanne Lausanne Vaud Suisse 1
#> access geometry
#> 1 POINT EMPTY POINT (8.30437 47.04954)
#> 2 POINT EMPTY POINT (8.9512 46.00297)
#> 3 POINT EMPTY POINT (6.63222 46.5196)
Not found addresses are deleted from the result. This means that the
sf
object may contain fewer rows than the original number
of addresses. The column "id"
matches the order of the the
input addresses. Using the "id"
column a corresponding
data.frame
"df"
with the addresses to geocode
could be joined to the coordinates after geocoding.
df <- data.frame(
company = c("Schweizerische Bundesbahnen SBB", "Bahnhof AG", "Deutsche Bahn AG"),
address = c("Wylerstrasse 123, 3000 Bern 65", "not_an_address", "Potsdamer Platz 2, 10785 Berlin"),
stringsAsFactors = FALSE
)
locs <- geocode(df$address)
geocoded_sfdf <- st_as_sf(data.frame(locs, df[locs$id, ]))
Print the geocoded addresses on an interactive leaflet map:
if (requireNamespace("mapview", quietly = TRUE)) {
mapview::mapview(geocoded,
label = geocoded$address,
col.regions = "red",
map.types = c("Esri.WorldTopoMap"),
legend = FALSE,
homebutton = FALSE
)
}
Note: Setting alternatives = TRUE
will
also return alternative locations in the same order as received from the
API (rank
column).
Instead of free-text address searches, there is also an option to
specify qualified queries using the keys "country"
,
"state"
, "county"
, "city"
,
"district"
, "street"
,
"houseNumber"
or "postalCode"
:
The autosuggestion endpoint of the Geocoding & Search API can be
accessed using the autosuggest()
function. The
results
parameter defines the maximum number of suggestions
that should be requested for each input address.
suggestions <- autosuggest(address, results = 3)
The return value is a data.frame
containing autocomplete
suggestions for the addresses. The variable id
matches the
index of the initial address vector, which was used as input and
order
stores the rank of the suggestion.
results <- data.frame(
input = address[suggestions$id],
id = suggestions$id,
rank = suggestions$rank,
suggestion = suggestions$suggestion
)
input | id | rank | suggestion |
---|---|---|---|
Luzern | 1 | 1 | Luzern, Schweiz |
Luzern | 1 | 2 | Hauptbahnhof SBB Luzern |
Luzern | 1 | 3 | Luzern-Stadt, Luzern, Schweiz |
Lugano | 2 | 1 | Lugano, Ticino, Svizzera |
Lugano | 2 | 2 | Stazione Lugano FFS (Lugano) |
Lugano | 2 | 3 | Lugano Airport |
The reverse geocoding feature of the Geocoding & Search API can
be accessed using the reverse_geocode()
function. The
function allows to retrieve addresses near POIs.
reverse_geocoded <- reverse_geocode(poi = poi, results = 3)
The function returns an sf
object, containing the
suggested addresses or landmark names of the reverse geocoded POIs. The
coordinates are different from the initially provided POIs since they
represent the locations of the suggested addresses or landmarks.
if (requireNamespace("mapview", quietly = TRUE)) {
m <-
mapview::mapview(poi,
alpha.region = 0, col.region = "transparent",
label = poi$city, cex = 30, layer.name = "POIs",
map.types = c("Esri.WorldTopoMap"), homebutton = FALSE
) +
mapview::mapview(reverse_geocoded,
col.region = "red", alpha = 0,
label = reverse_geocoded$label, layer.name = "Adresses",
homebutton = FALSE
)
m
}
If no addresses or landmarks are found near a POI, NULL
for this POI is returned. In this case the rows corresponding to this
particular POI are missing and merging the POIs by row is not possible.
However, in the returned sf
object, the column
"id"
matches the rows of the input POIs. The
"id"
column can be used to join the original POIs.