JTS 是一个用于创建和操作向量几何的Java库;本文主要介绍其基本概念及使用,文中所使用到的软件版本:Java 1.8.0_341、JTS 1.20.0。
1、简介
LocationTech JTS 拓扑套件™(JTS)是一个开源的 Java 软件库,提供了平面几何的对象模型以及一套基础的几何函数。JTS 遵循开放 GIS 联盟发布的 SQL 简单要素规范(Simple Features Specification for SQL)。JTS旨在作为基于矢量的地理信息软件(如地理信息系统)的核心组件使用。它还可以作为一个通用库,提供计算几何学中的算法。
JTS 提供了以下空间数据模型:
2、简单使用
2.1、引入依赖
<dependency><groupId>org.locationtech.jts</groupId><artifactId>jts-core</artifactId><version>1.20.0</version> </dependency>
2.2、创建几何图形
2.2.1、点(Point)
@Test public void point() throws ParseException {//Coordinate 方式创建Coordinate coordinate = new Coordinate(118.783607,32.058945);Point point = geometryFactory.createPoint(coordinate);log.info("point={}", point);//WKT 方式创建point = (Point) wktReader.read("POINT (118.783607 32.058945)"); }
2.2.2、多点(MultiPoint)
@Test public void multiPoint() throws ParseException {//Coordinate 方式创建Coordinate coordinate = new Coordinate(118.783607,32.058945);Point point = geometryFactory.createPoint(coordinate);Coordinate coordinate2 = new Coordinate(118.784201,32.050902);Point point2 = geometryFactory.createPoint(coordinate2);MultiPoint multiPoint = geometryFactory.createMultiPoint(new Point[]{point, point2});log.info("multiPoint={}", multiPoint);//WKT 方式创建multiPoint = (MultiPoint) wktReader.read("MULTIPOINT ((118.783607 32.058945), (118.784201 32.050902))"); }
2.2.3、线(LineString)
@Test public void lineString() throws ParseException {//Coordinate 方式创建Coordinate[] coordinates = new Coordinate[] {new Coordinate(370,290), new Coordinate(540,290), new Coordinate(480,210)};LineString lineString = geometryFactory.createLineString(coordinates);log.info("lineString={}", lineString);//WKT 方式创建lineString = (LineString) wktReader.read("LINESTRING (370 290, 540 290, 480 210)"); }
2.2.4、多线(MultiLineString)
@Test public void multiLineString() throws ParseException {//Coordinate 方式创建Coordinate[] coordinates = new Coordinate[] {new Coordinate(370,290), new Coordinate(540,290), new Coordinate(480,210)};LineString lineString = geometryFactory.createLineString(coordinates);Coordinate[] coordinates2 = new Coordinate[] {new Coordinate(370, 160), new Coordinate(500,160), new Coordinate(580,180)};LineString lineString2 = geometryFactory.createLineString(coordinates2);Coordinate[] coordinates3 = new Coordinate[] {new Coordinate(630,230), new Coordinate(728,275), new Coordinate(740, 180)};LineString lineString3 = geometryFactory.createLineString(coordinates3);MultiLineString multiLineString = geometryFactory.createMultiLineString(new LineString[]{lineString, lineString2, lineString3});log.info("multiLineString={}", multiLineString);//WKT 方式创建multiLineString = (MultiLineString) wktReader.read("MULTILINESTRING ((370 290, 540 290, 480 210), (370 160, 500 160, 580 180), (630 230, 728 275, 740 180))"); }
2.2.5、线性环(LinearRing)
@Test public void linearRing() throws ParseException {//Coordinate 方式创建Coordinate[] coordinates = new Coordinate[] {new Coordinate(370,290), new Coordinate(540,290), new Coordinate(480,210), new Coordinate(370,290)};LinearRing linearRing = geometryFactory.createLinearRing(coordinates);log.info("linearRing={}", linearRing);//WKT 方式创建linearRing = (LinearRing) wktReader.read("LINEARRING (370 290, 540 290, 480 210, 370 290)"); }
2.2.6、多边形(Polygon)
@Test public void polygon() throws ParseException {//Coordinate 方式创建Coordinate[] coordinates = new Coordinate[] {new Coordinate(450,360), new Coordinate(570,380), new Coordinate(570,310), new Coordinate(460,300), new Coordinate(450,360)};LinearRing linearRing = geometryFactory.createLinearRing(coordinates);coordinates = new Coordinate[] {new Coordinate(486,345), new Coordinate(530,350), new Coordinate(535,319), new Coordinate(486,345)};LinearRing hole = geometryFactory.createLinearRing(coordinates);Polygon polygon = geometryFactory.createPolygon(linearRing, new LinearRing[]{hole});log.info("polygon={}", polygon.getArea());//WKT 方式创建polygon = (Polygon) wktReader.read("POLYGON ((450 360, 570 380, 570 310, 460 300, 450 360), (486 345, 530 350, 535 319, 486 345))"); }
2.2.7、多多边形(MultiPolygon)
@Test public void multiPolygon() throws ParseException {//Coordinate 方式创建Coordinate[] coordinates = new Coordinate[] {new Coordinate(450,360), new Coordinate(570,380), new Coordinate(570,310), new Coordinate(460,300), new Coordinate(450,360)};LinearRing linearRing = geometryFactory.createLinearRing(coordinates);coordinates = new Coordinate[] {new Coordinate(486,345), new Coordinate(530,350), new Coordinate(535,319), new Coordinate(486,345)};LinearRing hole = geometryFactory.createLinearRing(coordinates);Polygon polygon = geometryFactory.createPolygon(linearRing, new LinearRing[]{hole});Coordinate[] coordinates2 = new Coordinate[]{new Coordinate(650,350), new Coordinate(730,420), new Coordinate(790,380), new Coordinate(765,301), new Coordinate(650,350)};LinearRing linearRing2 = geometryFactory.createLinearRing(coordinates2);coordinates2 = new Coordinate[] {new Coordinate(710,380), new Coordinate(760,380), new Coordinate(740,330), new Coordinate(710,380)};LinearRing hole2 = geometryFactory.createLinearRing(coordinates2);Polygon polygon2 = geometryFactory.createPolygon(linearRing2, new LinearRing[]{hole2});MultiPolygon multiPolygon = geometryFactory.createMultiPolygon(new Polygon[]{polygon, polygon2});log.info("multiPolygon={}", multiPolygon);//WKT 方式创建multiPolygon = (MultiPolygon) wktReader.read("MULTIPOLYGON (((450 360, 570 380, 570 310, 460 300, 450 360), (486 345, 530 350, 535 319, 486 345)), ((650 350, 730 420, 790 380, 765 301, 650 350), (710 380, 760 380, 740 330, 710 380)))"); }
2.2.8、图形集合(GeometryCollection)
@Test public void geometryCollection() throws ParseException {//Coordinate 方式创建Coordinate[] coordinates = new Coordinate[] {new Coordinate(450,360), new Coordinate(570,380), new Coordinate(570,310), new Coordinate(460,300), new Coordinate(450,360)};LinearRing linearRing = geometryFactory.createLinearRing(coordinates);coordinates = new Coordinate[] {new Coordinate(486,345), new Coordinate(530,350), new Coordinate(535,319), new Coordinate(486,345)};LinearRing hole = geometryFactory.createLinearRing(coordinates);Polygon polygon = geometryFactory.createPolygon(linearRing, new LinearRing[]{hole});LineString lineString = geometryFactory.createLineString(new Coordinate[]{new Coordinate(600,340), new Coordinate(660,340), new Coordinate(680,310)});Point point = geometryFactory.createPoint(new Coordinate(720, 330));GeometryCollection geometryCollection = geometryFactory.createGeometryCollection(new Geometry[]{polygon, lineString, point});log.info("geometryCollection={}", geometryCollection);//WKT 方式创建geometryCollection = (GeometryCollection) wktReader.read("GEOMETRYCOLLECTION (POLYGON ((450 360, 570 380, 570 310, 460 300, 450 360), (486 345, 530 350, 535 319, 486 345)), LINESTRING (600 340, 660 340, 680 310), POINT (720 330))"); }
2.3、几何关系判断
2.3.1、相等(equalsTopo)
判断两个几何图形在拓扑上是否相等。
@Test public void equalsTopo() throws ParseException {LineString lineString = (LineString)wktReader.read("LINESTRING (370 290, 540 290, 480 210)");LineString lineString2 = (LineString)wktReader.read("LINESTRING (370 290, 540 290, 480 210)");log.info("equalsTopo={}", lineString.equalsTopo(lineString2));//true lineString2 = (LineString)wktReader.read("LINESTRING (370 290, 540 290, 480 220)");log.info("equalsTopo={}", lineString.equalsTopo(lineString2));//false }
2.3.2、相交(intersects)
判断两个几何图形是否相交,两几何图形至少有一个公共点。
@Test public void intersects() throws ParseException {LineString lineString = (LineString)wktReader.read("LINESTRING (370 290, 540 290, 480 210)");LineString lineString2 = (LineString)wktReader.read("LINESTRING (440 230, 460 330, 630 360)");log.info("intersects={}", lineString.intersects(lineString2));//true lineString2 = (LineString)wktReader.read("LINESTRING (460 290, 495 348, 556 354)");log.info("intersects={}", lineString.intersects(lineString2));//true lineString2 = (LineString)wktReader.read("LINESTRING (410 300, 450 320, 545 311)");log.info("intersects={}", lineString.intersects(lineString2));//false }
2.3.3、不相交(disjoint)
判断两个几何图形是否不相交,disjoint 是 intersects 的反义。
@Test public void disjoint() throws ParseException {LineString lineString = (LineString)wktReader.read("LINESTRING (370 290, 540 290, 480 210)");LineString lineString2 = (LineString)wktReader.read("LINESTRING (440 230, 460 330, 630 360)");log.info("intersects={}", lineString.disjoint(lineString2));//false lineString2 = (LineString)wktReader.read("LINESTRING (460 290, 495 348, 556 354)");log.info("intersects={}", lineString.disjoint(lineString2));//false lineString2 = (LineString)wktReader.read("LINESTRING (410 300, 450 320, 545 311)");log.info("intersects={}", lineString.disjoint(lineString2));//true }
2.3.4、接触(touches)
判断两个几何图形是否相接触,两几何图形至少有一个公共点,但它们的内部不相交。
@Test public void touches() throws ParseException {LineString lineString = (LineString)wktReader.read("LINESTRING (370 290, 540 290, 480 210)");LineString lineString2 = (LineString)wktReader.read("LINESTRING (440 230, 460 330, 630 360)");log.info("intersects={}", lineString.touches(lineString2));//false lineString2 = (LineString)wktReader.read("LINESTRING (460 290, 495 348, 556 354)");log.info("intersects={}", lineString.touches(lineString2));//true lineString2 = (LineString)wktReader.read("LINESTRING (410 300, 450 320, 545 311)");log.info("intersects={}", lineString.touches(lineString2));//false }
2.3.5、交叉(crosses)
判断两个几何图形是否交叉,两个几何图形有一些但不是所有的内部点是公共的。与 intersects 的区别:
intersects 判断的条件更宽松,只要有交集就会返回 true。
crosses 要求交集的部分必须跨越另一个几何图形的内部,通常表示两个几何图形在某个区域穿越对方。
@Test public void crosses() throws ParseException {LineString lineString = (LineString)wktReader.read("LINESTRING (370 290, 540 290, 480 210)");LineString lineString2 = (LineString)wktReader.read("LINESTRING (440 230, 460 330, 630 360)");log.info("crosses={}", lineString.crosses(lineString2));//true lineString2 = (LineString)wktReader.read("LINESTRING (460 290, 495 348, 556 354)");log.info("crosses={}", lineString.crosses(lineString2));//false lineString2 = (LineString)wktReader.read("LINESTRING (410 300, 450 320, 545 311)");log.info("crosses={}", lineString.crosses(lineString2));//false }
2.3.6、内含(within)
判断一个几何图形是否在另一个几何图形内部。
@Test public void within() throws ParseException {Polygon polygon = (Polygon)wktReader.read("POLYGON ((340 270, 470 270, 470 190, 340 190, 340 270))");Point point = (Point) wktReader.read("POINT (380 240)");log.info("within={}", point.within(polygon));//true point = (Point)wktReader.read("POINT (400 270)");log.info("within={}", point.within(polygon));//false point = (Point)wktReader.read("POINT (540 230)");log.info("within={}", point.within(polygon));//false }
2.3.7、包含(contains)
判断一个几何图形是否包含另一个几何图形,contains 是 within 的逆操作。
@Test public void contains() throws ParseException {Polygon polygon = (Polygon)wktReader.read("POLYGON ((340 270, 470 270, 470 190, 340 190, 340 270))");Point point = (Point) wktReader.read("POINT (380 240)");log.info("contains={}", polygon.contains(point));//true point = (Point)wktReader.read("POINT (400 270)");log.info("contains={}", polygon.contains(point));//false point = (Point)wktReader.read("POINT (540 230)");log.info("contains={}", polygon.contains(point));//false }
2.3.8、重叠(overlaps)
判断两个几何图形是否重叠,两个几何图形各自至少有一个不与对方共享的点。
@Test public void overlaps() throws ParseException {Polygon polygon = (Polygon)wktReader.read("POLYGON ((340 270, 470 270, 470 190, 340 190, 340 270))");Polygon polygon2 = (Polygon) wktReader.read("POLYGON ((440 300, 560 300, 560 230, 440 230, 440 300))");log.info("overlaps={}", polygon.overlaps(polygon2));//true polygon2 = (Polygon) wktReader.read("POLYGON ((470 330, 530 330, 530 270, 470 270, 470 330))");log.info("overlaps={}", polygon.overlaps(polygon2));//false }
2.4、几何关系分析
2.4.1、缓冲区(buffer)
计算几何图形周围的缓冲区区域。
@Test public void buffer() throws ParseException {Polygon polygon = (Polygon)wktReader.read("POLYGON ((340 270, 470 270, 470 190, 340 190, 340 270))");Geometry geometry = polygon.buffer(10);log.info("geometry={}", geometry); }
2.4.2、凸壳(convexHull)
计算包含几何图形中所有点的最小凸多边形。
@Test public void convexHull() throws ParseException {Polygon polygon = (Polygon)wktReader.read("POLYGON ((290 330, 290 270, 400 330, 310 310, 290 330))");Geometry geometry = polygon.convexHull();log.info("geometry={}", geometry); }
2.4.3、交集(intersection)
计算两几何图形的交集,A∩B。
@Test public void intersection() throws ParseException {Polygon polygon = (Polygon)wktReader.read("POLYGON ((340 270, 470 270, 470 190, 340 190, 340 270))");Polygon polygon2 = (Polygon)wktReader.read("POLYGON ((416 295, 540 295, 540 230, 416 230, 416 295))");Geometry geometry = polygon.intersection(polygon2);log.info("geometry={}", geometry); }
2.4.4、并集(union)
计算两几何图形的合集,AUB。
@Test public void union() throws ParseException {Polygon polygon = (Polygon)wktReader.read("POLYGON ((340 270, 470 270, 470 190, 340 190, 340 270))");Polygon polygon2 = (Polygon)wktReader.read("POLYGON ((416 295, 540 295, 540 230, 416 230, 416 295))");Geometry geometry = polygon.union(polygon2);log.info("geometry={}", geometry); }
2.4.5、差集(difference)
计算一几何图形相对另一几何图形的差集,A-A∩B。
@Test public void difference() throws ParseException {Polygon polygon = (Polygon)wktReader.read("POLYGON ((340 270, 470 270, 470 190, 340 190, 340 270))");Polygon polygon2 = (Polygon)wktReader.read("POLYGON ((416 295, 540 295, 540 230, 416 230, 416 295))");Geometry geometry = polygon.difference(polygon2);log.info("geometry={}", geometry); }
2.4.6、对称差集(symDifference)
计算两集合图形的不同部分,AUB-A∩B。
@Test public void symDifference() throws ParseException {Polygon polygon = (Polygon)wktReader.read("POLYGON ((340 270, 470 270, 470 190, 340 190, 340 270))");Polygon polygon2 = (Polygon)wktReader.read("POLYGON ((416 295, 540 295, 540 230, 416 230, 416 295))");Geometry geometry = polygon.symDifference(polygon2);log.info("geometry={}", geometry); }
2.4.7、计算点到几何图形的最近距离的点(computeDistance)
@Test public void computeDistance() throws ParseException {LineString lineString = (LineString)wktReader.read("LINESTRING (350 226, 374 219, 395 223)");Coordinate coordinate = new Coordinate(371,227);PointPairDistance ppd = new PointPairDistance();DistanceToPoint.computeDistance(lineString, coordinate, ppd);log.info("distance={}", ppd.getDistance());for (Coordinate cc : ppd.getCoordinates()) {log.info("cc={}", cc);} }
2.4.8、根据起止点计算线的子线(extractLine)
@Test public void extractLine() throws ParseException {LineString lineString = (LineString)wktReader.read("LINESTRING (250 230, 360 320, 526 256, 525 256)");LocationIndexedLine locationIndexedLine = new LocationIndexedLine(lineString);LinearLocation start = locationIndexedLine.indexOf(new Coordinate(280, 280));LinearLocation end = locationIndexedLine.indexOf(new Coordinate(430, 310));Geometry geometry = locationIndexedLine.extractLine(start, end);log.info("geometry={}", geometry); }
2.4.9、计算线上距离起点一定距离的位置(extractPoint)
@Test public void extractPoint() throws ParseException {LineString lineString = (LineString)wktReader.read("LINESTRING (350 226, 374 219, 395 223)");LocationIndexedLine locationIndexedLine = new LocationIndexedLine(lineString);LinearLocation linearLocation = LengthLocationMap.getLocation(lineString, 20);Coordinate result = locationIndexedLine.extractPoint(linearLocation);log.info("result={}", result); }
2.5、完整代码

package com.abc.demo.jts;import lombok.extern.slf4j.Slf4j; import org.junit.Test; import org.locationtech.jts.algorithm.distance.DistanceToPoint; import org.locationtech.jts.algorithm.distance.PointPairDistance; import org.locationtech.jts.geom.*; import org.locationtech.jts.io.ParseException; import org.locationtech.jts.io.WKTReader; import org.locationtech.jts.linearref.LengthLocationMap; import org.locationtech.jts.linearref.LinearLocation; import org.locationtech.jts.linearref.LocationIndexedLine;@Slf4j public class JTSCase {private final GeometryFactory geometryFactory = new GeometryFactory();private final WKTReader wktReader = new WKTReader(geometryFactory);@Testpublic void point() throws ParseException {//Coordinate 方式创建Coordinate coordinate = new Coordinate(118.783607,32.058945);Point point = geometryFactory.createPoint(coordinate);log.info("point={}", point);//WKT 方式创建point = (Point) wktReader.read("POINT (118.783607 32.058945)");}@Testpublic void multiPoint() throws ParseException {//Coordinate 方式创建Coordinate coordinate = new Coordinate(118.783607,32.058945);Point point = geometryFactory.createPoint(coordinate);Coordinate coordinate2 = new Coordinate(118.784201,32.050902);Point point2 = geometryFactory.createPoint(coordinate2);MultiPoint multiPoint = geometryFactory.createMultiPoint(new Point[]{point, point2});log.info("multiPoint={}", multiPoint);//WKT 方式创建multiPoint = (MultiPoint) wktReader.read("MULTIPOINT ((118.783607 32.058945), (118.784201 32.050902))");}@Testpublic void lineString() throws ParseException {//Coordinate 方式创建Coordinate[] coordinates = new Coordinate[] {new Coordinate(370,290), new Coordinate(540,290), new Coordinate(480,210)};LineString lineString = geometryFactory.createLineString(coordinates);log.info("lineString={}", lineString);//WKT 方式创建lineString = (LineString) wktReader.read("LINESTRING (370 290, 540 290, 480 210)");}@Testpublic void multiLineString() throws ParseException {//Coordinate 方式创建Coordinate[] coordinates = new Coordinate[] {new Coordinate(370,290), new Coordinate(540,290), new Coordinate(480,210)};LineString lineString = geometryFactory.createLineString(coordinates);Coordinate[] coordinates2 = new Coordinate[] {new Coordinate(370, 160), new Coordinate(500,160), new Coordinate(580,180)};LineString lineString2 = geometryFactory.createLineString(coordinates2);Coordinate[] coordinates3 = new Coordinate[] {new Coordinate(630,230), new Coordinate(728,275), new Coordinate(740, 180)};LineString lineString3 = geometryFactory.createLineString(coordinates3);MultiLineString multiLineString = geometryFactory.createMultiLineString(new LineString[]{lineString, lineString2, lineString3});log.info("multiLineString={}", multiLineString);//WKT 方式创建multiLineString = (MultiLineString) wktReader.read("MULTILINESTRING ((370 290, 540 290, 480 210), (370 160, 500 160, 580 180), (630 230, 728 275, 740 180))");}@Testpublic void linearRing() throws ParseException {//Coordinate 方式创建Coordinate[] coordinates = new Coordinate[] {new Coordinate(370,290), new Coordinate(540,290), new Coordinate(480,210), new Coordinate(370,290)};LinearRing linearRing = geometryFactory.createLinearRing(coordinates);log.info("linearRing={}", linearRing);//WKT 方式创建linearRing = (LinearRing) wktReader.read("LINEARRING (370 290, 540 290, 480 210, 370 290)");}@Testpublic void polygon() throws ParseException {//Coordinate 方式创建Coordinate[] coordinates = new Coordinate[] {new Coordinate(450,360), new Coordinate(570,380), new Coordinate(570,310), new Coordinate(460,300), new Coordinate(450,360)};LinearRing linearRing = geometryFactory.createLinearRing(coordinates);coordinates = new Coordinate[] {new Coordinate(486,345), new Coordinate(530,350), new Coordinate(535,319), new Coordinate(486,345)};LinearRing hole = geometryFactory.createLinearRing(coordinates);Polygon polygon = geometryFactory.createPolygon(linearRing, new LinearRing[]{hole});log.info("polygon={}", polygon.getArea());//WKT 方式创建polygon = (Polygon) wktReader.read("POLYGON ((450 360, 570 380, 570 310, 460 300, 450 360), (486 345, 530 350, 535 319, 486 345))");}@Testpublic void multiPolygon() throws ParseException {//Coordinate 方式创建Coordinate[] coordinates = new Coordinate[] {new Coordinate(450,360), new Coordinate(570,380), new Coordinate(570,310), new Coordinate(460,300), new Coordinate(450,360)};LinearRing linearRing = geometryFactory.createLinearRing(coordinates);coordinates = new Coordinate[] {new Coordinate(486,345), new Coordinate(530,350), new Coordinate(535,319), new Coordinate(486,345)};LinearRing hole = geometryFactory.createLinearRing(coordinates);Polygon polygon = geometryFactory.createPolygon(linearRing, new LinearRing[]{hole});Coordinate[] coordinates2 = new Coordinate[]{new Coordinate(650,350), new Coordinate(730,420), new Coordinate(790,380), new Coordinate(765,301), new Coordinate(650,350)};LinearRing linearRing2 = geometryFactory.createLinearRing(coordinates2);coordinates2 = new Coordinate[] {new Coordinate(710,380), new Coordinate(760,380), new Coordinate(740,330), new Coordinate(710,380)};LinearRing hole2 = geometryFactory.createLinearRing(coordinates2);Polygon polygon2 = geometryFactory.createPolygon(linearRing2, new LinearRing[]{hole2});MultiPolygon multiPolygon = geometryFactory.createMultiPolygon(new Polygon[]{polygon, polygon2});log.info("multiPolygon={}", multiPolygon);//WKT 方式创建multiPolygon = (MultiPolygon) wktReader.read("MULTIPOLYGON (((450 360, 570 380, 570 310, 460 300, 450 360), (486 345, 530 350, 535 319, 486 345)), ((650 350, 730 420, 790 380, 765 301, 650 350), (710 380, 760 380, 740 330, 710 380)))");}@Testpublic void geometryCollection() throws ParseException {//Coordinate 方式创建Coordinate[] coordinates = new Coordinate[] {new Coordinate(450,360), new Coordinate(570,380), new Coordinate(570,310), new Coordinate(460,300), new Coordinate(450,360)};LinearRing linearRing = geometryFactory.createLinearRing(coordinates);coordinates = new Coordinate[] {new Coordinate(486,345), new Coordinate(530,350), new Coordinate(535,319), new Coordinate(486,345)};LinearRing hole = geometryFactory.createLinearRing(coordinates);Polygon polygon = geometryFactory.createPolygon(linearRing, new LinearRing[]{hole});LineString lineString = geometryFactory.createLineString(new Coordinate[]{new Coordinate(600,340), new Coordinate(660,340), new Coordinate(680,310)});Point point = geometryFactory.createPoint(new Coordinate(720, 330));GeometryCollection geometryCollection = geometryFactory.createGeometryCollection(new Geometry[]{polygon, lineString, point});log.info("geometryCollection={}", geometryCollection);//WKT 方式创建geometryCollection = (GeometryCollection) wktReader.read("GEOMETRYCOLLECTION (POLYGON ((450 360, 570 380, 570 310, 460 300, 450 360), (486 345, 530 350, 535 319, 486 345)), LINESTRING (600 340, 660 340, 680 310), POINT (720 330))");}@Testpublic void equalsTopo() throws ParseException {LineString lineString = (LineString)wktReader.read("LINESTRING (370 290, 540 290, 480 210)");LineString lineString2 = (LineString)wktReader.read("LINESTRING (370 290, 540 290, 480 210)");log.info("equalsTopo={}", lineString.equalsTopo(lineString2));//true lineString2 = (LineString)wktReader.read("LINESTRING (370 290, 540 290, 480 220)");log.info("equalsTopo={}", lineString.equalsTopo(lineString2));//false }@Testpublic void intersects() throws ParseException {LineString lineString = (LineString)wktReader.read("LINESTRING (370 290, 540 290, 480 210)");LineString lineString2 = (LineString)wktReader.read("LINESTRING (440 230, 460 330, 630 360)");log.info("intersects={}", lineString.intersects(lineString2));//true lineString2 = (LineString)wktReader.read("LINESTRING (460 290, 495 348, 556 354)");log.info("intersects={}", lineString.intersects(lineString2));//true lineString2 = (LineString)wktReader.read("LINESTRING (410 300, 450 320, 545 311)");log.info("intersects={}", lineString.intersects(lineString2));//false }@Testpublic void disjoint() throws ParseException {LineString lineString = (LineString)wktReader.read("LINESTRING (370 290, 540 290, 480 210)");LineString lineString2 = (LineString)wktReader.read("LINESTRING (440 230, 460 330, 630 360)");log.info("intersects={}", lineString.disjoint(lineString2));//false lineString2 = (LineString)wktReader.read("LINESTRING (460 290, 495 348, 556 354)");log.info("intersects={}", lineString.disjoint(lineString2));//false lineString2 = (LineString)wktReader.read("LINESTRING (410 300, 450 320, 545 311)");log.info("intersects={}", lineString.disjoint(lineString2));//true }@Testpublic void touches() throws ParseException {LineString lineString = (LineString)wktReader.read("LINESTRING (370 290, 540 290, 480 210)");LineString lineString2 = (LineString)wktReader.read("LINESTRING (440 230, 460 330, 630 360)");log.info("intersects={}", lineString.touches(lineString2));//false lineString2 = (LineString)wktReader.read("LINESTRING (460 290, 495 348, 556 354)");log.info("intersects={}", lineString.touches(lineString2));//true lineString2 = (LineString)wktReader.read("LINESTRING (410 300, 450 320, 545 311)");log.info("intersects={}", lineString.touches(lineString2));//false }@Testpublic void crosses() throws ParseException {LineString lineString = (LineString)wktReader.read("LINESTRING (370 290, 540 290, 480 210)");LineString lineString2 = (LineString)wktReader.read("LINESTRING (440 230, 460 330, 630 360)");log.info("crosses={}", lineString.crosses(lineString2));//true lineString2 = (LineString)wktReader.read("LINESTRING (460 290, 495 348, 556 354)");log.info("crosses={}", lineString.crosses(lineString2));//false lineString2 = (LineString)wktReader.read("LINESTRING (410 300, 450 320, 545 311)");log.info("crosses={}", lineString.crosses(lineString2));//false }@Testpublic void within() throws ParseException {Polygon polygon = (Polygon)wktReader.read("POLYGON ((340 270, 470 270, 470 190, 340 190, 340 270))");Point point = (Point) wktReader.read("POINT (380 240)");log.info("within={}", point.within(polygon));//true point = (Point)wktReader.read("POINT (400 270)");log.info("within={}", point.within(polygon));//false point = (Point)wktReader.read("POINT (540 230)");log.info("within={}", point.within(polygon));//false }@Testpublic void contains() throws ParseException {Polygon polygon = (Polygon)wktReader.read("POLYGON ((340 270, 470 270, 470 190, 340 190, 340 270))");Point point = (Point) wktReader.read("POINT (380 240)");log.info("contains={}", polygon.contains(point));//true point = (Point)wktReader.read("POINT (400 270)");log.info("contains={}", polygon.contains(point));//false point = (Point)wktReader.read("POINT (540 230)");log.info("contains={}", polygon.contains(point));//false }@Testpublic void overlaps() throws ParseException {Polygon polygon = (Polygon)wktReader.read("POLYGON ((340 270, 470 270, 470 190, 340 190, 340 270))");Polygon polygon2 = (Polygon) wktReader.read("POLYGON ((440 300, 560 300, 560 230, 440 230, 440 300))");log.info("overlaps={}", polygon.overlaps(polygon2));//true polygon2 = (Polygon) wktReader.read("POLYGON ((470 330, 530 330, 530 270, 470 270, 470 330))");log.info("overlaps={}", polygon.overlaps(polygon2));//false }@Testpublic void buffer() throws ParseException {Polygon polygon = (Polygon)wktReader.read("POLYGON ((340 270, 470 270, 470 190, 340 190, 340 270))");Geometry geometry = polygon.buffer(10);log.info("geometry={}", geometry);}@Testpublic void convexHull() throws ParseException {Polygon polygon = (Polygon)wktReader.read("POLYGON ((290 330, 290 270, 400 330, 310 310, 290 330))");Geometry geometry = polygon.convexHull();log.info("geometry={}", geometry);}@Testpublic void intersection() throws ParseException {Polygon polygon = (Polygon)wktReader.read("POLYGON ((340 270, 470 270, 470 190, 340 190, 340 270))");Polygon polygon2 = (Polygon)wktReader.read("POLYGON ((416 295, 540 295, 540 230, 416 230, 416 295))");Geometry geometry = polygon.intersection(polygon2);log.info("geometry={}", geometry);}@Testpublic void union() throws ParseException {Polygon polygon = (Polygon)wktReader.read("POLYGON ((340 270, 470 270, 470 190, 340 190, 340 270))");Polygon polygon2 = (Polygon)wktReader.read("POLYGON ((416 295, 540 295, 540 230, 416 230, 416 295))");Geometry geometry = polygon.union(polygon2);log.info("geometry={}", geometry);}@Testpublic void difference() throws ParseException {Polygon polygon = (Polygon)wktReader.read("POLYGON ((340 270, 470 270, 470 190, 340 190, 340 270))");Polygon polygon2 = (Polygon)wktReader.read("POLYGON ((416 295, 540 295, 540 230, 416 230, 416 295))");Geometry geometry = polygon.difference(polygon2);log.info("geometry={}", geometry);}@Testpublic void symDifference() throws ParseException {Polygon polygon = (Polygon)wktReader.read("POLYGON ((340 270, 470 270, 470 190, 340 190, 340 270))");Polygon polygon2 = (Polygon)wktReader.read("POLYGON ((416 295, 540 295, 540 230, 416 230, 416 295))");Geometry geometry = polygon.symDifference(polygon2);log.info("geometry={}", geometry);}@Testpublic void computeDistance() throws ParseException {LineString lineString = (LineString)wktReader.read("LINESTRING (350 226, 374 219, 395 223)");Coordinate coordinate = new Coordinate(371,227);PointPairDistance ppd = new PointPairDistance();DistanceToPoint.computeDistance(lineString, coordinate, ppd);log.info("distance={}", ppd.getDistance());for (Coordinate cc : ppd.getCoordinates()) {log.info("cc={}", cc);}}@Testpublic void extractLine() throws ParseException {LineString lineString = (LineString)wktReader.read("LINESTRING (250 230, 360 320, 526 256, 525 256)");LocationIndexedLine locationIndexedLine = new LocationIndexedLine(lineString);LinearLocation start = locationIndexedLine.indexOf(new Coordinate(280, 280));LinearLocation end = locationIndexedLine.indexOf(new Coordinate(430, 310));Geometry geometry = locationIndexedLine.extractLine(start, end);log.info("geometry={}", geometry);}@Testpublic void extractPoint() throws ParseException {LineString lineString = (LineString)wktReader.read("LINESTRING (350 226, 374 219, 395 223)");LocationIndexedLine locationIndexedLine = new LocationIndexedLine(lineString);LinearLocation linearLocation = LengthLocationMap.getLocation(lineString, 20);Coordinate result = locationIndexedLine.extractPoint(linearLocation);log.info("result={}", result);} }
2.6、TestBuilder 使用
JTS 提供了图形界面工具,可以直观的查看图形,并可进行计算测试;下载地址:https://github.com/locationtech/jts/releases。
参考:
https://blog.csdn.net/abu935009066/article/details/115304685
https://github.com/locationtech/jts