Live Earthquake Map with Shiny and Google Map API
This article is originally published at https://r-video-tutorial.blogspot.com/In the post Exchange data between R and the Google Maps API using Shiny I presented a very simple way to allow communication between R and javascript using Shiny.
This is an example of a practical approach for which the same system can be used. Here I created a tool to visualize seismic events, collected from USGS, in the Google Maps API using R to do some basic data preparation. The procedure to complete this experiment is pretty much identical to what I presented in the post mentioned above, so I will not repeated here.
The final map looks like this:
and it is accessible from this site, hosted on the Amazon Cloud: Earthquake
The colours of the markers depends on magnitude and they are set in R. For magnitudes below 2 the marker is green, between 2 and 4 is yellow, between 4 and 6 is orange and above 6 is red.
I also set R to export other information about the event to the json file that I then use to populate the infowindow of each marker.
The code for creating this map consists of two pieces, an index.html file (which needs to go in a folder names www) and the file server.r, available below:
Server.r
# server.R
#Title: Earthquake Visualization in Shiny
#Copyright: Fabio Veronesi
library(sp)
library(rjson)
library(RJSONIO)
shinyServer(function(input, output) {
output$json <- reactive ({
if(length(input$Earth)>0){
if(input$Earth==1){
hour <- read.table("http://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_hour.csv", sep = ",", header = T)
if(nrow(hour)>0){
lis <- list()
for(i in 1:nrow(hour)){
if(hour$mag[i]<=2){icon="http://maps.gstatic.com/mapfiles/ridefinder-images/mm_20_green.png"}
else if(hour$mag[i]>2&hour$mag[i]<=4){icon="http://maps.gstatic.com/mapfiles/ridefinder-images/mm_20_yellow.png"}
else if(hour$mag[i]>4&hour$mag[i]<=6){icon="http://maps.gstatic.com/mapfiles/ridefinder-images/mm_20_orange.png"}
else {icon="http://maps.gstatic.com/mapfiles/ridefinder-images/mm_20_red.png"}
Date.hour <- substring(hour$time[i],1,10)
Time.hour <- substring(hour$time[i],12,23)
lis[[i]] <- list(i,hour$longitude[i],hour$latitude[i],icon,hour$place[i],hour$depth[i],hour$mag[i],Date.hour,Time.hour)
}
#This code creates the variable test directly in javascript for export the grid in the Google Maps API
#I have taken this part from:http://stackoverflow.com/questions/26719334/passing-json-data-to-a-javascript-object-with-shiny
paste('<script>test=',
RJSONIO::toJSON(lis),
';setAllMap();Cities_Markers();',
'</script>')
}
}
else if(input$Earth==4){
month <- read.table("http://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_month.csv", sep = ",", header = T)
if(nrow(month)>0){
lis <- list()
for(i in 1:nrow(month)){
if(month$mag[i]<=2){icon="http://maps.gstatic.com/mapfiles/ridefinder-images/mm_20_green.png"}
else if(month$mag[i]>2&month$mag[i]<=4){icon="http://maps.gstatic.com/mapfiles/ridefinder-images/mm_20_yellow.png"}
else if(month$mag[i]>4&month$mag[i]<=6){icon="http://maps.gstatic.com/mapfiles/ridefinder-images/mm_20_orange.png"}
else {icon="http://maps.gstatic.com/mapfiles/ridefinder-images/mm_20_red.png"}
Date.month <- substring(month$time[i],1,10)
Time.month <- substring(month$time[i],12,23)
lis[[i]] <- list(i,month$longitude[i],month$latitude[i],icon,month$place[i],month$depth[i],month$mag[i],Date.month,Time.month)
}
#This code creates the variable test directly in javascript for export the grid in the Google Maps API
#I have taken this part from:http://stackoverflow.com/questions/26719334/passing-json-data-to-a-javascript-object-with-shiny
paste('<script>test=',
RJSONIO::toJSON(lis),
';setAllMap();Cities_Markers();',
'</script>')
}
}
else if(input$Earth==3){
week <- read.table("http://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_week.csv", sep = ",", header = T)
if(nrow(week)>0){
lis <- list()
for(i in 1:nrow(week)){
if(week$mag[i]<=2){icon="http://maps.gstatic.com/mapfiles/ridefinder-images/mm_20_green.png"}
else if(week$mag[i]>2&week$mag[i]<=4){icon="http://maps.gstatic.com/mapfiles/ridefinder-images/mm_20_yellow.png"}
else if(week$mag[i]>4&week$mag[i]<=6){icon="http://maps.gstatic.com/mapfiles/ridefinder-images/mm_20_orange.png"}
else {icon="http://maps.gstatic.com/mapfiles/ridefinder-images/mm_20_red.png"}
Date.week <- substring(week$time[i],1,10)
Time.week <- substring(week$time[i],12,23)
lis[[i]] <- list(i,week$longitude[i],week$latitude[i],icon,week$place[i],week$depth[i],week$mag[i],Date.week,Time.week)
}
#This code creates the variable test directly in javascript for export the grid in the Google Maps API
#I have taken this part from:http://stackoverflow.com/questions/26719334/passing-json-data-to-a-javascript-object-with-shiny
paste('<script>test=',
RJSONIO::toJSON(lis),
';setAllMap();Cities_Markers();',
'</script>')
}
}
else {
day <- read.table("http://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_day.csv", sep = ",", header = T)
if(nrow(day)>0){
lis <- list()
for(i in 1:nrow(day)){
if(day$mag[i]<=2){icon="http://maps.gstatic.com/mapfiles/ridefinder-images/mm_20_green.png"}
else if(day$mag[i]>2&day$mag[i]<=4){icon="http://maps.gstatic.com/mapfiles/ridefinder-images/mm_20_yellow.png"}
else if(day$mag[i]>4&day$mag[i]<=6){icon="http://maps.gstatic.com/mapfiles/ridefinder-images/mm_20_orange.png"}
else {icon="http://maps.gstatic.com/mapfiles/ridefinder-images/mm_20_red.png"}
Date.day <- substring(day$time[i],1,10)
Time.day <- substring(day$time[i],12,23)
lis[[i]] <- list(i,day$longitude[i],day$latitude[i],icon,day$place[i],day$depth[i],day$mag[i],Date.day,Time.day)
}
#This code creates the variable test directly in javascript for export the grid in the Google Maps API
#I have taken this part from:http://stackoverflow.com/questions/26719334/passing-json-data-to-a-javascript-object-with-shiny
paste('<script>test=',
RJSONIO::toJSON(lis),
';setAllMap();Cities_Markers();',
'</script>')
}
}
}
})
})
Index.html
<!DOCTYPE html>
<html>
<head>
<title>Earthquake Visualization in Shiny</title>
<!--METADATA-->
<meta name="author" content="Fabio Veronesi">
<meta name="copyright" content="©Fabio Veronesi">
<meta http-equiv="Content-Language" content="en-gb">
<meta charset="utf-8"/>
<style type="text/css">
html { height: 100% }
body { height: 100%; margin: 0; padding: 0 }
map-canvas { height: 100%; width:100% }
.btn {
background: #dde6d8;
background-image: -webkit-linear-gradient(top, #dde6d8, #859ead);
background-image: -moz-linear-gradient(top, #dde6d8, #859ead);
background-image: -ms-linear-gradient(top, #dde6d8, #859ead);
background-image: -o-linear-gradient(top, #dde6d8, #859ead);
background-image: linear-gradient(to bottom, #dde6d8, #859ead);
-webkit-border-radius: 7;
-moz-border-radius: 7;
border-radius: 7px;
font-family: Arial;
color: #000000;
font-size: 20px;
padding: 9px 20px 10px 20px;
text-decoration: none;
}
.btn:hover {
background: #f29f9f;
background-image: -webkit-linear-gradient(top, #f29f9f, #ab1111);
background-image: -moz-linear-gradient(top, #f29f9f, #ab1111);
background-image: -ms-linear-gradient(top, #f29f9f, #ab1111);
background-image: -o-linear-gradient(top, #f29f9f, #ab1111);
background-image: linear-gradient(to bottom, #f29f9f, #ab1111);
text-decoration: none;
}
</style>
<script type="text/javascript" src="https://google-maps-utility-library-v3.googlecode.com/svn/tags/markerclusterer/1.0/src/markerclusterer.js"></script>
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp&signed_in=true&libraries=drawing"></script>
<script type="application/shiny-singletons"></script>
<script type="application/html-dependencies">json2[2014.02.04];jquery[1.11.0];shiny[0.11.1];ionrangeslider[2.0.2];bootstrap[3.3.1]</script>
<script src="shared/json2-min.js"></script>
<script src="shared/jquery.min.js"></script>
<link href="shared/shiny.css" rel="stylesheet" />
<script src="shared/shiny.min.js"></script>
<link href="shared/ionrangeslider/css/normalize.css" rel="stylesheet" />
<link href="shared/ionrangeslider/css/ion.rangeSlider.css" rel="stylesheet" />
<link href="shared/ionrangeslider/css/ion.rangeSlider.skinShiny.css" rel="stylesheet" />
<script src="shared/ionrangeslider/js/ion.rangeSlider.min.js"></script>
<link href="shared/bootstrap/css/bootstrap.min.css" rel="stylesheet" />
<script src="shared/bootstrap/js/bootstrap.min.js"></script>
<script src="shared/bootstrap/shim/html5shiv.min.js"></script>
<script src="shared/bootstrap/shim/respond.min.js"></script>
<script type="text/javascript">
var map = null;
var Gmarkers = [];
function Cities_Markers() {
var infowindow = new google.maps.InfoWindow({ maxWidth: 500,maxHeight:500 });
//Loop to add markers to the map based on the JSON exported from R, which is within the variable test
for (var i = 0; i < test.length; i++) {
var lat = test[i][2]
var lng = test[i][1]
var marker = new google.maps.Marker({
position: new google.maps.LatLng(lat, lng),
title: 'test',
map: map,
icon:test[i][3]
});
//This sets up the infowindow
google.maps.event.addListener(marker, 'click', (function(marker, i) {
return function() {
infowindow.setContent('<div id="content"><p><b>Location</b> = '+
test[i][4]+'<p>'+
'<b>Depth</b> = '+test[i][5]+'Km <p>'+
'<b>Magnitude</b> = '+test[i][6]+ '<p>'+
'<b>Date</b> = '+test[i][7]+'<p>'+
'<b>Time</b> = '+test[i][8]+'</div>');
infowindow.open(map, marker);
}
})(marker, i));
Gmarkers.push(marker);
};
};
//Function to remove all the markers from the map
function setAllMap() {
for (var i = 0; i < Gmarkers.length; i++) {
Gmarkers[i].setMap(null);
}
}
//Initialize the map
function initialize() {
var mapOptions = {
center: new google.maps.LatLng(31.6, 0),
zoom: 3,
mapTypeId: google.maps.MapTypeId.TERRAIN
};
map = new google.maps.Map(document.getElementById('map-canvas'),mapOptions);
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
</head>
<body>
<div id="json" class="shiny-html-output"></div>
<button type="button" class="btn" id="hour" onClick="Shiny.onInputChange('Earth', 1)" style="position:absolute;top:1%;left:1%;width:100px;z-index:999">Last Hour</button>
<button type="button" class="btn" id="day" onClick="Shiny.onInputChange('Earth', 2)" style="position:absolute;top:1%;left:10%;width:100px;z-index:999">Last Day</button>
<button type="button" class="btn" id="week" onClick="Shiny.onInputChange('Earth', 3)" style="position:absolute;top:1%;left:20%;width:100px;z-index:999">Last Week</button>
<button type="button" class="btn" id="month" onClick="Shiny.onInputChange('Earth', 4)" style="position:absolute;top:1%;left:30%;width:100px;z-index:999">Last Month</button>
<div id="map-canvas" style="top:0%;right:0%;width:100%;height:100%;z-index:1"></div>
</body>
</html>
Created with CodeFormatterThanks for visiting r-craft.org
This article is originally published at https://r-video-tutorial.blogspot.com/
Please visit source website for post related comments.