使用 Leaflet 在 Zeppelin 上绘制热图
Heatmap on Zeppelin using Leaflet
我想使用带有 R 的 Leaflet 将热图添加到 Zeppelin 段落。我在 R Studio 中编写了一个脚本,它工作正常,但是当我迁移到 Zeppelin 时,热图没有显示。这是我在 R Studio
中的代码
map3 <- Leaflet$new()
map3$setView(c(29.7632836, -95.3632715), 10)
vector <- c( list(c(29.76,-95.36, 50)), list(c(29.77, -95.37, 50)), list(c(29.75,-95.39,50)))
#vector = toJSONArray2(na.omit(vector), json = F, names = F)
cat(rjson::toJSON(vector[1:3]))
map3$addAssets(jshead = c(
"http://leaflet.github.io/Leaflet.heat/dist/leaflet-heat.js"
))
map3$addAssets(jshead = c("http://leaflet.github.io/Leaflet.heat/dist/leaflet-heat.js"))
map3$setTemplate(afterScript = sprintf("
<script>
var addressPoints = %s
var heat = L.heatLayer(addressPoints).addTo(map)
</script>"
,rjson::toJSON(vector)))
map3
我在 Zeppelin 中的代码几乎完全相同。只有输入和输出方式改变:
library(SparkR)
sparkcontext <- sparkR.init("local[4]","cvspark",sparkEnvir=list(spark.executor.memory="1g"))
#sparkR.session()
positions <- sql("SELECT lat, long FROM my_table")
pos <- collect(positions)
map3 <- Leaflet$new()
map3$setView(c(39.93, 32.85))
vector <- c()
values1 <- pos[[1]]
values2 <- pos[[2]]
for (i in 1:length(values1))
vector <- c(vector, list(c(values1[i], values2[i], 1000)))
cat(rjson::toJSON(vector[1:3]))
map3$addAssets(jshead = c("http://leaflet.github.io/Leaflet.heat/dist/leaflet-heat.js"))
map3$setTemplate(afterScript = sprintf("
<script>
var addressPoints = %s
var heat = L.heatLayer(addressPoints).addTo(map)
</script>"
,rjson::toJSON(vector)))
map3$print("map3", include_assets=TRUE, cdn=TRUE)
以下代码显示输入是相同的:
cat(rjson::toJSON(vector[1:3]))
R Studio 输出:
[[29.76,-95.36,50],[29.77,-95.37,50],[29.75,-95.39,50]],
飞艇输出:
[[41.6406843380063,37.6892873258843,1000],[37.0194101218466,30.3908073266391,1000],[34.0236444385`445,40.5599139822316,1000]]
这里的问题是 map3$print("map3", include_assets=TRUE, cdn=TRUE)
在其输出中不包括热图层。据我所知,为了在 Zeppelin 上显示地图,必须调用此方法。问题是:我们如何让 print 方法包含 javascript 代码,从而在地图上启用热图图层。
我在 Zeppelin 中也收到以下错误。但我认为这与这个问题无关:
Error in sparkR.sparkContext(master, appName, sparkHome, convert`NamedListToEnv(sparkEnvir), : JVM is not ready after 10 seconds
此代码不会显示热图图层:
map3$print("map3", include_assets=TRUE, cdn=TRUE)
改为使用 %angular 解释器和变量绑定:
%angular
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet/0.7.5/leaflet.css" />
<script src="scripts/leaflet-heat.js"></script>
<input type="hidden" value="{{coordinates}}" id="coordinates_values">
<div id="map" style="height: 800px; width: 100%"></div>
<script type="text/javascript">
function initMap() {
var map = L.map('map').setView([39.95, 32.50], 10);
L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: 'Map data © <a href="http://openstreetmap.org">OpenStreetMap</a> contributors',
maxZoom: 12,
minZoom: 3
}).addTo(map);
var geoMarkers = L.layerGroup().addTo(map);
var el = angular.element($('#map').parent('.ng-scope'));
console.log( $("#coordinates_values").val())
var coordinates = $.parseJSON( $("#coordinates_values").val() );
var heat = L.heatLayer( coordinates, {radius: 35}).addTo(map);
angular.element(el).ready(function() {
window.locationWatcher = el.scope().compiledScope.$watch('locations', function(newValue, oldValue) {
// geoMarkers.clearLayers(); -- if you want to only show new data clear the layer first
angular.forEach(newValue, function(tweet) {
var marker = L.marker([ tweet.loc.lat, tweet.loc.lon ])
.bindPopup(tweet.user + ": " + tweet.tweet)
.addTo(geoMarkers);
});
})
});
}
if (window.locationWatcher) {
// clear existing watcher otherwise we'll have duplicates
window.locationWatcher();
}
// ensure we only load the script once, seems to cause issues otherwise
if (window.L) {
$("#coordinates_values").ready(function(){
initMap();
});
} else {
console.log('Loading Leaflet library');
var sc = document.createElement('script');
sc.type = 'text/javascript';
sc.src = 'https://cdnjs.cloudflare.com/ajax/libs/leaflet/0.7.5/leaflet.js';
sc.onload = initMap;
sc.onerror = function(err) { alert(err); }
document.getElementsByTagName('head')[0].appendChild(sc);
}
</script>
我想使用带有 R 的 Leaflet 将热图添加到 Zeppelin 段落。我在 R Studio 中编写了一个脚本,它工作正常,但是当我迁移到 Zeppelin 时,热图没有显示。这是我在 R Studio
中的代码map3 <- Leaflet$new()
map3$setView(c(29.7632836, -95.3632715), 10)
vector <- c( list(c(29.76,-95.36, 50)), list(c(29.77, -95.37, 50)), list(c(29.75,-95.39,50)))
#vector = toJSONArray2(na.omit(vector), json = F, names = F)
cat(rjson::toJSON(vector[1:3]))
map3$addAssets(jshead = c(
"http://leaflet.github.io/Leaflet.heat/dist/leaflet-heat.js"
))
map3$addAssets(jshead = c("http://leaflet.github.io/Leaflet.heat/dist/leaflet-heat.js"))
map3$setTemplate(afterScript = sprintf("
<script>
var addressPoints = %s
var heat = L.heatLayer(addressPoints).addTo(map)
</script>"
,rjson::toJSON(vector)))
map3
我在 Zeppelin 中的代码几乎完全相同。只有输入和输出方式改变:
library(SparkR)
sparkcontext <- sparkR.init("local[4]","cvspark",sparkEnvir=list(spark.executor.memory="1g"))
#sparkR.session()
positions <- sql("SELECT lat, long FROM my_table")
pos <- collect(positions)
map3 <- Leaflet$new()
map3$setView(c(39.93, 32.85))
vector <- c()
values1 <- pos[[1]]
values2 <- pos[[2]]
for (i in 1:length(values1))
vector <- c(vector, list(c(values1[i], values2[i], 1000)))
cat(rjson::toJSON(vector[1:3]))
map3$addAssets(jshead = c("http://leaflet.github.io/Leaflet.heat/dist/leaflet-heat.js"))
map3$setTemplate(afterScript = sprintf("
<script>
var addressPoints = %s
var heat = L.heatLayer(addressPoints).addTo(map)
</script>"
,rjson::toJSON(vector)))
map3$print("map3", include_assets=TRUE, cdn=TRUE)
以下代码显示输入是相同的:
cat(rjson::toJSON(vector[1:3]))
R Studio 输出:
[[29.76,-95.36,50],[29.77,-95.37,50],[29.75,-95.39,50]],
飞艇输出:
[[41.6406843380063,37.6892873258843,1000],[37.0194101218466,30.3908073266391,1000],[34.0236444385`445,40.5599139822316,1000]]
这里的问题是 map3$print("map3", include_assets=TRUE, cdn=TRUE)
在其输出中不包括热图层。据我所知,为了在 Zeppelin 上显示地图,必须调用此方法。问题是:我们如何让 print 方法包含 javascript 代码,从而在地图上启用热图图层。
我在 Zeppelin 中也收到以下错误。但我认为这与这个问题无关:
Error in sparkR.sparkContext(master, appName, sparkHome, convert`NamedListToEnv(sparkEnvir), : JVM is not ready after 10 seconds
此代码不会显示热图图层:
map3$print("map3", include_assets=TRUE, cdn=TRUE)
改为使用 %angular 解释器和变量绑定:
%angular
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet/0.7.5/leaflet.css" />
<script src="scripts/leaflet-heat.js"></script>
<input type="hidden" value="{{coordinates}}" id="coordinates_values">
<div id="map" style="height: 800px; width: 100%"></div>
<script type="text/javascript">
function initMap() {
var map = L.map('map').setView([39.95, 32.50], 10);
L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: 'Map data © <a href="http://openstreetmap.org">OpenStreetMap</a> contributors',
maxZoom: 12,
minZoom: 3
}).addTo(map);
var geoMarkers = L.layerGroup().addTo(map);
var el = angular.element($('#map').parent('.ng-scope'));
console.log( $("#coordinates_values").val())
var coordinates = $.parseJSON( $("#coordinates_values").val() );
var heat = L.heatLayer( coordinates, {radius: 35}).addTo(map);
angular.element(el).ready(function() {
window.locationWatcher = el.scope().compiledScope.$watch('locations', function(newValue, oldValue) {
// geoMarkers.clearLayers(); -- if you want to only show new data clear the layer first
angular.forEach(newValue, function(tweet) {
var marker = L.marker([ tweet.loc.lat, tweet.loc.lon ])
.bindPopup(tweet.user + ": " + tweet.tweet)
.addTo(geoMarkers);
});
})
});
}
if (window.locationWatcher) {
// clear existing watcher otherwise we'll have duplicates
window.locationWatcher();
}
// ensure we only load the script once, seems to cause issues otherwise
if (window.L) {
$("#coordinates_values").ready(function(){
initMap();
});
} else {
console.log('Loading Leaflet library');
var sc = document.createElement('script');
sc.type = 'text/javascript';
sc.src = 'https://cdnjs.cloudflare.com/ajax/libs/leaflet/0.7.5/leaflet.js';
sc.onload = initMap;
sc.onerror = function(err) { alert(err); }
document.getElementsByTagName('head')[0].appendChild(sc);
}
</script>