判断点是否在范围内
public static boolean isPtInPoly (double ALon , double ALat ,String area) {
String[] location = area.trim().split(";");
PointInfo[] ps = new PointInfo[location.length];
for (int i = 0; i < location.length; i++) {
PointInfo aPoints = new PointInfo();
String[] alocation = location[i].split(",");
aPoints.setX(new BigDecimal(alocation[0]).doubleValue());
aPoints.setY(new BigDecimal(alocation[1]).doubleValue());
ps[i] = aPoints;
}
int iSum, iCount, iIndex;
double dLon1 = 0, dLon2 = 0, dLat1 = 0, dLat2 = 0, dLon;
if (ps.length < 3) {
return false;
}
iSum = 0;
iCount = ps.length;
for (iIndex = 0; iIndex<iCount;iIndex++) {
if (iIndex == iCount - 1) {
dLon1 = ps[iIndex].getX();
dLat1 = ps[iIndex].getY();
dLon2 = ps[0].getX();
dLat2 = ps[0].getY();
} else {
dLon1 = ps[iIndex].getX();
dLat1 = ps[iIndex].getY();
dLon2 = ps[iIndex + 1].getX();
dLat2 = ps[iIndex + 1].getY();
}
// 以下语句判断A点是否在边的两端点的水平平行线之间,在则可能有交点,开始判断交点是否在左射线上
if (((ALat >= dLat1) && (ALat < dLat2)) || ((ALat >= dLat2) && (ALat < dLat1))) {
if (Math.abs(dLat1 - dLat2) > 0) {
//得到 A点向左射线与边的交点的x坐标:
dLon = dLon1 - ((dLon1 - dLon2) * (dLat1 - ALat) ) / (dLat1 - dLat2);
// 如果交点在A点左侧(说明是做射线与 边的交点),则射线与边的全部交点数加一:
if (dLon < ALon) {
iSum++;
}
}
}
}
if ((iSum % 2) != 0) {
return true;
}
return false;
}
判断点距离最近范围边距离
public static double getDistance(double ALon,double ALat,String area){
String[] location = area.trim().split(";");
PointInfo[] ps = new PointInfo[location.length];
//注意 最后一个点会和第一个点相同,所以不再进行比较 这里用length-1
for (int i = 0; i < location.length-1; i++) {
PointInfo aPoints = new PointInfo();
String[] alocation = location[i].split(",");
aPoints.setX(new BigDecimal(alocation[0]).doubleValue());
aPoints.setY(new BigDecimal(alocation[1]).doubleValue());
ps[i] = aPoints;
System.out.println("围栏第"+(i+1)+"个点的坐标为{经度X="+ps[i].getX()+",纬度Y="+ps[i].getY());
}
PointInfo localPoint = new PointInfo(ALon,ALat);
System.out.println("锁的当前坐标为 经度X="+localPoint.getX()+",纬度Y="+localPoint.getY());
/**
* . sqrt((x-x)^2 +(y-y)^2)
* 计算围栏哪个点 到 车锁位置最短
*/
PointInfo minPoint;
int index=-1;
double min= Double.MAX_VALUE;
double x2=ALon;
double y2=ALat;
//找到距离最近的点
for(int i=0;i<ps.length-1;i++){
Double x = ps[i].getX();
Double y=ps[i].getY();
double sqrt =get2PointDis(localPoint,ps[i]);
if(sqrt<=min){
min=sqrt;
index=i;
}
System.out.println("锁坐标正在与第"+(i+1)+"个点进行比较距离,距离为:"+sqrt);
}
System.out.println("我们得到最短的距离为:"+min);
//获取距离最近的点
if(index!=-1){
minPoint=ps[index];
System.out.println("该点为 第"+(index+1)+"个点,他的经度X="+minPoint.getX()+",纬度Y="+minPoint.getY());
//找到连接该点的 前后两个点
PointInfo beforePoint;
PointInfo afterPoint;
if(index==ps.length-1){
afterPoint=ps[0];
}else{
afterPoint=ps[index+1];
}
if (index==0) {
beforePoint=ps[ps.length-1];
}else{
beforePoint=ps[index-1];
}
System.out.println("我们已经找到最近点相连的前一个点,第"+(index)+"个他的坐标经度X="+beforePoint.getX()+",纬度Y="+beforePoint.getY());
System.out.println("我们已经找到最近点相连的后一个点,第"+(index+2)+"个他的坐标经度X="+afterPoint.getX()+",纬度Y="+afterPoint.getY());
/**
* 计算 锁点 到 距离最短点和其前后两点组成的线段 的距离哪个最短
*/
// 锁点1 最近点2 与最近点相连的前一点3
double a1;// 1 -2 的边长
double b1;// 2-3 的边长
double c1;// 3-1 的边长
// 海伦公式 得到三点围城三角形的面积
a1=get2PointDis(localPoint,minPoint);
b1=get2PointDis(minPoint,beforePoint);
c1=get2PointDis(beforePoint,localPoint);
System.out.println("通过计算,我们得到第一组三角形他们各边的边长是 { a="+a1+"b="+b1+"c="+c1+"}");
//****重点 判断三角形是否为锐角三角形
boolean acuteAngle1 = isAcuteAngle(a1, b1, c1);
double h1=a1;//距离 如果是锐角三角形 则高为最短距离,如果是钝角三角形,则最短距离是锁到最近点
if(acuteAngle1) {
double p1 = (a1 + b1 + c1) / 2;
System.out.println("我们得到他的边长为:" + (a1 + b1 + c1) + ",他的海伦公式中p=" + p1);
double S1 = Math.sqrt(p1 * (p1 - a1) * (p1 - b1) * (p1 - c1));
System.out.println("我们通过海伦公式得到他的面积为:" + S1);
//求高 也就是距离
h1 = (2 * S1) / b1;
System.out.println("该三角形是锐角三角形 以 除锁点其余两点 组成的边长为底 高为:" + h1);
}else{
System.out.println("该三角形是钝角三角形 以 除锁点其余两点 组成的边长为底 高为:" + h1);
}
// 锁点1 最近点2 与最近点相连的后一点3
double a2;// 1 -2 的边长
double b2;// 2-3 的边长
double c2;// 3-1 的边长
// 海伦公式 得到三点围城三角形的面积
a2=get2PointDis(localPoint,minPoint);
b2=get2PointDis(minPoint,afterPoint);
c2=get2PointDis(afterPoint,localPoint);
double h2=a2;
boolean acuteAngel2= isAcuteAngle(a2,b2,c2);
if(acuteAngel2){
System.out.println("通过计算,我们得到第二组三角形他们各边的边长是 { a="+a2+"b="+b2+"c="+c2+"}");
double p2=(a2+b1+c1)/2;
System.out.println("我们得到他的边长为:"+(a1+b1+c1)+",他的海伦公式中p="+p2);
double S2=Math.sqrt(p2*(p2-a2)*(p2-b2)*(p2-c2));
System.out.println("我们通过海伦公式得到他的面积为:"+S2);
//求高 也就是距离
h2=(2*S2)/b1;
System.out.println("该三角形是锐角三角形 以 除锁点其余两点 组成的边长为底 高为:"+h2);
}else{
System.out.println("该三角形是钝角三角形 以 除锁点其余两点 组成的边长为底 高为:" + h2);
}
if((acuteAngle1&´Angel2) || (!acuteAngle1&&!acuteAngel2)){
System.out.println("两个三角形同为锐角,或者同为钝角");
return h1<h2?h1:h2;
}else if(acuteAngle1 && !acuteAngel2){
System.out.println("一号三角形为 锐角,二号三角形为钝角,取锐角");
return h1;
}else if(!acuteAngle1&´Angel2){
System.out.println("一号三角形为钝角,二号三角形为锐角,取锐角");
return h2;
}
}
return 0;
}
private static double rad(double d){
return d*Math.PI/180.0;
}
private static final Double EARTH_RADIUS=6378.137;
/**
*计算距离
*/
private static double get2PointDis(PointInfo p1, PointInfo p2){
double radLat1= rad(p1.getY());
double radLat2=rad(p2.getY());
double a=radLat1-radLat2;
double b =rad(p1.getX())-rad(p2.getX());
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;
s=s*1000;
return s;
}
/**
* 判断是否锐角三角形.
*/
private static boolean isAcuteAngle(double a,double b,double c){
return ((a*a+b*b-c*c)>=0)&&((a*a+c*c-b*b)>=0);
}