class: left, top, title-slide .title[ # Geospatial Data
Geocoding ] .author[ ### Keith VanderLinden
Calvin University ] --- # Geocoding *Geocoding* converts between descriptions of locations and their geographic coordinates. We will use the [tidygeocoder](https://jessecambon.github.io/tidygeocoder/) to do our geocoding. ```r library(sf) library(ggspatial) library(tidygeocoder) ``` .footnote[All examples from the TidyGeocoder: https://jessecambon.github.io/tidygeocoder/] ??? Geocoding translates between: - machine-readable coordinates - human-readable street addresses. --- # Locations ```r addresses <- tibble(address = c( "3201 Burton Street SE, Grand Rapids, MI, 49546", # Calvin University "303 Monroe Ave NW, Grand Rapids, MI, 49503" # DeVos Performance Hall )) %>% geocode(address, method = "osm") %>% st_as_sf(coords = c("long", "lat")) %>% st_set_crs(4326) addresses ``` ``` Simple feature collection with 2 features and 1 field Geometry type: POINT Dimension: XY Bounding box: xmin: -85.67318 ymin: 42.93203 xmax: -85.58036 ymax: 42.96918 Geodetic CRS: WGS 84 # A tibble: 2 × 2 address geometry * <chr> <POINT [°]> 1 3201 Burton Street SE, Grand Rapids,… (-85.58036 42.93203) 2 303 Monroe Ave NW, Grand Rapids, MI,… (-85.67318 42.96918) ``` ??? - This code uses tidygeocoder to geocode the given street addresses. - It uses the API from OSM, the [open-street map](https://nominatim.org/). - It translates from the older `st` encoding to the newer `sf`. - Be careful, these systems tend to put longitude first. - It chooses the WGS84/EPSG4326 CRS for encoding the coordinates. - It returns a POINT geom specification (vector data). --- # Mapping the Locations .pull-left[ ```r addresses %>% ggplot() + annotation_map_tile( type = "osm", zoomin = 0 ) + geom_sf() ``` ] .pull-right[ <img src="geocoding_files/figure-html/unnamed-chunk-5-1.png" width="100%" style="display: block; margin: auto;" /> ] ??? - This code plots the locations on a (vector) map. - It pulls a (vector) map tile from open-street-maps. - It then plots the points (on the top right and bottom left of the map). --- # Reverse Geocoding .pull-left[ `tidygeocoder` can also reverse-geocode geospatial coordinates into location names and street addresses. We start with these latitude-longitude coordinates. ```r mystery_lat_longs ``` ``` # A tibble: 3 × 2 latitude longitude <dbl> <dbl> 1 38.9 -77.0 2 41.9 -87.6 3 37.8 -122. ``` ] -- .pull-right[ ```r reverse <- mystery_lat_longs %>% reverse_geocode( lat = latitude, long = longitude, method = 'osm', address = address, full_results = TRUE) %>% select(address) reverse ``` ``` # A tibble: 3 × 1 address <chr> 1 White House, 1600, Pennsylvania Avenue Northwest, Washington, … 2 Willis Tower, 233, South Wacker Drive, Printer's Row, Loop, Ch… 3 Transamerica Pyramid, 600, Montgomery Street, Financial Distri… ``` ] ??? - This example starts with a (hidden) specification of three known locations. - It uses OSM again. - `full_results` requests all the data, not just the lat-lon. - One wonders how close the lat-long has to be... --- # Computing Distances .pull-left[ We can compute *geodesic* distances between geo-coded locations. We return to the local sites of interest and use the [openroute service](https://www.openrouteservice.org) to do the computations. ```r # Defined earlier addresses ``` ``` Simple feature collection with 2 features and 1 field Geometry type: POINT Dimension: XY Bounding box: xmin: -85.67318 ymin: 42.93203 xmax: -85.58036 ymax: 42.96918 Geodetic CRS: WGS 84 # A tibble: 2 × 2 address geometry * <chr> <POINT [°]> 1 3201 Burton Street SE, Grand Rapids,… (-85.58036 42.93203) 2 303 Monroe Ave NW, Grand Rapids, MI,… (-85.67318 42.96918) ``` ] -- .pull-right[ ```r addresses %>% st_distance() %>% units::set_units("miles") ``` ``` Units: [miles] [,1] [,2] [1,] 0.000000 5.350074 [2,] 5.350074 0.000000 ``` ] ??? - This code computes the distance between the GR addresses (used above). - Distances: - *Geodesic* is "great circle" distance. - "Driving distance" is a more practical value. --- # Computing Routes ```r library(openrouteservice) ors_api_key(MY_API_KEY) calvin_devos <- addresses %>% st_coordinates() %>% as_tibble() ``` .pull-left[ Driving ```r route_driving <- calvin_devos %>% * ors_directions(profile = "driving-car", output = "sf") route_driving %>% st_length() %>% units::set_units("miles") ``` ``` 8.744641 [miles] ``` ] .pull-right[ Cycling ```r route_cycling <- calvin_devos %>% * ors_directions(profile = "cycling-regular", output = "sf") route_cycling %>% st_length() %>% units::set_units("miles") ``` ``` 7.343012 [miles] ``` ] ??? - This computation requires an ORS API key, generated at the OpenRouteService API website. - We can set a `preference = "fastest" / "recommended"`. - ORS clearly has a detailed (vector) representation of streets, distances, times, etc. - Is there some way to get times? Clearly the system knows that the car can handle longer distances in return for much higher speeds. --- # Mapping the Routes .pull-left[ The computed routes can easily be mapped. ```r library(leaflet) leaflet(height = "400px") %>% addTiles() %>% addPolylines(data = route_driving, weight = 7) %>% addPolylines(data = route_cycling, color = "green", weight = 7) ``` ] .pull-right[
] ???