地圖演算法(一):判斷當前點是不是在該線上

劉國棟發表於2017-10-30

判斷當前點是不是在該線上,適用於線路計算

//地圖演算法(一):判斷當前點是不是在該線上
public class LineAreaJudgeV2 {
    //線區域判斷
    private List<Double[]> lineLs = new ArrayList();
    private double width = 0.0D;

    //根據點與寬度建立區域
    public LineAreaJudgeV2(String points, String width) {
        createArea(points);
        this.width = Double.parseDouble(width);
    }

    //建立區域
    public void createArea(String points) {
        String[] ps = points.split(";");
        double dx1 = 0.0D;
        double dy1 = 0.0D;
        double dx0 = 0.0D;
        double dy0 = 0.0D;
        for (int i = 1; i < ps.length; i++) {
            String[] cord1 = ps[i].split(",");
            dx1 = Double.parseDouble(cord1[0]);
            dy1 = Double.parseDouble(cord1[1]);

            String[] cord0 = ps[(i - 1)].split(",");
            dx0 = Double.parseDouble(cord0[0]);
            dy0 = Double.parseDouble(cord0[1]);

            Double[] line = new Double[4];
            line[0] = Double.valueOf(dx0);
            line[1] = Double.valueOf(dy0);
            line[2] = Double.valueOf(dx1);
            line[3] = Double.valueOf(dy1);

            this.lineLs.add(line);
        }
    }

    //判斷當前點是不是在該面積
    public boolean isInArea(String x, String y) {
        for (int i = 0; i < this.lineLs.size(); i++) {
            Double[] linePoints = (Double[]) this.lineLs.get(i);

            double r = minDistenceOfPoint2Line(linePoints[0].doubleValue(), linePoints[1].doubleValue(),
                    linePoints[2].doubleValue(), linePoints[3].doubleValue(), Double.parseDouble(x),
                    Double.parseDouble(y));
            if (r <= this.width) {
                return true;
            }
        }

        return false;
    }

    public boolean isInArea(float x, float y) {
        return isInArea(x, y);
    }

    //test
    public static void main(String[] args) {
        LineAreaJudgeV2 line = new LineAreaJudgeV2("118.126592,30.130026;118.126692,30.130126", "100");
        System.out.println(line.isInArea("118.126592", "30.130026"));
    }

    public static double minDistenceOfPoint2Line(double x1, double y1, double x2, double y2, double x0, double y0) {
        double space = 0.0D;

        double a = computeLength(x1, y1, x2, y2);
        double b = computeLength(x1, y1, x0, y0);
        double c = computeLength(x2, y2, x0, y0);

        if ((c <= 1.0E-006D) || (b <= 1.0E-006D)) {
            space = 0.0D;
            return space;
        }

        if (a <= 1.0E-006D) {
            space = b;
            return space;
        }

        if (c * c >= a * a + b * b) {
            space = b;
            return space;
        }

        if (b * b >= a * a + c * c) {
            space = c;
            return space;
        }

        double p = (a + b + c) / 2.0D;
        double s = Math.sqrt(p * (p - a) * (p - b) * (p - c));
        space = 2.0D * s / a;

        return space;
    }

    public static double computeLength(double dwStartX, double dwStartY, double dwEndX, double dwEndY) {
        double PI = 3.1415926535898D;

        double latRadians1 = dwStartY * (PI / 180.0D);
        double latRadians2 = dwEndY * (PI / 180.0D);
        double latRadians = latRadians1 - latRadians2;
        double lngRadians = dwStartX * (PI / 180.0D) - dwEndX * (PI / 180.0D);
        double f = 2.0D * Math.asin(Math.sqrt(Math.pow(Math.sin(latRadians / 2.0D), 2.0D)
                + Math.cos(latRadians1) * Math.cos(latRadians2) * Math.pow(Math.sin(lngRadians / 2.0D), 2.0D)));
        return f * 6378137.0D;
    }
}

相關文章