基于平均权重而不是数据点数量的热图

use*_*796 16 heatmap google-maps-api-3

我正在使用Google API v3制作热图.我举个例子.让我们考虑一下地震的大小.我为每个点分配权重以指定它们的大小.但是谷歌会在缩小时考虑点的密度.一个地方的点数越多,它就越红.例如,如果两个地震发生在彼此的英里范围内,一个是3级,另一个是8级,第一个应该是绿色/蓝色,第二个应该是红色.但是一旦缩小并且两个点在地图中越来越近,谷歌地图会考虑点数而不是权重,因此它看起来是读取的.我希望它是平均值,即(3 + 8)/2=5.5 ......无论代表什么颜色.这可能吗?

小智 5

如果您像我一样没有足够的处理时间或能力来生成叠加层,并且您无法根据自己的喜好修改任何现有的库,那么有一个不错的解决方法。

我使用了谷歌地图热图库并将 maxIntensity 和 dissipating 设置为 false。将 maxIntensity 设置为您选择的值将解决您的热图点相对于彼此着色而不是 0 或设置值的问题。将 dissipating 设置为 false 将禁用更改缩放级别时发生的自动半径设置。

接下来,每次缩放级别更改时,我都会创建一个事件,在该事件中,我将半径设置为一个值,该值似乎以最准确的方式表示该缩放级别的数据。

现在为了解决地图上的数据点混合并添加到一个大红色斑点中的问题,我决定在我的地图上为我想要使用的每个缩放级别制作一个单独的网格。我将所有装箱在同一网格点内的值取平均值,并确保网格足够大以防止热图点重叠,但又足够小以使其看起来不像一堆圆圈。(我发现网格应该是地图上热点半径大小的 0.4 倍左右,以获得平滑的外观)。

热图点的半径由谷歌以像素为单位设置。我不知道如何将像素转换为纬度/经度,所以我只是通过绘制经过具有特定半径的圆的线并测量这些线之间的距离来测量它。如果您不打算绘制比小国更多的地图,那么这种转换方法将非常有效。

性能方面,这并不像我想象的那么糟糕。我加载了大约 2300 个点,地图加载的速度与我为每个缩放级别制作网格之前一样快,并且在更改缩放级别时实际上并没有看到数据点正在刷新。

以下是上述所有内容的一些代码:

地图设置:

map.heatmap.set('maxIntensity', 12000);
map.heatmap.set('dissipating', false);
Run Code Online (Sandbox Code Playgroud)

更改每个缩放级别的网格和半径:

map._on({
    obj: map.gMap,
    event: "zoom_changed",
    callback: function(){
        var zoomLevel = map.zoom();
        switch(zoomLevel){
            case 7:
                map.heatmap.setData(gridData[zoomLevel]);
                map.heatmap.set('radius', 0.04);
                break;
            case 8:
                map.heatmap.setData(gridData[zoomLevel]);
                map.heatmap.set('radius', 0.03);
                break;
            case 9:
                map.heatmap.setData(gridData[zoomLevel]);
                map.heatmap.set('radius', 0.02);
                break;
            case 10:
                map.heatmap.setData(gridData[zoomLevel]);
                map.heatmap.set('radius', 0.01);
                break;
            case 11:
                map.heatmap.setData(gridData[zoomLevel]);
                map.heatmap.set('radius', 0.005);
                break;
            case 12:
                map.heatmap.setData(gridData[zoomLevel]);
                map.heatmap.set('radius', 0.0025);
                break;
            case 13:
                map.heatmap.setData(gridData[zoomLevel]);
                map.heatmap.set('radius', 0.00225);
                break;
            default:
                map.heatmap.setData(gridData[zoomLevel]);
                map.heatmap.set('radius', 0.000625);
        }
    }
});
Run Code Online (Sandbox Code Playgroud)

我的网格是用 PHP 生成的,每个人看起来可能都不一样,但作为一个例子,这是我使用的函数:

function getHeatGrid($gridSize){
$mapGrid = false;
$mapData = false;
$radius = $gridSize * 2.8 * 0.3; //grid size is multiplied by 2.8 to convert from the heat map radius to lat/long values(works for my lat/long, maybe not yours). * 0.3 is arbitrary to avoid seeing the grid on the map.
$string = file_get_contents("mapData.json");
$json_a = json_decode($string, true);

forEach($json_a as $key => $value){
    $row = intval(round(($value['center_longitude'] / $radius)));
    $column = intval(round(($value['center_latitude'] / $radius)/68*111)); //around 52.0;5.0 latitude needs to be scaled to make a square grid with the used longitude grid size
    if(isset($mapGrid[$row][$column])){
        $mapGrid[$row][$column] = round(($value['solarValue'] + $mapGrid[$row][$column]) / 2);
    } else {
        $mapGrid[$row][$column] = $value['solarValue'];
    }
}

forEach($mapGrid as $long => $array){
    forEach($array as $lat => $weight){
        $mapData[] = array(
            "center_longitude" => $long * $radius,
            "center_latitude" => ($lat * $radius)/111*68,
            "solarValue" => $weight
        );
    }
}
return $mapData;
}
Run Code Online (Sandbox Code Playgroud)

不幸的是,我现在无法显示地图,因为它目前对我工作的公司的客户保密,但如果它公开可用,我将添加一个链接,以便您了解此方法的效果如何。

希望这可以帮助某人。

卢卡斯


Joh*_*nny 4

您可以通过在地图顶部叠加热图图像来实现。https://github.com/jeffkaufman/apartment_prices有一个非常好的开源示例