<p><div><div><div><div data-show-faces="false" data-height="21" data-width="100" data-layout="button_count" data-send="true" data-href="https://www.r-bloggers.com/where-to-go-observe-birds-in-radolfzell-an-answer-with-r-and-open-data/"></div></div><div></div></div><div></div></div>
<div>
(This article was first published on <strong><a href="https://ropensci.org/blog/2018/08/14/where-to-bird/"> rOpenSci - open tools for open science</a></strong>, and kindly contributed to <a rel="nofollow" href="https://www.r-bloggers.com/">R-bloggers)</a> </div>
<p>This post is the 1st post of a series showcasing various rOpenSci<br>
packages as if Maëlle were a birder trying to make the most of R in<br>
general and rOpenSci in particular. Although the series use cases will<br>
mostly feature <em>birds</em>, it’ll be the occasion to highlight rOpenSci’s<br>
packages that are more widely applicable, so read on no matter what your<br>
field is! Moreoever, each post should stand on its own.</p>
<p>A logical first step in this birder’s guide to rOpenSci is to use R to<br>
find where to observe birds! In this blog post, we shall use <strong>rOpenSci<br>
packages accessing open geographical data</strong> to locate and visualize<br>
where to observe birds near a given location.</p>
<h3>First of all, where are we now?</h3>
<p>The Max Planck Institute for Ornithology (henceforth shortened to MPI),<br>
where Maëlle will give a talk is located at <em>Am Obstberg 1 78315<br>
Radolfzell</em>. Let’s geolocate it using <a rel="nofollow" href="https://github.com/ropensci/opencage" target="_blank">rOpenSci’s <code>opencage</code><br>
package</a> that interfaces the<br>
<a rel="nofollow" href="https://opencagedata.com/" target="_blank">OpenCage Geocoder</a>, <a rel="nofollow" href="https://opencagedata.com/credits" target="_blank">a commercial service<br>
based on open data</a>. When choosing to<br>
get only one result via <code>limit = 1</code>, one gets what the API considers to<br>
be the best one.</p>
<pre><code>mpi &lt;- opencage::opencage_forward(&quot;Am Obstberg 1 78315 Radolfzell&quot;, limit = 1)$results
class(mpi)
</code></pre>
<pre><code>## [1] &quot;tbl_df&quot;     &quot;tbl&quot;        &quot;data.frame&quot;
</code></pre>
<pre><code>head(names(mpi))
</code></pre>
<pre><code>## [1] &quot;annotations.DMS.lat&quot;    &quot;annotations.DMS.lng&quot;   
## [3] &quot;annotations.MGRS&quot;       &quot;annotations.Maidenhead&quot;
## [5] &quot;annotations.Mercator.x&quot; &quot;annotations.Mercator.y&quot;
</code></pre>
<p>This gets us Am Obstberg 1, 78315 Radolfzell, Germany (<code>mpi$formatted</code>)<br>
which is in <img alt="🇩🇪" src="https://s.w.org/images/core/emoji/2.4/72x72/1f1e9-1f1ea.png" class="wp-smiley"> (<code>mpi$annotations.flag</code> gets us a flag!).</p>
<h3>Birding in a bird hide?</h3>
<h4>Where to find a bird hide?</h4>
<p>You can most certainly go birding anywhere, but if you can find a bird<br>
hide (or <em>bird blind</em> depending on the English you speak), it might be a<br>
very appropriate observation point. Now that we know where the MPI is,<br>
we can look for bird hide(s) in the vicinity. For that, we shall use<br>
<a rel="nofollow" href="https://github.com/ropensci/osmdata" target="_blank">rOpenSci’s <code>osmdata</code> package</a> by<br>
Mark Padgham and collaborators! Note that incidentally, Mark <a rel="nofollow" href="https://link.springer.com/article/10.1007/s10021-010-9397-3" target="_blank">did his<br>
PhD in<br>
ecology</a>.<br>
This package is an interface to <a rel="nofollow" href="https://wiki.openstreetmap.org/wiki/Overpass_API" target="_blank">OpenStreetMap’s Overpass<br>
API</a>. OpenStreetMap is<br>
a collective map of the world. It contains information about towns’<br>
limits, roads, placenames… but also tags of everything, from bars as<br>
seen in <a rel="nofollow" href="https://rgeomatic.hypotheses.org/1244" target="_blank">this blog post</a> to<br>
<a rel="nofollow" href="https://wiki.openstreetmap.org/wiki/Tag:natural%3Dtree" target="_blank">trees</a>. You can<br>
browse existing features <a rel="nofollow" href="https://wiki.openstreetmap.org/wiki/Main_Page" target="_blank">via OpenStreetMap’s<br>
wiki</a>. Some parts of the<br>
world are better mapped than others depending on the local OpenStreetMap<br>
community. Actually, OpenCage’s blog features an interesting series of<br>
<a rel="nofollow" href="https://blog.opencagedata.com/tagged/countryprofile" target="_blank">country profiles</a>.</p>
<p>To look for a bird hide, we first create a bounding box of 10km around<br>
the MPI, using <a rel="nofollow" href="https://github.com/ropensci/bbox" target="_blank">rOpenSci’s <code>bbox</code><br>
package</a>.</p>
<pre><code>bbox &lt;- bbox::lonlat2bbox(mpi$geometry.lng,
                          mpi$geometry.lat,
                          dist = 10, method = &quot;lawn&quot;)
</code></pre>
<p>We then use the <a rel="nofollow" href="https://wiki.openstreetmap.org/wiki/Tag:leisure%3Dbird_hide" target="_blank">key and value associated with bird hides in<br>
OpenStreetMap</a>:<br>
respectively <em>leisure</em> and <em>bird_hide</em>.</p>
<pre><code>library(&quot;osmdata&quot;)
</code></pre>
<pre><code>## Data (c) OpenStreetMap contributors, ODbL 1.0. http://www.openstreetmap.org/copyright
</code></pre>
<pre><code>library(&quot;magrittr&quot;)
(results &lt;- opq(bbox = bbox) %>%
  add_osm_feature(key = 'leisure', value = 'bird_hide') %>%
  osmdata_sf ())
</code></pre>
<pre><code>## Object of class 'osmdata' with:
##                  $bbox : 47.6865,8.8753,47.8494,9.1177
##         $overpass_call : The call submitted to the overpass API
##             $timestamp : [ Thu 5 Jul 2018 08:06:35 ]
##            $osm_points : 'sf' Simple Features Collection with 1 points
##             $osm_lines : 'sf' Simple Features Collection with 0 linestrings
##          $osm_polygons : 'sf' Simple Features Collection with 0 polygons
##        $osm_multilines : 'sf' Simple Features Collection with 0 multilinestrings
##     $osm_multipolygons : 'sf' Simple Features Collection with 0 multipolygons
</code></pre>
<pre><code>results$osm_points
</code></pre>
<pre><code>##              leisure            geometry
## 5004940425 bird_hide 8.920901, 47.741569
</code></pre>
<p>Yay, we now know where to find a bird hide not too far from the MPI!</p>
<h4>Visualizing our location and the bird hide</h4>
<p>So one could enter the coordinates of that bird hide in one’s favourite<br>
mapping software or app but to show you where the bird hide is we can<br>
actually step back and use<br>
<a rel="nofollow" href="https://github.com/ropensci/osmplotr" target="_blank"><code>osmplotr</code></a>, another package<br>
contributed to rOpenSci by Mark Padgham!</p>
<p>The way <code>osmplotr</code> works is letting you create a basemap, on which<br>
you’ll add different layers extracted from OpenStreetMap using<br>
<code>osmplotr::extract_osm_objects</code> or <code>osmdata</code> functions directly. Its<br>
strengths are therefore the use of open data, and the customization of<br>
what you’re using as background!</p>
<p>Let’s create a basemap for our bounding box, and then add roads and<br>
buildings to it.</p>
<pre><code>library(&quot;osmplotr&quot;)
</code></pre>
<pre><code>## Data (c) OpenStreetMap contributors, ODbL 1.0. http://www.openstreetmap.org/copyright
</code></pre>
<pre><code>bbox &lt;- get_bbox(bbox)
dat_B &lt;- extract_osm_objects (key = 'building', bbox = bbox)
dat_H &lt;- extract_osm_objects (key = 'highway', bbox = bbox)

map0 &lt;- osm_basemap(bbox = bbox, bg = 'gray20') %>%
  add_osm_objects (dat_B, col = 'gray40') %>%
  add_osm_objects (dat_H, col = 'gray80')
</code></pre>
<pre><code>map0 %>%
  add_axes() %>%
  print_osm_map (filename = 'map_a1.png', width = 600,
               units = 'px', dpi = 72)

library(&quot;magrittr&quot;)
magick::image_read('map_a1.png') %>%
  magick::image_annotate(&quot;Map data © OpenStreetMap contributors&quot;,
                         color = &quot;white&quot;,
                         boxcolor =  &quot;black&quot;,
                         size = 15,
                         gravity = &quot;south&quot;)
</code></pre>
<p><img src="https://i1.wp.com/ropensci.org/img/blog-images/2018-08-14-where-to-bird/map1-print-1.png?w=450&ssl=1" data-recalc-dims="1"></p>
<p>Quite pretty! The lakes can be seen because of the absence of roads and<br>
buildings on them.</p>
<p>Now, let’s plot the bird hide and the MPI on them. Since we used<br>
<code>osmdata::osmdata_sf</code>, we had gotten the data in a receivable class,<br>
<code>sf</code>.</p>
<pre><code>points_map &lt;- add_osm_objects(map0, results$osm_points, 
                              col = 'salmon',
                              size = 5)
</code></pre>
<p>For plotting the MPI, we’ll convert <code>opencage</code> output to an <code>sf</code> point<br>
with the same coordinate reference system as the OpenStreetMap data<br>
extracted with <code>osmdata</code>.</p>
<pre><code>coords &lt;- data.frame(lon = mpi$geometry.lng,
                     lat = mpi$geometry.lat)
crs &lt;- sf::st_crs(results$osm_points)

mpi_sf &lt;- sf::st_as_sf(coords,
                       coords = c(&quot;lon&quot;, &quot;lat&quot;), 
                      crs = crs)

points_map &lt;- add_osm_objects(points_map, mpi_sf, 
                             col = 'white',
                             size = 5)
</code></pre>
<p>We can now visualize both points on the map, the MPI in white and the<br>
bird hide in salmon, South-West from the MPI.</p>
<pre><code>points_map %>%
  add_axes() %>%
  print_osm_map (filename = 'map_a2.png', 
                 width = 600,
                 units = 'px', dpi = 72) 

magick::image_read('map_a2.png') %>%
  magick::image_annotate(&quot;Map data © OpenStreetMap contributors&quot;,
                         color = &quot;white&quot;,
                         boxcolor =  &quot;black&quot;,
                         size = 15,
                         gravity = &quot;south&quot;)
</code></pre>
<p><img src="https://i0.wp.com/ropensci.org/img/blog-images/2018-08-14-where-to-bird/map2-print-1.png?w=450&ssl=1" data-recalc-dims="1"></p>
<p>Aha, now we see where the bird hide is, fantastic! But as Mark noted,<br>
birds can actually be observed from other places.</p>
<h3>Birding where birds should be?</h3>
<p>Birds are most likely to be found <strong>where water lies close to natural<br>
areas</strong>, and we can translate this to R code! We shall get all water and<br>
(separately) all non-watery natural areas and find the shortest<br>
distances between them before plotting the results using<br>
<code>add_osm_surface</code>.</p>
<p>First, let’s get all water and (separately) all non-watery natural<br>
areas.</p>
<pre><code>dat &lt;- opq(bbox = bbox) %>%
     add_osm_feature(key = 'natural') %>%
     osmdata_sf (quiet = FALSE)
</code></pre>
<pre><code>## Issuing query to Overpass API ...

## Rate limit: 2

## Query complete!

## converting OSM data to sf format
</code></pre>
<pre><code>indx_W &lt;- which (dat$osm_polygons$natural %in% c (&quot;water&quot;, &quot;wetland&quot;))
indx_N &lt;- which (!dat$osm_polygons$natural %in% c (&quot;water&quot;, &quot;wetland&quot;))

xy_W &lt;- sf::st_coordinates (dat$osm_polygons [indx_W, ])
xy_N &lt;- sf::st_coordinates (dat$osm_polygons [indx_N, ])
</code></pre>
<p>Then we use Mark’s <a rel="nofollow" href="https://github.com/hypertidy/geodist" target="_blank"><code>geodist</code><br>
package</a> to get pairwise distances<br>
between all points, find minima, and make a data.frame to submit to<br>
<code>add_osm_surface()</code>. We have 7068 watery points and 10065 non-watery<br>
points so the speed of <code>geodist</code> is crucial here!</p>
<pre><code>t1 &lt;- Sys.time()
d &lt;- geodist::geodist (xy_W, xy_N)
# so fast!!!
Sys.time() - t1
</code></pre>
<pre><code>## Time difference of 13.57983 secs
</code></pre>
<pre><code>d1 &lt;- apply (d, 1, min)
d2 &lt;- apply (d, 2, min)
xy &lt;- cbind (rbind (xy_W, xy_N), c (d1, d2))
xy &lt;- xy [, c (1, 2, 5)]
colnames (xy) &lt;- c (&quot;x&quot;, &quot;y&quot;, &quot;z&quot;)
xy &lt;- xy [!duplicated (xy), ]
</code></pre>
<p>Finally we plot the results on the roads we had gotten earlier, although<br>
we do not recommend staying on the middle of a road to observe birds! We<br>
re-add the points corresponding to the MPI and bird hide after the<br>
surface coloring. With <code>osmplotr</code>, order matters because layers are<br>
added on top of each other. Note that plotting the distances takes a<br>
while.</p>
<pre><code># colorblind-friendly palette!
cols &lt;- viridis::viridis_pal (direction = -1) (30)

add_osm_surface (map0, dat_H,
                 dat = xy, col = cols) %>%
    add_axes()  %>%
  add_colourbar(cols = cols,
                zlim = range(xy[,&quot;z&quot;])) %>%
  add_osm_objects(mpi_sf, 
                  col = 'white', size = 5) %>%
  add_osm_objects(results$osm_points, 
                  col = 'white', size = 5)%>%
  print_osm_map (filename = 'map_a3.png', width = 600,
                 units = 'px', dpi = 72)

magick::image_read('map_a3.png') %>%
  magick::image_annotate(&quot;Map data © OpenStreetMap contributors&quot;,
                         color = &quot;white&quot;,
                         boxcolor =  &quot;black&quot;,
                         size = 15,
                         gravity = &quot;south&quot;)
</code></pre>
<p><img src="https://i1.wp.com/ropensci.org/img/blog-images/2018-08-14-where-to-bird/unnamed-chunk-9-1.png?w=450&ssl=1" data-recalc-dims="1"></p>
<p>On the map, the yellower/lighter a road is, the better it is to observe<br>
birds according to Mark’s assumption that birds are most likely to be<br>
found where water lies close to natural areas. With this metric, the MPI<br>
itself is not too badly located, which after all is not too surprising<br>
for an MPI of <em>ornithology</em>. Maybe one should just walk to the one of<br>
the nearest lakes to meet some birds.</p>
<h3>Conclusion</h3>
<h4>Open geographical data in R</h4>
<p>In this post we showcased three rOpenSci packages helping you use open<br>
geographical data in R:<br>
<a rel="nofollow" href="https://github.com/ropensci/opencage" target="_blank"><code>opencage</code></a>,<br>
<a rel="nofollow" href="https://ropensci.github.io/osmdata/" target="_blank"><code>osmdata</code></a>,<br>
<a rel="nofollow" href="https://ropensci.github.io/osmplotr" target="_blank"><code>osmplotr</code></a>, therefore mostly<br>
making use of the awesome OpenStreetMap data (The OpenCage Geocoder uses<br>
a bit more, but it only warrants <a rel="nofollow" href="https://opencagedata.com/faq#legal" target="_blank">attributing<br>
OpenStreetMap</a>). We therefore added<br>
the annotation “Map data © OpenStreetMap contributors” to all maps of<br>
this post using rOpenSci’s <code>magick</code> package. You might also have noticed<br>
in the code earlier that both <code>osmdata</code> and <code>osmplotr</code> have start-up<br>
messages indicating the data origin and licence.</p>
<p>Another package of rOpenSci’s interacting with open geographical data,<br>
that might be of interest for making maps, is<br>
<a rel="nofollow" href="https://github.com/ropensci/rnaturalearth" target="_blank"><code>rnaturalearth</code></a> that<br>
facilitates interaction with <a rel="nofollow" href="http://www.naturalearthdata.com/" target="_blank">Natural Earth map<br>
data</a>.</p>
<h4>Other R packages for spatial analyses</h4>
<p>We also used two other rOpenSci packages:<br>
<a rel="nofollow" href="https://github.com/ropensci/bbox" target="_blank"><code>bbox</code></a> to get a bounding box and<br>
<a rel="nofollow" href="https://github.com/ropensci/magick" target="_blank"><code>magick</code></a> for image manipulation.<br>
Explore more of our packages suite, including and beyond the geospatial<br>
category, <a rel="nofollow" href="https://ropensci.org/packages/" target="_blank">here</a>.</p>
<p>We also used the <a rel="nofollow" href="https://github.com/hypertidy/geodist" target="_blank"><code>geodist</code><br>
package</a> for ultra lightweight,<br>
ultra fast calculation of geo distances. This package is developed in<br>
the <a rel="nofollow" href="https://github.com/hypertidy" target="_blank">hypertidy GitHub organization</a> which<br>
is a good place to find useful R geospatial packages. Other good<br>
resources for geospatial analyses with R include the <a rel="nofollow" href="https://www.r-spatial.org/" target="_blank">r-spatial.org<br>
website</a> and <a rel="nofollow" href="https://geocompr.robinlovelace.net/" target="_blank">this great book by Robin<br>
Lovelace, Jakub Nowosad and Jannes<br>
Muenchow</a>, and <a rel="nofollow" href="https://itsalocke.com/blog/r-spatial-resources/" target="_blank">more links<br>
presented in this blog post of Steph<br>
Locke’s</a>.</p>
<h4>More birding soon!</h4>
<p>Stay tuned for the next post in this series, about getting bird<br>
observation data in R! In the meantime, happy birding!</p>
	<p>
<div>
<div>To <strong>leave a comment</strong> for the author, please follow the link and comment on their blog: <strong><a href="https://ropensci.org/blog/2018/08/14/where-to-bird/"> rOpenSci - open tools for open science</a></strong>.</div>
<hr>
<a rel="nofollow" href="https://www.r-bloggers.com/">R-bloggers.com</a> offers <strong><a rel="nofollow" href="https://feedburner.google.com/fb/a/mailverify?uri=RBloggers">daily e-mail updates</a></strong> about <a rel="nofollow" href="https://www.r-project.org/" title="The R Project for Statistical Computing">R</a> news and <a rel="nofollow" href="https://www.r-bloggers.com/search/tutorial" title="R tutorials">tutorials</a> on topics such as: <a rel="nofollow" href="https://www.r-bloggers.com/search/data%20science" title="Data science">Data science</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/Big%20Data" title="Big Data">Big Data, <a rel="nofollow" href="https://www.r-users.com/" title="R jobs">R jobs</a>, visualization (<a rel="nofollow" href="https://www.r-bloggers.com/search/ggplot2" title="ggplot and ggplot2 tutorials">ggplot2</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/boxplot" title="Boxplots using lattice and ggplot2 tutorials">Boxplots</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/map" title="Maps and gis">maps</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/animation" title="Animation in R">animation</a>), programming (<a rel="nofollow" href="https://www.r-bloggers.com/search/RStudio" title="RStudio IDE for R">RStudio</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/sweave" title="Sweave and literate programming">Sweave</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/LaTeX" title="LaTeX in R">LaTeX</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/SQL" title="SQL and databases">SQL</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/eclipse" title="Eclipse IDE for R">Eclipse</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/git" title="git and github, Version Control System">git</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/hadoop" title="Large data in R using Hadoop">hadoop</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/Web+Scraping" title="Web Scraping of google, facebook, yahoo, twitter and more using R">Web Scraping</a>) statistics (<a rel="nofollow" href="https://www.r-bloggers.com/search/regression" title="Regressions and ANOVA analysis tutorials">regression</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/PCA" title="principal component analysis tutorial">PCA</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/time+series" title="Time series">time series</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/trading" title="finance trading">trading</a>) and more...
<img width="1" alt="" src="http://feeds.feedburner.com/~r/RBloggers/~4/ro_BHMHXj8Y" height="1"></a></div>