線段交叉類型判斷

線段交叉類型判斷

  • 如圖判斷是T Y X 類型

    1558419778574

操作思路

  1. 預處理數據集: 將所有LineString 打斷,最終結果爲 LineString 只有起點 終點2個點

  2. 獲取所有線段的交點 ,並製作成如下格式

    1. {
      "交點座標":[相交線段]
      }
      
  3. 求相交線段的夾角

    1. {
      "交點座標":[夾角角度]
      }
      
  4. 自定義環節: 怎麼樣纔算是一個XYT 目前已經計算出角度, 後續如何判斷XYT 就因人而異了

    三個角 ∠1,∠2,∠3 具體在什麼範圍內時Y 或者T 請根據個人需求進行操作

    1558420457149

代碼

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]
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章