Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/hypertidy/ceramic

read image server tiles direct with GDAL, or download image server tiles to a local cache
https://github.com/hypertidy/ceramic

Last synced: 3 months ago
JSON representation

read image server tiles direct with GDAL, or download image server tiles to a local cache

Awesome Lists containing this project

README

        

---
output: github_document
editor_options:
chunk_output_type: console
---

[![CRAN status](https://www.r-pkg.org/badges/version/ceramic)](https://CRAN.R-project.org/package=ceramic)
[![R-CMD-check](https://github.com/hypertidy/ceramic/actions/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/hypertidy/ceramic/actions/workflows/R-CMD-check.yaml)

```{r setup, include = FALSE}

knitr::opts_chunk$set(
collapse = TRUE,
comment = "#>",
fig.path = "man/figures/README-",
out.width = "100%",
dev = "png"
#, dev.args = list( jpeg = list(quality =50))
)
options(warn = -1)
```
# ceramic

The goal of ceramic is to obtain web map tiles. Use a spatial object to define the region of interest.

```{r extent1}
library(ceramic)
roi <- ext(100, 160, -50, 10)
im <- cc_location(roi)

plotRGB(im)
```

The terra package is always loaded by ceramic, so we can assume the use of its functions, ceramic accepts a wider range of inputs than terra does however.

We can use wk, geos, terra, raster, sp, sf, or stars objects, or an input lon,lat point
and a buffer (in metres) to define an extent. This provides a very easy way to
obtain imagery or elevation data for any almost any region using our own data.

```{r extent2, fig.width=8, fig.height=10}
sql <- "SELECT shapeGroup FROM geoBoundariesCGAZ_ADM0 WHERE shapeGroup IN ('BOL')"
dsn <- "/vsizip//vsicurl/https://github.com/wmgeolab/geoBoundaries/raw/main/releaseData/CGAZ/geoBoundariesCGAZ_ADM0.zip"
bol <- vect(dsn, query = sql)

im <- cc_location(bol)
plotRGB(im)
```

Even if the data uses a map projection it will be converted into a region to match the Mercator extents used by Mapbox image servers.

```{r warn, include = FALSE}
options(warn = -1)
```

```{r nz-spData, include = FALSE}
data("nz", package = "spData")

library(sf)
im_nz2 <- cc_location(nz)
plotRGB(im_nz2)
plot(st_transform(nz, crs(im_nz2))[0], add = TRUE, col = rainbow(nrow(nz), alpha = 0.5))
```

There are basic heuristics to decide if data is projected or just in "longitude,latitude" in the usual way.

Raster elevation data is also available.

```{r}
north <- nz[nz$Island == "North", ]
dem_nz <- cc_elevation(north, type = "elevation-tiles-prod" )

## plot elevation data for NZ north
dem_nz[!dem_nz > 0] <- NA

plot(dem_nz, col = grey.colors(128))
plot(st_transform(st_cast(north, "MULTILINESTRING")["Name"], terra::crs(dem_nz)), add = TRUE, lwd = 5)

```

## I thought you said *tiles*?

Indeed, here's a function called `read_tiles()`, it shares the same interface as `get_tiles()`.

```{r read-tiles}
read_tiles()
```

Note that, the `cc_location()` and `cc_elevation()` functions no longer use tiles, they read directly from the internet using GDAL and are not related to the tile download facilities.

But, they used to run `get_tiles()` behind the scenes. The separation is still a little unfinished, but I want ceramic to have separation of loading data from the internet with downloading tiles.

This function and its counterparts `get_tiles_zoom()`, `get_tiles_dim()` and `get_tiles_buffer()` will *only download files*.

```{r tiles}
tile_summ <- get_tiles_zoom(north, zoom = 8)
length(tile_summ$files)
str(tile_summ$tiles)

(tile_rect <- tiles_to_polygon(ceramic_tiles(zoom = 8)))

```

This is really for expert use when you want to control the downloaded tile files yourself directly.

## Providers

The default map provider is [Mapbox](https://www.mapbox.com/), but ceramic is written for general usage and also provides access to the [joerd AWS tiles](https://github.com/tilezen/joerd/) via the `type = "elevation-tiles-prod"` argument.

```{r}
pt <- cbind(175.6082, -37.994)
nz_z12 <- cc_location(pt, buffer = 100000, type = "elevation-tiles-prod")
```

```{r, eval=FALSE, include = FALSE}
north_carolina <- sf::read_sf(system.file("gpkg/nc.gpkg", package = "sf", mustWork = TRUE))
nc_image <- cc_location(north_carolina)

rowan_dem <- cc_elevation(dplyr::filter(north_carolina, NAME == "Rowan"))
rowan_dem
```

## Installation

Install ceramic from CRAN with:

```R
install.packages("ceramic")
```

You can install the development version of ceramic from Github.

```R
## install.packages("remotes")
remotes::install_github("hypertidy/ceramic")
```

Set your mapbox API key with

```R
Sys.setenv(MAPBOX_API_KEY = "")
```

## Example

This complete example gets tiled imagery that we can use as real data.

The code here

- generates a bounding box in longitude-latitude
- reads the raster data using GDAL

then we look at the actual tiles involved,

- uses [slippymath](https://CRAN.r-project.org/package=slippymath) to
find sensible tiles for the region
- downloads them to a local cache
- summarizes the tiles as a spatial (wk) object

```{r example01}
library(ceramic)
## a point in longlat, and a buffer with in metres
pt <- cbind(136, -34)
im <- cc_location(pt, buffer = c(1e6, 5e5), type = "mapbox.satellite")
op <- par(bg = "black")
plotRGB(im)

## get the approximately matching tiles (zoom is magic here, it's all wrapped - needs thought)

tileset <- get_tiles(pt, buffer = c(1e6, 5e5))
tiles <- ceramic_tiles(zoom = tileset$tiles$zoom, type = "mapbox.satellite")
plot(tiles_to_polygon(tiles), add = TRUE, border = "white")

middle <- function(x, y) {
x + (y - x)/2
}
text(middle(tiles$xmin, tiles$xmax), middle(tiles$ymin, tiles$ymax), lab = sprintf("[%i,%i]", tiles$tile_x, tiles$tile_y),
col = "yellow")

par(op)
```

## Tasmap maps

```{r tasmap}
library(ceramic)
library(terra)
template <- rast(ext(527358, 527880, 5252204, 5252704), res = .3, crs = "EPSG:32755")
ortho <- cc_location(template, type = "tasmap_orthophoto")

plot(ortho)

plot(cc_location(template, type = "tasmap_street"))

plot(cc_location(template, type = "tasmap_tasmapraster"))

plot(cc_location(template, type = "tasmap_hillshade"))

plot(cc_location(template, type = "tasmap_hillshadegrey"))
plot(cc_location(template, type = "tasmap_esgismapbookpublic")) ## nope
plot(cc_location(template, type = "tasmap_topographic"))

plot(cc_location(template, type = "tasmap_tasmap25k")) ## also 100k, 250k, 500k

```

```{r smash,include=FALSE}
quantize_figs <- function(dir = "man/figures") {
f <- fs::dir_ls(dir, regexp = "png$")
for (i in seq_along(f)) {
tf <- tempfile(fileext = ".png")
im <- magick::image_read(f[i])
magick::image_write(magick::image_quantize(im), tf)

## I don't know how to properly unlink the original pointer, this just a guess (not sure it matters)
rm(im)
fs::file_delete(f[i])
fs::file_move(tf, f[i])
}
}
quantize_figs()
```

---

Please note that the 'ceramic' project is released with a [Contributor Code of Conduct](https://github.com/hypertidy/ceramic/blob/master/CODE_OF_CONDUCT.md). By contributing to this project, you agree to abide by its terms.