1.实体类,存放点数据
public class Point{/*** x轴坐标 经度*/double x;/*** y轴坐标 纬度*/double y;public Point setPoint(Point point){this.x = point.getX();this.y = point.getY();return this;}public Point() {}public Point(Float[] point){this.x = point[0];this.y = point[1];}public Point(Double[] point) {this.x = point[0];this.y = point[1];}public Point(double x, double y) {this.x = x;this.y = y;}public double getX() {return x;}public void setX(double x) {this.x = x;}public double getY() {return y;}public void setY(double y) {this.y = y;}}
2.枚举类,存放默认参数
public enum PointRelationEnum {POINT_IN_SCOPE(1,"在区域内"),POINT_OUT_SCOPE(2,"在区域外"),POINT_ON_BORDER(3,"在区域边界上");/*** 编码*/private int code;/*** 描述*/private String description;PointRelationEnum(int code,String description){this.code = code;this.description = description;}public int getCode() {return code;}public void setCode(int code) {this.code = code;}public String getDescription() {return description;}public void setDescription(String description) {this.description = description;}
}
3.工具类
public class testUtil{private static double earth_radius = 6378245.0;/**判断点与多边形的关系根据回转法**/public static PointRelationEnum poinWithPolygon(Point point, List<Point> points) {double px = point.getX(), py = point.getY(), sum = 0;for (int i = 0, l = points.size(), j = l - 1; i < l; j = i, i++) {double sx = points.get(i).getX(), sy = points.get(i).getY(), tx = points.get(j).getX(), ty = points.get(j).getY();// 点与多边形定点重合或多边形的边上if ((sx - px) * (px - tx) >= 0 && (sy - px) * (px - tx) >= 0&& (px - sx) * (ty - sy) == (py - sy) * (tx - sx)) {return PointRelationEnum.POINT_ON_BORDER;}// 点与相邻顶点连线的夹角double angle = Math.atan2(sy - py, sx - px)- Math.atan2(ty - py, tx - px);// 确保夹角不超出取值范围(-π 到 π)if (angle >= Math.PI) {angle = angle - Math.PI * 2;} else if (angle <= -Math.PI) {angle = angle + Math.PI * 2;}sum += angle;}// 计算回转数并判断点和多边形的几何关系return Math.round(sum / Math.PI) == 0 ? PointRelationEnum.POINT_OUT_SCOPE: PointRelationEnum.POINT_IN_SCOPE;}// 计算地球上两点的距离private static double getTwoPointsDistance(Point pointA, Point pointB) {double distance = 0.0;if (pointA != null && pointB != null) {double x1 = 0.0, y1 = 0.0, x2 = 0.0, y2 = 0.0, dx1 = 0.0, dy1 = 0.0, dx2 = 0.0, dy2 = 0.0, a = earth_radius;x1 = getLoop(pointA.getX(), -180, 180);y1 = getRange(pointA.getY(), -90, 90);x2 = getLoop(pointB.getX(), -180, 180);y2 = getRange(pointB.getY(), -90, 90);dx1 = degreeToRad(x1);dy1 = degreeToRad(y1);dx2 = degreeToRad(x2);dy2 = degreeToRad(y2);distance = a*Math.acos((Math.sin(dy1)*Math.sin(dy2) + Math.cos(dy1) * Math.cos(dy2) * Math.cos(dx2 - dx1)));}return distance;}/** 计算地球上一点与区域边界的最小距离 **/private static double getPointRangeDistance(Point point, List<Point> points) {double mindis = -1.0;if (point != null && points != null && points.size() > 0) {double a = 0.0;double b = 0.0;double c = 0.0;double dis = 0.0;for (int i = 0; i < points.size(); i++) {if (i < points.size() - 1) {a = get2PointsDistance(points.get(i), points.get(i + 1));b = get2PointsDistance(points.get(i), point);c = get2PointsDistance(points.get(i + 1), point);}else{a = get2PointsDistance(points.get(i), points.get(0));b = get2PointsDistance(points.get(i), point);c = get2PointsDistance(points.get(0), point);}dis = pointToLine(a, b, c);if (mindis < 0) {mindis = dis;} else if (dis < mindis) {mindis = dis;}}}return mindis;}/*** 计算地球上一点与一段道路的最小距离*/public static double getPointLineDistance(Point point, List<Point> points) {double mindis = -1.0;if (point != null && points != null && points.size() > 0) {double a = 0.0;double b = 0.0;double c = 0.0;double dis = 0.0;for (int i = 0; i < points.size()-1; i++) {a = get2PointsDistance(points.get(i), points.get(i + 1));b = get2PointsDistance(points.get(i), point);c = get2PointsDistance(points.get(i + 1), point);dis = pointToLine(a, b, c);if (mindis < 0) {mindis = dis;} else if (dis < mindis) {mindis = dis;}}}return mindis;}/*** 计算点到线的距离*/private static double pointToLine(double a, double b, double c) {double space = 0;if (c <= 0.000001 || b <= 0.000001) {space = 0;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;/** 海伦公式算面积 **/double s = Math.sqrt(p * (p - a) * (p - b) * (p - c));space = 2 * s / a;return space;}// 经度用private static double getLoop(double lng, double a, double b) {while (lng > b) {lng -= b - a;}while (lng < a) {lng += b - a;}return lng;}// 纬度用private static double getRange(double lat, double a, double b) {if (a != 0) {lat = Math.max(lat, a);}if (b != 0) {lat = Math.min(lat, b);}return lat;}// 将弧度转化为度private static double degreeToRad(double n) {return Math.PI * n / 180;}
}