谷歌地图热图图层点半径

Google Maps heatmap layer point radius

本文关键字:图层 谷歌地图      更新时间:2023-09-26

我希望能够以米为单位有效地指定点的半径。API的配置使radius属性对像素保持不变,因此放大会导致热图侵蚀(我知道你可以使用dissipating属性使热图不被侵蚀,但这会引发其他问题,即必须手动调整半径才能使热图正确显示。以下是热图参考。

具体来说,我试图在地图上显示概率分布。我有图像形式的分布,并希望将0-1权重映射到热图层。(我可以也不想叠加图像)。

有什么建议吗?

好的,我尝试了一些东西:

使用墨卡托投影示例(检查源)从一个latLng中提取任何点的x,y像素坐标,以便以后使用几何图形库,特别是computeOffset函数,将另一个latLng与前一个LatL的右侧距离"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示例的包装精美的coffeescript版本的人,您可以查看我使用他的代码创建的MercatorProjection coffeesccript类的要点。

一旦加载了类,就可以将其与以下内容一起使用:

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()函数中,我使半径相对于缩放发生了变化。

即。var radius=(somemultiplication factor)/(Math.pow(2,(20缩放)));

这是因为每个缩放的缩放比为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()});
});

在我的情况下,它有点滞后,所以在固定半径的热图出现之前,它显示了(愚蠢的聚合和考虑不周的)默认热图。也许有一种方法可以延迟渲染以使过渡更平滑,但这是另一个问题。