Author: Tarak Shah
Date: 2023-10-17

# Introduction to rmapzen

#### Tarak Shah

#### 2023-10-17

## Introduction

`rmapzen` is a client for any implementation of the Mapzen API. Though Mapzen itself has gone out of business, `rmapzen` can be set up to work with any provider who hosts Mapzen’s open-source software, including geocode.earth, Nextzen, and NYC GeoSearch from NYC Planning Labs. For more information, see https://www.mapzen.com/documentation/. The project is available on github as well as CRAN.

`rmapzen` provides access to the following Mapzen API services:

- Search: Structured and unstructured search and geocoding, reverse geocoding, and autocomplete.
- Vector Tiles: Basemap vector data.
- Isochrone: Calculation of areas reachable from a specified locations.

## Set-up

`rmapzen` works with API providers who implement the Mapzen API. In order to specify provider information (such as URL and API key), use `mz_set_host`. There are custom set-up functions for the following providers:

- geocode.earth, for search services. Use the function `mz_set_search_host_geocode.earth`
- Nextzen, for vector tiles. Use the function `mz_set_tile_host_nextzen`.
- NYC GeoSearch, for search services using New York City’s Property Address Directory. Use `mz_set_search_host_nyc_geosearch`.

As of this writing, there are no public providers offering the Mapzen isochrone service.

## Search

All of the services in Mapzen search have been implemented. Search functions:

- `mz_search`
- `mz_reverse_geocode`
- `mz_autocomplete`
- `mz_place`
- `mz_structured_search` (what’s this?)

Each of those functions returns a `mapzen_geo_list`. The sample dataset `oakland_public` contains the results of `mz_search("Oakland public library branch")` on January 8, 2017:

    #> GeoJSON response from Mapzen
    #> Attribution info: https://search.mapzen.com/v1/attribution
    #> Bounds (lon/lat): (-122.29, 37.74) - (-122.17, 37.85)
    #> 25 locations:
    #>    Oakland Public Library - Temescal Branch (-122.26, 37.84)
    #>    Oakland Public Library - Rockridge Branch (-122.25, 37.84)
    #>    Lakeview Branch Oakland Public Library (-122.25, 37.81)
    #>    Golden Gate Branch Oakland Public Library (-122.28, 37.84)
    #>    Brookfield Village Branch Oakland Public Library (-122.19, 37.74)
    #>   ...

    mz_bbox(oakland_public)
    #> # A tibble: 1 × 4
    #>   min_lon min_lat max_lon max_lat
    #>     <dbl>   <dbl>   <dbl>   <dbl>
    #> 1   -122.    37.7   -122.    37.8
    as.data.frame(oakland_public)
    #> # A tibble: 25 × 26
    #>    id         gid   layer source source_id name  housenumber confidence accuracy
    #>    <chr>      <chr> <chr> <chr>  <chr>     <chr> <chr>            <dbl> <chr>
    #>  1 way:12568… open… venue opens… way:1256… Oakl… 5205             0.926 point
    #>  2 way:43255… open… venue opens… way:4325… Oakl… <NA>             0.926 point
    #>  3 way:36977… open… venue opens… way:3697… Lake… <NA>             0.664 point
    #>  4 5352843    geon… venue geona… 5352843   Gold… <NA>             0.663 point
    #>  5 node:3681… open… venue opens… node:368… Broo… <NA>             0.663 point
    #>  6 way:43919… open… venue opens… way:4391… West… 1801             0.663 point
    #>  7 node:3681… open… venue opens… node:368… Elmh… <NA>             0.663 point
    #>  8 node:3681… open… venue opens… node:368… Mont… <NA>             0.663 point
    #>  9 way:28376… open… venue opens… way:2837… Main… 125              0.663 point
    #> 10 node:3681… open… venue opens… node:368… Lati… <NA>             0.663 point
    #> # ℹ 15 more rows
    #> # ℹ 17 more variables: country <chr>, country_gid <chr>, country_a <chr>,
    #> #   region <chr>, region_gid <chr>, region_a <chr>, county <chr>,
    #> #   county_gid <chr>, locality <chr>, locality_gid <chr>, neighbourhood <chr>,
    #> #   neighbourhood_gid <chr>, label <chr>, street <chr>, postalcode <chr>,
    #> #   lon <dbl>, lat <dbl>

Search can, optionally, be constrained to a particular country, data layer, boundary rectangle, or boundary circle. Furthermore, search can prioritize results near a given “focus” point. See `?mz_search`.

## Vector tile service

`rmapzen` provides an interface to Mapzen’s vector tiles service. Tile requests can be specified using the x, y, zoom coordinates of the tile service, as well as with a lat/long bounding box. Multiple tiles are stitched together and returned as an object of class `mz_vector_tiles`. See `?mz_vector_tiles`. The sample data set `ca_tiles` contains zoomed out vector tile data for all of California as well as parts of neighboring states.

    ca_tiles
    #> Mapzen vector tile data
    #> Layers: (count of features in parentheses)
    #>     water (144)
    #>     buildings (0)
    #>     places (28)
    #>     transit (10)
    #>     pois (30)
    #>     boundaries (22)
    #>     roads (308)
    #>     earth (4)
    #>     landuse (176)

Each element of a vector tile response includes point, line, and/or polygon data for an individual map layer, and has class `mapzen_vector_layer`. Like other response types, the `mapzen_vector_layer` can be converted to `sf` objects for further processing, using the generic function `as_sf`

    # points of interest
    as_sf(ca_tiles$pois)
    #> The legacy packages maptools, rgdal, and rgeos, underpinning the sp package,
    #> which was just loaded, were retired in October 2023.
    #> Please refer to R-spatial evolution reports for details, especially
    #> https://r-spatial.org/r/2023/05/15/evolution4.html.
    #> It may be desirable to make the sf package available;
    #> package maintainers should consider adding sf to Suggests:.
    #> Registered S3 method overwritten by 'geojsonsf':
    #>   method        from
    #>   print.geojson geojson
    #> Simple feature collection with 30 features and 11 fields
    #> Geometry type: POINT
    #> Dimension:     XY
    #> Bounding box:  xmin: -123.536 ymin: 32.009 xmax: -112.58 ymax: 48.808
    #> Geodetic CRS:  WGS 84
    #> # A tibble: 30 × 12
    #>    kind          protect_class area     operator `name:de` source min_zoom tier
    #>    <chr>         <chr>         <chr>    <chr>    <chr>     <chr>  <chr>    <chr>
    #>  1 national_park 2             1377580… United … <NA>      opens… 5.58     1
    #>  2 national_park 2             2035390… United … <NA>      opens… 5.29     1
    #>  3 national_park 2             2132460… United … National… opens… 3.6      1
    #>  4 national_park 2             2543010… United … <NA>      opens… 5.13     1
    #>  5 national_park 2             2552470… United … Sequoia-… opens… 5.13     1
    #>  6 national_park 2             2740480… United … National… opens… 5.08     1
    #>  7 national_park 2             2812880… United … Kings-Ca… opens… 5.06     1
    #>  8 national_park 2             4671080… United … Joshua-T… opens… 4.7      1
    #>  9 national_park 2             4858760… United … Yosemite… opens… 4.67     1
    #> 10 national_park 2             7790180… United … Olympic-… opens… 4.33     1
    #> # ℹ 20 more rows
    #> # ℹ 4 more variables: osm_relation <chr>, name <chr>, id <chr>,
    #> #   geometry <POINT [°]>

## `sf` conversion

Any object returned by a Mapzen service can be converted to the appropriate `sf` object using the generic `as_sf`, for easy interoperability with other packages. You can also convert most objects directly to data frames, allowing for use within tidy pipelines:

    library(dplyr)
    library(sf)
    as_sf(oakland_public) %>%
        select(name, confidence, region, locality, neighbourhood)
    #> Simple feature collection with 25 features and 5 fields
    #> Geometry type: POINT
    #> Dimension:     XY
    #> Bounding box:  xmin: -122.2854 ymin: 37.73742 xmax: -122.1749 ymax: 37.84632
    #> Geodetic CRS:  WGS 84
    #> # A tibble: 25 × 6
    #>    name       confidence region locality neighbourhood             geometry
    #>    <chr>           <dbl> <chr>  <chr>    <chr>                  <POINT [°]>
    #>  1 Oakland P…      0.926 Calif… Oakland  Shafter       (-122.2625 37.83824)
    #>  2 Oakland P…      0.926 Calif… Oakland  Rockridge        (-122.2511 37.84)
    #>  3 Lakeview …      0.664 Calif… Oakland  <NA>           (-122.249 37.80919)
    #>  4 Golden Ga…      0.663 Calif… Oakland  Gaskill       (-122.2822 37.83937)
    #>  5 Brookfiel…      0.663 Calif… Oakland  South Stoneh… (-122.1886 37.73742)
    #>  6 West Oakl…      0.663 Calif… Oakland  Ralph Bunche  (-122.2854 37.81296)
    #>  7 Elmhurst …      0.663 Calif… Oakland  Webster       (-122.1749 37.75154)
    #>  8 Montclair…      0.663 Calif… Oakland  Montclair     (-122.2141 37.83204)
    #>  9 Main Bran…      0.663 Calif… Oakland  Civic Center  (-122.2638 37.80101)
    #> 10 Latin Ame…      0.663 Calif… Oakland  St. Elizabeth (-122.2225 37.78354)
    #> # ℹ 15 more rows

## Accessor methods

Currently, the following methods are available to pull out commonly used pieces of a response:

- `mz_coordinates` (only available for search results): extracts lat/lon coordinates from search results, and returns them as a `data.frame`.
- `mz_bbox`: returns the bounding box of an object as a `data.frame` with columns `min_lon`, `min_lat`, `max_lon`, and `max_lat`.

    mz_bbox(ca_tiles)
    #> # A tibble: 1 × 4
    #>   min_lon min_lat max_lon max_lat
    #> *   <dbl>   <dbl>   <dbl>   <dbl>
    #> 1    -135    32.0   -112.    48.9