我希望能够以米为单位有效地指定点的半径。API 配置为使radius
属性对于像素保持不变,因此放大会导致热图腐蚀(我知道您可以使热图不随dissipating
属性腐蚀,但这会引发其他问题,即必须手动弄乱半径以使我的热图正确显示。这是热图参考。
具体来说,我正在尝试在地图上显示概率分布。我有图像形式的分布,并希望将 0-1 权重映射到热图图层。(我可以而且不想覆盖图像)。
有什么建议么?
我希望能够以米为单位有效地指定点的半径。API 配置为使radius
属性对于像素保持不变,因此放大会导致热图腐蚀(我知道您可以使热图不随dissipating
属性腐蚀,但这会引发其他问题,即必须手动弄乱半径以使我的热图正确显示。这是热图参考。
具体来说,我正在尝试在地图上显示概率分布。我有图像形式的分布,并希望将 0-1 权重映射到热图图层。(我可以而且不想覆盖图像)。
有什么建议么?
好的,我尝试了一些方法:
使用墨卡托投影示例(检查源)从 latLng 中提取任何点的 x,y 像素坐标,以便稍后使用几何库,特别是 computeOffset 函数获取另一个 latLng 距离“DM”(以米为单位)到在前一个的右侧,将差值(以像素为单位)作为绝对值“DP”,然后从那里得到“pixelsPerMeter”比率 DP/DM。
因此,如果您希望半径为 100 米,只需将属性设置为{radius:Math.floor(desiredRadiusPerPointInMeters*pixelsPerMeter)}
并且要处理缩放的变化,只需使用监听器
google.maps.event.addListener(map, 'zoom_changed', function () {
heatmap.setOptions({radius:getNewRadius()});
});
我上传了一个小例子(尝试缩放),您可以使用底部的按钮检查距离是否正确。
对于任何想要拥有@lccarrasco 的 jsbin 示例的精美包装的咖啡脚本版本的人,您可以查看我使用他的代码创建的MercatorProjection 咖啡脚本类的要点。
加载类后,可以将其与以下内容一起使用:
map = new google.maps.Map(...)
heatmap = new google.maps.visualization.HeatmapLayer({map: map})
google.maps.event.addListener(map, 'zoom_changed', () ->
projection = new MercatorProjection()
heatmap.setOptions(radius: projection.getNewRadius(map, 15))
)
其中“15”是以米为单位的半径,您可以使用它或通过其他方式以编程方式设置,以使您的热图看起来像您想要的那样。
我通过使用@lccarrasco 使用的侦听器解决了这个问题,但是在我的 getNewRadius() 函数中,我使半径相对于缩放发生了变化。
IE。var radius = (somemultiplicationfactor)/(Math.pow(2,(20-zoom)));
这是因为每个缩放的缩放比例为 2:1
基于谷歌论坛帖子和这个 GIS 帖子,我想出了一个简单而完整的解决方案。
首先,定义一个函数以获取给定缩放级别的半径(以米为单位):因为不同纬度存在缩放差异,您需要输入someLatValue
,例如您计划使用的地图中心。虽然是一个近似值,但对于一个小国家大小的准确结果来说已经足够了。您还需要以米为单位指定所需的半径大小。
如果您愿意,您可以更改函数以将这些值作为参数读取(例如,获取当前地图视图中心的纬度和/或基于数据属性的半径),但如果它们是静态的,这使得他们的全局变量更容易。
var someLatValue = 35.726332;
var desiredRadiusInMeters = 1500;
function getHeatmapRadius(){
metersPerPx = 156543.03392 * Math.cos(someLatValue * Math.PI / 180) / Math.pow(2,theMap.getZoom());
return desiredRadiusInMeters / metersPerPx;
};
这将返回所需米数和特定纬度周围缩放级别的(近似)半径(以像素为单位)。该值156543.03392
基于谷歌实际用于谷歌地图的地球的近似半径。
所以,假设你有一个这样的热图:
fixedRadiusHeatmap = new google.maps.visualization.HeatmapLayer({
data: myCoords,
map: theMap
});
为了设置初始视图,只需在将热图添加到地图之前调用该函数。
fixedRadiusHeatmap.setOptions({radius: getHeatmapRadius()});
fixedRadiusHeatmap.setMap(theMap);
然后每次缩放地图时都需要重新设置半径,可以这样完成:
google.maps.event.addListener(theMap, 'zoom_changed', function () {
fixedRadiusHeatmap.setOptions({radius: getHeatmapRadius()});
});
在我的情况下,它有点滞后,所以它在固定半径出现之前显示(愚蠢地聚合和考虑不周)默认热图。也许有一种方法可以延迟渲染以使过渡更平滑,但这是一个不同的问题。