【JTS】JTS的几何图形的基本关系方法

拓扑关系——九交模型

2015年06月11日 08:42:30

阅读数:4541

空间关系

中文名称

OGC标准

解释

Contains

包含

一个几何图形的内部完全包含了另一个几何图形的内部和边界。

CoveredBy

覆盖

一个几何图形被另一个几何图形所包含,并且它们的边界相交。Point和MultiPoint不支持此空间关系,因为它们没有边界。

Crosses

交叉

一个几何图形的内部和另一个几何图形的边界和内部相交,但是它们的边界不相交。(两条线相交于一点,一条线和一个面相交)

Disjoint

分离

两个几何图形的边界和内部不相交。

EnvelopeIntersects

封套相交

两个几何图形的外接矩形相交。

Equal

相等

两个几何图形具有相同的边界和内部。

Inside

内部

一个几何图形在另一个几何图形的内部,但是和它的边界不接触。

Intersects

相交

两个几何图形没有分离(Non-DisJoint)。

Overlaps

重叠

两个几何图形的边界和内部相交(Intersect)。

Touch

接触

两个几何图形的边界相交,但是内部不相交。

Within

包含于

一个几何图形的内部和边界完全在另一个几何图形的内部。

MapGuide所支持的11种空间关系

维度扩展九交模式的形式如下所示,I(A)和I(B)表示A和B的内部(inside),B(A)和B(B)表示A和B的边界(border),E(A)和E(B)表示A和B的外部。

 

 

 

内部

边界

外部

内部

dim(I(a)ÇI(b))

dim(I(a)ÇB(b))

dim(I(a)ÇE(b))

边界

dim(B(a)ÇI(b))

dim(B(a)ÇB(b))

dim(B(a)ÇE(b))

外部

dim(E(a)ÇI(b))

dim(E(a)ÇB(b))

dim(E(a)ÇE(b))

维度扩展九交模型

空间关系描述:

 

 

SpatialRelDescription 描述
T********面与面内部相交
  

 

JTS基本概念和使用

简介

  1. JTS是加拿大的 Vivid Solutions公司做的一套开放源码的 Java API。它提供了一套空间数据操作的核心算法。为在兼容OGC标准的空间对象模型中进行基础的几何操作提供2D空间谓词API。

操作

  1. 表示Geometry对象
    1. Geometry类型介绍见另一篇文章:WKT WKB和GeoJSON
    2. package com.alibaba.autonavi;
      
      
      import com.vividsolutions.jts.geom.Coordinate;
      import com.vividsolutions.jts.geom.Geometry;
      import com.vividsolutions.jts.geom.GeometryCollection;
      import com.vividsolutions.jts.geom.GeometryFactory;
      import com.vividsolutions.jts.geom.LineString;
      import com.vividsolutions.jts.geom.LinearRing;
      import com.vividsolutions.jts.geom.Point;
      import com.vividsolutions.jts.geom.Polygon;
      import com.vividsolutions.jts.geom.MultiPolygon;
      import com.vividsolutions.jts.geom.MultiLineString;
      import com.vividsolutions.jts.geom.MultiPoint;
      import com.vividsolutions.jts.io.ParseException;
      import com.vividsolutions.jts.io.WKTReader;
      
      
      public class GeometryDemo {
      
          private GeometryFactory geometryFactory = new GeometryFactory();
      
          /**
           * create a point
           * @return
           */
          public Point createPoint(){
              Coordinate coord = new Coordinate(109.013388, 32.715519);
              Point point = geometryFactory.createPoint( coord );
              return point;
          }
          
          /**
           * create a point by WKT
           * @return
           * @throws ParseException 
           */
          public Point createPointByWKT() throws ParseException{
              WKTReader reader = new WKTReader( geometryFactory );
              Point point = (Point) reader.read("POINT (109.013388 32.715519)");
              return point;
          }
          
          /**
           * create multiPoint by wkt
           * @return
           */
          public MultiPoint createMulPointByWKT()throws ParseException{
              WKTReader reader = new WKTReader( geometryFactory );
              MultiPoint mpoint = (MultiPoint) reader.read("MULTIPOINT(109.013388 32.715519,119.32488 31.435678)");
              return mpoint;
          }
          /**
           * 
           * create a line
           * @return
           */
          public LineString createLine(){
              Coordinate[] coords  = new Coordinate[] {new Coordinate(2, 2), new Coordinate(2, 2)};
              LineString line = geometryFactory.createLineString(coords);
              return line;
          }
          
          /**
           * create a line by WKT
           * @return
           * @throws ParseException
           */
          public LineString createLineByWKT() throws ParseException{
              WKTReader reader = new WKTReader( geometryFactory );
              LineString line = (LineString) reader.read("LINESTRING(0 0, 2 0)");
              return line;
          }
          
          /**
           * create multiLine 
           * @return
           */
          public MultiLineString createMLine(){
              Coordinate[] coords1  = new Coordinate[] {new Coordinate(2, 2), new Coordinate(2, 2)};
              LineString line1 = geometryFactory.createLineString(coords1);
              Coordinate[] coords2  = new Coordinate[] {new Coordinate(2, 2), new Coordinate(2, 2)};
              LineString line2 = geometryFactory.createLineString(coords2);
              LineString[] lineStrings = new LineString[2];
              lineStrings[0]= line1;
              lineStrings[1] = line2;
              MultiLineString ms = geometryFactory.createMultiLineString(lineStrings);
              return ms;
          }
          
          /**
           * create multiLine by WKT
           * @return
           * @throws ParseException
           */
          public MultiLineString createMLineByWKT()throws ParseException{
              WKTReader reader = new WKTReader( geometryFactory );
              MultiLineString line = (MultiLineString) reader.read("MULTILINESTRING((0 0, 2 0),(1 1,2 2))");
              return line;
          }
          
          /**
           * create a polygon(多边形) by WKT
           * @return
           * @throws ParseException
           */
          public Polygon createPolygonByWKT() throws ParseException{
              WKTReader reader = new WKTReader( geometryFactory );
              Polygon polygon = (Polygon) reader.read("POLYGON((20 10, 30 0, 40 10, 30 20, 20 10))");
              return polygon;
          }
          
          /**
           * create multi polygon by wkt
           * @return
           * @throws ParseException
           */
          public MultiPolygon createMulPolygonByWKT() throws ParseException{
              WKTReader reader = new WKTReader( geometryFactory );
              MultiPolygon mpolygon = (MultiPolygon) reader.read("MULTIPOLYGON(((40 10, 30 0, 40 10, 30 20, 40 10),(30 10, 30 0, 40 10, 30 20, 30 10)))");
              return mpolygon;
          }
          
          /**
           * create GeometryCollection  contain point or multiPoint or line or multiLine or polygon or multiPolygon
           * @return
           * @throws ParseException
           */
          public GeometryCollection createGeoCollect() throws ParseException{
              LineString line = createLine();
              Polygon poly =  createPolygonByWKT();
              Geometry g1 = geometryFactory.createGeometry(line);
              Geometry g2 = geometryFactory.createGeometry(poly);
              Geometry[] garray = new Geometry[]{g1,g2};
              GeometryCollection gc = geometryFactory.createGeometryCollection(garray);
              return gc;
          }
          
          /**
           * create a Circle  创建一个圆,圆心(x,y) 半径RADIUS
           * @param x
           * @param y
           * @param RADIUS
           * @return
           */
          public Polygon createCircle(double x, double y, final double RADIUS){
              final int SIDES = 32;//圆上面的点个数
              Coordinate coords[] = new Coordinate[SIDES+1];
              for( int i = 0; i < SIDES; i++){
                  double angle = ((double) i / (double) SIDES) * Math.PI * 2.0;
                  double dx = Math.cos( angle ) * RADIUS;
                  double dy = Math.sin( angle ) * RADIUS;
                  coords[i] = new Coordinate( (double) x + dx, (double) y + dy );
              }
              coords[SIDES] = coords[0];
              LinearRing ring = geometryFactory.createLinearRing( coords );
              Polygon polygon = geometryFactory.createPolygon( ring, null );
              return polygon;
          }
      
          /**
           * @param args
           * @throws ParseException 
           */
          public static void main(String[] args) throws ParseException {
              GeometryDemo gt = new GeometryDemo();
              Polygon p = gt.createCircle(0, 1, 2);
              //圆上所有的坐标(32个)
              Coordinate coords[] = p.getCoordinates();
              for(Coordinate coord:coords){
                  System.out.println(coord.x+","+coord.y);
              }
          }
      }

       

  2. Geometry之间的关系
    1. 支持的空间操作包括

相等(Equals):

几何形状拓扑上相等。

脱节(Disjoint):

几何形状没有共有的点。

相交(Intersects):

几何形状至少有一个共有点(区别于脱节)

接触(Touches):

几何形状有至少一个公共的边界点,但是没有内部点。

交叉(Crosses):

几何形状共享一些但不是所有的内部点。

内含(Within):

几何形状A的线都在几何形状B内部。

包含(Contains):

几何形状B的线都在几何形状A内部(区别于内含)

重叠(Overlaps):

几何形状共享一部分但不是所有的公共点,而且相交处有他们自己相同的区域。

package com.alibaba.autonavi;

import com.vividsolutions.jts.geom.*;
import com.vividsolutions.jts.io.ParseException;
import com.vividsolutions.jts.io.WKTReader;

/**
 * gemotry之间的关系
 * @author xingxing.dxx
 *
 */
public class GeometryRelated {

    private GeometryFactory geometryFactory = new GeometryFactory();
    
    /**
     *  两个几何对象是否是重叠的
     * @return
     * @throws ParseException
     */
    public boolean equalsGeo() throws ParseException{
        WKTReader reader = new WKTReader( geometryFactory );
        LineString geometry1 = (LineString) reader.read("LINESTRING(0 0, 2 0, 5 0)");
        LineString geometry2 = (LineString) reader.read("LINESTRING(5 0, 0 0)");
        return geometry1.equals(geometry2);//true
    }
    
    /**
     * 几何对象没有交点(相邻)
     * @return
     * @throws ParseException
     */
    public boolean disjointGeo() throws ParseException{
        WKTReader reader = new WKTReader( geometryFactory );
        LineString geometry1 = (LineString) reader.read("LINESTRING(0 0, 2 0, 5 0)");
        LineString geometry2 = (LineString) reader.read("LINESTRING(0 1, 0 2)");
        return geometry1.disjoint(geometry2);
    }
    
    /**
     * 至少一个公共点(相交)
     * @return
     * @throws ParseException
     */
    public boolean intersectsGeo() throws ParseException{
        WKTReader reader = new WKTReader( geometryFactory );
        LineString geometry1 = (LineString) reader.read("LINESTRING(0 0, 2 0, 5 0)");
        LineString geometry2 = (LineString) reader.read("LINESTRING(0 0, 0 2)");
        Geometry interPoint = geometry1.intersection(geometry2);//相交点
        System.out.println(interPoint.toText());//输出 POINT (0 0)
        return geometry1.intersects(geometry2);
    }

    /**
     * 判断以x,y为坐标的点point(x,y)是否在geometry表示的Polygon中
     * @param x
     * @param y
     * @param geometry wkt格式
     * @return
     */
    public boolean withinGeo(double x,double y,String geometry) throws ParseException {

        Coordinate coord = new Coordinate(x,y);
        Point point = geometryFactory.createPoint( coord );

        WKTReader reader = new WKTReader( geometryFactory );
        Polygon polygon = (Polygon) reader.read(geometry);
        return point.within(polygon);
    }
    /**
     * @param args
     * @throws ParseException 
     */
    public static void main(String[] args) throws ParseException {
        GeometryRelated gr = new GeometryRelated();
        System.out.println(gr.equalsGeo());
        System.out.println(gr.disjointGeo());
        System.out.println(gr.intersectsGeo());
        System.out.println(gr.withinGeo(5,5,"POLYGON((0 0, 10 0, 10 10, 0 10,0 0))"));
    }

}

 

 

关系判断

  1. Geometry之间的关系有如下几种:

相等(Equals):

几何形状拓扑上相等。

脱节(Disjoint):

几何形状没有共有的点。

相交(Intersects):

几何形状至少有一个共有点(区别于脱节)

接触(Touches):

几何形状有至少一个公共的边界点,但是没有内部点。

交叉(Crosses):

几何形状共享一些但不是所有的内部点。

内含(Within):

几何形状A的线都在几何形状B内部。

包含(Contains):

几何形状B的线都在几何形状A内部(区别于内含)

重叠(Overlaps):

几何形状共享一部分但不是所有的公共点,而且相交处有他们自己相同的区域。

  1. 如下例子展示了如何使用Equals,Disjoint,Intersects,Within操作:

复制代码

package com.alibaba.autonavi;

import com.vividsolutions.jts.geom.*;
import com.vividsolutions.jts.io.ParseException;
import com.vividsolutions.jts.io.WKTReader;

/**
 * gemotry之间的关系
 * @author xingxing.dxx
 *
 */
public class GeometryRelated {

    private GeometryFactory geometryFactory = new GeometryFactory();
    
    /**
     *  两个几何对象是否是重叠的
     * @return
     * @throws ParseException
     */
    public boolean equalsGeo() throws ParseException{
        WKTReader reader = new WKTReader( geometryFactory );
        LineString geometry1 = (LineString) reader.read("LINESTRING(0 0, 2 0, 5 0)");
        LineString geometry2 = (LineString) reader.read("LINESTRING(5 0, 0 0)");
        return geometry1.equals(geometry2);//true
    }
    
    /**
     * 几何对象没有交点(相邻)
     * @return
     * @throws ParseException
     */
    public boolean disjointGeo() throws ParseException{
        WKTReader reader = new WKTReader( geometryFactory );
        LineString geometry1 = (LineString) reader.read("LINESTRING(0 0, 2 0, 5 0)");
        LineString geometry2 = (LineString) reader.read("LINESTRING(0 1, 0 2)");
        return geometry1.disjoint(geometry2);
    }
    
    /**
     * 至少一个公共点(相交)
     * @return
     * @throws ParseException
     */
    public boolean intersectsGeo() throws ParseException{
        WKTReader reader = new WKTReader( geometryFactory );
        LineString geometry1 = (LineString) reader.read("LINESTRING(0 0, 2 0, 5 0)");
        LineString geometry2 = (LineString) reader.read("LINESTRING(0 0, 0 2)");
        Geometry interPoint = geometry1.intersection(geometry2);//相交点
        System.out.println(interPoint.toText());//输出 POINT (0 0)
        return geometry1.intersects(geometry2);
    }

    /**
     * 判断以x,y为坐标的点point(x,y)是否在geometry表示的Polygon中
     * @param x
     * @param y
     * @param geometry wkt格式
     * @return
     */
    public boolean withinGeo(double x,double y,String geometry) throws ParseException {

        Coordinate coord = new Coordinate(x,y);
        Point point = geometryFactory.createPoint( coord );

        WKTReader reader = new WKTReader( geometryFactory );
        Polygon polygon = (Polygon) reader.read(geometry);
        return point.within(polygon);
    }
    /**
     * @param args
     * @throws ParseException 
     */
    public static void main(String[] args) throws ParseException {
        GeometryRelated gr = new GeometryRelated();
        System.out.println(gr.equalsGeo());
        System.out.println(gr.disjointGeo());
        System.out.println(gr.intersectsGeo());
        System.out.println(gr.withinGeo(5,5,"POLYGON((0 0, 10 0, 10 10, 0 10,0 0))"));
    }

}

复制代码

 

关系分析

  1. 关系分析有如下几种

缓冲区分析(Buffer)

包含所有的点在一个指定距离内的多边形和多多边形

凸壳分析(ConvexHull)

包含几何形体的所有点的最小凸壳多边形(外包多边形)

交叉分析(Intersection)

A∩B 交叉操作就是多边形AB中所有共同点的集合

联合分析(Union)

AUB AB的联合操作就是AB所有点的集合

差异分析(Difference)

(A-A∩B) AB形状的差异分析就是A里有B里没有的所有点的集合

对称差异分析(SymDifference)

(AUB-A∩B) AB形状的对称差异分析就是位于A中或者B中但不同时在AB中的所有点的集合

 

 

 

 

 

 

 

 

 

     2. 我们来看看具体的例子

复制代码

package com.alibaba.autonavi;

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.LineString;

/**
 * gemotry之间的关系分析
 *
 * @author xingxing.dxx
 */
public class Operation {

    private GeometryFactory geometryFactory = new GeometryFactory();

    /**
     * create a Point
     *
     * @param x
     * @param y
     * @return
     */
    public Coordinate point(double x, double y) {
        return new Coordinate(x, y);
    }


    /**
     * create a line
     *
     * @return
     */
    public LineString createLine(List<Coordinate> points) {
        Coordinate[] coords = (Coordinate[]) points.toArray(new Coordinate[points.size()]);
        LineString line = geometryFactory.createLineString(coords);
        return line;
    }

    /**
     * 返回a指定距离内的多边形和多多边形
     *
     * @param a
     * @param distance
     * @return
     */
    public Geometry bufferGeo(Geometry a, double distance) {
        return a.buffer(distance);
    }

    /**
     * 返回(A)与(B)中距离最近的两个点的距离
     *
     * @param a
     * @param b
     * @return
     */
    public double distanceGeo(Geometry a, Geometry b) {
        return a.distance(b);
    }

    /**
     * 两个几何对象的交集
     *
     * @param a
     * @param b
     * @return
     */
    public Geometry intersectionGeo(Geometry a, Geometry b) {
        return a.intersection(b);
    }

    /**
     * 几何对象合并
     *
     * @param a
     * @param b
     * @return
     */
    public Geometry unionGeo(Geometry a, Geometry b) {
        return a.union(b);
    }

    /**
     * 在A几何对象中有的,但是B几何对象中没有
     *
     * @param a
     * @param b
     * @return
     */
    public Geometry differenceGeo(Geometry a, Geometry b) {
        return a.difference(b);
    }


    public static void main(String[] args) {
        Operation op = new Operation();
        //创建一条线
        List<Coordinate> points1 = new ArrayList<Coordinate>();
        points1.add(op.point(0, 0));
        points1.add(op.point(1, 3));
        points1.add(op.point(2, 3));
        LineString line1 = op.createLine(points1);
        //创建第二条线
        List<Coordinate> points2 = new ArrayList<Coordinate>();
        points2.add(op.point(3, 0));
        points2.add(op.point(3, 3));
        points2.add(op.point(5, 6));
        LineString line2 = op.createLine(points2);

        System.out.println(op.distanceGeo(line1, line2));//out 1.0
        System.out.println(op.intersectionGeo(line1, line2));//out GEOMETRYCOLLECTION EMPTY
        System.out.println(op.unionGeo(line1, line2)); //out MULTILINESTRING ((0 0, 1 3, 2 3), (3 0, 3 3, 5 6))
        System.out.println(op.differenceGeo(line1, line2));//out LINESTRING (0 0, 1 3, 2 3)
    }
}
  • 3
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值