JTS 介绍

news/2025/3/24 17:26:02/文章来源:https://www.cnblogs.com/wuyongyin/p/18689594

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);}
}
JTSCase.java

2.6、TestBuilder 使用

JTS 提供了图形界面工具,可以直观的查看图形,并可进行计算测试;下载地址:https://github.com/locationtech/jts/releases。

 

 

参考:
https://blog.csdn.net/abu935009066/article/details/115304685
https://github.com/locationtech/jts

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/904099.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【笔记】力扣 134. 加油站——贪心

134. 加油站 中等 在一条环路上有 n 个加油站,其中第 i 个加油站有汽油 gas[i] 升。 你有一辆油箱容量无限的的汽车,从第 i 个加油站开往第 i+1 个加油站需要消耗汽油 cost[i] 升。你从其中的一个加油站出发,开始时油箱为空。 给定两个整数数组 gas 和 cost ,如果你可以按顺…

2025.3.23 鲜花

[省选联考 2025] 追忆 题解[省选联考 2025] 追忆 题解hello (bpm) 2025恭喜获得 最速被击破奖🏆不会 bitset,赛时想不到分块也是没救了。 首先必然要坚定 bitset 信念,因为其严格难于导出子图。 维护后继直接 bitset 就是 \(\frac{nm}w\) 的。 考虑到第二个限制 \(l, r\) 如…

给wordpress文章提供在线翻译和朗读的功能

之前有一个用wordpress搭的英文站点,我想给文章每个段落下面加两个“朗读”和“翻译”的按钮,方便英语不好的浏览者快速的了解中文意思和读法。 下面给出实现思路,全部是deepseek给出的代码实现的。 1、在(functions.php)文件末尾加上如下代码function enqueue_custom_scrip…

第五章 影响估算的因素

对软件项目产生影响的因素,可以有多种分类方式。了解这些影响因素有助于提高估算的准确度,并改善对软件项目动态特性的整体理解。 影响到项目工作量、成本和进度的最具决定性的因素毫无疑问是项目的规模。其次是正在开发的软件的类型,紧随其后的是人员因素。开发中使用的编程…

2025.3.25(周二)

4、航空服务查询问题:根据航线,仓位,飞行时间查询航空服务。 假设一个中国的航空公司规定:① 中国去欧美的航线所有座位都有食物供应,每个座位都可以播放电影。② 中国去非欧美的国外航线都有食物供应,只有商务仓可以播放电影。③ 中国国内的航班的商务仓有食物供应,但是…

2025.3.19(周三)

2、找零钱最佳组合假设商店货品价格(R) 都不大于100元(且为整数),若顾客付款(P)在100元内,现有一个程序能在每位顾客付款后给出找零钱的最佳组合(找给顾客货币张数最少)。假定此商店的货币面值只包括:50元(N50)、10元(N10)、 5元(N5)、1元(N1) 四种。请结合等价类划分法…

如何使用microSD卡模块与Arduino

MicroSD卡模块 ESP32有不同的microSD卡模块兼容。我们使用microSD卡模块,它使用SPI通信协议进行通信。您可以使用带有SPI接口的任何其他microSD卡模块。这个microSD卡模块也与Arduino板等其他微控制器兼容。学习如何使用microSD卡模块与Arduino。您可以使用默认SPI引脚将其连接…

VMware ESXi 8.0U3d macOS Unlocker OEM BIOS 集成 Marvell AQC 网卡驱动定制版 (集成驱动版)

VMware ESXi 8.0U3d macOS Unlocker & OEM BIOS 集成 Marvell AQC 网卡驱动定制版 (集成驱动版)VMware ESXi 8.0U3d macOS Unlocker & OEM BIOS 集成 Marvell AQC 网卡驱动定制版 (集成驱动版) VMware ESXi 8.0U3d macOS Unlocker & OEM BIOS 集成网卡驱动和 NVMe …

2025.3.10(周一)

实验二:UI设计 实验目的 本次实验的目的是让大家熟悉Android开发中的UI设计,包括了解和熟悉常用控件的使用、界面布局和事件处理等内容。 实验要求熟悉和掌握界面控件设计 了解Android界面布局 掌握控件的事件处理实验内容 一、 常用控件 1、 常用控件介绍 (1)基本控…

设计一个简单的圆柱形情绪灯

步骤1:打印零件和闪光WLED 3D打印外壳 下载提供的STL或STEP文件,并将它们加载到您首选的切片软件中。调整设置(填充,层高度,支撑),如果需要,打印每个部分。我使用白色PLA,填充15%,层高0.2mm。对于扩散器,它只是一个固体圆柱体,在花瓶模式下打印它。 一旦打印完成,把…

构建一个Pedro Robot

Pedro 2.0是一个完全开源的项目,旨在为每个人提供可访问和可定制的服务。Pedro Robot是一个完全开源的项目,设计为每个人都可以访问和定制。组装起来很容易,不需要螺丝,不需要胶水,不需要工具!完美的制造商,学生和教育工作者希望探索机器人和编程。 所有文档都可以在Pedr…