線段交叉類型判斷
-
如圖判斷是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]