空间几何运算方法

private static final Logger logger = LoggerFactory.getLogger(AnalyseKit.class);
/***************************************************************************
* 边界
*/
private static final double dis = 0.0000000001;
// 地图常量
public final static double _C_P = 0.017453292519943295;
// 地球经纬度, 偏差度
public final static double EARTH_RADIUS = 6371008.77141506;
// 单位经度
public static final long LONGITUDE_METER = 111413;
// 单位纬度
public static final long LATITUDE_METER = 111133;

/**
* 求亮点之间的距离
*
* @param str 坐标1
* @param str2 坐标2
* @return
*/
public static double getDistance(String str, String str2) {

PointBean point1 = new PointBean();
point1.setX(Double.parseDouble(str.split(",")[0]));
point1.setY(Double.parseDouble(str.split(",")[1]));

PointBean point2 = new PointBean();
point2.setX(Double.parseDouble(str2.split(",")[0]));
point2.setY(Double.parseDouble(str2.split(",")[1]));

double meter = getDistance(point1, point2);
return meter;
}

/**
* 计算点是否在圆内
*
* @param point 点坐标
* @param pointPolygon 面边框坐标
* @return
*/
public static boolean judgeMeetCircle(String point, String criclePoint, float r) {
PointBean point1 = new PointBean();
point1.setX(Double.parseDouble(point.split(",")[0]));
point1.setY(Double.parseDouble(point.split(",")[1]));

PointBean point2 = new PointBean();
point2.setX(Double.parseDouble(criclePoint.split(",")[0]));
point2.setY(Double.parseDouble(criclePoint.split(",")[1]));

double d = getDistance(point1, point2);
if (d <= r)
return true;
else
return false;

}

/**
* 判断是否在矩形内
*
* @param minPt
* @param maxPt
* @param pt
* @return
*/
public static boolean judgeInRect(PointBean minPt, PointBean maxPt, PointBean pt) {
if (pt.getX() >= minPt.getX() && pt.getX() <= maxPt.getX() && pt.getY() >= minPt.getY()
&& pt.getY() <= maxPt.getY()) {
return true;
} else {
return false;
}
}

/**
* 计算点是否在多边形内
*
* @param point 点坐标
* @param pointPolygon 面边框坐标
* @return
*/
public static boolean judgeMeetPolygon(String linestr, String pointPolygon) {
String string = pointPolygon;
int index = 0;
// 判断是否是飞地
if (string.indexOf(";") != -1) {
String[] points = string.split(";");
for (String point : points) {
if (AnalyseKit.judgeMeetPoint(linestr, point)) {
return true;
} else {
index++;
}
}
return (index == 0 || index > 1) ? false : true;
} else if (string.indexOf("|") != -1) {// 判断是否是有洞
String[] points = string.split("|");
for (String point : points) {
if (AnalyseKit.judgeMeetPoint(linestr, point))
index++;
}
return (index == 0 || index > 1) ? false : true;
} else {
return AnalyseKit.judgeMeetPoint(linestr, string);
}
}

// #################################私有方法#################################
private static boolean judgeMeetPoint(String point, String pointPolygon) {
PointBean point2 = new PointBean();
point2.setX(Double.parseDouble(point.split(",")[0]));
point2.setY(Double.parseDouble(point.split(",")[1]));
List<PointBean> list = AnalyseKit.evalPoints(pointPolygon);
if (list.size() == 2) {
return AnalyseKit.judgeInRect(list.get(0), list.get(1), point2);
} else {
return AnalyseKit.judgeMeetPoint(point2, list);
}
}

/**
* 转换坐标串
*
* @param points
* @return
*/
private static List<PointBean> evalPoints(String points) {
List<PointBean> list = new ArrayList<PointBean>();
String[] split = points.split(",");
for (int i = 1; i < split.length; i++) {
if (i % 2 == 1) {
PointBean point3 = new PointBean();
point3.setX(Double.parseDouble(split[i - 1]));
point3.setY(Double.parseDouble(split[i]));
list.add(point3);
}
}
return list;
}

/**
* 判断点是否在面内的算法
*
* @param tpt 点坐标
* @param polygonPtArray 面外边框坐标集合
* @return
*/
private static boolean judgeMeetPoint(PointBean tpt, List<PointBean> polygonPtArray) {
int MeetPointNum = 0;
for (int i = 1; i < polygonPtArray.size(); i++) {
PointBean pt1 = polygonPtArray.get(i - 1);
PointBean pt2 = polygonPtArray.get(i);
if (((tpt.getX() <= pt1.getX() && tpt.getX() >= pt2.getX())
|| (tpt.getX() >= pt1.getX() && tpt.getX() <= pt2.getX()))
& (tpt.getY() >= pt1.getY() || tpt.getY() >= pt2.getY())
& (pt1.getX() != pt2.getX() && pt1.getY() != pt2.getY())) {
// 判断点是否在线上
if (judgePtInLine(pt1, pt2, tpt)) {
return true;
}
// 处理特殊情况,交点是端点的情况
double temp;
// temp相当于被除数(斜率的分母)
temp = pt1.getX() - pt2.getX();
if (temp >= -dis && temp <= dis) {
// 处理交点情况
double dx = tpt.getX() - pt1.getX();
if (dx >= -dis && dx <= dis) {
int[] indexs = new int[2];
indexs[0] = 0;
indexs[1] = 0;
getNotSame(polygonPtArray, i, indexs);
PointBean linePt1, linePt2;
linePt1 = polygonPtArray.get(indexs[0]);
linePt2 = polygonPtArray.get(indexs[1]);
if (i > indexs[0]) {
break;
} else {
i = indexs[0] + 1;
}
if (tpt.getY() > pt1.getY() && ((tpt.getX() >= linePt1.getX() && tpt.getX() <= linePt2.getX())
|| (tpt.getX() >= linePt2.getX() && tpt.getX() <= linePt1.getX())))
MeetPointNum++;
}

} else {
double kk, bb;
double MeetPtY, MeetPtX;
kk = (pt1.getY() - pt2.getY()) / (pt1.getX() - pt2.getX());
bb = pt1.getY() - kk * pt1.getX();
MeetPtY = kk * tpt.getX() + bb;
MeetPtX = tpt.getX();
// 处理特殊情况,交点是端点的情况
double dx, dy, dx2, dy2;
dx = MeetPtX - pt1.getX();
dy = MeetPtY - pt1.getY();
dx2 = MeetPtX - pt2.getX();
dy2 = MeetPtY - pt2.getY();
if ((dx >= -dis && dx <= dis && dy >= -dis && dy <= dis)) {
PointBean pt3;
if (i == 1) {
pt3 = polygonPtArray.get(polygonPtArray.size() - 2);
} else {
pt3 = polygonPtArray.get(i - 2);
}
// 提取交点的上下两点分别在垂线的两侧
if (tpt.getY() > MeetPtY && ((MeetPtX >= pt3.getY() && MeetPtX <= pt2.getX())
|| (MeetPtX >= pt2.getX() && MeetPtX <= pt3.getX())))
MeetPointNum++;
} else if (!(dx2 >= -dis && dx2 <= dis && dy2 >= -dis && dy2 <= dis)) {
if (tpt.getY() > MeetPtY) {
MeetPointNum++;
}
}
}
}
}
if (MeetPointNum % 2 == 1)
return true;
else
return false;
}

/**
* 判断点是否在线上
*
* @param tpt1
* @param tpt2
* @param tpt
* @return
*/
private static boolean judgePtInLine(PointBean tpt1, PointBean tpt2, PointBean tpt) {
double dx1 = getDistance(tpt1, tpt2);
double dx2 = getDistance(tpt, tpt1);
double dx3 = getDistance(tpt, tpt2);
double dx = dx3 + dx2 - dx1;
if (dx >= -dis && dx <= dis) {
return true;
}
return false;
}

private static double getDistance(PointBean p1, PointBean p2) {
double k = 0.0;
double h = (p2.x - p1.x) * _C_P;
double g = (p2.y - p1.y) * _C_P;
double f = Math.sin(0.5 * g) * Math.sin(0.5 * g)
+ Math.cos(p1.y * _C_P) * Math.cos(p2.y * _C_P) * (Math.sin(0.5 * h) * Math.sin(0.5 * h));

f = Math.abs(f);

if (f > 1) {
logger.info("不合法数据:" + f + ",P1:" + p1.toString() + ",P2:" + p2.toString());
return -1;
}
double m = 2 * Math.atan2(Math.sqrt(f), Math.sqrt(1 - f));
k = m * EARTH_RADIUS;
if (Math.abs(p2.x - p1.x) > 180 || Math.abs(p2.y - p1.y) > 180) {
k = 2 * Math.PI * EARTH_RADIUS - k;
}
k = Math.ceil(k);

int meter = (int) k;

return meter;
}

/**
* 在链表中获取x轴不相同的点
*
* @param pointArray
* @param index
* @param indexs
*/
private static void getNotSame(List<PointBean> pointArray, int index, int[] indexs) {
indexs[0] = indexs[1] = -1;
int size = pointArray.size();
PointBean buftpt, tpt;
tpt = pointArray.get(index);
for (int i = index; i < size; i++) {
buftpt = pointArray.get(i);
if (buftpt.getX() != tpt.getX()) {
indexs[0] = i;
break;
}
}
if (indexs[0] == -1) {
for (int i = 0; i < size; i++) {
buftpt = (PointBean) pointArray.get(i);
if (buftpt.getX() != tpt.getX()) {
indexs[0] = i;
break;
}
}
}
for (int j = index; j >= 0; j--) {
buftpt = (PointBean) pointArray.get(j);
if (buftpt.getX() != tpt.getX()) {
indexs[1] = j;
break;
}
}
if (indexs[1] == -1) {
for (int j = size - 1; j >= 0; j--) {
buftpt = pointArray.get(j);
if (buftpt.getX() != tpt.getX()) {
indexs[1] = j;
break;
}
}
}
}

/**
* 计算指定处的距离(米)换算为距离(度) ---纬度方向上
*
* @param distance 单位m
* @return 纬度方向上
*/
public static double lenToLat(double distance) {
return distance / LATITUDE_METER;
}

/**
* 计算指定处的距离(米)换算为距离(度) ---经度方向上
*
* @param distnace 单位m
* @param r 指定点的纬度值
* @return
*/
public static double lenToLong(double distnace, double degree) {
double dLatRaian = degree * Math.PI / 180;
return distnace / (LONGITUDE_METER * Math.cos(dLatRaian));
}

关注公众号“大模型全栈程序员”回复“小程序”获取1000个小程序打包源码。更多免费资源在http://www.gitweixin.com/?p=2627

发表评论

邮箱地址不会被公开。 必填项已用*标注