Google地图热图图层点半径

时间:2012-09-06 00:24:24

标签: javascript google-maps google-maps-api-3 google-earth

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

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

有什么建议吗?

4 个答案:

答案 0 :(得分:13)

好的,我尝试过一些事情:

使用Mercator Projection example (check the source)提取latLng中任意点的x,y像素坐标,以后使用geometry library, specifically the computeOffset function获取另一个latLng距离“DM”(以米为单位)前一个,得到差值(以像素为单位)作为绝对值“DP”,从那里你得到你的“pixelsPerMeter”比率DP / DM。

那么,如果您希望半径为100米,则只需将属性设置为{radius:Math.floor(desiredRadiusPerPointInMeters*pixelsPerMeter)}

要处理缩放变化,只需使用监听器

 google.maps.event.addListener(map, 'zoom_changed', function () {
          heatmap.setOptions({radius:getNewRadius()});
      });

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

答案 1 :(得分:1)

对于那些想要拥有一个包装良好的coffeescript版本的@ lccarrasco的jsbin示例的人,你可以查看我使用他的代码创建的MercatorProjection coffeescript class的要点。

加载完课程后,您可以使用以下内容:

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

答案 2 :(得分:1)

我通过使用@lccarrasco使用的侦听器解决了这个问题,但在我的getNewRadius()函数中,我相对于缩放进行了半径更改。

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

这适用于每次缩放的缩放比例为2:1

答案 3 :(得分:0)

基于Google网上论坛帖子和this GIS post,我根据相同的思路提出了一个简单而完整的解决方案。

首先,定义一个函数以获取给定缩放级别的半径(以米为单位):由于不同纬度存在缩放比例差异,因此您需要输入someLatValue,例如计划的地图中心使用。尽管是一个近似值,但对于一个小国大小的准确结果来说,已经足够了。您还需要以米为单位指定所需半径的大小。

如果愿意,可以更改函数以将这些值作为参数读取(例如,获取当前地图视图中心的纬度和/或基于数据属性的半径),但是如果它们是静态的,这使它们更易于全局。

var someLatValue = 35.726332;
var desiredRadiusInMeters = 1500;

function getHeatmapRadius(zoomLevel){
  metersPerPx = 156543.03392 * Math.cos(someLatValue * Math.PI / 180) / Math.pow(2,theMap.getZoom());
  return desiredRadiusInMeters / metersPerPx;
};

这将返回期望的米数和特定纬度周围的缩放级别的(近似)半径(以像素为单位)。值156543.03392是基于google实际用于Google Maps的地球的近似半径。

因此,假设您有这样的热图:

fixedRadiusHeatmap = new google.maps.visualization.HeatmapLayer({
  data: myCoords,
  map: theMap
});

要设置初始视图,只需在将热图添加到地图之前调用该函数即可。

fixedRadiusHeatmap.setOptions({radius: getHeatmapRadius(theMap.getZoom())});
fixedRadiusHeatmap.setMap(theMap);

然后,每次地图缩放时,您都需要重置半径,可以这样做:

google.maps.event.addListener(theMap, 'zoom_changed', function () {
  fixedRadiusHeatmap.setOptions({radius: getHeatmapRadius(theMap.getZoom())});
});

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