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

时间:2013-01-22 15:22:20

标签: google-maps-api-3 heatmap

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

5 个答案:

答案 0 :(得分:4)

您可以通过在地图上方叠加热图图像来实现。在https://github.com/jeffkaufman/apartment_prices

有一个非常好的开源示例

答案 1 :(得分:4)

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

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

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

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

热图点的半径由google以像素为单位设置。我不知道如何将像素转换为Lat / Long,所以我只是通过绘制线经过一定半径的圆来测量它并测量这些线之间的距离。如果你没有计划映射远远超过一个小国家,那么转换方法将会很好用。

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

以下是上述所有代码:

地图设置:

map.heatmap.set('maxIntensity', 12000);
map.heatmap.set('dissipating', false);

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

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);
        }
    }
});

我的网格是用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;
}

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

希望这有助于某人。

的Lukas

答案 2 :(得分:3)

根据定义,热图可以考虑点密度以及分配给每个点的权重。据我所知,至少谷歌的热图以这种方式工作。 所以你真正需要的不是热图,而是一个点的地图,它们将根据值被着色。

我还需要更改Google热图所考虑的比例密度/重量,以便为地图着色但我找不到任何方法。 目前热图的主要因素是密度,重量的变化对颜色的影响很小。

答案 3 :(得分:3)

作为部分解决方案,我修改了以下项目中的heatmap.js: https://github.com/pa7/heatmap.js

为了获得单个长/纬度点的平均值,我修改了_organiseData函数,为每个x,y位置存储PointCount和PointSum;并且使用这些值,我得到平均值:

store [x] [y] = storePointSum [x] [y] / storePointCount [x] [y];

当多个x,y coords在不同的地图分辨率下堆叠时,我仍在研究如何修改“混合”...如果我弄清楚,我会发布它。

欢呼声

〜亚伦

答案 4 :(得分:1)

此示例使用热图作为地图上的图层,希望它有助于:http://maps.forum.nu/v3/gm_customTiles.html