ropensci / unconf14

Repo to brainstorm ideas (unconference style) for the rOpenSci hackathon.
28 stars 3 forks source link

Interactive polygon/bounding box selection #17

Open sckott opened 10 years ago

sckott commented 10 years ago

For our new spocc package, we want to provide a way for users to within R pick an area to delimit a search for occurrence data (observations of species in nature). Right now you have to somehow already know the coordinates you want to search within, or you go to some website to get coordinates for an area. Would be nice to do this in R.

It makes sense to do this interactively so that they can make one fxn call to a) go anywhere on a map at any zoom level, and b) draw a polygon to create an area to search in. Ideally in b) drawing this polygon gives them back the coordinates for the polygon (in well known text (WKT)) or a box (so 4 corners, equal side lengths) if there is a way to let a user draw a box.

Can we make a function to pull up a shiny app to look at a map, allow user to draw polygon/box, get coordinates for the poygon/box, then feed to function to search for occurrence data.

We could then easily feed these coordinates to the search function and display in the shiny app as well.

karthik commented 10 years ago

To add more notes to this discussion, @jcheng5 and I briefly talked (at Metamarket) about embedding Shiny inside search functions in R packages that would allow users to interactively set geographic bounds on leaflet (or other) maps, and have those returned back to the R kernel (to be saved with the result set). So there would be a component of interactivity but it wouldn't detract from the reproducible nature of the exercise.

sckott commented 10 years ago

nice :+1:

jcheng5 commented 10 years ago

Yes--very doable.

Here's an example of running a Shiny app on-the-fly and returning a value. Source this code, then try print(ikmeans(cars)). https://github.com/jcheng5/kmeans/blob/a472925b0c263580f7437759b540a7d118e0d04c/ikmeans.R

For the Leaflet component, here's the package: https://github.com/jcheng5/leaflet-shiny

I imagine that for each click you'd want to 1) map$addMarker(), 2) map$clearShapes(), 3) map$addPolygon(). Then have an Accept button that calls shiny::stopApp() with the polygon data.

karthik commented 10 years ago

Fantastic! Thanks @jcheng5!

As a first pass, we should add this to packages that allow searching by bounding box (Spocc, ecoengine, AntWeb etc).

AmeliaMN commented 10 years ago

I agree that it would be useful in a variety of venues to be able to interactively bound and zoom. This has some crossover with the mapping thread, so I wasn't sure where to post it, but it seems more appropriate here.

I work with high school teachers & students, who we want to be able to use R to do some simple tasks, one of which is map spatial data. Some important features for the users were having a nice-looking base map (i.e. not just the blank page you get when plotting spatial data in base R plots) and being able to "zoom in." When I looked around for these features (a few years ago now) the best package I found was dismo, because of the nice gmap() function. So, in our package (https://github.com/mobilizingcs/MobilizeSimple) we use that for the mapping, and the regular old drawExtent() from the raster package for zooming. It's pretty rough, and I know that our users would love a smoother interface!

karthik commented 10 years ago

I work with high school teachers & students, who we want to be able to use R to do some simple tasks, one of which is map spatial data. Some important features for the users were having a nice-looking base map (i.e. not just the blank page you get when plotting spatial data in base R plots) and being able to "zoom in." When I looked around for these features (a few years ago now) the best package I found was dismo, because of the nice gmap() function. So, in our package (https://github.com/mobilizingcs/MobilizeSimple) we use that for the mapping, and the regular old drawExtent() from the raster package for zooming. It's pretty rough, and I know that our users would love a smoother interface!

We can definitely start a new mapping thread if necessary. Right now we have some interactive maps based on LeafletJS in a couple of packages. But it would be nice to just move that out into a general one. So for e.g. this does what you're asking above:

install_github("ropensci/ecoengine")
library(ecoengine)
vulpes <- ee_observations(genus = "vulpes", georeferenced = TRUE, quiet = TRUE, page = "all")
ee_map(vulpes)

renders this on a local browser:

image

It's fully interactive and the tooltips can be customized based on any field in the data.frame. So maybe something we should consider implementing more generally? Perhaps as part of rMaps?

karthik commented 10 years ago

As for bounding box, I find it hard to do this manually. Right now I use this website: http://boundingbox.klokantech.com/

Would be nice to use @jcheng5's approach and say:

get_bounding_box()

and a map pops up and we choose a region and hit ok. Then it returns those values to the appropriate R kernel.

karthik commented 10 years ago

@AmeliaMN That MobilizeSimple package looks great!

AmeliaMN commented 10 years ago

Yes, I wrote the MobilizeSimple stuff for teachers/students, but now that I have it put together I've definitely found myself reaching for it in my own work. The drawExtent() hack works pretty well, so you don't have to do the manual bounding box stuff. But, there's something off in our current implementation. The resulting bounding box is just slightly off from what you actually draw! Barely enough to be noticeable, but I've been trying to track it down to no avail.