Skip to content

mdsumner/distancetocoast

master
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Code

Files

Permalink
Failed to load latest commit information.
Type
Name
Latest commit message
Commit time
R
 
 
 
 
 
 
 
 
man
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Travis build status

AppVeyor Build Status

distancetocoast

The goal of distancetocoast is to provide an easy lookup for the "distance to coastline" for longitude and latitude coordinates.

Use at your own risk! Literally each of "distance", "to" and "coast" are hard to define carefully, but often we need an easy way to find approximations.

Installation

The distancetocoast package may be installed from Github using devtools.

devtools::install_github("mdsumner/distancetocoast")

Example

There is an in-built data set, in raster format. The raster package includes an extract function which will look up a cell value at a given longitude and latitude location.

This value is the distance (metres) to the coastline from the centre of the cell.

library(distancetocoast)
library(raster)
#> Loading required package: sp
## beware of clashing with tidyr::extract
raster::extract(distance_to_coastline_lowres, cbind(147, -42))
#>       
#> 65628

This is a very approximate value, and it will depend on the content and quality of the coastline data used, on the resolution of the grid itself, some un-quantified local distortions due to coordinate transformations and discretization, and may not be accurate for some applications.

There will be some regions inside oceans, inside land, and inside lakes as defined by the coastline. We make no distinction for "inside" anything, this is purely distance to the line. A matching "land mask" layer could be added to provide a flag for these regions, but this is a deep can of worms ...

This grid was created by process it in tiles, reprojecting the coastline and the grid pixel centres to a local Lambert Azimuthal Equidistant projection (aeqd in PROJ.4 terms) and calculating shortest Cartesian distance to the coastline coordinate in that projection. (We used the nabor package).

plot(distance_to_coastline_lowres, col = viridis::viridis(64))
plot(rnaturalearth::ne_coastline(), add = TRUE)

The in-built data can be interrogated directly for its properties.

## resolution (cell size in native coordinates)
raster::res(distance_to_coastline_lowres)
#> [1] 0.5 0.5

## dimensions (number of columns and rows)
dim(distance_to_coastline_lowres)
#> [1] 360 720   1

## the extent, in native coordinates
raster::extent(distance_to_coastline_lowres)
#> class       : Extent 
#> xmin        : -180 
#> xmax        : 180 
#> ymin        : -90 
#> ymax        : 90

## the "CRS", coordinate reference system (the map projection)
raster::projection(distance_to_coastline_lowres)
#> [1] "+init=epsg:4326 +proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0"

## the range of values (distance in metres)
cellStats(distance_to_coastline_lowres, min)
#> [1] 1
cellStats(distance_to_coastline_lowres, max)
#> [1] 5297879

All of this information may be seen in one step by using the print method.

distance_to_coastline_lowres
#> class       : RasterLayer 
#> dimensions  : 360, 720, 259200  (nrow, ncol, ncell)
#> resolution  : 0.5, 0.5  (x, y)
#> extent      : -180, 180, -90, 90  (xmin, xmax, ymin, ymax)
#> coord. ref. : +init=epsg:4326 +proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0 
#> data source : in memory
#> names       : layer 
#> values      : 1, 5297879  (min, max)

There are also higher resolution layers created from the Natural Earth coastline "50" and "10" scale coastline data sets.

ex <- extent(140, 160, -60, -40)
plot(crop(distance_to_coastline_10, ex), col = viridis::viridis(64))
plot(rnaturalearth::ne_coastline(10), add = TRUE)
abline(v = 147, h = -42)

plot(crop(distance_to_coastline_10, extent(157, 160, -57, -54)), col = viridis::viridis(64))
plot(rnaturalearth::ne_coastline(10), add = TRUE)

extract(distance_to_coastline_10, cbind(147, -42))
#>       
#> 90146
extract(distance_to_coastline_lowres, cbind(147, -42))
#>       
#> 65628

See '/data-raw/' for the code used to produce all layer.

Development

We hope to add more data sets with a wider choice of methods so that an appropriate choice can be made for specific applications.

Fun

For a bit of fun, let's plot as a globe (might not work on Github, but easy enough to run locally).

library(quadmesh)
library(rgl)
library(proj4)

to_globe <- function(x, fact = 12) {
  if (fact > 1) x <- raster::aggregate(distance_to_coastline_lowres, fact = fact)
  qm <- quadmesh(x)
  v <- proj4::ptransform( t(qm$vb[1:3, ]) * pi/180, 
                          raster::projection(x), 
                         "+proj=geocent +datum=WGS84")
  qm$vb[1:3, ] <- t(v)
  scl <- function(x) {rg <- range(x, na.rm = TRUE);(x - rg[1])/diff(rg)}

  qm$material <- list(color = rep(viridis::viridis(64L)[scl(raster::values(x)) * 63L + 1], each = 4))
  qm
}
globe <- to_globe(distance_to_coastline_lowres, fact = 4)
rgl::rgl.clear()
rgl::shade3d(globe, specular = "black")

library(tidyverse)
#> ── Attaching packages ──────────────────────────────────────── tidyverse 1.2.1 ──
#> ✔ ggplot2 2.2.1.9000     ✔ purrr   0.2.4     
#> ✔ tibble  1.4.2          ✔ dplyr   0.7.4     
#> ✔ tidyr   0.7.2          ✔ stringr 1.2.0     
#> ✔ readr   1.1.1          ✔ forcats 0.2.0
#> ── Conflicts ─────────────────────────────────────────── tidyverse_conflicts() ──
#> ✖ ggplot2::calc()  masks raster::calc()
#> ✖ tidyr::extract() masks raster::extract()
#> ✖ dplyr::filter()  masks stats::filter()
#> ✖ dplyr::lag()     masks stats::lag()
#> ✖ dplyr::select()  masks raster::select()
library(spbabel)
rbind_na <- function(x) rbind(x, NA)
mk_lines <- function(x) {
  mat <- spbabel::sptable(x) %>% 
    split(.$branch_) %>% 
    purrr::map_df(rbind_na) %>% 
    dplyr::select(x_, y_) %>%   dplyr::slice(-1) %>% as.matrix()
    as_tibble(proj4::ptransform( as.matrix(mat) * pi/180, 
                          raster::projection(x), 
                         "+proj=geocent +datum=WGS84"))
}
#rgl.clear()
rgl::lines3d(mk_lines(rnaturalearth::ne_coastline()), col = "black", lwd = 3)
#rgl::rglwidget()
#rgl::rgl.snapshot("man/figures/globe1.png")

globe distance

Please note that this project is released with a Contributor Code of Conduct. By participating in this project you agree to abide by its terms.

About

distance to coast, for some definition of "distance", "to", and "coast"

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages