线段交叉类型判断
-
如图判断是T Y X 类型
操作思路
-
预处理数据集: 将所有LineString 打断,最终结果为 LineString 只有起点 终点2个点
-
获取所有线段的交点 ,并制作成如下格式
-
{ "交点座标":[相交线段] }
-
-
求相交线段的夹角
-
{ "交点座标":[夹角角度] }
-
-
自定义环节: 怎么样才算是一个XYT 目前已经计算出角度, 后续如何判断XYT 就因人而异了
三个角 ∠1,∠2,∠3 具体在什么范围内时Y 或者T 请根据个人需求进行操作
代码
package com.huifer.pointverify;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import org.geotools.geometry.jts.JTSFactoryFinder;
import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.geom.GeometryFactory;
import org.locationtech.jts.geom.LineString;
import org.locationtech.jts.geom.Point;
import org.locationtech.jts.io.ParseException;
import org.locationtech.jts.io.WKTReader;
/**
* <p>Title : RoadType </p>
* <p>Description : </p>
*
* @author huifer
* @date 2019-05-21
*/
public class RoadType {
private static GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory();
public static void main(String[] args) throws Exception {
List<LineString> lss = initData();
// 打散线段
List<LineString> lineStrings = splitLine(lss);
// 线段求交点
List<Point> points = intersectionPoint(lineStrings);
// 交点过滤 { 交点座标:连接线段list}
HashMap<Point, List<LineString>> pointListHashMap = pointFilter(points, lineStrings);
// 求相交线段的夹角
HashMap<Point, List<Double>> pointrota = getPointRota(pointListHashMap);
System.out.println("结果查看");
pointListHashMap.forEach(
(k, v) -> {
System.out.println(k + "\t" + v);
}
);
System.out.println("===================");
pointrota.forEach(
(k, v) ->
{
System.out.println(k + "\t" + v);
}
);
}
/**
* 计算交点 上的线段夹角
*
* @return {交点:[角度列表]}
*/
public static HashMap<Point, List<Double>> getPointRota(
HashMap<Point, List<LineString>> pointListHashMap) {
HashMap<Point, List<Double>> pointrota = new HashMap<>();
pointListHashMap.forEach(
(k, v) -> {
int size = v.size();
List<Double> rota = new ArrayList<>();
for (int i = 0; i < size; i++) {
if (i + 1 == size) {
{
double rotationBetweenLines = getRotationBetweenLines(
v.get(size - 1).getStartPoint().getX(),
v.get(size - 1).getStartPoint().getY(),
v.get(size - 1).getEndPoint().getX(),
v.get(size - 1).getEndPoint().getY(),
v.get(0).getStartPoint().getX(),
v.get(0).getStartPoint().getY(),
v.get(0).getEndPoint().getX(),
v.get(0).getEndPoint().getY()
);
rota.add(rotationBetweenLines);
}
} else {
{
double rotationBetweenLines = getRotationBetweenLines(
v.get(i).getStartPoint().getX(),
v.get(i).getStartPoint().getY(),
v.get(i).getEndPoint().getX(),
v.get(i).getEndPoint().getY(),
v.get(i + 1).getStartPoint().getX(),
v.get(i + 1).getStartPoint().getY(),
v.get(i + 1).getEndPoint().getX(),
v.get(i + 1).getEndPoint().getY()
);
rota.add(rotationBetweenLines);
}
}
}
pointrota.put(k, rota);
}
);
return pointrota;
}
/**
* 两条直线的角度
*
* @param a l1sx
* @param b l1sy
* @param c l1ex
* @param d l1ey
* @param e l2sx
* @param f l2sy
* @param g l2ex
* @param h l2ey
* @return 角度
*/
public static double getRotationBetweenLines(double a, double b, double c, double d,
double e, double f, double g, double h) {
double s = c * g - c * e - a * g + a * e + d * h - d * f - b * h + b * f;
double ls = Math.sqrt(Math.pow(c - a, 2) + Math.pow(d - b, 2)) * Math
.sqrt(Math.pow(g - e, 2) + Math.pow(h - f, 2));
double sa = s / ls;
return Math.toDegrees(Math.acos(sa));
}
/**
* @return {交点:[线段列表]}
*/
private static HashMap<Point, List<LineString>> pointFilter(List<Point> points,
List<LineString> lineStrings) {
HashMap<Point, List<LineString>> result = new HashMap<>();
for (Point point : points) {
// 当前点与那些线段相交
List<LineString> os = new ArrayList<>();
for (LineString lineString : lineStrings) {
boolean intersects = lineString.intersects(point.buffer(0.001));
if (intersects) {
os.add(lineString);
}
}
result.put(point, os);
}
return result;
}
/**
* 求交点
*/
private static List<Point> intersectionPoint(List<LineString> lss) {
HashSet<Point> pset = new HashSet<>();
List<LineString> ls = new ArrayList<>();
for (int i = 0; i < lss.size(); i++) {
for (int j = 0; j < lss.size(); j++) {
LineString lsi = lss.get(i);
LineString lsj = lss.get(j);
Geometry intersection = lsi.intersection(lsj);
if (intersection instanceof Point) {
pset.add(
geometryFactory.createPoint(
intersection.getCoordinate()
)
);
}
}
}
return new ArrayList<>(pset);
}
/**
* 初始化模拟数据
*/
public static List<LineString> initData() throws ParseException {
String[] strings = new String[]{
"LINESTRING ( 111.8199 28.9654,114.1484 31.9977 ,117.5706 27.9781, 123.1980 32.7692,126.2143 30.7989)",
"LINESTRING ( 117.5706 27.9781,115.7713 23.2886, 123.3574 20.3779)",
"LINESTRING ( 131.1701 26.2847,147.2933 30.0222)",
"LINESTRING ( 137.3795 34.6059,140.6958 23.4992)",
"LINESTRING ( 119.6647 43.7578,136.8110 45.1329)",
"LINESTRING ( 128.9082 35.5071,128.1916 44.4417)",
};
List<LineString> lss = new ArrayList<>();
for (String s : strings) {
LineString lineString = (LineString) new WKTReader().read(s);
lss.add(lineString);
}
return lss;
}
/**
* 将线段集合全部打散
*
* @param lss 线段集合
* @return 线段集合
*/
private static List<LineString> splitLine(List<LineString> lss) {
List<LineString> lineList = new ArrayList<>();
for (LineString lineString : lss) {
lineList.addAll(
splitLine(lineString)
);
}
return lineList;
}
/**
* 线段全部打散
*
* @param ls 单一线段
* @return 线段集合
*/
private static List<LineString> splitLine(LineString ls) {
Coordinate[] coordinates = ls.getCoordinates();
List<LineString> lineList = new ArrayList<>();
for (int i = 0; i < coordinates.length - 1; i++) {
LineString lineString = geometryFactory.createLineString(
new Coordinate[]{
coordinates[i], coordinates[i + 1]
}
);
lineList.add(lineString);
}
return lineList;
}
}
POINT (117.5706 27.9781) [LINESTRING (114.1484 31.9977, 117.5706 27.9781), LINESTRING (117.5706 27.9781, 123.198 32.7692), LINESTRING (117.5706 27.9781, 115.7713 23.2886)]
POINT (115.7713 23.2886) [LINESTRING (117.5706 27.9781, 115.7713 23.2886), LINESTRING (115.7713 23.2886, 123.3574 20.3779)]
POINT (139.30129149861725 28.169581923320553) [LINESTRING (131.1701 26.2847, 147.2933 30.0222), LINESTRING (137.3795 34.6059, 140.6958 23.4992)]
POINT (114.1484 31.9977) [LINESTRING (111.8199 28.9654, 114.1484 31.9977), LINESTRING (114.1484 31.9977, 117.5706 27.9781)]
POINT (128.19160471462752 44.44164121781868) [LINESTRING (119.6647 43.7578, 136.811 45.1329), LINESTRING (128.9082 35.5071, 128.1916 44.4417)]
POINT (123.198 32.7692) [LINESTRING (117.5706 27.9781, 123.198 32.7692), LINESTRING (123.198 32.7692, 126.2143 30.7989)]
===================
POINT (117.5706 27.9781) [90.000319080046, 151.40182612766463, 61.40150704761087]
POINT (115.7713 23.2886) [89.99991868685416, 89.99991868685416]
POINT (139.30129149861725 28.169581923320553) [86.42629217635765, 86.42629217635765]
POINT (114.1484 31.9977) [102.06902891552221, 102.06902891552221]
POINT (128.19160471462752 44.44164121781868) [90.00039767200474, 90.00039767200474]
POINT (123.198 32.7692) [73.56394232170145, 73.56394232170145]