72 在Java中操作几何体.docx

上传人:b****6 文档编号:4405052 上传时间:2022-12-01 格式:DOCX 页数:24 大小:49.18KB
下载 相关 举报
72 在Java中操作几何体.docx_第1页
第1页 / 共24页
72 在Java中操作几何体.docx_第2页
第2页 / 共24页
72 在Java中操作几何体.docx_第3页
第3页 / 共24页
72 在Java中操作几何体.docx_第4页
第4页 / 共24页
72 在Java中操作几何体.docx_第5页
第5页 / 共24页
点击查看更多>>
下载资源
资源描述

72 在Java中操作几何体.docx

《72 在Java中操作几何体.docx》由会员分享,可在线阅读,更多相关《72 在Java中操作几何体.docx(24页珍藏版)》请在冰豆网上搜索。

72 在Java中操作几何体.docx

72在Java中操作几何体

7.2 在Java中操作几何体

如你所见,空间对象以SDO_GEOMETRY类型存储在数据库表中。

要在Java中对其进行处理,必须首先使用JDBC从数据库中读取它们,然后把它们映射为Java类。

把SDO_GEOMETRY类型映射为Java类是比较简单的,这都归功于OracleSpatial提供的API接口。

API本身是比较简单的:

它有一个主要的包(oracle.spatial.geometry),该包中包含两个主要的类(JGeometry和J3D_Geometry)。

这个API在OracleDatabase11g中被显著地加强了。

它现在包含许多几何体的处理函数,同时也包含可以在一些标准格式(GML、WKT和ESRI等格式)间进行几何体格式转换的工具函数。

这些工具都位于oracle.spatial.util包中。

OracleSpatial的JavaAPI由位于Oracle安装目录($ORACLE_HOME/md/jlib)下的两个JAR文件(sdoapi.jar和sdoutl.jar)组成。

要在应用中使用API,须记得要在类路径(classpath)中包含上述目录。

你也需要JDBC驱动和XML解析器(仅用于处理GML)。

下面是在Windows环境中你的类路径的设置:

1.C:

\>set classpath=.;%ORACLE_HOME%\jdbc\lib\ojdbc14.jar; 

2.%ORACLE_HOME%\md\jlib\sdoapi.jar;%ORACLE_HOME%\md\jlib\sdoutl.jar;

3.%ORACLE_HOME%\lib\xmlparserv2.jar; 

OracleSpatialJavaAPI的文档(Javadoc)在Oracle文档全集中有,也可以在你的Oracle安装目录中的两个文档$ORACLE_HOME/md/doc/sdoapi.zip和sdoutl.zip中找到。

在Apress站点中可以找到大量的关于如何读、写和处理几何体的Java完整示例。

表7-1中列出了这些程序。

表7-1 程序示例

程序

返回信息

SdoPrint.java

打印出任意表中几何体的结构

SdoExport.java

把表中一部分或全部的几何体导

出到格式为WKT、WKB、

GML或其他的文件

SdoImport.java

把先前导出的几何体导入到表中

7.2.1 使用JGeometry类

Java中操作几何体的主要工具就是JGeometry类。

它使你可以对数据库中的几何体进行读写,同时也可以对几何体进行检查,创建新的几何体和对这些几何体进行一系列的转换。

1.几何体的读写

当你用SQL的SELECT语句读取对象类型(如SDO_GEOMETRY类型)时,JDBC返回一个Java结构--更精确地说,是oracle.sql.STRUCT对象。

在写一个对象的时候(用INSERT或UPDATE语句),你仍需要通过oracle.sql.STRUCT对象来传递。

对STRUCT的解码和构造都是相当复杂的,而OracleSpatialJavaAPI(JGeometry类)的主要目标就是使得这种操作变得简单。

JGeometry类提供了两种把STRUCT转换成JGeometry对象的方法:

load()方法用于读入STRUCT,返回JGeometry对象。

当你对由SELECT语句返回的几何体进行转换的时候,用该方法。

store()方法与load()方法相反。

它把JGeometry对象转换成可以通过INSERT或UPDATE语句写回数据库中的STRUCT对象。

图7-3展示了转换的过程。

 

(点击查看大图)图7-3 在Java中对几何体的读写

在OracleDatabase11g中,load()和store()方法得到了强化,以提供自己的为几何体对象而优化的序列化(pickling)及反序列化(unpickling)方法。

因此它们应当执行得更好。

对于读取一个几何体,首先要把这个对象以字节数组的形式读入,然后把这个数组传递给load()方法。

图7-4展示了这个过程。

 

图7-4 用优化的"序列化"工具在Java中对几何体进行读写

下面的这个例子,首先用结果集的getObject()方法,把各行的几何体对象提取为STRUCT类型,然后使用JGeometry的静态方法load()把它转换成JGeometry对象。

1.STRUCT dbObject = (STRUCT) rs.getObject

(1); 

2.JGeometry geom = JGeometry.load(dbObject); 

要使用优化的反序列化工具(unpickler),首先使用结果集的getBytes()方法提取几何体到一个字节数组中。

然后再次使用JGeometry的静态方法load()把它转换成JGeometry对象。

1.byte[] image = rs. getBytes 

(1); 

2.JGeometry geom = JGeometry.load(image); 

2.检查几何体

你现在可以用多个get()方法从几何对象中提取信息。

表7-2中总结了主要的方法。

在表7-3中附加的is()方法对几何体的特性进行了细化。

表7-2 JGeometry中主要的get()方法

方法

返回信息

getType()

几何体类型(1表示点,2表示线,依次类推)

getDimensions()

维度

getSRID()

空间参考系ID

getNumPoints()

几何体中的点数

getPoint()

点对象的坐标(如果几何体是点)

getFirstPoint()

几何体中的第一点

getLastPoint()

几何体中的最后一点

getMBR()

几何体的MBR

getElemInfo()

SDO_ELEM_INFO数组的内容

getOrdinatesArray()

SDO_ORDINATES数组的内容

getLabelPoint()

返回SDO_POINT结构的坐标。

当用来填充线

或多边形几何体时,这通常被用来当标记点

getJavaPoint()

对一个单点对象来说,以java.awt.

geom.Point2D对象的形式返回点坐标

getJavaPoints()

对多点对象来说,返回一个java.awt.

geom.Point2D对象数组

getElements()

得到一个JGeometry对象数组,每个对

象都表示几何体的一个元素

getElementAt()

以JGeometry格式提取几何体的一个元素

createShape()

把几何体转换成java.awt.Shape对象,

为绘制和使用java.awt包中的工具做准备

表7-3 主要的JGeometryis()方法

方法

返回信息

isPoint()

是不是点

isOrientedPoint()

是不是有向点

isCircle()

是不是圆

isGeodeticMBR()

是不是大地测量学的MBR

isMultiPoint()

是不是多点

isRectangle()

是不是矩形

hasCircularArcs()

几何体中是否包含弧

isLRSGeometry()

是不是一个线性参照的几何体

表7-2中的两个方法(getElements()和getElementAt())可以对复杂几何体的结构进行检查:

你可以提取独立的元素作为单独的JGeometry对象。

第一个方法返回所有元素到独立的JGeometry对象数组中。

第二个方法返回一个指定元素,通过其在几何体中的位置来标识。

警告:

对element术语的理解应参见OGCSimpleFeaturesforSQL规范。

例如,一个有孔多边形被看作是一个单元素,尽管它由多个环(在Oracle概念中,每个都是一个单元素)组成。

在第5章中讨论的验证函数(VALIDATE_GEOMETRY_WITH_CONTEXT()和EXTRACT())表现出同样的方式。

这就意味着getElements()方法不允许你从一个有孔多边形中提取孔。

警告:

元素的编号方式是从1开始的,而不是0。

3.创建几何体

向数据库中写入几何体(用INSERT或UPDATE语句)要求先创建一个新的JGeometry对象,并用JGeometry.store()方法把它转换成STRUCT。

然后把STRUCT传递给INSERT或UPDATE语句。

同load()方法一样,也可以使用速度更快的空间序列化工具。

图7-3和7-4展示了这两个方法。

下面是这两个方法的例子。

首先用JGeometry的静态方法store()把它转换为STRUCT,然后用setObject()方法把它插入到准备好的SQL语句中。

1.STRUCT dbObject = JGeometry.store (geom, dbConnection); 

2.stmt.setObject (1,dbObject); 

使用优化的序列化工具除了与store()方法的参数顺序相反以外,其他的都一样:

先是定义数据库连接对象,然后是创建JGeometry对象。

1.STRUCT dbObject = JGeometry.store (dbConnection, geom); 

2.stmt.setObject (1,dbObject); 

有两种方法可以构造新的JGeometry对象。

一种是使用表7-4中的构造函数。

另一种方法是用静态的方法来创建不同的几何体。

表7-5列出了这些方法。

表7-4 JGeometry转换器

构造函数

目的

JGeometry(doublex,doubley,intsrid)

构造点

JGeometry(doublex,doubley,doublez,intsrid)

构造三维点

JGeometry(doubleminX,doubleminY,doublemaxX,

doublemaxY,intsrid)

创建矩形

JGeometry(intgtype,intsrid,int[]

elemInfo,double[]ordinates)

构造一般几何体

表7-5 静态JGeometry创建方法

创建方法

目的

createPoint(double[]coord,intdim,intsrid)

创建点

createLinearLineString(double[]coords,intdim,intsrid)

创建简单线串

createLinearPolygon(double[]coords,intdim,intsrid)

创建简单多边形

createMultiPoint(java.lang.Object[]coords,intdim,intsrid)

创建多重点对象

createLinearMultiLineString(java.lang.Object[]

coords,intdim,intsrid)

创建多重线串对象

createLinearPolygon(java.lang.Object[]coords,intdim,intsrid)

创建多重多边形

createCircle(doublex1,doubley1,doublex2,

doubley2,doublex3,doubley3,intsrid)

用圆上三点创建圆

createCircle(doublex,doubley,doubleradius,intsrid)

用中心和半径创建圆

4.修改存在的几何体

JGeometry类没有提供任何用于修改几何体的方法。

例如,没有方法用来从一个线上删除或添加一点。

为了执行那些更新,你需要用某个方法,如getOrdinatesArray(),来提取点序列,然后更新由此产生的Java数组,最后用其结果来创建一个新的JGeometry对象。

像先前讨论的那样把修改后的几何体写入到数据库中:

用store()方法把JGeometry对象转换为STRUCT,然后把STRUCT传给SQL中的INSERT或UPDATE语句。

5.处理几何体

JavaAPI也提供了大量的用于对几何体执行各种转换的方法。

表7-6中列出了主要的方法。

它们以JGeometry对象作为输入而以生成的新几何体作为输出。

注意,这些函数大部分都由数据库提供,并通过PL/SQL来对其进行调用,这一内容将在第9章中详述。

表7-6 几何体处理函数

方法

目的

buffer(doublebufferWidth)

在几何体周围形成一个缓冲区

simplify(doublethreshold)

简化几何体

densifyArcs(doublearc_tolerance)

在几何体中增加所有弧的密度

clone()

复制一个几何体

affineTransforms(...)

基于提供的参数(平移、缩放、旋转、切变、

反射)在输入几何体上应用仿射变换

projectToLTP(doublesmax,doubleflat)

把一个几何体从经度/纬度投影到一个切面上

projectFromLTP()

把一个几何体从一个本地切面投影到经度/纬度上

表7-7总结了API提供的一些辅助方法。

这些函数都不涉及JGeometry对象(除了equals),用来辅助处理一定的任务。

equals()函数用来比较两个JGeometry对象,判断它们是否相同。

然而,这种比较是基于几何体的内部编码的:

如果两个几何体的所有点的坐标都相同且顺序相同,那么就认为这两个几何体相同。

该方法不真正进行涉及容差的几何体的比较。

表7-7 几何体辅助函数

方法

目的

equals()

判断两个几何体是否相同

computeArc(doublex1,doubley1,doublex2,

doubley2,doublex3,doubley3)

从三个坐标点来计算这

个弧的中心、半径和角度

linearizeArc(doublex1,doubley1,double

x2,doubley2,doublex3,doubley3)

把一个弧转换成一组二维线段

reFormulateArc(double[]d)

通过重新计算角度重构一条弧

expandCircle(doublex1,doubley1,doublex2,

doubley2,doublex3,doubley3)

通过把圆转换成一组二维

线段来实现对其的线性化

monoMeasure(double[]coords,intdim)

判断一条线是否有变

长或缩短的方法

7.2.2 使用3D几何体:

J3D_Geometry类

OracleDatabase11g的一个主要的新功能就是它能够对复杂的3D对象(表面和立方体)进行建模。

新的J3D_Geometry类能够帮助你操作那些结构。

注意,它是JGeometry的子类,所以到目前为止,你已经了解的所有方法都是适用的。

像处理JGeometry一样,从数据库中读取J3D_Geometry对象,然后由JGeometry对象构造一个J3D_Geometry对象。

例如:

1.byte[] image = rs. getBytes 

(1); 

2.JGeometry geom = JGeometry.load(image); 

3.J3D_Geometry geom3D = new J3D_Geometry ( 

4.geom.getType(), geom.getSRID(), 

5.geom.getElemInfo(), geom.getOrdinatesArray() 

6.); 

仅通过使用规则的JGeometry.store()函数向数据库中写入J3D_Geometry对象:

1.STRUCT dbObject = JGeometry.store (dbConnection, geom3d); 

2.stmt.setObject (1,dbObject); 

与JGeometry相似,它提供给你大量的方法用来对几何体进行不同的操作。

表7-8总结了这些方法。

表7-8 3D几何体处理函数

方法

目的

anyInteract(J3D_GeometryA,doubletolerance)

判断两个三维几何体是否相交

extrusion(JGeometrypolygon,doublegrdHeight,

doubleheight,Connectionconn,booleancond,

doubletolerance)

通过对一个二维多边形

进行拉伸返回一个三维几何体

closestPoints(J3D_GeometryA,doubletolerance)

计算出两个三维几何体

中离得最近的点

getMBH(J3D_Geometrygeom)

对一个三维几何体返

回一个三维的边界框

validate(doubletolerance)

验证一个三维图像的有效性

area(doubletolerance)

计算一个面或立方体

中一面的面积

length(intcount_shared_edges,doubletolerance)

计算三维形状的长度

volume(doubletolerance)

计算三维立方体的体积

distance(J3D_GeometryA,doubletolerance)

计算两个三维几何体之间的距离

7.2.3 从3D几何体中提取元素:

ElementExtractor类

3D对象可能是复杂的。

立方体尤其符合这种情况。

一个复杂的立方体由多个简单的立方体组成。

这些简单的立方体又由表面组成,它们中的某些几何体构成了立方体中的孔。

表面本身由各种元素构成,而这些元素又由环组成。

ElementExtractor类使得对复杂对象的检查和独立组件的提取变得容易,如组成立方体的一个或多个表面。

注意,你也可以对一些规则的二维几何体使用提取器。

例如,在一个复杂的多边形中,它对提取一个环的线性等高线是很有用的。

可以通过两种方式使用提取器:

一个是提取指定的元素,另一个是对所有有效的元素进行迭代。

提示:

ElementExtractor类并不只局限于3D几何体,对2D图形也适用。

但是因为其输入必须是J3D_Geometry对象,所以首先要把JGeometry对象转换成一个J3D_Geometry对象。

1.提取独立元素

你需要做的就是调用静态的getElementByLabel()方法,传入一个用于唯一标记待提取几何体元素的标签。

这个标签是一个由逗号分隔的ID号码字符串,该号码指定了待返回的几何体的子集。

根据需要可以对以下列出的元素进行指定(对在最后一个指定的元素前的任何一个null元素,为其输入一个逗号)。

点ID

边ID

环ID

多边形ID

表面ID

立方体ID

多重立方体ID

这些ID号是每个元素在每一级上的序列号。

序列号从1开始:

在多重多边形中第一个多边形是多边形1。

它的环从1到N编号。

第二个多边形是多边形2,其中的环仍从1到N编号。

例如,下面的代码将从简单立方体的表面2中返回3号多边形:

1.J3D_Geometry ring=ElementExtractor.

getElementByLabel(solid,"0,0,0,3,2"); 

注意,当有错误发生时,J3D_Geometry中的validate()方法将返回这样一个标记。

你可以通过向ElementExtractor.getElementByLabel()传递这个标记来分离发生错误的元素。

2.对元素进行迭代

创建一个ElementExtractor对象,向它传递你的查询的参数。

这实际上将创建一个在一定详细程度上初始化的迭代器。

接着,你可以通过其nextElement()方法来逐个提取对象的组件。

然后还可以用另一个ElementExtractor对象进一步地检查第一次循环所得到的每个元素。

表7-9详细介绍了创建一个ElementExtractor对象所要用到的参数。

这些参数控制提取器的行为方式。

表7-9 ElementExtractor的参数

参数

目的

geometry

待分析的3D几何体

firstElement

开始提取的位置,在几何体的SDO_ELEM_INFO

数组中被定义为偏移量。

默认值为0

extractionLevel

这个参数决定迭代器处理几何体中元素的方法。

请参见“提取级别”一节获取详细信息

allow_comp_sub_elements

指定为true(默认值)或false。

MULTICOMP_TOSIMPLE提取级别上,

用户可以通过把这个参数设置为FALSE,

从多个或复合几何体中直接提取

简单几何体。

默认值为TRUE,

这意味着用户将先从多几何体中提取复合几何体

3.提取级别

extractionLevel参数控制提取器的操作方式。

以下面的值对其进行指定。

名称为在类中所定义的常量。

Level0=MULTICOMP_TOSIMPLE:

它返回一个在多重几何体中的连续元素。

例如,它将返回多立方体中的每个立方体或多重多边形中的每个多边形。

可以把它想象成对元素的水平扫描。

Level1=INNER_OUTER:

如果存在,它将返回内部/外部元素。

对于多边形,它先返回外环,接着返回内环。

Level2=LOWER_LEVEL:

它返回子元素;也就是,它返回下一个层次中的元素(例如,对立方体而言它的下一级是表面,而对于多边形而言是边,以此类推)。

让我们来看看一个有多个孔的多重多边形的简单例子。

我们首先用MULTICOMP_TOSIMPLE对其进行充分的扫描。

这将把这个多重多边形分解为单个简单的多边形。

下一步是从这些多边形中提取环。

首先要用INNER_OUTER扫描由第一步返回的多边形。

对于无孔的多边形,结果不会变。

但是对于那些有孔的多边形,你首先得到的是表示外环的多边形,然后是一个或多个表示内环的多边形。

最后,为了进一步分解几何体,用LOWER_LEVEL对每一个环进行扫描。

这种扫描将把每个环分解成一个边集--有两个顶点的简单的线串集。

下面是用提取器把一个多重几何体分解为元素的一个例子:

1.// Create new extractor 

2.ElementExtractor e = new ElementExtractor ( 

3.geom3d, 0, ElementExtractor.MULTICOMP_TOSIMPLE); 

4.// Geo

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高中教育 > 初中教育

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1