2

我有一个 MySQL 表包含

  • (亿)美国位置的纬度/经度坐标
  • 居住在该地点一平方英里半径内的人数

问题:在 Google 地图或 Openstreetmaps 上生成并覆盖热图后,必须在地图上鼠标光标所在的任何位置确定居住在平方英里半径内的人数。(可以使用使用相邻数据点的简单平均)

你如何生成这样的热图?是否推荐使用 Mapreduce?

在此处输入图像描述

最初的想法

热图必须在服务器端预渲染

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

更好的选择:处理服务器端,渲染客户端

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

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

映射/减少?

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

现有解决方案

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

4

1 回答 1

3

要回答这个问题,我们必须首先考虑 map/reduce 非常适合的问题类型。map/reduce 的最佳问题是那些可以分解为可以单独解决的小子问题的问题。考虑此类问题的一个很好的类比可能是考虑 SQLGROUP BY构造,它有效地将结果集分成多个块并在每个块上计算一个聚合函数:如果您可以想象通过 a GROUP BY(尽管数据集大小)解决问题,那么它可能非常适合 map/reduce。

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

解决此问题的一种自然方法是从一个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函数的任务是获取一组具有相同键的值,并生成一个代表整个数据组的单个值。在不知道您手头问题的细节的情况下,我将假设确定每个组中的总人口就足够了,我们可以通过简单地将所有值相加来实现。一个reduce函数接收一个键和一个在映射器输出中具有该键的所有值的列表,因此我们的 reducer 可以看起来像这样简单(再次,在伪代码中):

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

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

| key           | value |
| 37.78,-122.43 | 8551  |
| 37.79,-122.43 | 8029  |

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

尽管为了简单起见,我在这里使用了简单的整数计数,但实际上任何类型都可以用作值,因此您可以使用特定类或数组的实例,或者在给定单行数据时可以生成的任何其他值一次。在您的屏幕截图中,您显示了一个悬停提示,它给出了合并以产生给定数据点的记录数,您可以通过让减速器不仅求和而且同时计算行数,并在某种对象中一起返回两者或数据结构。

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

于 2013-03-22T14:57:06.330 回答