JTS拓扑套件中的STRtree:批量加载数据和构建索引

时间:2015-03-18 03:35:15

标签: apache-spark hdfs r-tree jts

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

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树索引的正确方法(只需使用insert方法)吗?

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

最后,是否有任何想法将R树保存到文件中进行存储,并且有利于恢复供以后使用?

修改 现在我读了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)))})

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

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

1 个答案:

答案 0 :(得分:0)

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

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

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