生成人口热图:Mapreduce?

时间:2013-03-22 05:03:37

标签: php google-maps hadoop mapreduce postgis

我有一个包含

的MySQL表
  • (1亿)美国境内的Lat / Lng坐标
  • 居住在该地点半径范围内的人数

问题:在Google地图或Openstreet地图上生成并覆盖热图后,无论鼠标光标位于何处,都必须在地图上的任意位置确定半径为平方英里的人数。定位于。 (可以使用相邻数据点进行简单平均)

如何生成这样的热图?是否建议使用Mapreduce?

enter image description here

初步想法

热图必须预先渲染服务器

将所有必要的点下载到浏览器然后生成热图客户端可能是个问题:必须从数据库中检索大量坐标(繁重的数据库负载)并将其传输到浏览器(大型数据集),此外,浏览器必须处理大量的点以生成热图。这将太慢,所以我想我们必须预先渲染热图服务器并检索热图贴图以在地图上重叠。

更好的选择:处理服务器端,呈现客户端

我们不是完全渲染热图服务器端并提供图像切片,而是通过将靠近在一起的点聚类成单个点和权重/偏差来简化数据,然后发送这些简化点数据的较小数据集(通过JSON)到浏览器的客户端渲染热图(使用heatmapjs)。发送lat / lng点而不是图像切片将使应用程序/网站更具响应性。

这也允许我们直接从Javscript读取热图强度值,并在Javascript / jQuery中实现悬停弹出框(见上图)。如果我们将热图贴图发送到浏览器,则不确定如何执行此操作。

地图/减少吗

我们可能需要将作业(处理1亿个数据点)拆分为更小的块,并在多个节点之间生成热图。这将每月进行一次。有几个节点生成热图会让我想到mapreduce和hadoop,虽然我之前没有使用它们。

现有解决方案

gheat按需生成热图,因此对我们来说太慢了。但是,我们仍然需要一个用于我们预渲染的热图贴图的贴图服务器,也许我们可以使用OSM贴图服务器。

1 个答案:

答案 0 :(得分:3)

要回答这个问题,我们必须首先考虑map / reduce的各种问题非常适合。 map / reduce的最佳问题是可以分解为可以单独解决的小子问题。考虑这类问题的一个很好的类比可能是考虑SQL GROUP BY构造,它有效地将结果集分解为多个块并在每个块上计算聚合函数:如果你能想象通过{{求解问题' 1}}(尽管数据集大小)然后它可能非常适合map / reduce。

您的具体问题需要将数据划分为地理空间区域,然后为每个区域计算某种聚合。然后,您将这些区域渲染为可以叠加在Google地图上的二维平铺图像。

接下来的一种自然方法是从GROUP BY函数开始,该函数接受来自数据源的行的流,该行包括地理空间点(纬度/经度)和计数。 map函数的合约是发出map形式的元组,因此在这种情况下,您的映射器需要“简化”创建密钥的点 - 即降低其准确性这样几个相邻的点将共享相同的值 - 并将该值与当前点的总体一起返回。这是一些伪代码:

(key, value)

这将生成一个中间数据集,其中包含以下项目:

function map(row):
    key = simplify_point(row.point) # implementation of this function TBD by you
    emit(key, row.population_count)

请注意,每个不同的键现在都有多个与之关联的值。 | key | value | | 37.78,-122.43 | 2303 | | 37.78,-122.43 | 2009 | | 37.78,-122.43 | 3001 | | 37.78,-122.43 | 1238 | | 37.79,-122.43 | 1343 | | 37.79,-122.43 | 3005 | | 37.79,-122.43 | 2145 | | 37.79,-122.43 | 1536 | 函数的任务是使用相同的键获取一组值,并生成表示整组数据的值。在不知道手头问题的细节的情况下,我将假设确定每个组中的总人口就足够了,我们可以通过简单地将所有值加在一起来实现。 reduce函数接收映射器输出中具有该键的所有值的键和列表,因此我们的reducer可能看起来像这样简单(再次,在伪代码中):

reduce

对于上面的示例结果集,这将导致以下最终结果:

function reduce(key, population_counts):
    sum = 0
    for value in population_counts:
        sum = sum + value
    emit(key, sum)

然后,您可以使用这一组较小的点和值,并将它们渲染为地图上不同颜色的区域,从而创建可视热图。

虽然为了简单起见我在这里使用了简单的整数计数,但实际上任何类型都可以用作值,因此您可以使用特定类或数组的实例,或者给定单行可以生成的任何其他值一次数据。在屏幕截图中,您显示了一个hovertip,它提供了合并以生成给定数据点的记录数,您可以通过使reducer不仅总和而且同时计算行数,并将它们返回到某种对象或数据结构。

以上概述了map / reduce操作的逻辑工作流程,并介绍了使用map / reduce创建热图的一种方法。我确信我没有完全解决您的问题,但如果您可以在我上面描述的工作流程中构建您的问题,那么它可能非常适合地图/减少解决方案。我也专注于map / reduce的理论,而不是Hadoop中的具体实现,但希望你可以轻松地将我描述的概念映射到Hadoop提供的构造中。