JTS

JTS Geometry Operations

JTS拓扑套件是一个GeoTools的外部套件来提供一个地理信息数据结构的实现。主要的好处就是经过多年的努力在数值上是稳定的。
GooToots都是关于实现空间解决方案的,我们尽最大努力遵循一个不自己疯狂造*的主旨。优秀的JTS拓扑套件项目提供了我们在整个库中使用的几何实现。

GeoTools中提供了一些组件辅助JTS

  1. gt-api 提供了帮助类和扩展JTS的CurvedGeometryFactory工厂来处理弧线。
  2. gt-main 提供了帮助类来讲Geometry转换为Java形态展示。

Geometry 空间分析方法几何图形操作包:

在operation包内,包含buffer、distance、linemerge、overlap、polygonize、predicate、relate、valide八个子包;

分别对应着计算图形的缓冲、距离、线段融合、图形覆盖、多边形化、断言、关联、有效性等的操作。所有的操作针对的都是在geom包中定义的Geometry对象。

由于在计算机中,所有的图形都是离散的点组成,所以所有的操作都是在组成图形的点的集合上进行的.
一个图形(Geometry)的缓冲(buffer)

距离操作(distance)是个二元操作,操作对象Geometry A、B,返回(A)与(B)中距离最近的两个点的距离。

线段的融合(linemerge)是将Geometry A中相互连接的线段进行连接。

多边形化操作(polygonize)对Geometry A进行计算,返回一个多边形(Polygon)。将由许多个点表示的图形,用少量的点来表示,减少图形的信息,即对图形进行降维。

断言(predicate)是一个二维的操作,对Geometry之间的关系进行判断的操作。

关联(relate) 根据DE-9IM(The Dimensionally Extended Nine-Intersection Model),该方法返回两个Geometry A与B的相交矩阵IM(Intersections Matrix)。这个矩阵在计算图形关系上用到。

一、pom.xml
    <properties>
        <geospark.version>1.2.0</geospark.version>
        <geotools.version>14.1</geotools.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.scala-lang</groupId>
            <artifactId>scala-library</artifactId>
            <version>2.11.0</version>
        </dependency>
        <dependency>
            <groupId>org.datasyslab</groupId>
            <artifactId>geospark</artifactId>
            <version>${geospark.version}</version>
        </dependency>
        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-geometry</artifactId>
            <version>20.0</version>
        </dependency>
        <dependency>
            <groupId>com.vividsolutions</groupId>
            <artifactId>jts</artifactId>
            <version>1.13</version>
        </dependency>
        <dependency>
            <groupId>org.json</groupId>
            <artifactId>json</artifactId>
            <version>20180813</version>
        </dependency>
        <dependency>
            <groupId>com.esri.geometry</groupId>
            <artifactId>esri-geometry-api</artifactId>
            <version>2.2.2</version>
        </dependency>
        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-geojson</artifactId>
            <version>${geotools.version}</version>
        </dependency>
        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-api</artifactId>
            <version>${geotools.version}</version>
        </dependency>
        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-referencing</artifactId>
            <version>${geotools.version}</version>
        </dependency>
        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-epsg-hsql</artifactId>
            <version>${geotools.version}</version>
        </dependency>
    </dependencies>
    <repositories>
        <repository>
            <id>osgeo</id>
            <name>Open Source Geospatial Foundation Repository</name>
            <url>http://download.osgeo.org/webdav/geotools/</url>
        </repository>
        <repository>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
            <id>boundless</id>
            <name>Boundless Maven Repository</name>
            <url>http://repo.boundlessgeo.com/main</url>
        </repository>
    </repositories>
</project>
二、JTS Geometry Operation

列举了distance,intersection,union,difference 操作:

import java.util.ArrayList;
import java.util.List;
 import org.geotools.geometry.jts.JTSFactoryFinder;
 import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.GeometryFactory;
import com.vividsolutions.jts.geom.LineString;
/**  
 * Description 几何对象操作
 */
public class Operation {
	
	private GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory( null );
	
		/**
	 * 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)与(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)
	}
}
三、 Buffer,LineMerger,Polygonization,UnionLine,凹壳分析,Overlays

构造器:GeometryFactory.java

import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.io.ParseException;
import com.vividsolutions.jts.io.WKTReader;
 
public class GeometryFactory {
	
	private WKTReader reader;
		private  GeometryFactory instance = null;
	
	public static synchronized GeometryFactory getInstance(){
		if(instance==null){
			instance = new GeometryFactory();
		}
		return instance;
	}
	
	public void getReader(){
		reader = new WKTReader();
	}
	
	public Geometry buildGeo(String str){
		try {
			if(reader==null){
				reader = new WKTReader();
			}
			return reader.read(str);
		} catch (ParseException e) {
			throw new RuntimeException("buildGeometry Error",e);
		}
	}
 }

3.1 Buffer,返回的结果是一个Polygon或者 MultiPolygon

import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.operation.buffer.BufferOp;
 
public class Buffers {
 
	private GeometryFactory factory = GeometryFactory.getInstance();
 
	public Geometry buildGeo(String str) {
		return factory.buildGeo(str);
	}
 
	public static void main(String[] args) {
		Buffers bs = new Buffers();
		String line1 = "LINESTRING (0 0, 1 1, 2 2,3 3)";
		Geometry g1 = bs.buildGeo(line1);
		//方式(一)
		Geometry g = g1.buffer(2);
 
		方式(二) BufferOP
		BufferOp bufOp = new BufferOp(g1);
		bufOp.setEndCapStyle(BufferOp.CAP_BUTT);
		Geometry bg = bufOp.getResultGeometry(2);
	}
}

3.2 Polygonization 面处理类

import java.util.ArrayList;
import java.util.List;
import java.util.Collection;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.operation.polygonize.Polygonizer;
 
public class Polygonization {
 
	private static GeometryFactory factory = GeometryFactory.getInstance();
 
	public static void main(String[] args) {
		List<Geometry> list = new ArrayList<Geometry>();
		list.add(factory.buildGeo("LINESTRING (0 0,1 1)")); 
		list.add(factory.buildGeo("LINESTRING (6 3,6 10)"));
		list.add(factory.buildGeo("LINESTRING (2 2,4 4,6 3)"));
		list.add(factory.buildGeo("LINESTRING (2 2,5 1,6 3)"));
		list.add(factory.buildGeo("LINESTRING (6 3,6 4)"));
		list.add(factory.buildGeo("LINESTRING (9 5,7 1,6 4)"));
		list.add(factory.buildGeo("LINESTRING (9 5,8 8,6 4)"));
		Polygonizer p = new Polygonizer();
		p.add(list);
		Collection<Geometry> polys = p.getPolygons(); //面
		Collection<Geometry> dangles = p.getDangles();//悬挂线
		Collection<Geometry> cuts = p.getCutEdges(); //面和面的连接线
		System.out.println(polys.size()+":"+polys.toString());
		System.out.println(dangles.size()+":"+dangles.toString());
		System.out.println(cuts.size()+":"+cuts.toString());
	}
}

输出结果:

2:[POLYGON ((2 2, 4 4, 6 3, 5 1, 2 2)), POLYGON ((6 4, 8 8, 9 5, 7 1,
6 4))] 2:[LINESTRING (6 3, 6 10), LINESTRING (0 0, 1 1)] 1:[LINESTRING
(6 3, 6 4)]

3.3 LineMerger 线路合并,线路之间不能有交点,并且只在线路末尾有公共交点

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
 
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.operation.linemerge.LineMerger;
 
public class MergerLine {
 
	private static GeometryFactory factory = GeometryFactory.getInstance();
 
	public static void main(String[] args) {
		LineMerger lineMerger = new LineMerger();
		List<Geometry> list = new ArrayList<Geometry>();
		list.add(factory.buildGeo("LINESTRING (3 3,2 2,0 0)"));
		list.add(factory.buildGeo("LINESTRING (3 3,6 6,0 10)"));
		list.add(factory.buildGeo("LINESTRING (0 10,3 1,10 1)"));
		lineMerger.add(list);
		Collection<Geometry> mergerLineStrings = lineMerger.getMergedLineStrings();
		for (Geometry g : mergerLineStrings) {
			System.out.println(g.toText());
		}
	}
}

输出结果:LINESTRING (0 0, 2 2, 3 3, 6 6, 0 10, 3 1, 10 1)

lineMerger 和union区别,union可以在两条相交的线中生成交点(noded)

3.4 union 线路合并,并且生成交叉点

import java.util.ArrayList;
import java.util.List;
 
import com.vividsolutions.jts.geom.Geometry;
 
public class UnionLine {
 
	private static GeometryFactory factory = GeometryFactory.getInstance();
 
	public static void main(String[] args) {
		List<Geometry> list = new ArrayList<Geometry>();
		list.add(factory.buildGeo("LINESTRING (10 10,2 2,0 0)"));
		list.add(factory.buildGeo("LINESTRING (10 0,6 6,0 10)"));
		list.add(factory.buildGeo("LINESTRING (1 1,3 1,10 1)"));
		Geometry nodedLine = list.get(0);
		for (int i = 1; i < list.size(); i++) {
			nodedLine = nodedLine.union(list.get(i));
		}
		int num = nodedLine.getNumGeometries();
		for (int j = 0; j < num; j++) {
			Geometry eachG = nodedLine.getGeometryN(j);
			System.out.println(eachG.toText());
		}
	}
}
上一篇:DIV+CSS专题:第一天 XHTML CSS基础知识


下一篇:多线程编程之Apue3rd_Chapter11之互斥锁_读写锁_自旋锁