用大量的地理位置数据标记带有纬度/经度的大量元素列表

Posted

技术标签:

【中文标题】用大量的地理位置数据标记带有纬度/经度的大量元素列表【英文标题】:Tag huge list of elements with lat/long with large list of geolocation data 【发布时间】:2015-10-22 13:33:48 【问题描述】:

我有大量的地理定位事件:

Event (1 billion)
------
id
datetime
lat
long

以及从开放街道地图加载的兴趣点列表:

POI (1 million)
------
id
tag   (shop, restaurant, etc.)
lat
long

我想为每个事件分配兴趣点的标签。解决这个问题的最佳架构是什么?我们尝试使用 Google BigQuery,但我们必须进行交叉连接,但它不起作用。我们愿意使用任何其他大数据系统。

【问题讨论】:

这里也提到过:***.com/questions/33280064/optimize-query-in-bigquery 【参考方案1】:

使用 Dataflow,您可以使用 CoGroupByKey 轻松进行交叉连接。使用这种方法,只有您要加入的事件和 POI 需要放入内存(如果给定键的项目列表太大而无法放入内存,数据流将自动溢出到磁盘)。

这里有更多细节。

创建由纬度和经度键入的事件的 PCollection。 创建一个以经纬度为关键字的 POI 的 PCollection 使用 CoGroupByKey 加入两个 PCollection。 编写一个处理CoGbkResult的DoFn

DoFn 看起来像:


PCollection<T> finalResultCollection =
coGbkResultCollection.apply(ParDo.of(
  new DoFn<KV<K, CoGbkResult>, T>() 
    @Override
    public void processElement(ProcessContext c) 
      KV<K, CoGbkResult> e = c.element();
      // Get all collection 1 values
      Iterable<Event> eventVals = e.getValue().getAll(eventTag);
      // Now get collection 2 values
      Iterable<Poi> poiVals = e.getValue().getAll(poiTag);
      for (Event e : eventVals) 
        for (Poi p : poiVal) 
          ...
          c.output(...tagged event...);
        
      
    
  ));

正如Answer 中所讨论的,您还可以使用侧面输入来传递地图,其键是纬度和经度,值是 POI 的详细信息。如果数据可以放入内存,该方法将起作用。如果您只有 100 万个 POI,并且只存储列出的字段,那么它可能适合内存。

注意:我在 Dataflow 团队。

【讨论】:

【参考方案2】:

你能打开包含开放街道地图表的数据集吗? (毕竟是开放数据)。使用该表,我可以尝试优化查询。

对于一个类似的问题,我通过为每一行生成键来优化它,以避免在整个数据集上进行交叉连接。

http://googlecloudplatform.blogspot.com/2014/03/geoip-geolocation-with-google-bigquery.html

堆栈O:How to improve performance of GeoIP query in BigQuery?

【讨论】:

以上是关于用大量的地理位置数据标记带有纬度/经度的大量元素列表的主要内容,如果未能解决你的问题,请参考以下文章

无法将 SSMS 中的列转换为数据类型地理

Laravel 和谷歌地图:foreach 纬度/经度显示标记或地图

功能缩放到集群关闭具有相同纬度/经度的多个标记的集群

应用启动时在 android 谷歌地图中获取当前位置(纬度,经度)

如何将谷歌地图标记的纬度和经度发送到 Firebase - android? [关闭]

如何将纬度/经度对转换为 PostGIS 地理类型?