Skip to content

Instantly share code, notes, and snippets.

@ramnathv
Last active August 21, 2017 16:27
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ramnathv/6144287 to your computer and use it in GitHub Desktop.
Save ramnathv/6144287 to your computer and use it in GitHub Desktop.
Google Maps with Shiny

This is a minor modification of this post. The basic problem is that to update the histogram, one had to (a) click on a point on the map, (2) go to the numeric input box and (3) press enter. This can be simplified by adding three pieces of code.

setValue

First, we modify the setValue function so that in addition to modifying the value of the row clicked, it also communicates this value to the Shiny input variable row.

function SetValue(i) {
	document.getElementById("row").value = i;
  Shiny.onInputChange("row", i)
	document.getElementById("row").focus();
}

observeEvent

Inside server.R, we use a function observeEvent to receive such messages, and update the input variable, which will then trigger change in the histogram through Shiny's reactive mechanisms. Note that observeEvent is a function in server.R, but there are plans to add it to the Shiny package explicitly.

observeEvent(input$row, function(){
  updateNumericInput(session, "row", value = input$row)
})
<!DOCTYPE html>
<html>
<head>
<title>Interfacing R and Google maps</title>
<meta charset=utf-8">
<script src="http://code.jquery.com/jquery-1.10.2.min.js" type="text/javascript"></script>
<script src="shared/shiny.js" type="text/javascript"></script>
<link rel="stylesheet" type="text/css" href="shared/slider/css/jquery.slider.min.css"/>
<script src="shared/slider/js/jquery.slider.min.js"></script>
<link rel="stylesheet" type="text/css" href="shared/shiny.css"/>
<script type="text/javascript"
src="https://maps.googleapis.com/maps/api/js?&sensor=false&language=en">
</script>
<script type="text/javascript" src="http://www.fabioveronesi.net/ShinyApp/Points2.json"></script>
<script type="text/javascript">
var cluster = null;
function SetValue(i) {
document.getElementById("row").value = i;
Shiny.onInputChange("row", i)
document.getElementById("row").focus();
}
function initialize() {
var mapOptions = {
center: new google.maps.LatLng(51.781436,-1.03363),
zoom: 8,
mapTypeId: google.maps.MapTypeId.ROADMAP,
mapTypeControl: false,
disableDefaultUI: true,
navigationControl:false,
disableDoubleClickZoom: true,
scrollwheel: false,
};
var map = new google.maps.Map(document.getElementById("map-canvas"),
mapOptions);
var Layer0 = new google.maps.KmlLayer("http://www.fabioveronesi.net/ShinyApp/layer0.kml");
var Layer1 = new google.maps.KmlLayer("http://www.fabioveronesi.net/ShinyApp/layer1.kml");
document.getElementById('lay0').onclick = function() {
Layer0.setMap(map);
};
document.getElementById('lay1').onclick = function() {
Layer1.setMap(map);
};
var Gmarkers = [];
var infowindow = new google.maps.InfoWindow();
for (var i = 0; i < Points.length; i++) {
var lat = Points[i][1]
var lng = Points[i][0]
var marker = new google.maps.Marker({
position: new google.maps.LatLng(lat, lng),
title: i.toString(),
icon: 'http://www.fabioveronesi.net/ShinyApp/icon.png',
map: map
});
google.maps.event.addListener(marker, 'click',
(function(i) {
return function() {
SetValue(i+1);
}
})(i));
Gmarkers.push(marker);
};
document.getElementById('clear').onclick = function() {
Layer1.setMap(null);
Layer0.setMap(null);
};
};
google.maps.event.addDomListener(window, 'load', initialize);
</script>
</head>
<body>
<h1>Interfacing R with Google maps</h1>
<label for="row">ID:</label>
<input name="row" id="row" type="number" value="1"/>
<button type="button" id="lay1">Add Mean</button>
<button type="button" id="lay0">Add SD</button>
<button type="button" id="clear">Clear Map</button>
<div id="plot" class="shiny-plot-output"
style="position:absolute;top:20%;right:2%;width: 40%; height: 40%"></div>
<div id="map-canvas" style="position:absolute;top:20%;left:2%;width: 50% ; height: 50%"></div>
<div style="position:absolute;top:75%;left:2%;width:40%;heigth:100px">
<h3>Instructions</h3>
<p style="text-align:justify;">The map is not zoomable. This is because otherwise you won't be able to click on the invisible markers.<br>
To use the app just select one of the two available maps from the buttons below the title. Click on one of the pixels to update the ID field, and then click "enter" twice to submit the change and update the plot</p></div>
</body>
</html>
library(shiny)
data_file<-read.table("http://www.fabioveronesi.net/ShinyApp/point_grid.csv",sep=";",header=T)
# From a future version of Shiny
# Stolen from @jcheng5
# ---
observeEvent <- function(eventExpr, callback, env=parent.frame(), quoted=FALSE) {
eventFunc <- exprToFunction(eventExpr, env, quoted)
initialized <- FALSE
invisible(observe({
eventVal <- eventFunc()
if (!initialized)
initialized <<- TRUE
else
isolate(callback())
}))
}
# ---
shinyServer(function(input,output, session){
# Observe for changes to row and update the numeric input
observeEvent(input$row, function(){
updateNumericInput(session, "row", value = input$row)
})
#---
output$plot <- renderPlot({
sub<-data_file[input$row,]
data<-rnorm(10000,mean=sub$Wind_Media,sd=sub$StDev_smoo)
hist(data)
})
})
require(shiny)
shinyUI(
includeHTML("index.html")
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment