JTS 笔记

JTS 笔记几何模型 Point 点 Coordinateco newCoordinat 102 8124 6068 Pointpoint newGeometryF createPoint coord 或 WKTReaderrea newWKTReader newGeometryF Pointpoint Point reader read POINT 102

简介

JTS官方文档    WKT 在线查看工具

Maven 依赖

<dependency> <groupId>com.vividsolutions 
     groupId> <artifactId>jts 
      artifactId> <version>1.13 
       version>  
        dependency> 

几何模型

Point 点

在这里插入图片描述

Coordinate coord = new Coordinate(102.81 24.6068); Point point = new GeometryFactory().createPoint( coord ); 

WKTReader reader = new WKTReader(new GeometryFactory()); Point point = (Point)reader.read("POINT(102.81 24.6068)"); 

MultiPoint 多点

在这里插入图片描述

WKTReader reader = new WKTReader(new GeometryFactory()); MultiPoint mpoint = (MultiPoint)reader.read("MULTIPOINT((102.81 24.6068),(102.28 24.918))"); 

LineString 线

在这里插入图片描述

Coordinate[] coords = new Coordinate[]{ 
   new Coordinate(102.801, 24.1004), new Coordinate(102.142, 24.65)}; LineString line = new GeometryFactory().createLineString(coords); 

WKTReader reader = new WKTReader(new GeometryFactory()); LineString line = (LineString)reader.read("LINESTRING(102.801 24.1004,102.142 24.65)"); 

MultiLineString 多线

在这里插入图片描述

GeometryFactory geometryFactory = new GeometryFactory(); Coordinate[] coords1 = new Coordinate[] { 
   new Coordinate(102.801, 24.1004), new Coordinate(102.142, 24.65)}; LineString line1 = geometryFactory.createLineString(coords1); Coordinate[] coords2 = new Coordinate[] { 
   new Coordinate(102.113, 24.8945), new Coordinate(102.477,24.4412)}; LineString line2 = geometryFactory.createLineString(coords2); LineString[] lineStrings = new LineString[2]; lineStrings[0]= line1; lineStrings[1] = line2; MultiLineString ms = geometryFactory.createMultiLineString(lineStrings); 

WKTReader reader = new WKTReader(new GeometryFactory()); MultiLineString line = (MultiLineString)reader.read("MULTILINESTRING((102.801 24.1004,102.142 24.65),(102.113 24.8945,102.477 24.4412))"); 

Polygon 面

在这里插入图片描述

WKTReader reader = new WKTReader(new GeometryFactory()); Polygon polygon = (Polygon)reader.read("POLYGON((102.801 24.541,102.008 24.988,102.941 24.202,102.583 24.1406,102.801 24.541))"); 

MultiPolygon 多面

在这里插入图片描述

WKTReader reader = new WKTReader(new 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)))"); 

GeometryCollection 几何集合

在这里插入图片描述

GeometryFactory geometryFactory = new GeometryFactory(); LineString line = (LineString)reader.read("LINESTRING(102.801 24.1004,102.142 24.65)"); Polygon polygon = (Polygon)reader.read("POLYGON((102.801 24.541,102.008 24.988,102.941 24.202,102.583 24.1406,102.801 24.541))"); Geometry g1 = geometryFactory.createGeometry(line); Geometry g2 = geometryFactory.createGeometry(polygon); GeometryCollection gc = geometryFactory.createGeometryCollection(new Geometry[]{ 
   g1,g2}); 

Circle 圆

在这里插入图片描述

 / * create a Circle 创建一个圆,圆心(x,y) 半径RADIUS * @param x * @param y * @param RADIUS * @return */ public Polygon createCircle(double x, double y, final double RADIUS){ 
    GeometryFactory geometryFactory = new GeometryFactory(); 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; } 

几何操作

拓扑有效性检查

WKTReader reader = new WKTReader(new GeometryFactory()); Polygon polygon = (Polygon)reader.read("POLYGON((102.801 24.541,102.008 24.988,102.941 24.202,102.583 24.1406,102.801 24.541))"); boolean valid = polygon.isValid(); System.out.println("valid: " + valid); 

面积计算

WKTReader reader = new WKTReader(new GeometryFactory()); Polygon polygon = (Polygon)reader.read("POLYGON((102.801 24.541,102.008 24.988,102.941 24.202,102.583 24.1406,102.801 24.541))"); double area = polygon.getArea(); 

长度/周长计算

WKTReader reader = new WKTReader(new GeometryFactory()); LineString line = (LineString)reader.read("LINESTRING(102.801 24.1004,102.142 24.65)"); double length = line.getLength(); 

WKTReader reader = new WKTReader(new GeometryFactory()); Polygon polygon = (Polygon)reader.read("POLYGON((102.801 24.541,102.008 24.988,102.941 24.202,102.583 24.1406,102.801 24.541))"); double length = polygon.getLength(); 

距离计算

在这里插入图片描述

几何之间的距离

WKTReader reader = new WKTReader(new GeometryFactory()); Polygon polygon1 = (Polygon)reader.read("POLYGON((102.91 24.5505,102.454 24.305,102.445 24.602,102.254 24.1066,102.91 24.5505))"); Polygon polygon2 = (Polygon)reader.read("POLYGON((102.166 24.388,102.922 24.8764,102.947 24.3165,102.618 24.3526,102.166 24.388))"); double distance = polygon1.distance(polygon2); // 0.0036727 

几何之间的距离是否在指定范围内

WKTReader reader = new WKTReader(new GeometryFactory()); Polygon polygon1 = (Polygon)reader.read("POLYGON((102.91 24.5505,102.454 24.305,102.445 24.602,102.254 24.1066,102.91 24.5505))"); Polygon polygon2 = (Polygon)reader.read("POLYGON((102.166 24.388,102.922 24.8764,102.947 24.3165,102.618 24.3526,102.166 24.388))"); double distance = polygon1.distance(polygon2); // 0.0036727 boolean withinDistance = polygon1.isWithinDistance(polygon2, 0.00395); // true 

空间关系

contains 包含

在这里插入图片描述

WKTReader reader = new WKTReader(new GeometryFactory()); Polygon polygon1 = (Polygon)reader.read("POLYGON((102.77 24.5475,102.147 24.2693,102.53 24.5475,102.796 25.00,102.77 24.5475))"); Polygon polygon2 = (Polygon)reader.read("POLYGON((102.637 24.6425,102.538 24.0398,102.034 24.0263,102.624 25.0000,102.637 24.6425))"); boolean contains = polygon1.contains(polygon2); // true 

within 内含

在这里插入图片描述

WKTReader reader = new WKTReader(new GeometryFactory()); Polygon polygon1 = (Polygon)reader.read("POLYGON((102.77 24.5475,102.147 24.2693,102.53 24.5475,102.796 25.00,102.77 24.5475))"); Polygon polygon2 = (Polygon)reader.read("POLYGON((102.637 24.6425,102.538 24.0398,102.034 24.0263,102.624 25.0000,102.637 24.6425))"); boolean within = polygon2.within(polygon1); // true 

covers 覆盖

在这里插入图片描述

WKTReader reader = new WKTReader(new GeometryFactory()); Polygon polygon1 = (Polygon)reader.read("POLYGON((102.77 24.5475,102.147 24.2693,102.53 24.5475,102.796 25.00,102.77 24.5475))"); Polygon polygon2 = (Polygon)reader.read("POLYGON((102.637 24.6425,102.538 24.0398,102.034 24.0263,102.624 25.0000,102.637 24.6425))"); boolean contains = polygon1.contains(polygon2); // true 

coveredBy 被掩盖

在这里插入图片描述

WKTReader reader = new WKTReader(new GeometryFactory()); Polygon polygon1 = (Polygon)reader.read("POLYGON((102.77 24.5475,102.147 24.2693,102.53 24.5475,102.796 25.00,102.77 24.5475))"); Polygon polygon2 = (Polygon)reader.read("POLYGON((102.637 24.6425,102.538 24.0398,102.034 24.0263,102.624 25.0000,102.637 24.6425))"); boolean coveredBy = polygon2.coveredBy(polygon1); // true 

intersects 相交

在这里插入图片描述

WKTReader reader = new WKTReader(new GeometryFactory()); Polygon polygon1 = (Polygon)reader.read("POLYGON((102.92 24.1584,102.484 24.45,102.96 24.126,102.617 24.4026,102.92 24.1584))"); Polygon polygon2 = (Polygon)reader.read("POLYGON((102.139 24.7893,102.92 24.7746,102.297 24.8765,102.635 24.9824,102.139 24.7893))"); boolean intersects = polygon1.intersects(polygon2); // true 

disjoint 脱节(不相交)

在这里插入图片描述

WKTReader reader = new WKTReader(new GeometryFactory()); Polygon polygon1 = (Polygon)reader.read("POLYGON((102.377 24.0962,102.909 24.702,102.722 24.4396,102.854 24.8236,102.377 24.0962))"); Polygon polygon2 = (Polygon)reader.read("POLYGON((102.212 25.000,102.721 24.0962,102.965 25.000,102.336 25.0096,102.212 25.000))"); boolean disjoint = polygon1.disjoint(polygon2); // true 

crosses 交叉

在这里插入图片描述

WKTReader reader = new WKTReader(new GeometryFactory()); LineString line1 = (LineString)reader.read("LINESTRING(102.496 24.3924,102.099 24.09)"); LineString line2 = (LineString)reader.read("LINESTRING(102.278 25.00000,102.774 24.6003)"); boolean crosses = line1.crosses(line2); // true 

overlaps 重叠

在这里插入图片描述

WKTReader reader = new WKTReader(new GeometryFactory()); Polygon polygon1 = (Polygon)reader.read("POLYGON((102.955 24.367,102.43 24.074,102.297 24.5815,102.67 24.325,102.955 24.367))"); Polygon polygon2 = (Polygon)reader.read("POLYGON((102.615 24.0365,102.264 24.288,102.621 24.1303,102.549 24.41,102.615 24.0365))"); boolean overlaps = polygon1.overlaps(polygon2); // true 

touches 接触

在这里插入图片描述

WKTReader reader = new WKTReader(new GeometryFactory()); Polygon polygon1 = (Polygon)reader.read("POLYGON((1 0,6 0,6 5,1 5,1 0))"); Polygon polygon2 = (Polygon)reader.read("POLYGON((6 0,6 1,7 1,7 0,6 0))"); boolean touches = polygon1.touches(polygon2); // true 

equals 等于

在这里插入图片描述

WKTReader reader = new WKTReader(new GeometryFactory()); Polygon polygon1 = (Polygon)reader.read("POLYGON((102.801 24.541,102.008 24.988,102.941 24.202,102.583 24.1406,102.801 24.541))"); boolean equals = polygon1.equals(polygon1); // true 

relate 关系

WKTReader reader = new WKTReader(new GeometryFactory()); Polygon polygon1 = (Polygon)reader.read("POLYGON((102.92 24.1584,102.484 24.45,102.96 24.126,102.617 24.4026,102.92 24.1584))"); Polygon polygon2 = (Polygon)reader.read("POLYGON((102.139 24.7893,102.92 24.7746,102.297 24.8765,102.635 24.9824,102.139 24.7893))"); boolean relate = polygon1.relate(polygon2, "T*T*T"); // true 

空间分析

intersection 交叉分析

在这里插入图片描述

WKTReader reader = new WKTReader(new GeometryFactory()); Polygon polygon1 = (Polygon)reader.read("POLYGON((102.566 24.0957,102.942 24.153,102.113 24.3284,102.466 24.6316,102.566 24.0957))"); Polygon polygon2 = (Polygon)reader.read("POLYGON((102.989 24.0463,102.924 24.706,102.876 24.6425,102.79 25.0000,102.989 24.0463))"); Geometry intersection = polygon1.intersection(polygon2); 

在这里插入图片描述

difference 差异分析

,
在这里插入图片描述

WKTReader reader = new WKTReader(new GeometryFactory()); Polygon polygon1 = (Polygon)reader.read("POLYGON((102.566 24.0957,102.942 24.153,102.113 24.3284,102.466 24.6316,102.566 24.0957))"); Polygon polygon2 = (Polygon)reader.read("POLYGON((102.989 24.0463,102.924 24.706,102.876 24.6425,102.79 25.0000,102.989 24.0463))"); Geometry difference = polygon1.difference(polygon2); 

在这里插入图片描述

union 联合分析

在这里插入图片描述

WKTReader reader = new WKTReader(new GeometryFactory()); Polygon polygon1 = (Polygon)reader.read("POLYGON((102.566 24.0957,102.942 24.153,102.113 24.3284,102.466 24.6316,102.566 24.0957))"); Polygon polygon2 = (Polygon)reader.read("POLYGON((102.989 24.0463,102.924 24.706,102.876 24.6425,102.79 25.0000,102.989 24.0463))"); Geometry union = polygon1.union(polygon2); 

在这里插入图片描述

symmetric difference 对称差异分析

在这里插入图片描述

WKTReader reader = new WKTReader(new GeometryFactory()); Polygon polygon1 = (Polygon)reader.read("POLYGON((102.566 24.0957,102.942 24.153,102.113 24.3284,102.466 24.6316,102.566 24.0957))"); Polygon polygon2 = (Polygon)reader.read("POLYGON((102.989 24.0463,102.924 24.706,102.876 24.6425,102.79 25.0000,102.989 24.0463))"); Geometry symDifference = polygon1.symDifference(polygon2); 

在这里插入图片描述

Buffer 缓冲区分析

在这里插入图片描述

WKTReader reader = new WKTReader(new GeometryFactory()); Polygon polygon1 = (Polygon)reader.read("POLYGON((102.566 24.0957,102.942 24.153,102.113 24.3284,102.466 24.6316,102.566 24.0957))"); Geometry buffer = polygon1.buffer(0.0005); 

在这里插入图片描述

Convex hull 凸包分析

在这里插入图片描述

WKTReader reader = new WKTReader(new GeometryFactory()); MultiPoint multiPoint = (MultiPoint)reader.read("MULTIPOINT((102.14 24.9005),(102.345 24.2628),(102.485 24.6872),(102.608 25.000),(102.284 25.009),(102.551 25.0000))"); Geometry convexHull = multiPoint.convexHull(); 

在这里插入图片描述

精度操作

精度模型

    精度模型是数值计算的核心,JTS适用于默认的双精度模型。当使用较大的值时,Java中内置的数学并不是非常精确,可以通过配置 GeometryFactoryPrecisionModel 使用不同的精度。
    通过显式捕获PrecisionModel JTS中的”round-off”过程,JTS允许管理这类错误,并对工作的速度和准确性进行适当的权衡。Round-off(例如 :6.0000001)经常发生即使是双精度模型。尤其是你的工作坐标系数字很大并且离着原点很远。这里面其实也是根据需要,如果你的使用精度要求不那么高那么可以减小精度模型。

精度操作(降低精度)

精度模型常量:

  • FIXED 固定精度表示坐标有固定的小数位数,小数点的位数由比例因子的对数10决定;
  • FLOATING 浮动精度对应于标准的Java双精度浮点表示,它是基于IEEE-754标准的;
  • FLOATING_SINGLE 浮动单精度对应于标准的Java单精度浮点表示,它是基于IEEE-754标准的。
PrecisionModel precisionModel = new PrecisionModel(PrecisionModel.FLOATING_SINGLE); WKTReader reader = new WKTReader(new GeometryFactory(precisionModel)); Polygon polygon1 = (Polygon)reader.read("POLYGON((102.566 24.0957,102.942 24.153,102.113 24.3284,102.466 24.6316,102.566 24.0957))"); Polygon polygon2 = (Polygon)reader.read("POLYGON((102.989 24.0463,102.924 24.706,102.876 24.6425,102.79 25.0000,102.989 24.0463))"); Geometry intersection = polygon1.intersection(polygon2); System.out.println(intersection.toText()); 

使用 precisionModel 前:

POLYGON ((102.54 24.9838, 102.275 24.302, 102.016 24.6877, 102.645 24.649, 102.54 24.9838)) 

使用 precisionModel 后:

POLYGON ((102. 24., 102. 24., 102. 24., 102. 24., 102. 24.)) 

几何结构

Delaunay三角剖分

GeometryFactory geometryFactory = new GeometryFactory(); WKTReader reader = new WKTReader(geometryFactory); MultiPoint multiPoint = (MultiPoint)reader.read("MULTIPOINT((102.264 24.376), (102.11 24.7196), (102.702 24.8882), (102.645 25.0004), (102.354 25.004))"); DelaunayTriangulationBuilder builder = new DelaunayTriangulationBuilder(); builder.setSites(multiPoint); // 实际为GeometryCollection(组成的geometry紧密相连) Geometry geometry = builder.getTriangles(geometryFactory); System.out.println(geometry.toText()); // 以0的距离进行缓冲(因为各多边形两两共边),生成一个多边形 // 此时则将点云构造成了多边形 Geometry buffer = geometry.buffer(0); System.out.println(buffer.toText()); 

在这里插入图片描述
在这里插入图片描述

限定Delaunay三角剖分

GeometryFactory geometryFactory = new GeometryFactory(); WKTReader reader = new WKTReader(geometryFactory); MultiPoint multiPoint = (MultiPoint)reader.read("MULTIPOINT((102.264 24.376), (102.11 24.7196), (102.702 24.8882), (102.645 25.0004), (102.354 25.004))"); ConformingDelaunayTriangulationBuilder builder = new ConformingDelaunayTriangulationBuilder(); builder.setSites(multiPoint); // 实际为GeometryCollection(组成的geometry紧密相连) Geometry geometry = builder.getTriangles(geometryFactory); System.out.println(geometry.toText()); // 以0的距离进行缓冲(因为各多边形两两共边),生成一个多边形 // 此时则将点云构造成了多边形 Geometry buffer = geometry.buffer(0); System.out.println(buffer.toText()); 

在这里插入图片描述
在这里插入图片描述

泰森多边形图

泰森多边形(Voronoi diagram),是由荷兰气候学家A•H•Thiessen提出了一种根据离散分布的气象站的降雨量来计算平均降雨量的方法,即将所有相邻气象站连成三角形,作这些三角形各边的垂直平分线,于是每个气象站周围的若干垂直平分线便围成一个多边形。用这个多边形内所包含的一个唯一气象站的降雨强度来表示这个多边形区域内的降雨强度,并称这个多边形为泰森多边形。

从几何角度来看,两基站的分界线是两点之间连线的铅直等分线,将全平面分为两个半平面,各半平面中任何一点与本半平面内基站的间隔都要比到另一基站间隔小。当基站数量在二个以上时,全平面会划分为多个包罗一个基站的区域,区域中任何一点都与本区域内基站间隔最近,是以这些个区域可以看作是基站的覆盖区域,我们将这种由多个点将平面划分成的图称为泰森多边形,又称为Voronoi 图。

泰森多边形的特性是:

  • 每个泰森多边形内仅含有一个基站;
  • 泰森多边形区域内的点到相应基站的距离最近;
  • 位于泰森多边形边上的点到其两边的基站的距离相等。
    在这里插入图片描述

GeometryFactory geometryFactory = new GeometryFactory(); WKTReader reader = new WKTReader(geometryFactory); MultiPoint multiPoint = (MultiPoint)reader.read("MULTIPOINT((102.264 24.376), (102.11 24.7196), (102.702 24.8882), (102.645 25.0004), (102.354 25.004))"); VoronoiDiagramBuilder builder = new VoronoiDiagramBuilder(); builder.setSites(multiPoint); Geometry geometry = builder.getDiagram(geometryFactory); System.out.println(geometry.toText()); Geometry buffer = geometry.buffer(0); System.out.println(buffer.toText()); 

在这里插入图片描述
在这里插入图片描述

最小可穿过圆的直径

最小直径

最小封闭矩形

在这里插入图片描述

GeometryFactory geometryFactory = new GeometryFactory(); WKTReader reader = new WKTReader(geometryFactory); Polygon multiPoint = (Polygon)reader.read("POLYGON((102.691 24.566,102.747 24.144,102.098 24.817,102.193 25.0004,102.259 25.0005,102.357 25.0085,102.742 25.0000,102.691 24.566))"); MinimumDiameter diameter = new MinimumDiameter(multiPoint); System.out.println(diameter.getLength()); Geometry geometry = diameter.getMinimumRectangle(); System.out.println(geometry.toText()); 

在这里插入图片描述

最小边界圆

在这里插入图片描述

GeometryFactory geometryFactory = new GeometryFactory(); WKTReader reader = new WKTReader(geometryFactory); Polygon multiPoint = (Polygon)reader.read("POLYGON((102.691 24.566,102.747 24.144,102.098 24.817,102.193 25.0004,102.259 25.0005,102.357 25.0085,102.742 25.0000,102.691 24.566))"); MinimumBoundingCircle diameter = new MinimumBoundingCircle(multiPoint); System.out.println(diameter.getRadius()); Geometry geometry = diameter.getCircle(); System.out.println(geometry.toText()); 

在这里插入图片描述

度量函数

距离

在这里插入图片描述

GeometryFactory geometryFactory = new GeometryFactory(); WKTReader reader = new WKTReader(geometryFactory); Polygon multiPoint1 = (Polygon)reader.read("POLYGON((102.283 24.3418,102.551 24.651,102.875 24.0217,102.458 24.5673,102.283 24.3418))"); Polygon multiPoint2 = (Polygon)reader.read("POLYGON((102.735 25.0026,102.907 25.000,102.979 25.000,102.106 25.008,102.735 25.0026))"); DistanceOp distance = new DistanceOp(multiPoint1, multiPoint2); System.out.println(distance.distance());// 0.0010254 

豪斯多夫距离

GeometryFactory geometryFactory = new GeometryFactory(); WKTReader reader = new WKTReader(geometryFactory); Polygon multiPoint1 = (Polygon)reader.read("POLYGON((102.283 24.3418,102.551 24.651,102.875 24.0217,102.458 24.5673,102.283 24.3418))"); Polygon multiPoint2 = (Polygon)reader.read("POLYGON((102.735 25.0026,102.907 25.000,102.979 25.000,102.106 25.008,102.735 25.0026))"); DiscreteHausdorffDistance distance = new DiscreteHausdorffDistance(multiPoint1, multiPoint2); System.out.println(distance.distance());// 0.00 

面积

在这里插入图片描述

GeometryFactory geometryFactory = new GeometryFactory(); WKTReader reader = new WKTReader(geometryFactory); Polygon multiPoint1 = (Polygon)reader.read("POLYGON((102.8 24.6086,102.153 24.369,102.833 24.7703,102.88 25.0005,102.8 24.6086))"); Polygon multiPoint2 = (Polygon)reader.read("POLYGON((102.608 24.013,102.448 24.996,102.462 24.8347,102.866 24.5036,102.608 24.013))"); SimilarityMeasure similarityMeasure = new AreaSimilarityMeasure(); System.out.println(similarityMeasure.measure(multiPoint1, multiPoint2));// 0.9302 

豪斯多夫测度

GeometryFactory geometryFactory = new GeometryFactory(); WKTReader reader = new WKTReader(geometryFactory); Polygon multiPoint1 = (Polygon)reader.read("POLYGON((102.283 24.3418,102.551 24.651,102.875 24.0217,102.458 24.5673,102.283 24.3418))"); Polygon multiPoint2 = (Polygon)reader.read("POLYGON((102.735 25.0026,102.907 25.000,102.979 25.000,102.106 25.008,102.735 25.0026))"); SimilarityMeasure similarityMeasure = new HausdorffSimilarityMeasure(); System.out.println(similarityMeasure.measure(multiPoint1, multiPoint2));// 0. 

空间算法

线段相交算法

在这里插入图片描述

Coordinate p1 = new Coordinate(102.857, 24.4806); Coordinate p2 = new Coordinate(102.998, 24.8198); Coordinate q1 = new Coordinate(102.707, 24.5674); Coordinate q2 = new Coordinate(102.661, 24.0333); RobustLineIntersector intersector = new RobustLineIntersector(); intersector.computeIntersection(p1, p2, q1, q2); System.out.println(intersector.isInteriorIntersection()); // true 

计算线段排列和线段序列结点

java doc

实现线绳编码的Snap Rounding算法

java doc

确定几何体中点的拓扑位置

java doc

数学函数

角度分析

在这里插入图片描述

Angle angle = new Angle(); Coordinate c1 = new Coordinate(102.857, 24.4806); Coordinate c2 = new Coordinate(102.707, 24.5674); Coordinate c3 = new Coordinate(102.661, 24.0333); // 返回两个无向最小差异角度,范围 [0, 180] double radia1 = angle.angle(c1, c2); double radia2 = angle.angle(c2, c3); System.out.println(angle.toDegrees(angle.diff(radia1, radia2))); // 111.487 // 返回两个向量之间的最小夹角,范围[0,180] double ang1 = angle.angleBetween(c1, c2, c3); System.out.println(angle.toDegrees(ang1)); //68.013 // 从angle到angle按什么方向旋转 // 顺时针: -1 // 逆时针: 1 System.out.println(angle.getTurn(radia1, radia2)); // 1 // 判断是否是锐角 System.out.println(angle.isAcute(c1, c2, c3)); // true // 判断是否是钝角 System.out.println(angle.isObtuse(c1, c2, c3)); // false // 角度 -> 弧度的转换 System.out.println(angle.toDegrees(Math.PI)); // 180.0 // 弧度 -> 角度的转换 System.out.println(angle.toRadians(180)); // 3.9793 

Spatial structures 空间结构

空间索引

四叉树

注意,它可能会返回事实上没有与查询矩形相交的项目。需要一个二级过滤器来测试查询矩形和每个候选项目的包络之间的实际相交。二级过滤器可以显式执行,也可以由项目的后续操作隐式提供(例如,如果索引查询之后计算了查询几何体和树形项目之间的空间谓词,则自动执行包络线交叉检查。

这个实现不需要事先指定插入的项目的范围。它将自动扩展以适应数据集的任何范围。

WKTReader reader = new WKTReader(new GeometryFactory()); Polygon polygon1 = (Polygon)reader.read("POLYGON((102.558 24.2443,102.857 24.092,102.486 24.8342,102.309 24.917,102.558 24.2443))"); Polygon polygon2 = (Polygon)reader.read("POLYGON((102.58 24.5337,102.332 24.046,102.264 24.8202,102.24 24.1305,102.58 24.5337))"); Polygon polygon3 = (Polygon)reader.read("POLYGON((102.478 24.5497,102.836 24.5005,102.343 24.082,102.984 24.1945,102.478 24.5497))"); Polygon polygon4 = (Polygon)reader.read("POLYGON((102.76 25.0003,102.27 24.0945,102.716 25.0003,102.178 25.0007,102.76 25.0003))"); Polygon polygon5 = (Polygon)reader.read("POLYGON((102.001 24.22,102.27 24.666,102.628 24.505,102.876 25.0005,102.001 24.22))"); Polygon polygon6 = (Polygon)reader.read("POLYGON((102.564 25.0008,102.145 24.1444,102.5 24.791,102.921 25.0002,102.564 25.0008))"); Polygon polygon7 = (Polygon)reader.read("POLYGON((102.094 24.3027,102.8 24.0905,102.742 24.7735,102.671 24.7533,102.094 24.3027))"); Quadtree quadtree = new Quadtree(); quadtree.insert(polygon1.getEnvelopeInternal(), polygon1); quadtree.insert(polygon2.getEnvelopeInternal(), polygon2); quadtree.insert(polygon3.getEnvelopeInternal(), polygon3); quadtree.insert(polygon4.getEnvelopeInternal(), polygon4); quadtree.insert(polygon5.getEnvelopeInternal(), polygon5); quadtree.insert(polygon6.getEnvelopeInternal(), polygon6); quadtree.insert(polygon7.getEnvelopeInternal(), polygon7); // 点 Point q1 = (Point)reader.read("POINT(102.668 24.7182)"); for (Object o : quadtree.query(q1.getEnvelopeInternal())) { 
    Polygon polygon = (Polygon) o; if (q1.intersects(polygon)) { 
    System.out.println(polygon.toText()); } } System.out.println("--- --- --- ---"); // 线 LineString q2 = (LineString)reader.read("LINESTRING(102.013 24.1945,102.951 24.1022)"); for (Object o : quadtree.query(q2.getEnvelopeInternal())) { 
    Polygon polygon = (Polygon) o; if (q2.intersects(polygon)) { 
    System.out.println(polygon.toText()); } } System.out.println("--- --- --- ---"); // 面 Polygon q3 = (Polygon)reader.read("POLYGON((102.013 24.6086,102.602 24.392,102.257 24.9715,102.185 24.689,102.013 24.6086))"); for (Object o : quadtree.query(q3.getEnvelopeInternal())) { 
    Polygon polygon = (Polygon) o; if (q3.intersects(polygon)) { 
    System.out.println(polygon.toText()); } } 

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述




STR树

请注意:

  • 向树中插入项目不是线程安全的。在一个以上的线程上进行的插入必须在外部进行同步。
  • 查询一棵树是线程安全的。

构建阶段是同步进行的,而查询是无状态的。

WKTReader reader = new WKTReader(new GeometryFactory()); Polygon polygon1 = (Polygon)reader.read("POLYGON((102.558 24.2443,102.857 24.092,102.486 24.8342,102.309 24.917,102.558 24.2443))"); Polygon polygon2 = (Polygon)reader.read("POLYGON((102.58 24.5337,102.332 24.046,102.264 24.8202,102.24 24.1305,102.58 24.5337))"); Polygon polygon3 = (Polygon)reader.read("POLYGON((102.478 24.5497,102.836 24.5005,102.343 24.082,102.984 24.1945,102.478 24.5497))"); Polygon polygon4 = (Polygon)reader.read("POLYGON((102.76 25.0003,102.27 24.0945,102.716 25.0003,102.178 25.0007,102.76 25.0003))"); Polygon polygon5 = (Polygon)reader.read("POLYGON((102.001 24.22,102.27 24.666,102.628 24.505,102.876 25.0005,102.001 24.22))"); Polygon polygon6 = (Polygon)reader.read("POLYGON((102.564 25.0008,102.145 24.1444,102.5 24.791,102.921 25.0002,102.564 25.0008))"); Polygon polygon7 = (Polygon)reader.read("POLYGON((102.094 24.3027,102.8 24.0905,102.742 24.7735,102.671 24.7533,102.094 24.3027))"); STRtree strTree = new STRtree(); strTree.insert(polygon1.getEnvelopeInternal(), polygon1); strTree.insert(polygon2.getEnvelopeInternal(), polygon2); strTree.insert(polygon3.getEnvelopeInternal(), polygon3); strTree.insert(polygon4.getEnvelopeInternal(), polygon4); strTree.insert(polygon5.getEnvelopeInternal(), polygon5); strTree.insert(polygon6.getEnvelopeInternal(), polygon6); strTree.insert(polygon7.getEnvelopeInternal(), polygon7); // 点 Point q1 = (Point)reader.read("POINT(102.668 24.7182)"); for (Object o : strTree.query(q1.getEnvelopeInternal())) { 
    Polygon polygon = (Polygon) o; if (q1.intersects(polygon)) { 
    System.out.println(polygon.toText()); } } System.out.println("--- --- --- ---"); // 线 LineString q2 = (LineString)reader.read("LINESTRING(102.013 24.1945,102.951 24.1022)"); for (Object o : strTree.query(q2.getEnvelopeInternal())) { 
    Polygon polygon = (Polygon) o; if (q2.intersects(polygon)) { 
    System.out.println(polygon.toText()); } } System.out.println("--- --- --- ---"); // 面 Polygon q3 = (Polygon)reader.read("POLYGON((102.013 24.6086,102.602 24.392,102.257 24.9715,102.185 24.689,102.013 24.6086))"); for (Object o : strTree.query(q3.getEnvelopeInternal())) { 
    Polygon polygon = (Polygon) o; if (q3.intersects(polygon)) { 
    System.out.println(polygon.toText()); } } 

压覆图形同上!

KD树

请注意,KD树的结构取决于插入点的顺序。如果插入的点是连贯的(例如,在一个或两个维度上是单调的),那么一棵树可能会变得不平衡。一个完全平衡的树的深度只有log2(N),但一个不平衡的树可能会更深。这对查询效率有严重影响。更糟糕的是,由于递归被用于查询树,一个极深的树可能会导致StackOverflowException。解决这个问题的方法之一是在插入前随机化点的顺序(例如,通过使用Fisher-Yates洗牌)。

KdTree kdTree = new KdTree(); kdTree.insert(new Coordinate(102.225, 24.1945)); kdTree.insert(new Coordinate(102.16, 24.5575)); kdTree.insert(new Coordinate(102.305, 24.672)); kdTree.insert(new Coordinate(102.3, 24.921)); kdTree.insert(new Coordinate(102.41, 24.9704)); kdTree.insert(new Coordinate(102.265, 24.7703)); kdTree.insert(new Coordinate(102.484, 24.569)); kdTree.insert(new Coordinate(102.549, 24.1373)); kdTree.insert(new Coordinate(102.874, 25.0005)); kdTree.insert(new Coordinate(102.775, 24.0945)); kdTree.insert(new Coordinate(102.919, 24.1843)); kdTree.insert(new Coordinate(102.854, 24.774)); GeometryFactory geometryFactory = new GeometryFactory(); WKTReader reader = new WKTReader(geometryFactory); // 点 无重叠 Point q1 = (Point)reader.read("POINT(102.668 24.7182)"); for (Object o : kdTree.query(q1.getEnvelopeInternal())) { 
    KdNode node = (KdNode)o; Point point = (Point)reader.read("POINT(" + node.getX() + " " + node.getY() + ")"); System.out.println(point.toText()); } System.out.println("--- --- --- ---"); // 线 LineString q2 = (LineString)reader.read("LINESTRING(102.013 24.1945,102.951 24.1022)"); for (Object o : kdTree.query(q2.getEnvelopeInternal())) { 
    KdNode node = (KdNode)o; Point point = (Point)reader.read("POINT(" + node.getX() + " " + node.getY() + ")"); System.out.println(point.toText()); } System.out.println("--- --- --- ---"); // 面 Polygon q3 = (Polygon)reader.read("POLYGON((102.013 24.6086,102.602 24.392,102.257 24.9715,102.185 24.689,102.013 24.6086))"); for (Object o : kdTree.query(q3.getEnvelopeInternal())) { 
    KdNode node = (KdNode)o; Point point = (Point)reader.read("POINT(" + node.getX() + " " + node.getY() + ")"); System.out.println(point.toText()); } 

在这里插入图片描述
在这里插入图片描述

Interval R树

包含用于实现一维区间的R树索引的包。

单调链

包含实现单调链的包。

可平面图

可平面图算法

在平面图上实现图算法的包。

输入/输出

WKT 导入 / 导出

GeometryFactory factory = new GeometryFactory(); // 导入 String wkt = "POLYGON((102.013 24.6086,102.602 24.392,102.257 24.9715,102.185 24.689,102.013 24.6086))"; WKTReader reader = new WKTReader(factory); Geometry geometry = reader.read(wkt); System.out.println(geometry); // 导出 WKTWriter writer = new WKTWriter(2); String wkt2 = writer.write(geometry); System.out.println(wkt2); 

WKB 导入 / 导出

GeometryFactory factory = new GeometryFactory(); // 导入 byte[] wkb = { 
   0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 5, 64, 89, -85, -123, -30, 0, 0, 0, 64, 56, -1, -41, 97, 38, -92, 108, 64, 89, -85, -93, 16, 0, 0, 0, 64, 56, -1, 50, -9, -109, 74, 36, 64, 89, -85, -74, 102, 0, 0, 0, 64, 56, -1, 99, 102, 36, -18, 112, 64, 89, -85, -106, -62, 0, 0, 0, 64, 56, -1, -7, -54, 124, -2, 20, 64, 89, -85, -123, -30, 0, 0, 0, 64, 56, -1, -41, 97, 38, -92, 108}; WKBReader reader = new WKBReader(factory); Geometry geometry = reader.read(wkb); System.out.println(geometry); // 导出 WKBWriter writer = new WKBWriter(2); byte[] bytes = writer.write(geometry); System.out.println(new String(bytes, StandardCharsets.UTF_8)); 

GML(V2) 导入 / 导出

GeometryFactory factory = new GeometryFactory(); // 导入 String gml = " 
    
     
      
      
        102.013,24.6086 102.602,24.392 102.257,24.9715 102.185,24.689 102.013,24.6086 
       
      
     
   "; GMLReader reader = new GMLReader(); Geometry geometry = reader.read(gml, factory); System.out.println(geometry); // 导出 GMLWriter writer = new GMLWriter(); String write = writer.write(geometry); System.out.println(write); 

高精度算法

2×2双精度行列式的鲁棒性评估

执行一种算法,以稳健地计算双精度值的2×2行列式的符号。

DoubleDouble扩展精度算术

实施扩展精度的浮点数,保持106位(约30位小数)的精度。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/215848.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月18日 下午1:01
下一篇 2026年3月18日 下午1:01


相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号