如果我们需要用java进行一些空间关系的判断,例如:
java判断两个面是否相交;
java判断点是否在面内;
java计算线与面相交的部分;
java计算面与面相交的部分;
java计算多边形面积、周长、线段长度。
等等。。。
那么我们可以尝试使用下面的讨论来编写java代码:
1、引入maven依赖:
<dependency>
<groupId>org.wowtools</groupId>
<artifactId>giscat-vector-pojo</artifactId>
<version>g1.7.0</version>
</dependency>
2、在class中import需要的类
import org.wowtools.giscat.vector.pojo.converter.FoolStyleFeatureConverter;
import org.locationtech.jts.geom.*;
其中FoolStyleFeatureConverter类可以方便地构造出geometry对象,而geom.*中包含了点、线、面等geometry对象及其相应的空间计算方法。
3、编写代码
示例1 判断两个面是否相交并取其相交部分:
Polygon p1 = FoolStyleFeatureConverter.array2Polygon(new double[]{150, 330, 260, 380, 380, 240});
Polygon p2 = FoolStyleFeatureConverter.array2Polygon(new double[]{190, 260, 269, 325, 290, 160});
System.out.println("p1与p2是否相交 "+p1.intersects(p2));//true
System.out.println("p1与p2的交集 "+p1.intersection(p2));//POLYGON ((274.56738768718805 281.25623960066554, 234.76427923844062 296.83136899365365, 269 325, 274.56738768718805 281.25623960066554))
System.out.println("交集的面积 "+p1.intersection(p2).getArea());//827.2124277609248
System.out.println("交集的周长 "+p1.intersection(p2).getLength());//131.17314524175666
示例2 线与面的计算和判断
LineString l1 = FoolStyleFeatureConverter.array2Line(new double[]{190, 180, 170, 240, 250, 320, 323, 205});
Polygon p1 = FoolStyleFeatureConverter.array2Polygon(new double[]{150, 330, 260, 380, 380, 240});
System.out.println("线与多边形是否相交 " + l1.intersects(p1));//true
System.out.println("线与多边形的交集 "+l1.intersection(p1));//LINESTRING (229.0625 299.0625, 250 320, 274.60261569416497 281.2424547283702)
System.out.println("相交线段长度 "+l1.intersection(p1).getLength());//75.51691528550752
示例3 点与面的计算和判断
Point p = FoolStyleFeatureConverter.xy2Point(250, 310);
Polygon p1 = FoolStyleFeatureConverter.array2Polygon(new double[]{150, 330, 260, 380, 380, 240});
System.out.println("点与多边形是否相交 " + p.intersects(p1));//true
FoolStyleFeatureConverter除了支持传入数组构造geometry,也支持传入list或string来构造,例如:
//将list转为线,例如[[1,2],[3,4]]转为LINESTRING(1 2,3 4)
LineString line = FoolStyleFeatureConverter.array2Line(new double[]{1, 2, 3, 4});
//将string转为线,例如str2Line("10,2;15,3",",",";")转为LINESTRING(10 2,15 3)
LineString line = FoolStyleFeatureConverter.str2Line("1,2;3,4",",",";");
示例4 结合其它字段
实际应用中的数据,除了其坐标,往往还带有id、名称等其它属性,此时可以用Feature对象关联坐标和其它属性,方便地计算和关联。
以下代码演示了生成n个点的坐标、id、名称,判断这些点是否与输入的面相交,若相交则打印name。
//import org.wowtools.giscat.vector.pojo.Feature;
//随机生成n个点,每个点都有各自的id和name
int n = 100;
Random random = new Random(0);
List<Feature> features = new ArrayList<>();
for (int i = 0; i < n; i++) {
Point p = FoolStyleFeatureConverter.xy2Point(random.nextInt(500), random.nextInt(500));
//将geometry和属性构造成要素,以便后续查找
Feature feature = new Feature(p, Map.of("id", i, "name", "点" + i));
features.add(feature);
}
//判断这些点是否与输入的面相交,若相交则打印name
Polygon p1 = FoolStyleFeatureConverter.array2Polygon(new double[]{150, 330, 260, 380, 380, 240});
for (Feature feature : features) {
if (p1.intersects(feature.getGeometry())) {
System.out.println(feature.getProperties().get("name") + "与输入的面相交");
}
}
打印结果为:
点4与输入的面相交
点9与输入的面相交
点53与输入的面相交
点61与输入的面相交
-----------------
结语,利用FoolStyleFeatureConverter、geom.*类可以快速地解决java计算几何图形关系的问题。
如果需发布一些空间计算的服务,可以考虑使用giscat-server:
https://doc.giscat.top/giscat-server/quickstart/