zoukankan      html  css  js  c++  java
  • java判断坐标是否在某一个区域内(圆形,多边形)

    import java.awt.geom.Point2D;
    import java.util.ArrayList;
    import java.util.List;
    
    public class regionUtil {
          private static double EARTH_RADIUS = 6378137;
        //private static double EARTH_SEA = 1.852;海里
    
        private static double rad(double d) {
            return d * Math.PI / 180.0;
        }
    
        /**
         * 判断是否在多边形区域内
         *
         * @param pointLon 要判断的点的横坐标 经度
         * @param pointLat 要判断的点的纵坐标 维度
         * @param lon      区域各顶点的横坐标数组
         * @param lat      区域各顶点的纵坐标数组
         * @return
         */
        public static boolean isInPolygon(double pointLon, double pointLat, Double[] lon,
                                          Double[] lat) {
            // 将要判断的横纵坐标组成一个点
            Point2D.Double point = new Point2D.Double(pointLon, pointLat);
            // 将区域各顶点的横纵坐标放到一个点集合里面
            List<Point2D.Double> pointList = new ArrayList<Point2D.Double>();
            double polygonPoint_x = 0.0, polygonPoint_y = 0.0;
            for (int i = 0; i < lon.length; i++) {
                polygonPoint_x = lon[i];
                polygonPoint_y = lat[i];
                Point2D.Double polygonPoint = new Point2D.Double(polygonPoint_x, polygonPoint_y);
                pointList.add(polygonPoint);
            }
            return check(point, pointList);
        }
    
        /**
         * @param point   要判断的点的横纵坐标
         * @param polygon 组成的顶点坐标集合
         * @return
         */
        private static boolean check(Point2D.Double point, List<Point2D.Double> polygon) {
            java.awt.geom.GeneralPath peneralPath = new java.awt.geom.GeneralPath();
    
            Point2D.Double first = polygon.get(0);
            // 通过移动到指定坐标(以双精度指定),将一个点添加到路径中
            peneralPath.moveTo(first.x, first.y);
            polygon.remove(0);
            for (Point2D.Double d : polygon) {
                // 通过绘制一条从当前坐标到新指定坐标(以双精度指定)的直线,将一个点添加到路径中。
                peneralPath.lineTo(d.x, d.y);
            }
            // 将几何多边形封闭
            peneralPath.lineTo(first.x, first.y);
            peneralPath.closePath();
            // 测试指定的 Point2D 是否在 Shape 的边界内。
            return peneralPath.contains(point);
        }
    
        /**
         * 通过经纬度获取距离(单位:米)
         *
         * @param lat1 纬度1
         * @param lng1 经度1
         * @param lat2 纬度2
         * @param lng2 经度2
         * @return 距离
         */
        public static double getDistance(double lat1, double lng1, double lat2,
                                         double lng2) {
            double radLat1 = rad(lat1);
            double radLat2 = rad(lat2);
            double a = radLat1 - radLat2;
            double b = rad(lng1) - rad(lng2);
            double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) +
                    Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(b / 2), 2)));
            s = s * EARTH_RADIUS;
            s = Math.round(s * 10000d) / 10000d;
            //double len=s/EARTH_SEA;
            //s = s / 1000;
            return s;
        }
    
        /**
         * @param lat1   纬度
         * @param lat2   纬度
         * @param lng1   经度
         * @param lng2   经度
         * @param radius 判断一个点是否在圆形区域内,比较坐标点与圆心的距离是否小于半径
         */
        public static boolean isInCircle(double lng1, double lat1, double lng2, double lat2, double radius) {
            double distance = getDistance(lat1, lng1, lat2, lng2);
            if (distance > radius) {
                return false;
            } else {
                //System.err.println("经度:"+lng1+"维度:"+lat1+"经度:"+lng2+"维度:"+lat2+"距离:"+distance);
                return true;
            }
        }
    
    }
    package util;
    
    import java.awt.Point;
    import java.awt.geom.Point2D;
    import java.util.ArrayList;
    import java.util.List;
    
    import com.alibaba.fastjson.JSONArray;
    
    /**
     * 判断坐标点位置状态
     */
    public class GisPointUtil {
        
        private static double EARTH_RADIUS = 6378137d;
         
        private static double rad(double d) {
            return d * Math.PI / 180.0;
        }
     
        /**
         * 通过经纬度获取距离(单位:米)
         *
         * @param lat1
         * @param lng1
         * @param lat2
         * @param lng2
         * @return
         */
        public static double getDistance(double lat1, double lng1, double lat2,
                                         double lng2) {
            double radLat1 = rad(lat1);
            double radLat2 = rad(lat2);
            double a = radLat1 - radLat2;
            double b = rad(lng1) - rad(lng2);
            double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) +
                    Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(b / 2), 2)));
            s = s * EARTH_RADIUS;
            s = Math.round(s * 10000d) / 10000d;
            return s;
        }
     
        /**
        * 判断一个点是否在圆形区域内
        * @param radius 半径
        * @param lat1  圆心纬度
        * @param lng1  圆心经度
        * @param lat2  坐标纬度
        * @param lng2  坐标经度
        */
        public static boolean isInCircle(double lng1, double lat1, double lng2, double lat2, String radius) {
            return getDistance(lat1, lng1, lat2, lng2) > Double.parseDouble(radius);
        }
        
        /**
         * 判断是否在多边形区域内
         * 
         * @param pointLon
         *            要判断的点的纵坐标
         * @param pointLat
         *            要判断的点的横坐标
         * @param lon
         *            区域各顶点的纵坐标数组
         * @param lat
         *            区域各顶点的横坐标数组
         * @return
         */
        public static boolean isInPolygon(double pointLon, double pointLat, JSONArray points) {
            // 将要判断的横纵坐标组成一个点
            Point2D.Double point = new Point.Double(pointLon, pointLat);
            // 将区域各顶点的横纵坐标放到一个点集合里面
            List<Point2D.Double> pointList = new ArrayList<Point2D.Double>();
            double polygonPoint_x = 0.0, polygonPoint_y = 0.0;
            int len = points.size();
            for (int i = 0; i < len; i++) {
                polygonPoint_x = points.getJSONObject(i).getDouble("x");
                polygonPoint_y = points.getJSONObject(i).getDouble("y");
                Point2D.Double polygonPoint = new Point2D.Double(polygonPoint_x, polygonPoint_y);
                pointList.add(polygonPoint);
            }
            return check(point, pointList);
        }
     
        /**
         * 一个点是否在多边形内
         * 
         * @param point
         *            要判断的点的横纵坐标
         * @param polygon
         *            组成的顶点坐标集合
         * @return
         */
        private static boolean check(Point2D.Double point, List<Point2D.Double> polygon) {
            java.awt.geom.GeneralPath peneralPath = new java.awt.geom.GeneralPath();
     
            Point2D.Double first = polygon.get(0);
            // 通过移动到指定坐标(以双精度指定),将一个点添加到路径中
            peneralPath.moveTo(first.x, first.y);
            polygon.remove(0);
            for (Point2D.Double d : polygon) {
                // 通过绘制一条从当前坐标到新指定坐标(以双精度指定)的直线,将一个点添加到路径中。
                peneralPath.lineTo(d.x, d.y);
            }
            // 将几何多边形封闭
            peneralPath.lineTo(first.x, first.y);
            peneralPath.closePath();
            // 测试指定的 Point2D 是否在 Shape 的边界内。
            return peneralPath.contains(point);
        }
        
        public static void main(String[] args) {
            String points = "[{"sets":[{"name":"sswg","value":"402881f6681232c00168129b896e0078"}],"where":[{"name":"id","value":3231735,"type":"="}]},{"sets":[{"name":"sswg","value":"000000006817dd6f0168313b9b89049a"}],"where":[{"name":"id","value":3231735,"type":"="}]}]";
            JSONArray pointArray = (JSONArray)JSONArray.parse(points);
            System.out.println(isInPolygon(120.636514,31.341752, pointArray));
    //        String points = "[{"x":120.61123416,"y":31.32889074,"z":137.05},{"x":120.61312695,"y":31.31892631,"z":128.61},{"x":120.61455616,"y":31.30808702,"z":43.66},{"x":120.62127327,"y":31.30899876,"z":62.21},{"x":120.63003506,"y":31.31057071,"z":29.43},{"x":120.63726235,"y":31.31203339,"z":92.90},{"x":120.64536616,"y":31.31334188,"z":78.36},{"x":120.64402082,"y":31.31947999,"z":13.19},{"x":120.64136126,"y":31.32757908,"z":87.36},{"x":120.63689776,"y":31.33287239,"z":60.62},{"x":120.63502091,"y":31.33742080,"z":114.21},{"x":120.63071787,"y":31.33793104,"z":32.99},{"x":120.62952446,"y":31.34483170,"z":164.79},{"x":120.62710968,"y":31.34801804,"z":164.15},{"x":120.62731359,"y":31.34823458,"z":189.53},{"x":120.62700980,"y":31.34894193,"z":194.24},{"x":120.62700980,"y":31.34894193,"z":194.24},{"x":120.62700980,"y":31.34894193,"z":194.24},{"x":120.62665860,"y":31.34861797,"z":155.41},{"x":120.61706620,"y":31.34846463,"z":200.05},{"x":120.61854348,"y":31.34267516,"z":138.68},{"x":120.62111689,"y":31.33313042,"z":154.61}]";
    //        JSONArray pointArray = (JSONArray)JSONArray.parse(points);
    //        System.out.println(isInPolygon(120.66615036,31.33525453, pointArray));//不在范围内
    //        System.out.println(isInPolygon(120.62171413,31.32044689, pointArray));//在范围内
        }
    }
  • 相关阅读:
    layui 3种导航栏
    SQL语句内做除法得出百分比
    JS 日期比较方法
    JDK 13 的 12 个新特性,真心涨姿势了
    怎么实现单点登录?面试必问!
    厉害了,Apache架构师们遵循的 30 条设计原则
    面试官问线程安全的List,看完再也不怕了!
    Java 类在 Tomcat 中是如何加载的?
    Redis 21问,你接得住不?
    String hashCode 这个数字,很多人不知道!
  • 原文地址:https://www.cnblogs.com/xiejn/p/13963875.html
Copyright © 2011-2022 走看看