前言:

如果您对JTS这三个词还是没有一个概念,那么推荐您关注一下sinoly的博客。这个我能够找到为数不多的关于jts的中文资料。

http://www.blogjava.net/sinoly/archive/2007/02/09/99042.html

下面这段话就是摘抄自sinoly老兄的博客:

............它主要是完成了java对几何对象、空间拓扑得核心操作算法。.......集成了java对几何对象(点、线、面等)的对象管理外更大一部分工作是在完成对各种几何对象的buffer、analyze以及空间索引.

本文想要向您展示的就是一个空间索引的小小demo!

jts本身有一个包就叫Index,当中分别给出了SpatialIndex接口的几个实现。本文展现的就是quadtree的用法。

quadtree翻译过来就是四叉树的意思,有一个很简单的例子可以来理解四叉树和空间索引的关系。那就是把中国的版图来个十字型的分割,这样就形成一个中心点和四个子节点。然后将每个子节点再次的进行十字分割。当分割到极小处时,整个中国的版图就可以使用一个挂载很多节点的四叉树来表示。每一个节点可以认为是一个具有经纬度及其描述信息的对象。

当我们手中有很多点的时候,想要建立成一颗四叉树,只要把上边的思路反过来就可以了(对于每个节点之间的距离是否相等,目前我还没有好的认识)。

正如我们研发部local search的文斌而言,思路很简单,但是不是每个人你都能够实现。接下来,让demo的代码说话。

1.建立一个对象,这个对象描述point除了经纬度外的其他信息(如果需要可以加上经纬度)。

1

/** *//**2 *3 *@authorlang4 * @date 2007-12-175 * @email lanfanss@126.com6 * @desc 代表point的信息7 *@since8 *9*/10

publicclassPointInfo{11

/** *//**12     * 名称13*/14privateString name;15privateString info;1617

publicString getInfo(){18returninfo;19    }2021

publicvoidsetInfo(String info){22this.info=info;23    }2425

publicPointInfo(String name){26super();27this.name=name;28    }2930

publicString getName(){31returnname;32    }3334

publicvoidsetName(String name){35this.name=name;36    }37}

2.接下来就是建立一颗树,代码如下

publicstaticvoidmain(String[] args){

        Quadtree quatree=newQuadtree();

//构建几个点PointInfo info1=newPointInfo("故宫");

        quatree.insert(newEnvelope(newCoordinate(11638937,3992178)), info1);

        PointInfo info2=newPointInfo("太和殿");

        info2

                .setInfo("太和殿,俗称金銮殿,是宫殿群中最大的建筑。殿高36米,宽63米,面积为2380平方米。 “太和”语出《周易》,太和是“阴阳会和,冲和之气也”,“混同宇内以玉太和”之意,即指宇宙万物,和谐圆满。太和殿坐落在“工”字形须弥座上,汉白玉雕成,分上中下三层,称为丹墀或丹陛。雕栏称为望柱,柱头雕以云龙云图案。那些伸出的为螭首,口中小孔为出水孔。共有螭首1142个。如遇雨天,可见千龙吐水之奇观。 台基上放置18个大铜炉,据说代表当时的18个省份。太和殿台基上面的大平台,放置铜龟、铜鹤各一对,象征“龟鹤千秋”,意为长寿。东有日晷西有喜量,象征皇权公正平允。这里是举行大典奏九韶之乐的地方。");

        quatree.insert(newEnvelope(newCoordinate(11639073,3991605)), info2);

        PointInfo info3=newPointInfo("中和殿");

        info3

                .setInfo("中和殿在太和殿后,平面呈方形。“中和”语出《礼记.中庸》,指不偏不倚,凡事做到恰如其分。 殿为方形攒尖顶,在三大殿中居中,也最小,是皇帝去太和殿大典之前休息的地方。皇帝去天、地、日、月四坛祭祀时,前一天也要在中和殿里看祭文。每年二月皇帝到先农坛举行亲耕仪式,前一天要来这里阅视种子、农具、祝文。这里现陈列的是乾隆年间的两顶肩舆,即八抬大轿。");

        quatree.insert(newEnvelope(newCoordinate(11639081,3991647)), info3);

        PointInfo info4=newPointInfo("保和殿");

        info4

                .setInfo("保和殿,其意为“志不外驰,恬神守志”,就是说神志得专一,以保持宇内的和谐,才能福寿安乐,天下太平。 保和殿比太和殿规模小些,为重檐歇山顶。明朝册立皇后,太子时,皇帝在此殿受贺。在清朝是举行盛大宴会的地方。每年初一和十五在此宴请外族王公大臣,场面是十分壮观的。公主下嫁时,也在这个殿里宴请附马。这个殿最有名的事是举行殿试。殿试就是皇帝本人亲自监考、主考,是科举考试的最高层次。前三名分别为状元、榜眼、探花。 保和殿后是故宫最大的一块雕石——云龙雕石,这块苑叶青石长16.57米,宽3.07米,厚1.7米,总重二百多吨。上雕游龙,双龙戏珠,游于云雾之中。");

        quatree.insert(newEnvelope(newCoordinate(11639079,3991698)), info4);

        PointInfo info5=newPointInfo("乾清宫");

        info5

                .setInfo("乾清宫明朝时为皇帝居住之处,皇帝在此处理政务、召见臣仆和外国使节。从清朝雍正皇帝之后,皇帝迁到养心殿居住,但仍在此批阅奏报,召见大臣。 乾清宫除是皇帝的寝宫和日常自理政务外,还举行元旦、灯节、端午、中秋、冬至、万寿等节的家宴。殿内宝座上方有一块匾,上书“正大光明”四个漂亮的正楷字,其意为公正、光明磊落。这块匾很有名气,与秘密立储关系密切。皇帝生前,亲自从皇子中选一个德才兼备的作为皇太子——嗣皇帝,不予宣布,而是由皇帝秘密亲书预立皇太子的名字的“御书”,密封匣内,茂于那块匾后,等皇帝死后或死前,由御前大臣、军机大臣等共同启示,按御书所定,嗣皇帝即位。相传雍正的第四子弘历即乾隆皇帝,就是这…");

        quatree.insert(newEnvelope(newCoordinate(11639067,3991873)), info5);

        PointInfo info6=newPointInfo("坤宁宫");

        quatree.insert(newEnvelope(newCoordinate(11639067,3991907)), info6);

//几个离故宫较远的点PointInfo info7=newPointInfo("香山公园");

        quatree.insert(newEnvelope(newCoordinate(11619151,3999031)), info7);

        PointInfo info8=newPointInfo("香山寺");

        quatree.insert(newEnvelope(newCoordinate(11619150,3999039)), info8);

        PointInfo info9=newPointInfo("眼镜湖");

        quatree.insert(newEnvelope(newCoordinate(11618154,3999566)), info9);

当中需要说明的部分如下:

quatree.insert(new Envelope(new Coordinate(11638937, 3992178)), info1);

当中的Coordinate代表了一个只是包含经纬度的点(point)。在jts中,还有另外一个专门的对象表示点,就是point对象,但是这里我们只是想用经纬度来建立好节点之间的关系,故而只是采用了Coordinate。

而Envelope,这个对象其实代表的是一个矩形框。可能是因为信封就是一个矩形框的原因,所以,加拿大人就用这个单词来表示矩形了。Envelope的构造函数中需要给出矩形的对角坐标。但是我们这里只是有一个点,所以,jts会把这一个单独的点也作为一个矩形。

这就是说明,jts中结点不是简单的point,而是一个矩形(Envelope)。

至于最后的info,则是表示点的其他描述信息。

需要补充的是,jts目前只是支持二维,三维的z坐标永远是0。

3. 建立一颗树的目的不是等待他发芽,而是为了搜索(everyone has his purpose!)

quatree 提供了三个搜索方法,签名分别如下:

publicList query(Envelope searchEnv){

/** *//**         * the items that are matched are the items in quads which overlap the

         * search envelope

*/        ArrayListVisitor visitor=newArrayListVisitor();

        query(searchEnv, visitor);

returnvisitor.getItems();

    }

publicvoidquery(Envelope searchEnv, ItemVisitor visitor){

/** *//**         * the items that are matched are the items in quads which overlap the

         * search envelope

*/        root.visit(searchEnv, visitor);

    }

/** *//**     * Return a list of all items in the Quadtree

*/

publicList queryAll(){

        List foundItems=newArrayList();

        root.addAllItems(foundItems);

returnfoundItems;

    }

每个函数的含义也是很简单的,分别表示搜索范围搜索,范围过滤搜索和全部搜索。

接下来我们就分别尝试分为搜索和范围过滤搜索:

范围搜索很简单,只要给出一个矩形框,然后传入就可以了,代码如下:

//看看在故宫旁边能够找到什么System.out.println("看看在故宫旁边能够找到什么");

        Listpoints=quatree.query(newEnvelope(newCoordinate(

11638937,3992178)));

for(PointInfo pointInfo : points){

//结果是什么,居然就是故宫一个结果System.out.println(pointInfo.getName());

        }//只能够调整经纬度,来看看故宫周围有什么System.out.println("=================================");

        System.out.println("只能够调整经纬度,来看看故宫周围有什么,这个就相当于地图上的周边搜索的概念");

        points=quatree.query(newEnvelope(newCoordinate(11638937,3991605),

newCoordinate(11639081,3992178)));

for(PointInfo pointInfo : points){

//结果是什么?System.out.println(pointInfo.getName());

        }

可以看到,当只是输入故宫的点的时候,结果只是一个故宫。所以,我就找了一范围来搜,模拟文斌在http://www.51ditu.com上实现的那个周边搜索的概念。结果会是什么呢?

说起周边搜索,不可能没有关键词,比如我们经常在群里说得那个搜索模式,我想知道在上地周边哪里有好的酒吧,下班后可以去喝一杯!

这就是周边过滤搜索的概念了。

quadtree存在着这样的一个方法:

public void query(Envelope searchEnv, ItemVisitor visitor) ,这个当中的ItemVisitor 是一个接口。实现的类似于一个访问者的功能,挨个询问过路人:“你可见到戈多,我在等他”!我们可以看一下默认的ArrayListVisitor。看后,也会觉得jts在这个地方多此一举了。

/** *//** *@version1.7

*/publicclassArrayListVisitor

implementsItemVisitor

{

privateArrayList items=newArrayList();

publicArrayListVisitor(){

  }

publicvoidvisitItem(Object item)

{

    items.add(item);

  }

publicArrayList getItems(){returnitems; }

}

可以看到,这个类对于过路人什么都没有问。

接下来,我就仿照着实现一个询问器,问问那个宫殿中悬挂着“正大光明”牌匾。

publicvoidvisitItem(Object item){

        PointInfo info=(PointInfo) item;

if(info.getInfo()!=null&&!"".equals(info.getInfo())

&&info.getInfo().contains("正大光明")){

            items.add(item);

        }    }

最后在quatree中用法如下:

//既然可以实现周边搜索,那么就可以在故宫旁边搜索那个宫殿中含有正大光明的牌匾System.out.println("=================================");

        System.out.println("既然可以实现周边搜索,那么就可以在故宫旁边搜索那个宫殿中含有正大光明的牌匾");

        UseArrayListVisitor visitor=newUseArrayListVisitor();

        quatree.query(newEnvelope(newCoordinate(11638937,3991605),

newCoordinate(11639081,3992178)), visitor);

        points=visitor.getItems();

for(PointInfo pointInfo : points){

//结果是什么?System.out.println(pointInfo.getName());

        }

结果是什么呢,当然就是乾清宫!

可以说,Jts是一个优雅的空间实用包,但是如果我在刚才过滤器中搜索的词不是那么简单呢,我想向文本搜索一样牵涉到分词,排序的概念呢。

如果我真的要在中国范围内找某一个酒吧呢?

我对于这些问题的一个思路就是,让lucene和jts合作!不过这是下一篇博客的内容了。

posted on 2007-12-21 13:47 张氏兄弟 阅读(3516) 评论(3)  编辑  收藏 所属分类: 51ditu.com

java jts点到面的距离_jts-空间索引相关推荐

  1. HDU3662(求三维凸包表面的多边形个数,表面三角形个数,体积,表面积,凸包重心,凸包中点到面的距离)

    题目:3D Convex Hull   题意:给定空间中的n个点,求这n个点形成的凸包的表面的多边形个数. 增量法求解:首先任选4个点形成的一个四面体,然后每次新加一个点,分两种情况: 1> 在 ...

  2. python计算点到面的距离

    python计算点到面的距离 已知M个点,记P∈R^(M*3),目的是求M个点到平面Z= aX + bY + c的距离解法1: 使用平面的法向量来求解 平面Z= aX + bY + c的法向量为[a, ...

  3. java高德点到ian距离,高德地图(点到线段的最短距离算法)不调用高德API

    package com.sage.dss.util; import java.math.BigDecimal; /** * 提取自 AMapUtils(版本 com.amap.api:map2d:2. ...

  4. CloudComparePCL 点云点匹配(基于点到面的距离)

    文章目录 一.简介 二.PCL中的匹配类型 三.实现代码 四.实现效果 参考文献 一.简介 在ICP算法中经常会使用到一个点到另一个点切平面的垂直距离("点到平面"误差度量,如下图 ...

  5. creo怎么测量点到面的距离

    要点: 分析–测量–选"距离", 这时候会让选两个特征,选完第一个特征后,按住ctrl,才能选第二个!

  6. 点到面距离公式向量法_点到线或面的距离公式

    我们知道高中解析几何或立体几何题中时常需要知道点到线的距离或点到面的距离.下面我们给出这两个公式以及它们的巧妙证明. 点到线的距离 已知直线 的方程为 ,平面上任意一点 到该直线的距离 的公式为: 证 ...

  7. n维椭球体积公式_【“数”你好看】点到直线与面的距离公式

    点到直线的距离公式是高中常见的解析几何公式,形式很优美,但很多人不清楚它的由来,本篇主要来推导一下这个公式,并推广到点到面的距离公式. 基础知识 向量(vector):方向(direction)+大小 ...

  8. java jts获取线上任意一点到起点的距离

    java jts获取线上任意一点到起点的距离 近期项目要求计算某段公路上一辆车的运行轨迹,通过路上的设备实时获取车辆的经纬度信息并发送到后台接收. 抽象出来就是获取线上任意一点到起点的距离,按照一定每 ...

  9. POJ 1584 A Round Peg in a Ground Hole 判断凸多边形,点到线段距离,点在多边形内

    ACM博客_kuangbin POJ 1584 A Round Peg in a Ground Hole(判断凸多边形,点到线段距离,点在多边形内) A Round Peg in a Ground H ...

最新文章

  1. 清华校长一针见血:这类孩子看起来很聪明,长大后却容易没出息
  2. 前端开发这么多年,你真的了解浏览器页面渲染机制吗?
  3. 考研复习——时间安排小结
  4. Python字符串split()和join()方法应用一例
  5. 数据库维护管理和监视新特性
  6. 关闭VS2019和VAssistX的导航栏
  7. c语言程序如何编写选择题,c语言程序 如何编写挑选题
  8. 按键精灵手机助手界面三级联动
  9. 阿里云服务器学生免费领取指南
  10. 看完必会的正则表达式和递归
  11. vue js监听浏览器tab页切换
  12. Packet Tracer 5.0建构CCNA实验攻略——帧中继Frame Relay
  13. 洛谷 - P3374 树状数组1
  14. ad账户与linux集成,Ubuntu 通过ldap集成AD账号登录(nslcd方式)
  15. Java容器【集合】笔记
  16. 打开VT-x/VT-d功能
  17. maya遇到渲染慢渲染卡顿问题怎么办?
  18. html引入外部js失效不起作用的解决办法
  19. 【数据异常校验】狄克逊准则(Dixon Criterion)处理异常数据
  20. 短波红外应用领域大揭秘-军事领域

热门文章

  1. 小聊聊NGUI中Panel的Clip功能(之一)
  2. 最新postfix的main.cf配置参考
  3. 探究APP换肤机制的设计与实现
  4. 一首特别适合冥想的音乐
  5. 51单片机mysql_51单片机之蓝牙遥控小车_效果展示+单片机知识+完整蓝牙电车代码...
  6. session如何设置超时时间
  7. “后网联时代”聚合支付发展方向思考
  8. Oxidized-20180912-docker 版本的网络设备备份系统
  9. Echart在Openlayers的应用-航班的炫光特效
  10. 关于在使用迅雷下载的时候,C盘一下爆满的问题