1. 程式人生 > >JTS Geometry合併、裁切、疊加分析等

JTS Geometry合併、裁切、疊加分析等

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)。這個矩陣在計算圖形關係上用到。

1.distance,intersection,union,difference 示例程式碼:

package com.mapbar.geo.jts.operation;
 
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;
/**  
 * Class Operation.java 
 * Description 幾何物件操作
 * Company mapbar 
 * author Chenll E-mail: 
[email protected]
* Version 1.0 * Date 2012-2-21 上午10:47:47 */ 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) } }

2.一些高階操作, Buffer,LineMerger,Polygonization,UnionLine,凹殼分析,Overlays

package com.mapbar.jst;
 
 
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);
		}
	}
 
}

2.1 緩衝區操作:

package com.mapbar.jst;
 
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);
	}
}

bufOp.setEndCapStyle 緩衝樣式的設定,總共有三種CAP_ROUND,CAP_BUTT,CAP_SQUARE 對應如下三種情況

2.2 Polygonization 

多邊形化是由線條包圍區域形成多邊形的過程,各線段不能交叉,只能在端點接觸,且完全閉合。

package com.mapbar.jst;
 
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)]

2.3 LineMerger 線路合併,線路之間不能有交點,並且只在線路末尾有公共交點

package com.mapbar.jst;
 
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)

2.4 union 線路合併,並且生成交叉點

package com.mapbar.jst;
 
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());
		}
	}
}

2.5 凹殼分析  包含幾何形體的所有點的最小凸殼多邊形(外包多邊形)

2.6 疊加操作  疊加可以用來確定任何幾何圖形的布林組合

通過對兩個資料進行的一系列集合運算,產生新資料的過程。疊加分析的目的就是通過對空間資料的加工或分析,提取使用者需要的新的空間幾何資訊。
疊加分析型別包括:
交叉分析(Intersection) 交叉操作就是多邊形AB中所有共同點的集合。
聯合分析(Union) AB的聯合操作就是AB所有點的集合。
差異分析(Difference) AB形狀的差異分析就是A裡有B裡沒有的所有點的集合。
對稱差異分析(SymDifference) AB形狀的對稱差異分析就是位於A中或者B中但不同時在AB中的所有點的集合

	public void overlaps() throws ParseException, FileNotFoundException{
		WKTReader reader = new WKTReader(geometryFactory);
		Polygon geometry1 = (Polygon) reader.read("POLYGON((0 0, 2 0 ,2 2, 0 2,0 0))");
		Polygon geometry2 = (Polygon) reader.read("POLYGON((0 0, 4 0 , 4 1, 0 1, 0 0))");
	    OverlayOp op = new OverlayOp(geometry1,geometry2);
	    Geometry g =op.getResultGeometry(OverlayOp.INTERSECTION);//POLYGON ((2 0, 0 0, 0 1, 2 1, 2 0))
	    Geometry g2 = op.getResultGeometry(OverlayOp.UNION);
	    Geometry g3 = op.getResultGeometry(OverlayOp.DIFFERENCE);
	    Geometry g4 = op.getResultGeometry(OverlayOp.SYMDIFFERENCE);
	    PlanarGraph p = op.getGraph(); //圖<v,e>
	}