Author: Daniel Possenriede, Jesse Sadler, Maëlle Salmon
Date: 2021-02-18

# Output options

### Get different kinds of output from OpenCage

#### Daniel Possenriede, Jesse Sadler, Maëlle Salmon

#### 2021-02-18

{opencage} contains two main types of main functions distinguished by the manner in which the results are returned:

1. The `oc_forward_df()`/`oc_reverse_df()` functions always return a single tibble.
2. The `oc_forward()`/`oc_reverse()` functions return a list of various types, depending on the `return` value you specify. The possible `return` values are `df_list`, `json_list`, `geojson_list` and `url_only`.

Use of the `oc_forward_df()`/`oc_reverse_df()` functions is demonstrated in the “Introduction to opencage” and the “Customise your query” vignettes (`vignette("opencage")` and `vignette("customise_query")`, respectively) . The function arguments mentioned in these other vignettes are also generally available with `oc_forward()`/`oc_reverse()`. Here we will show the different return values available with `oc_forward()`/`oc_reverse()`.

## `df_list`

The default return value is `df_list`. It returns a list of tibbles.

    stations <- c("Casey Station", "McMurdo Station")
    oc_forward(stations, return = "df_list")
    #> [[1]]
    #> # A tibble: 2 x 18
    #>   oc_confidence oc_formatted oc_northeast_lat oc_northeast_lng oc_southwest_lat oc_southwest_lng oc_category oc_type oc_continent oc_hamlet
    #>           <int> <chr>                   <dbl>            <dbl>            <dbl>            <dbl> <chr>       <chr>   <chr>        <chr>
    #> 1             9 Casey Stati~            -66.3             111.            -66.3             111. commerce    office  Antarctica   Casey St~
    #> 2             9 Casey Stati~             NA                NA              NA                NA  travel/tou~ point_~ Antarctica   <NA>
    #> # ... with 8 more variables: oc_office <chr>, oc_iso_3166_1_alpha_2 <chr>, oc_iso_3166_1_alpha_3 <chr>, oc_country <chr>,
    #> #   oc_country_code <chr>, oc_point_of_interest <chr>, oc_lat <dbl>, oc_lng <dbl>
    #>
    #> [[2]]
    #> # A tibble: 1 x 12
    #>   oc_confidence oc_formatted oc_northeast_lat oc_northeast_lng oc_southwest_lat oc_southwest_lng oc_category oc_type oc_continent oc_town
    #>           <int> <chr>                   <dbl>            <dbl>            <dbl>            <dbl> <chr>       <chr>   <chr>        <chr>
    #> 1             7 McMurdo Sta~            -77.8             167.            -77.9             167. place       city    Antarctica   McMurd~
    #> # ... with 2 more variables: oc_lat <dbl>, oc_lng <dbl>

The `df_list` type drives the `oc_forward_df()`/`oc_reverse_df()` functions. You can use the `df_list` output in a `dplyr::mutate()` chain to replicate the functionality of `oc_forward_df()`:

    library(dplyr, warn.conflicts = FALSE)

    oc_data <-
      tibble(place = stations) %>%
      mutate(oc_result = oc_forward(place))

    oc_data
    #> # A tibble: 2 x 2
    #>   place           oc_result
    #>   <chr>           <list>
    #> 1 Casey Station   <tibble [2 x 18]>
    #> 2 McMurdo Station <tibble [1 x 12]>

This creates a list column `oc_result`, which can be easily unnested with `tidyr::unnest()`:

    library(tidyr, warn.conflicts = FALSE)

    oc_data %>% unnest(oc_result)
    #> # A tibble: 3 x 20
    #>   place oc_confidence oc_formatted oc_northeast_lat oc_northeast_lng oc_southwest_lat oc_southwest_lng oc_category oc_type oc_continent
    #>   <chr>         <int> <chr>                   <dbl>            <dbl>            <dbl>            <dbl> <chr>       <chr>   <chr>
    #> 1 Case~             9 Casey Stati~            -66.3             111.            -66.3             111. commerce    office  Antarctica
    #> 2 Case~             9 Casey Stati~             NA                NA              NA                NA  travel/tou~ point_~ Antarctica
    #> 3 McMu~             7 McMurdo Sta~            -77.8             167.            -77.9             167. place       city    Antarctica
    #> # ... with 10 more variables: oc_hamlet <chr>, oc_office <chr>, oc_iso_3166_1_alpha_2 <chr>, oc_iso_3166_1_alpha_3 <chr>,
    #> #   oc_country <chr>, oc_country_code <chr>, oc_point_of_interest <chr>, oc_lat <dbl>, oc_lng <dbl>, oc_town <chr>

## `json_list`

OpenCage’s main output format is JSON. When you specify `json_list` as the return type, you get the JSON as an R `list()`.

    oc_forward("Casey Station", return = "json_list")
    #> [[1]]
    #> [[1]]$documentation
    #> [1] "https://opencagedata.com/api"
    #>
    #> [[1]]$licenses
    #> [[1]]$licenses[[1]]
    #> [[1]]$licenses[[1]]$name
    #> [1] "see attribution guide"
    #>
    #> [[1]]$licenses[[1]]$url
    #> [1] "https://opencagedata.com/credits"
    #>
    #>
    #>
    #> [[1]]$results
    #> [[1]]$results[[1]]
    #> [[1]]$results[[1]]$bounds
    #> [[1]]$results[[1]]$bounds$northeast
    #> [[1]]$results[[1]]$bounds$northeast$lat
    #> [1] -66.28255
    #>
    #> [[1]]$results[[1]]$bounds$northeast$lng
    #> [1] 110.5267
    #>
    #>
    #> [[1]]$results[[1]]$bounds$southwest
    #> [[1]]$results[[1]]$bounds$southwest$lat
    #> [1] -66.28265
    #>
    #> [[1]]$results[[1]]$bounds$southwest$lng
    #> [1] 110.5266
    #>
    #>
    #>
    #> [[1]]$results[[1]]$components
    #> [[1]]$results[[1]]$components$`_category`
    #> [1] "commerce"
    #>
    #> [[1]]$results[[1]]$components$`_type`
    #> [1] "office"
    #>
    #> [[1]]$results[[1]]$components$continent
    #> [1] "Antarctica"
    #>
    #> [[1]]$results[[1]]$components$hamlet
    #> [1] "Casey Station"
    #>
    #> [[1]]$results[[1]]$components$office
    #> [1] "Casey Station"
    #>
    #>
    #> [[1]]$results[[1]]$confidence
    #> [1] 9
    #>
    #> [[1]]$results[[1]]$formatted
    #> [1] "Casey Station"
    #>
    #> [[1]]$results[[1]]$geometry
    #> [[1]]$results[[1]]$geometry$lat
    #> [1] -66.2826
    #>
    #> [[1]]$results[[1]]$geometry$lng
    #> [1] 110.5266
    #>
    #>
    #>
    #> [[1]]$results[[2]]
    #> [[1]]$results[[2]]$components
    #> [[1]]$results[[2]]$components$`ISO_3166-1_alpha-2`
    #> [1] "AQ"
    #>
    #> [[1]]$results[[2]]$components$`ISO_3166-1_alpha-3`
    #> [1] "ATA"
    #>
    #> [[1]]$results[[2]]$components$`_category`
    #> [1] "travel/tourism"
    #>
    #> [[1]]$results[[2]]$components$`_type`
    #> [1] "point_of_interest"
    #>
    #> [[1]]$results[[2]]$components$continent
    #> [1] "Antarctica"
    #>
    #> [[1]]$results[[2]]$components$country
    #> [1] "Antarctica"
    #>
    #> [[1]]$results[[2]]$components$country_code
    #> [1] "aq"
    #>
    #> [[1]]$results[[2]]$components$point_of_interest
    #> [1] "Casey Station"
    #>
    #>
    #> [[1]]$results[[2]]$confidence
    #> [1] 9
    #>
    #> [[1]]$results[[2]]$formatted
    #> [1] "Casey Station, Antarctica"
    #>
    #> [[1]]$results[[2]]$geometry
    #> [[1]]$results[[2]]$geometry$lat
    #> [1] -66.28225
    #>
    #> [[1]]$results[[2]]$geometry$lng
    #> [1] 110.5278
    #>
    #>
    #>
    #>
    #> [[1]]$status
    #> [[1]]$status$code
    #> [1] 200
    #>
    #> [[1]]$status$message
    #> [1] "OK"
    #>
    #>
    #> [[1]]$stay_informed
    #> [[1]]$stay_informed$blog
    #> [1] "https://blog.opencagedata.com"
    #>
    #> [[1]]$stay_informed$twitter
    #> [1] "https://twitter.com/OpenCage"
    #>
    #>
    #> [[1]]$thanks
    #> [1] "For using an OpenCage API"
    #>
    #> [[1]]$timestamp
    #> [[1]]$timestamp$created_http
    #> [1] "Thu, 18 Feb 2021 19:02:13 GMT"
    #>
    #> [[1]]$timestamp$created_unix
    #> [1] 1613674933
    #>
    #>
    #> [[1]]$total_results
    #> [1] 2

## `geojson_list`

When you choose `geojson_list` as the return type, the geocoder response will be returned as GeoJSON specified as an R `list()`.

    gjsn_lst <- oc_forward("Casey Station", return = "geojson_list")
    gjsn_lst
    #> [[1]]
    #> $documentation
    #> [1] "https://opencagedata.com/api"
    #>
    #> $features
    #> $features[[1]]
    #> $features[[1]]$geometry
    #> $features[[1]]$geometry$coordinates
    #> $features[[1]]$geometry$coordinates[[1]]
    #> [1] 110.5266
    #>
    #> $features[[1]]$geometry$coordinates[[2]]
    #> [1] -66.2826
    #>
    #>
    #> $features[[1]]$geometry$type
    #> [1] "Point"
    #>
    #>
    #> $features[[1]]$properties
    #> $features[[1]]$properties$bounds
    #> $features[[1]]$properties$bounds$northeast
    #> $features[[1]]$properties$bounds$northeast$lat
    #> [1] -66.28255
    #>
    #> $features[[1]]$properties$bounds$northeast$lng
    #> [1] 110.5267
    #>
    #>
    #> $features[[1]]$properties$bounds$southwest
    #> $features[[1]]$properties$bounds$southwest$lat
    #> [1] -66.28265
    #>
    #> $features[[1]]$properties$bounds$southwest$lng
    #> [1] 110.5266
    #>
    #>
    #>
    #> $features[[1]]$properties$components
    #> $features[[1]]$properties$components$`_category`
    #> [1] "commerce"
    #>
    #> $features[[1]]$properties$components$`_type`
    #> [1] "office"
    #>
    #> $features[[1]]$properties$components$continent
    #> [1] "Antarctica"
    #>
    #> $features[[1]]$properties$components$hamlet
    #> [1] "Casey Station"
    #>
    #> $features[[1]]$properties$components$office
    #> [1] "Casey Station"
    #>
    #>
    #> $features[[1]]$properties$confidence
    #> [1] 9
    #>
    #> $features[[1]]$properties$formatted
    #> [1] "Casey Station"
    #>
    #>
    #> $features[[1]]$type
    #> [1] "Feature"
    #>
    #>
    #> $features[[2]]
    #> $features[[2]]$geometry
    #> $features[[2]]$geometry$coordinates
    #> $features[[2]]$geometry$coordinates[[1]]
    #> [1] 110.5278
    #>
    #> $features[[2]]$geometry$coordinates[[2]]
    #> [1] -66.28225
    #>
    #>
    #> $features[[2]]$geometry$type
    #> [1] "Point"
    #>
    #>
    #> $features[[2]]$properties
    #> $features[[2]]$properties$components
    #> $features[[2]]$properties$components$`ISO_3166-1_alpha-2`
    #> [1] "AQ"
    #>
    #> $features[[2]]$properties$components$`ISO_3166-1_alpha-3`
    #> [1] "ATA"
    #>
    #> $features[[2]]$properties$components$`_category`
    #> [1] "travel/tourism"
    #>
    #> $features[[2]]$properties$components$`_type`
    #> [1] "point_of_interest"
    #>
    #> $features[[2]]$properties$components$continent
    #> [1] "Antarctica"
    #>
    #> $features[[2]]$properties$components$country
    #> [1] "Antarctica"
    #>
    #> $features[[2]]$properties$components$country_code
    #> [1] "aq"
    #>
    #> $features[[2]]$properties$components$point_of_interest
    #> [1] "Casey Station"
    #>
    #>
    #> $features[[2]]$properties$confidence
    #> [1] 9
    #>
    #> $features[[2]]$properties$formatted
    #> [1] "Casey Station, Antarctica"
    #>
    #>
    #> $features[[2]]$type
    #> [1] "Feature"
    #>
    #>
    #>
    #> $licenses
    #> $licenses[[1]]
    #> $licenses[[1]]$name
    #> [1] "see attribution guide"
    #>
    #> $licenses[[1]]$url
    #> [1] "https://opencagedata.com/credits"
    #>
    #>
    #>
    #> $rate
    #> named list()
    #>
    #> $status
    #> $status$code
    #> [1] 200
    #>
    #> $status$message
    #> [1] "OK"
    #>
    #>
    #> $stay_informed
    #> $stay_informed$blog
    #> [1] "https://blog.opencagedata.com"
    #>
    #> $stay_informed$twitter
    #> [1] "https://twitter.com/OpenCage"
    #>
    #>
    #> $thanks
    #> [1] "For using an OpenCage API"
    #>
    #> $timestamp
    #> $timestamp$created_http
    #> [1] "Thu, 18 Feb 2021 19:02:15 GMT"
    #>
    #> $timestamp$created_unix
    #> [1] 1613674935
    #>
    #>
    #> $total_results
    #> [1] 2
    #>
    #> $type
    #> [1] "FeatureCollection"
    #>
    #> attr(,"class")
    #> [1] "geo_list"

In fact, {opencage} returns a list of results in `geo_list` format, which should be compatible with the {geojsonio} package.

    class(gjsn_lst[[1]])
    #> [1] "geo_list"

## `url_only`

`url_only` returns the OpenCage URL for debugging purposes.

    oc_forward("Casey Station", return = "url_only")
    #> [[1]]
    #> [1] "https://api.opencagedata.com/geocode/v1/json?q=Casey%20Station&limit=10&no_annotations=1&roadinfo=0&no_dedupe=0&no_record=1&abbrv=0&add_request=0&key=OPENCAGE_KEY"

Your OpenCage API key is masked with the `OPENCAGE_KEY` string, by default. If you really want {opencage} to display your API key with the URL, set the `show_key` argument in `oc_config()` to `TRUE`.

    oc_config(show_key = TRUE)

Note that the API key will only be returned with the URL in `base::interactive()` mode.

## `xml`

{opencage} does not support the XML response type at the moment. Please file an issue or a pull-request if you have a use-case that requires this.

## Return query text

`oc_forward()` and `oc_reverse()` have an `add_request` argument, indicating whether the request is returned again with the results. If the `return` value is a `df_list`, the `placename` or `latitude,longitude` is added as a column to the results without a roundtrip to the API. `json_list` results will contain all request parameters as returned by the API. This would normally include your OpenCage API key, but {opencage} masks the key and replaces it with the `OPENCAGE_KEY` string in the output. `add_request` is currently ignored by OpenCage for GeoJSON results.