如何使用JAVA语言构建R树索引并提供查询的例子

1、背景

        在最近的工作当中,需要在空间中找到指定范围的目标点。由此想到了R树索引,利用R树索引进行高性能查询,将返回指定范围内的经纬度坐标点。大致的方向已明确,便开始寻找相关实现。通过在互联网上查找资料,已经有开源的JTS工具包可进行相关的索引构建工作,并提供查询功能。本文由此简单的说明如何利用jts进行相关操作。

2、相关代码

2.1 索引的构建,具体代码如下:

STRtree tree=new STRtree();
GeometryFactory factory=new GeometryFactory();
    	
com.vividsolutions.jts.geom.Point point=factory.createPoint(new Coordinate(112.971585, 28.265007));//长沙
tree.insert(point.getEnvelopeInternal(), point);

point=factory.createPoint(new Coordinate(113.040862, 28.192062));//芙蓉区
tree.insert(point.getEnvelopeInternal(), point);
        
point=factory.createPoint(new Coordinate(112.902882, 28.223639));//岳麓区
tree.insert(point.getEnvelopeInternal(), point);
        
point=factory.createPoint(new Coordinate(113.040862, 28.142129));//雨花区
tree.insert(point.getEnvelopeInternal(), point);
        
point=factory.createPoint(new Coordinate(111.491465, 27.269792));//邵阳市
tree.insert(point.getEnvelopeInternal(), point);
point=factory.createPoint(new Coordinate(109.982886, 27.630889));//怀化市
tree.insert(point.getEnvelopeInternal(), point);
        
tree.build();
System.out.println("R树索引创建成功!");

通过将各坐标点添加到索引中,最后调用build方法即可完成索引的构建。

2.2 基于R树索引的查询

  根据传入的点创建查询范围

public static Geometry generateSearchGeo(double left_top_x,double left_top_y,double right_bottom_x,double right_bottom_y){
        Coordinate[] coors=new Coordinate[5];
        coors[0]=new Coordinate(left_top_x, left_top_y);
        coors[1]=new Coordinate(right_bottom_x, left_top_y);
        coors[2]=new Coordinate(left_top_x, right_bottom_y);
        coors[3]=new Coordinate(right_bottom_x, right_bottom_y);
        coors[4]=new Coordinate(left_top_x, left_top_y);
        LinearRing ring = new LinearRing(new CoordinateArraySequence(coors), new 
        GeometryFactory());
        return ring;
}

在这里需要注意的是,由于构建的是完整点,所以一定要保证起始点在一起即闭合。所以,coors[4] 的值和coors[0]一致。否则会报错。

调用R树索引进行查询。

/**
  * R树查询
  * param tree
  * @param searchGeo
  * @return
  */
 @SuppressWarnings("rawtypes")
 public static List query(STRtree tree,Geometry searchGeo){
       List  result=new ArrayList();
       List list=tree.query(searchGeo.getEnvelopeInternal());
       for (Object object : list) {
		    Point point = (Point)object;
			result.add(point);
	   }
       return result;
  }

3、写在后面

3.1 本文使用的资源jar包为:


	
		   com.vividsolutions
		   jts-core
		   1.14.0
	

3.2 感谢KingWang_WHU提供的例子程序,解决了一些基础性的问题。他的博客中有一些关于R树的科普及相关说明。详情可参考【JTS】利用JTS生成R树索引。

3.3 完整的代码如下:

package nudt.dbrg.jtsdemo.test;

import java.util.ArrayList;
import java.util.List;

import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.GeometryFactory;
import com.vividsolutions.jts.geom.LinearRing;
import com.vividsolutions.jts.geom.Point;
import com.vividsolutions.jts.geom.Polygon;
import com.vividsolutions.jts.geom.impl.CoordinateArraySequence;
import com.vividsolutions.jts.index.strtree.STRtree;

public class TestMain3 {

    /**
     * R树查询
     * @param tree
     * @param searchGeo
     * @return
     */
    @SuppressWarnings("rawtypes")
	public static List query(STRtree tree,Geometry searchGeo){
        List  result=new ArrayList();
        List list=tree.query(searchGeo.getEnvelopeInternal());
        for (Object object : list) {
			Point point = (Point)object;
			result.add(point);
		}
        return result;
    }
    
    public static Geometry generateSearchGeo(double left_top_x,double left_top_y,double right_bottom_x,double right_bottom_y){
        Coordinate[] coors=new Coordinate[5];
        coors[0]=new Coordinate(left_top_x, left_top_y);
        coors[1]=new Coordinate(right_bottom_x, left_top_y);
        coors[2]=new Coordinate(left_top_x, right_bottom_y);
        coors[3]=new Coordinate(right_bottom_x, right_bottom_y);
        coors[4]=new Coordinate(left_top_x, left_top_y);
        LinearRing ring = new LinearRing(new CoordinateArraySequence(coors), new GeometryFactory());
        return ring;
    }
    
    
    public static void main(String[] args) {
    	STRtree tree=new STRtree();
    	GeometryFactory factory=new GeometryFactory();
    	
        com.vividsolutions.jts.geom.Point point=factory.createPoint(new Coordinate(112.971585, 28.265007));//长沙
    	tree.insert(point.getEnvelopeInternal(), point);
        
        point=factory.createPoint(new Coordinate(113.040862, 28.192062));//芙蓉区
        tree.insert(point.getEnvelopeInternal(), point);
        
        point=factory.createPoint(new Coordinate(112.902882, 28.223639));//岳麓区
        tree.insert(point.getEnvelopeInternal(), point);
        
        point=factory.createPoint(new Coordinate(113.040862, 28.142129));//雨花区
        tree.insert(point.getEnvelopeInternal(), point);
        
        point=factory.createPoint(new Coordinate(111.491465, 27.269792));//邵阳市
        tree.insert(point.getEnvelopeInternal(), point);
        point=factory.createPoint(new Coordinate(109.982886, 27.630889));//怀化市
        tree.insert(point.getEnvelopeInternal(), point);
        
        tree.build();
        System.out.println("R树索引创建成功!");
        Geometry searchGeo = TestMain3.generateSearchGeo(112.764903, 28.18409, 113.484697,28.264261);
        List list = TestMain3.query(tree, searchGeo);
        
        for (Point p : list) {
			System.out.println("p==>" + p);
			System.out.println(p.getX() + "\t" + p.getY());
		}
        System.out.println("找到数据条数为==> " + list.size());
    	
	}
}

你可能感兴趣的:(java,javaEE,java,jts,R树,R,TREE)