gbif_photos.r
#' View photos from GBIF.
#'
#' @importFrom whisker whisker.render
#' @export
#' @param input Input output from occ_search
#' @param output Output folder path. If not given uses temporary folder.
#' @param which One of map or table (default).
#' @param browse (logical) Browse output (default: TRUE)
#' @details The max number of photos you can see when which="map" is ~160, so cycle through
#' if you have more than that.
#' @examples \dontrun{
#' (res <- occ_search(mediatype = 'StillImage', return = "media"))
#' gbif_photos(res)
#' gbif_photos(res, which='map')
#'
#' res <- occ_search(scientificName = "Aves", mediatype = 'StillImage', return = "media", limit=150)
#' gbif_photos(res)
#' gbif_photos(res, output = '~/barfoo')
#' }
gbif_photos <- function(input, output = NULL, which='table', browse = TRUE) {
if(which=='map'){
photos <- foo(input)
outfile <- dirhandler(output)
filepath <- system.file("singlemaplayout.html", package = "rgbif")
ff <- paste(readLines(filepath), collapse = "\n")
rr <- whisker.render(ff)
write(rr, file = outfile)
if(browse) browseURL(outfile)
} else {
if(length(input) > 20){
outdir <- dirhandler(output, 'dir')
input <- split(input, ceiling(seq_along(input)/20))
filenames <- replicate(length(input), path.expand(tempfile(fileext=".html", tmpdir = outdir)))
filenames <- as.list(filenames)
links <- list()
for(i in seq_along(filenames)) links[[i]] <- list(url=filenames[[i]], pagenum=i)
for(i in seq_along(input)){
photos <- foo(input[[i]])
mappaths <- makemapfiles(photos, outdir)
photos <- Map(function(x,y) c(x, mappath=y), photos, mappaths)
rendered <- whisker.render(template)
paginated <- whisker.render(pagination)
rendered <- paste0(rendered, paginated, footer)
write(rendered, file = filenames[[i]])
}
if(browse) browseURL(filenames[[1]])
} else {
outfile <- dirhandler(output)
outdir <- dirname(outfile)
photos <- foo(input)
mappaths <- makemapfiles(photos, outdir)
photos <- Map(function(x,y) c(x, mappath=y), photos, mappaths)
rendered <- whisker.render(template)
rendered <- paste0(rendered, footer)
write(rendered, file = outfile)
if(browse) browseURL(outfile)
}
}
}
dirhandler <- function(x, which="file"){
if(is.null(x)){
dir <- tempdir()
dir.create(dir, recursive = TRUE, showWarnings = FALSE)
switch(which, file=file.path(dir, "index.html"), dir=dir)
} else {
if(!file.exists(x)) dir.create(x, recursive = TRUE, showWarnings = FALSE)
switch(which, file=file.path(x, "index.html"), dir=x)
}
}
foo <- function(x){
photos <- lapply(x, function(y){
if(is.null(y$decimalLatitude) || is.null(y$decimalLongitude)){ NULL } else {
tmp <- y[c('key','species','decimalLatitude','decimalLongitude','country')]
tmp[sapply(tmp, is.null)] <- "none"
names(tmp) <- c('key','species','decimalLatitude','decimalLongitude','country')
list(c(tmp, y[!names(y) %in% c('key','species','decimalLatitude','decimalLongitude','country')][[1]][c(3:4)]))
}
})
do.call(c, unname(rgbif_compact(photos)))
}
template <- '
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<title>rgbif - photos</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="View photos from GBIF query">
<meta name="author" content="ecoengine">
<link href="http://netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet">
<link href="http://netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.css" rel="stylesheet">
</head>
<body>
<div class="container">
<center><h2>rgbif photo viewer</h2></center>
<table class="table table-striped table-hover" align="center">
<thead>
<tr>
<th>Species</th>
<th>Photo</th>
<th>Location</th>
</tr>
</thead>
<tbody>
{{#photos}}
<tr>
<td><i>{{species}}</i></td>
<td><a href="{{{references}}}"><img src="{{{identifier}}}" height="200" style="border-radius: 10px 10px 10px 10px; max-width: 400px"></a></td>
<td><iframe src="{{mappath}}" width="400" height="200" frameborder="0"></iframe></td>
</tr>
{{/photos}}
</tbody>
</table>
</div>
'
pagination <- '
<center>
<ul class="pagination pagination-lg">
{{#links}}
<li><a href="{{url}}">{{pagenum}}</a></li>
{{/links}}
</ul>
</center>
'
footer <- '
<script src="http://code.jquery.com/jquery-2.0.3.min.js"></script>
<script src="http://netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js"></script>
</body>
</html>'
makemapfiles <- function(x, dir){
mapfiles <- list()
for(i in seq_along(x)){
file <- path.expand(tempfile("map", tmpdir = dir, fileext = ".html"))
mapfiles[[i]] <- file
tmp <- whisker.render(map, data = x[[i]])
write(tmp, file = file)
}
mapfiles
}
map <- '
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8 />
<title>Single marker</title>
<meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" />
<script src="https://api.tiles.mapbox.com/mapbox.js/v1.6.4/mapbox.js"></script>
<link href="https://api.tiles.mapbox.com/mapbox.js/v1.6.4/mapbox.css" rel="stylesheet" />
<style>
body { margin:0; padding:0; }
#map { position:absolute; top:0; bottom:0; width:100%; }
</style>
</head>
<body>
<div id="map"></div>
<script>
var map = L.mapbox.map("map", "examples.map-i86nkdio")
.setView([{{decimalLatitude}}, {{decimalLongitude}}], 5);
L.mapbox.featureLayer({
type: "Feature",
geometry: {
type: "Point",
coordinates: [ {{decimalLongitude}}, {{decimalLatitude}} ]
},
properties: {
"title": "{{species}}",
"marker-size": "large",
"marker-color": "#FB8A24",
"marker-symbol": "garden"
}
}).addTo(map);
</script>
</body>
</html>
'