经纬度计算, 本质上是球面三角函数的应用, 将数学公式转换为代码的过程,
站在前人的肩膀上, 自己又补充了一点:
package com.iwhere.easy.travel.tool; public class GeoTools { public static String getScopeByGeoLevel(Integer geolevel) {
return (( - geolevel) * ) + "公里";
} public static double getAngle(double lat1, double lng1, double lat2, double lng2) {
double x1 = lng1;
double y1 = lat1;
double x2 = lng2;
double y2 = lat2;
double pi = Math.PI;
double w1 = y1 / * pi;
double j1 = x1 / * pi;
double w2 = y2 / * pi;
double j2 = x2 / * pi;
double ret;
if (j1 == j2) {
if (w1 > w2)
return ; // 北半球的情况,南半球忽略
else if (w1 < w2)
return ;
else
return -;// 位置完全相同
}
ret = * Math.pow(Math.sin((w1 - w2) / ), )
- Math.pow(Math.sin((j1 - j2) / ) * (Math.cos(w1) - Math.cos(w2)), );
ret = Math.sqrt(ret);
double temp = (Math.sin(Math.abs(j1 - j2) / ) * (Math.cos(w1) + Math.cos(w2)));
ret = ret / temp;
ret = Math.atan(ret) / pi * ;
if (j1 > j2) { // 1为参考点坐标
if (w1 > w2)
ret += ;
else
ret = - ret;
} else if (w1 > w2)
ret = - ret;
return ret;
} /**
* @param lat1
* 纬度1,参考点
* @param lng1
* 经度1,参考点
* @param lat2
* 纬度2
* @param lng2
* 经度2
* @return 方向
*/
public static String getDirection(double lat1, double lng1, double lat2, double lng2) {
double jiaodu = getAngle(lat1, lng1, lat2, lng2);
if ((jiaodu <= ) || (jiaodu > ))
return "正东方";
if ((jiaodu > ) && (jiaodu <= ))
return "东北方";
if ((jiaodu > ) && (jiaodu <= ))
return "正北方";
if ((jiaodu > ) && (jiaodu <= ))
return "西北方";
if ((jiaodu > ) && (jiaodu <= ))
return "正西方";
if ((jiaodu > ) && (jiaodu <= ))
return "西南方";
if ((jiaodu > ) && (jiaodu <= ))
return "正南方";
if ((jiaodu > ) && (jiaodu <= ))
return "东南方";
return "";
} /**
* 获取方位角描述
* 前一个点
* 参照点
* 目标点
* @author wenbronk
*/
public static String getAzimuth(double preLng, double preLat, double referLng, double referLat, double poiLng,
double poiLat) {
double jiaodu1 = getAngle(preLat, preLng, referLat, referLng);
double jiaodu2 = getAngle(referLat, referLng, poiLat, poiLng);
double jiaodu = jiaodu2 - jiaodu1;
if (((jiaodu <= && jiaodu > ) || jiaodu > ) || ((jiaodu >= - && jiaodu < ) || jiaodu < -)) {
return "正前方";
}else if ((jiaodu <= && jiaodu > ) || (jiaodu >= - && jiaodu < -)) {
return "左前方";
}else if ((jiaodu <= && jiaodu > ) || (jiaodu >= - && jiaodu < -)) {
return "左侧";
}else if ((jiaodu <= && jiaodu > ) || (jiaodu >= - && jiaodu < -)) {
return "左后方";
}else if ((jiaodu <= && jiaodu > ) || (jiaodu >= - && jiaodu < -)) {
return "后方";
}else if ((jiaodu <= && jiaodu > ) || (jiaodu >= - && jiaodu < -)) {
return "右后方";
}else if ((jiaodu <= && jiaodu > ) || (jiaodu >= - && jiaodu < -)) {
return "右侧";
}else if ((jiaodu <= && jiaodu > ) || (jiaodu >= - && jiaodu < -)) {
return "右前方";
}
return "";
} /**
* 判断是否在后方
* @author wenbronk
*/
public static Boolean isBehine(double preLng, double preLat, double referLng, double referLat,
double poiLng, double poiLat) {
double x1 = referLng - preLng;
double y1 = referLat - preLat;
double x2 = poiLng - referLng;
double y2 = poiLat - referLat; // 求 (x1, y1), (x2, y2) 向量的夹角的cos值
double cos = (x1 * x2 + y1 * y2) /
(Math.sqrt(Math.pow(x1, ) + Math.pow(y1, )) + Math.sqrt(Math.pow(x2, ) + Math.pow(y2, )));
if (cos >= ) {
return false;
}
return true;
} public static void main(String[] args) {
String str = getDirection(, , -, -);
System.out.println(str);
}
}