【问题标题】:STRtree in JTS Topology Suite : bulk load data and build indexJTS Topology Suite 中的 STRtree:批量加载数据和构建索引
【发布时间】:2015-03-18 03:35:15
【问题描述】:

现在我在文本文件中有一组数据(足够大),假设每一行代表一个矩形:

x1,y1,x2,y2

读取文件后,如何使用 http://www.vividsolutions.com/jts/javadoc/index.html 批量加载和构建 R-tree 索引?

我查看了它的API,批量加载时似乎只有insert可以使用。

这是我的测试代码:

    STRtree rtree = new STRtree();

    rtree.insert(new Envelope(1.0,2.0,1.2,3.4),new Integer(1));
    rtree.insert(new Envelope(4.0,3.2,1.9,4.4),new Integer(2));
    rtree.insert(new Envelope(3.4,3.8,2.2,5.2),new Integer(3));
    rtree.insert(new Envelope(2.1,5.3,5.2,3.6),new Integer(4));
    rtree.insert(new Envelope(4.2,2.2,2.9,10.3),new Integer(5));

    List<Object> list = rtree.query(new Envelope(1.4,5.6,2.0,3.0));

构建 R-tree 索引的方法是否正确(只需使用insert 方法)?

另一个问题是, 假设输入文件足够大,例如GB甚至TB规模,存储在HDFS中,在这种情况下,我想要上面基于Apache Spark的并行版本的代码。

最后,有什么想法可以将 R-tree 保存到文件中进行存储,并便于恢复以供以后使用?

编辑: 现在我阅读了HDFS 文件来构建索引,这是我的代码:

    val inputDataPath = "hdfs://localhost:9000/user/chenzhongpu/testData.dat"
    val conf = new SparkConf().setAppName("Range Query")

    // notice that: the function names for queries differ accoss systems.
    // here we simply refer intersect.

    val sc = new SparkContext(conf)

    val inputData = sc.textFile(inputDataPath).cache()

    val strtree = new STRtree

    inputData.foreach(line => {val array = line.split(",").map(_.toDouble); strtree.insert(new Envelope(array(0),array(1),array(2),array(3)),
      new Rectangle(array(0),array(1),array(2),array(3)))})

我在foreach中调用了insert,当我打印strtree的大小时,是零!

为什么foreach 中的insert 方法不起作用?我错过了什么吗?

【问题讨论】:

  • 这段代码不正确,除非广播,否则无法访问STRtree
  • 如果我打电话给inputDatacollect(),它可以工作。但是如果有一个大数据集,这将导致它无法放入内存中。正如你所说,先做partition会更好。

标签: apache-spark hdfs r-tree jts


【解决方案1】:

您正在正确构建所有内容,STRTree 会进行批量加载,直到您查询,之后它不允许您添加或删除节点。如果您想将其与 apache spark 并行化,您可以制作一个自定义分区器(类似于范围分区器),将您的区域划分为一个大网格,然后为每个分区运行一个 STRTree。在 spark(和标准 java)中,您可以轻松地将 STRTree 保存到文件中,因为它实现了可序列化。

RangePartioner 的代码非常复杂,因为它对输入数据进行采样并创建范围的概率分区,如果您已经知道最大界限,您可以通过根据您想要的并行度制作网格来做一些更简单的事情(分区器基本上可以工作,通过查找几何体是网格的哪一部分并将所有几何体发送到该分区,分区器还可能使用 STRTree 来提高速度)

还有一个建议,为简单起见,您可以使用 spark 中的标准 RangePartitioner 仅在 x 或仅 y 上分区,但使用自定义 RangePartitioner 可能会更好

【讨论】:

  • 如你所说,STRTree does bulk loading until you query 。似乎保存 STRTree 对象本身没有意义,因为当我稍后从文件进行反序列化并再次调用 query 时,将再次执行批量加载工作。对吗?
  • @ChenZhongPu 我怀疑他们会以这种方式实现它,他们可能使用内部数据结构来存储它,并且只有在反序列化时才加载
  • @ChenZhongPu 你使用它的方式是行不通的,理想情况下你应该在 mapPartitions 中创建它并以这种方式使用它
猜你喜欢
  • 2018-03-08
  • 1970-01-01
  • 1970-01-01
  • 2012-01-11
  • 2017-10-28
  • 2016-01-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多