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));//在范圍內
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM