12

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

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

有什么建议么?

4

4 回答 4

14

好的,我尝试了一些方法:

使用墨卡托投影示例(检查源)从 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()});
      });

我上传了一个小例子(尝试缩放),您可以使用底部的按钮检查距离是否正确。

于 2012-09-06T02:31:27.307 回答
1

对于任何想要拥有@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”是以米为单位的半径,您可以使用它或通过其他方式以编程方式设置,以使您的热图看起来像您想要的那样。

于 2014-06-26T16:58:26.420 回答
1

我通过使用@lccarrasco 使用的侦听器解决了这个问题,但是在我的 getNewRadius() 函数中,我使半径相对于缩放发生了变化。

IE。var radius = (somemultiplicationfactor)/(Math.pow(2,(20-zoom)));

这是因为每个缩放的缩放比例为 2:1

于 2016-04-05T03:21:51.807 回答
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()});
});

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

于 2019-01-25T05:37:43.497 回答