Administrator
2023-08-22 e8a4f9014fbea4159ea15642226c6793d57d13ee
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
package com.ruoyi.utils.tools;
 
import org.gavaghan.geodesy.Ellipsoid;
import org.gavaghan.geodesy.GeodeticCalculator;
import org.gavaghan.geodesy.GlobalCoordinates;
 
import java.awt.geom.Point2D;
import java.util.ArrayList;
import java.util.List;
 
/**
 * @Description:
 * @ClassName: GisTool
 * @Author: 刘苏义
 * @Date: 2023年06月15日13:26
 * @Version: 1.0
 **/
public class GisTool {
    public static GeodeticCalculator geodeticCalculator = new GeodeticCalculator();
    /**
     * 根据经纬度,计算两点间的距离
     *
     * @param From 第一个点的经纬度
     * @param To  第二个点的经纬度
     * @return 返回距离 单位米
     */
    public static double getDistance(double[] From, double[] To) {
        double longitudeFrom = From[0];
        double latitudeFrom = From[1];
        double longitudeTo = To[0];
        double latitudeTo = To[1];
        GlobalCoordinates source = new GlobalCoordinates(latitudeFrom, longitudeFrom);
        GlobalCoordinates target = new GlobalCoordinates(latitudeTo, longitudeTo);
        return geodeticCalculator.calculateGeodeticCurve(Ellipsoid.WGS84, source, target).getEllipsoidalDistance();
    }
 
    public static void main(String[] args) {
//        // 被检测的经纬度点
//        Point point= new Point(126.649261,45.687377);
//        // 商业区域(百度多边形区域经纬度集合)
//        List<Point> partitionLocation = new ArrayList<>();
//        partitionLocation.add(new Point(126.64459,45.688548));
//        partitionLocation.add(new Point(126.653376,45.68938));
//        partitionLocation.add(new Point(126.645776,45.685048));
//        partitionLocation.add(new Point(126.654184,45.685778));
//        System.out.println(isInPolygon(point,partitionLocation));
    }
 
    /**
     * 判断当前位置是否在多边形区域内
     * @param orderLocation 当前点
     * @param partitionLocation 区域顶点
     * @return
     */
    public static boolean isInPolygon(Point orderLocation,List<Point> partitionLocation){
 
        double p_x =orderLocation.getLongitude();
        double p_y =orderLocation.getLatitude();
        Point2D.Double point = new Point2D.Double(p_x, p_y);
 
        List<Point2D.Double> pointList= new ArrayList<Point2D.Double>();
 
        for (Point points : partitionLocation){
            double polygonPoint_x=points.getLongitude();
            double polygonPoint_y=points.getLatitude();
            Point2D.Double polygonPoint = new Point2D.Double(polygonPoint_x,polygonPoint_y);
            pointList.add(polygonPoint);
        }
        return IsPtInPoly(point,pointList);
    }
    /**
     * 判断点是否在多边形内,如果点位于多边形的顶点或边上,也算做点在多边形内,直接返回true
     * @param point 检测点
     * @param pts   多边形的顶点
     * @return      点在多边形内返回true,否则返回false
     */
    public static boolean IsPtInPoly(Point2D.Double point, List<Point2D.Double> pts){
 
        int N = pts.size();
        boolean boundOrVertex = true; //如果点位于多边形的顶点或边上,也算做点在多边形内,直接返回true
        int intersectCount = 0;//cross points count of x
        double precision = 2e-10; //浮点类型计算时候与0比较时候的容差
        Point2D.Double p1, p2;//neighbour bound vertices
        Point2D.Double p = point; //当前点
 
        p1 = pts.get(0);//left vertex
        for(int i = 1; i <= N; ++i){//check all rays
            if(p.equals(p1)){
                return boundOrVertex;//p is an vertex
            }
 
            p2 = pts.get(i % N);
            if(p.x < Math.min(p1.x, p2.x) || p.x > Math.max(p1.x, p2.x)){
                p1 = p2;
                continue;
            }
 
            if(p.x > Math.min(p1.x, p2.x) && p.x < Math.max(p1.x, p2.x)){
                if(p.y <= Math.max(p1.y, p2.y)){
                    if(p1.x == p2.x && p.y >= Math.min(p1.y, p2.y)){
                        return boundOrVertex;
                    }
 
                    if(p1.y == p2.y){
                        if(p1.y == p.y){
                            return boundOrVertex;
                        }else{//before ray
                            ++intersectCount;
                        }
                    }else{
                        double xinters = (p.x - p1.x) * (p2.y - p1.y) / (p2.x - p1.x) + p1.y;
                        if(Math.abs(p.y - xinters) < precision){
                            return boundOrVertex;
                        }
 
                        if(p.y < xinters){
                            ++intersectCount;
                        }
                    }
                }
            }else{
                if(p.x == p2.x && p.y <= p2.y){
                    Point2D.Double p3 = pts.get((i+1) % N);
                    if(p.x >= Math.min(p1.x, p3.x) && p.x <= Math.max(p1.x, p3.x)){
                        ++intersectCount;
                    }else{
                        intersectCount += 2;
                    }
                }
            }
            p1 = p2;
        }
 
        if(intersectCount % 2 == 0){//偶数在多边形外
            return false;
        } else { //奇数在多边形内
            return true;
        }
    }
 
}