我希望能有效地指定点的半径单位为米。该 API 配置了radius
属性为像素常数,因此缩放会导致热力图被腐蚀(我知道您可以使用dissipating
属性使热力图不腐蚀,但这会引起其他问题,即必须手动调整半径以正确显示我的热力图。这里是热力图的参考文档。
具体来说,我正在尝试在地图上显示概率分布。我有分布的图像形式,并希望将0-1权重映射到热力图层上(我不能也不想叠加图像)。
有什么建议吗?
我希望能有效地指定点的半径单位为米。该 API 配置了radius
属性为像素常数,因此缩放会导致热力图被腐蚀(我知道您可以使用dissipating
属性使热力图不腐蚀,但这会引起其他问题,即必须手动调整半径以正确显示我的热力图。这里是热力图的参考文档。
具体来说,我正在尝试在地图上显示概率分布。我有分布的图像形式,并希望将0-1权重映射到热力图层上(我不能也不想叠加图像)。
有什么建议吗?
好的,我尝试了一些方法:
使用Mercator投影示例(检查源代码)从latLng中提取任意点的x,y像素坐标,以便稍后使用几何库,特别是computeOffset函数获取前一个点向右距离为“DM”(以米为单位)的另一个latLng,将差异(以像素为单位)作为绝对值“DP”,然后您就可以得到您的“每米像素”比率DP/DM。
因此,如果您想让半径为100米,只需将属性设置为{radius:Math.floor(desiredRadiusPerPointInMeters*pixelsPerMeter)}
要处理缩放变化,只需使用监听器
google.maps.event.addListener(map, 'zoom_changed', function () {
heatmap.setOptions({radius:getNewRadius()});
});
我上传了一个小例子(尝试缩放),你可以使用底部的按钮来检查距离是否正确。
256
,这是任意的吗?默认情况下,地图的瓦片大小是 (256x256) 吗?我该如何获取正确的瓦片大小? - eqzxgetNewRadius()
方法中添加以下代码可以使点呈现为非扩散(不准确),但至少它们被呈现出来了(在初始化时dissipating=false
)。if(totalPixelSize == 0 && dissipating == true) { heatmap.setOptions({dissipating: false}); totalPixelSize=.01; dissipate=false;} else if(totalPixelSize > 0 && dissipate==false) {heatmap.setOptions({dissipating: true}); dissipate=true;} else if(totalPixelSize == 0) { totalPixelSize=.01;}
- eqzx因为基本的Mercator Google地图瓦片是256 x 256像素,可用的世界坐标空间是{0-256},{0-256}
在此文档页面,感谢您对消散的反馈 :) - lccarrascoreturn multiplicator * Math.pow(2,zoom);
这个怎么样? - Melounek如果你想要一个精美打包的@lccarrasco jsbin示例的coffeescript版本,你可以查看我使用他的代码创建的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”是半径,以米为单位,您可以使用其他方式进行编程设置,以便使您的热力图看起来符合您的要求。
基于一个Google小组论坛帖子和这篇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
基于谷歌实际用于Google Maps的地球近似半径。
因此,假设您有以下热力图:
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()});
});