html - 用传单绘制两个热图
html - plotting two heatmaps with leaflet
我正在尝试使用 Leaflet.Heat 在一个文档中绘制两个热图。但是,在第一张地图中,heat 保持在相对于地图框架的位置(即当您缩放地图 in/out 时它不会移动)。第二张地图的行为符合预期。
两张地图应该是一样的,所以我错过了什么?
注意: html
不是我特别熟悉的语言,所以我可能遗漏了一些明显的东西,这段代码将以
代码
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<body>
<!-- heatmap-->
<div id="map1">
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet/v0.7.7/leaflet.css" />
<script src="http://cdn.leafletjs.com/leaflet/v0.7.7/leaflet.js"></script>
<script src="http://leaflet.github.io/Leaflet.heat/dist/leaflet-heat.js"></script>
<style>
#map1 { width: 800px; height: 600px; }
body { font: 16px/1.4 "Helvetica Neue", Arial, sans-serif; }
.ghbtns { position: relative; top: 4px; margin-left: 5px; }
a { color: #0077ff; }
</style>
<script>
var map1 = L.map('map1').setView([47.5982623,-122.3415519], 12);
var tiles = L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
attribution: '© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors',
}).addTo(map1);
var heat = L.heatLayer([[47.5982623,-122.3415519, 20], [47.6182623,-122.3417519,50]]).addTo(map1);
</script>
</div>
Plotting another map
<div id="map2">
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet/v0.7.7/leaflet.css" />
<script src="http://cdn.leafletjs.com/leaflet/v0.7.7/leaflet.js"></script>
<script src="http://leaflet.github.io/Leaflet.heat/dist/leaflet-heat.js"></script>
<style>
#map2 { width: 800px; height: 600px; }
body { font: 16px/1.4 "Helvetica Neue", Arial, sans-serif; }
.ghbtns { position: relative; top: 4px; margin-left: 5px; }
a { color: #0077ff; }
</style>
<script>
var map2 = L.map('map2').setView([47.5982623,-122.3415519], 12);
var tiles = L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
attribution: '© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors',
}).addTo(map2);
var heat = L.heatLayer([[47.5982623,-122.3415519, 20], [47.6182623,-122.3417519,50]]).addTo(map2);
</script>
</div>
</body>
</html>
更新-解决方案
经过反复试验,删除第二个
<script scr="http://cdn.leafletjs.com/leaflet/v0.7.7/leaflet.js
解决了。我不知道为什么这是错误的原因,所以如果有人能在答案中提供解释,我会很乐意接受。
如您所知,您只需要一个传单脚本实例,就可以重复使用它来创建多张地图。您的插件也是如此:只加载一次就足够了。通常,所有 JavaScript 个库都是如此:避免多次加载同一文件。因此,如果您还没有这样做,您也应该摆脱 "leaflet-heat.js" 的第二次加载。
发生的事情完全是由于 JavaScript 的指定行为造成的。第二个传单加载覆盖全局 L
变量。 L
之前的内容仍然存在于内存中,并且仍然链接到您的第一个 map
、tiles
和 heat
。这就是为什么第一张地图仍然有效(您可以使用键盘导航进行缩放和平移)。
然而,第一个热图不是(防止通过鼠标拖动进行平移)。这是因为 Leaflet.heat 插件没有按照模块定义技术(例如 UMD)包装,所以它插入初始 L
(即加载时),同时使用当前L
在交互期间(因此重新加载传单后的新值)。这种差异破坏了它的算法并引入了意想不到的行为,就像你看到你的热图被重新绘制但没有更新(值和位置)。第二张热图很好,因为它插入并使用相同的值 L
(重新加载的)。
但是,如果该插件在加载后没有使用 L
,或者正确地引用了它最初的内容,它就不会损坏。如您所见,多次加载同一个脚本文件可能会或可能不会引入错误,具体取决于算法的构建方式。 这正是发明模块定义技术的原因。
还有一个 L.noConflict
method 可用于解决此类情况,但它对您的情况没有帮助,因为 Leaflet.heat 插件没有像上面所说的那样被包装为模块,所以即使你使用这个技巧,第一个或第二个热图被破坏。
如果那个插件被纠正,一切都会神奇地工作。可能是在插件 GitHub 回购上提出问题并指出 Leaflet recommendation.
的不合规之处(传单作者本人......:-))
加载Leaflet和Leaflet.heat两次的演示,但是通过模块定义的第二个插件:http://jsfiddle.net/psraudy5/(所以它仍然需要调用L.noConflict
来恢复第一个热图行为).
顺便说一下,不要忘记更正第二个脚本调用的结束标记:</s cript>
应该是 </script>
。浏览器应该足够聪明以容忍该错误。 Web 技术是为了容忍许多错误而构建的,但缺点是它们可能会悄无声息地引入错误,就像您最初的 post.
我正在尝试使用 Leaflet.Heat 在一个文档中绘制两个热图。但是,在第一张地图中,heat 保持在相对于地图框架的位置(即当您缩放地图 in/out 时它不会移动)。第二张地图的行为符合预期。
两张地图应该是一样的,所以我错过了什么?
注意: html
不是我特别熟悉的语言,所以我可能遗漏了一些明显的东西,这段代码将以
代码
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<body>
<!-- heatmap-->
<div id="map1">
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet/v0.7.7/leaflet.css" />
<script src="http://cdn.leafletjs.com/leaflet/v0.7.7/leaflet.js"></script>
<script src="http://leaflet.github.io/Leaflet.heat/dist/leaflet-heat.js"></script>
<style>
#map1 { width: 800px; height: 600px; }
body { font: 16px/1.4 "Helvetica Neue", Arial, sans-serif; }
.ghbtns { position: relative; top: 4px; margin-left: 5px; }
a { color: #0077ff; }
</style>
<script>
var map1 = L.map('map1').setView([47.5982623,-122.3415519], 12);
var tiles = L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
attribution: '© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors',
}).addTo(map1);
var heat = L.heatLayer([[47.5982623,-122.3415519, 20], [47.6182623,-122.3417519,50]]).addTo(map1);
</script>
</div>
Plotting another map
<div id="map2">
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet/v0.7.7/leaflet.css" />
<script src="http://cdn.leafletjs.com/leaflet/v0.7.7/leaflet.js"></script>
<script src="http://leaflet.github.io/Leaflet.heat/dist/leaflet-heat.js"></script>
<style>
#map2 { width: 800px; height: 600px; }
body { font: 16px/1.4 "Helvetica Neue", Arial, sans-serif; }
.ghbtns { position: relative; top: 4px; margin-left: 5px; }
a { color: #0077ff; }
</style>
<script>
var map2 = L.map('map2').setView([47.5982623,-122.3415519], 12);
var tiles = L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
attribution: '© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors',
}).addTo(map2);
var heat = L.heatLayer([[47.5982623,-122.3415519, 20], [47.6182623,-122.3417519,50]]).addTo(map2);
</script>
</div>
</body>
</html>
更新-解决方案
经过反复试验,删除第二个
<script scr="http://cdn.leafletjs.com/leaflet/v0.7.7/leaflet.js
解决了。我不知道为什么这是错误的原因,所以如果有人能在答案中提供解释,我会很乐意接受。
如您所知,您只需要一个传单脚本实例,就可以重复使用它来创建多张地图。您的插件也是如此:只加载一次就足够了。通常,所有 JavaScript 个库都是如此:避免多次加载同一文件。因此,如果您还没有这样做,您也应该摆脱 "leaflet-heat.js" 的第二次加载。
发生的事情完全是由于 JavaScript 的指定行为造成的。第二个传单加载覆盖全局 L
变量。 L
之前的内容仍然存在于内存中,并且仍然链接到您的第一个 map
、tiles
和 heat
。这就是为什么第一张地图仍然有效(您可以使用键盘导航进行缩放和平移)。
然而,第一个热图不是(防止通过鼠标拖动进行平移)。这是因为 Leaflet.heat 插件没有按照模块定义技术(例如 UMD)包装,所以它插入初始 L
(即加载时),同时使用当前L
在交互期间(因此重新加载传单后的新值)。这种差异破坏了它的算法并引入了意想不到的行为,就像你看到你的热图被重新绘制但没有更新(值和位置)。第二张热图很好,因为它插入并使用相同的值 L
(重新加载的)。
但是,如果该插件在加载后没有使用 L
,或者正确地引用了它最初的内容,它就不会损坏。如您所见,多次加载同一个脚本文件可能会或可能不会引入错误,具体取决于算法的构建方式。 这正是发明模块定义技术的原因。
还有一个 L.noConflict
method 可用于解决此类情况,但它对您的情况没有帮助,因为 Leaflet.heat 插件没有像上面所说的那样被包装为模块,所以即使你使用这个技巧,第一个或第二个热图被破坏。
如果那个插件被纠正,一切都会神奇地工作。可能是在插件 GitHub 回购上提出问题并指出 Leaflet recommendation.
的不合规之处(传单作者本人......:-))加载Leaflet和Leaflet.heat两次的演示,但是通过模块定义的第二个插件:http://jsfiddle.net/psraudy5/(所以它仍然需要调用L.noConflict
来恢复第一个热图行为).
顺便说一下,不要忘记更正第二个脚本调用的结束标记:</s cript>
应该是 </script>
。浏览器应该足够聪明以容忍该错误。 Web 技术是为了容忍许多错误而构建的,但缺点是它们可能会悄无声息地引入错误,就像您最初的 post.