ArcSDE SDK中的几何对象定义分布在很多地方,他们各自有不同的用途。其中一部分几何对象类型组织在com.esri.sde.sdk.geom包中、在com.esri.sde.sdk.client包中包含有SeShape和SDEPoint等类型。
com.esri.sde.sdk.geom包中组织的是符合OGC规范的简单对象,它们之间的关系如下图:
图 1 com.esri.sde.sdk.geom包的类关系图
com.esri.sde.sdk.client包中组织的则是ArcSDE客户端中的几何对象。
构造SeGeometry对象还需要一个空间参考对象SeCoordRef,比如一个点对象应该用如下的方式构造:
SeCoordRef cr = new SeCoordRef();
SePoint pt = new SePoint(cr, 116.39, 39.9);
这里通过X、Y坐标值就可以构造一个点对象,类似的,线对象和面对象则可以通过SePoint点的集合来进行构造:
SeCoordRef cr = new SeCoordRef();
SePoint[] lsPts = new SePoint[] { new SePoint(cr, 0, 0),
new SePoint(cr, 10, 0), new SePoint(cr, 10, 10) };
SeLinestring ls = new SeLinestring(cr, lsPts);
System.out.print(ls.toString());
System.out.println("长度" + ls.length());
System.out.println();
SePoint[][] pgPts = new SePoint[][] {
{ new SePoint(cr, 0, 0), new SePoint(cr, 100, 0),
new SePoint(cr, 100, 100), new SePoint(cr, 0, 100),
new SePoint(cr, 0, 0) },
{ new SePoint(cr, 20, 20), new SePoint(cr, 40, 20),
new SePoint(cr, 40, 40), new SePoint(cr, 20, 40),
new SePoint(cr, 20, 20) } };
SePolygon pg = new SePolygon(cr, pgPts);
System.out.print(pg.toString());
System.out.println("面积" + pg.area());
这里将构造成的对象及其长度、面积打印出来以验证对象的正确性:注意,这里生成的多边形是一个带洞的多边形。
SeLinestring:
(SePoint : 0 dx=0.0,dy=0.0)
(SePoint : 1 dx=10.0,dy=0.0)
(SePoint : 2 dx=10.0,dy=10.0)
长度20.0
SePolygon:
(SePoint : 0 dx=0.0,dy=0.0)
(SePoint : 1 dx=100.0,dy=0.0)
(SePoint : 2 dx=100.0,dy=100.0)
(SePoint : 3 dx=0.0,dy=100.0)
(SePoint : 4 dx=0.0,dy=0.0)
(SePoint : 5 dx=20.0,dy=20.0)
(SePoint : 6 dx=40.0,dy=20.0)
(SePoint : 7 dx=40.0,dy=40.0)
(SePoint : 8 dx=20.0,dy=40.0)
(SePoint : 9 dx=20.0,dy=20.0)
面积9600.0
SeShape位于com.esri.sde.sdk.client包下,它可以被看作是一个在ArcSDE客户端存在的ESRI Shape对象。注意,在数据库里存储的ESRI Shape对象不但包括几何对象的节点坐标信息,还包括坐标点数、边界范围、长度、面积等信息。
我们可以直接从一个SeGeometry对象生成一个SeShape对象:
SeCoordRef cr = new SeCoordRef();
SePoint[][] pgPts = new SePoint[][] {
{ new SePoint(cr, 0, 0), new SePoint(cr, 100, 0),
new SePoint(cr, 100, 100), new SePoint(cr, 0, 100),
new SePoint(cr, 0, 0) },
{ new SePoint(cr, 20, 20), new SePoint(cr, 40, 20),
new SePoint(cr, 40, 40), new SePoint(cr, 20, 40),
new SePoint(cr, 20, 20) } };
SePolygon pg = new SePolygon(cr, pgPts);
SeShape shape = new SeShape();
shape.fromSeGeometry(pg);
或者从WKT字符串生成一个SeShape:
SeShape shape = new SeShape(cr);
shape.generateFromText("POLYGON((2 2,2 4,4 4,4 2,2 2))");
或者从服务器上获得一个SeShape:
SeRow row = query.fetch();
while (row != null) {
try {
SeShape shape = row.getShape(1);
} catch (Exception e) {
e.printStackTrace();
}
row = query.fetch();
}
查看SeShape的属性可以发现,除了节点坐标信息,还有其它很多辅助信息:
图 2 SeShape中的辅助信息
对SeGeometry对象和SeShape对象都可以进行空间关系的判断和空间运算,当然,大多数进行空间关系判断和运算的情况都发生在获取服务器数据之后,因此使用SeShape的情况更多一些。下面就用SeShape来展示如何判断两个几何对象是否满足各种空间关系:
try {
SeShape shape1 = new SeShape();
shape1.generateFromText("LINESTRING(0 0,10 10,10 20)");
SeShape shape2 = new SeShape();
shape2.generateFromText("POLYGON((0 0,10 0,10 10,0 0))");
System.out.println("contain:"+shape2.isContaining(shape1));
System.out.println("cross:"+shape2.isCrossing(shape1));
System.out.println("disjoint:"+shape2.isDisjoint(shape1));
System.out.println("overlap:"+shape2.isOverlapping(shape1));
System.out.println("touch:"+shape2.isTouching(shape1));
System.out.println("within:"+shape2.isWithin(shape1));
} catch (Exception ex) {
ex.printStackTrace();
}
对一个几何对象,可以进行缓冲、闭包、标注点等计算:
try {
SeShape shape = new SeShape();
shape.generateFromText("POLYGON((10 10,20 10,20 20,18 12,10 10))");
SeShape buffer = shape.generateBuffer(2, 100);//缓冲
System.out.println(buffer.getArea());
SeShape convexHull = shape.generateConvexHull();//闭包
System.out.println(convexHull.getArea());
SDEPoint labelPoint = shape.generateLabelPoint();//标注点
System.out.println("x:" + labelPoint.getX() + ",y:" + labelPoint.getY());
} catch (Exception ex) {
ex.printStackTrace();
}
对两个几何对象,可以进行合并、求交等运算:
try {
SeShape shape1 = new SeShape();
shape1.generateFromText("POLYGON((10 10,30 10,30 30,10 30,10 10))");
SeShape shape2 = new SeShape();
shape2.generateFromText("POLYGON((0 0,20 0,20 20,0 20,0 0))");
SeShape union = shape1.union(shape2);//合并
System.out.println(union.getArea());
SeShape[] intersect = shape1.intersect(shape2);//求交
double area = 0;
for(int i=0,num=intersect.length;i
area += intersect[i].getArea();
}
System.out.println(area);
SeShape xor = shape1.symmetricalDifference(shape2);//合并去交
System.out.println(xor.getArea());
SeShape difference = shape1.difference(shape2);//求差
System.out.println(difference.getArea());
} catch (Exception ex) {
ex.printStackTrace();
}
另外,比如求两个几何对象间的最短距离:
try {
SeShape shape1 = new SeShape();
shape1.generateFromText("POLYGON((20 20,30 20,30 30,20 30,20 20))");
SeShape shape2 = new SeShape();
shape2.generateFromText("POLYGON((0 0,10 0,10 10,0 10,0 0))");
double distance = shape1.calculateDistance(shape2, true);
System.out.println(distance);
} catch (Exception ex) {
ex.printStackTrace();
}