下面的代码是一个工具类,可直接拿去使用。
package com.framework.util;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.springframework.stereotype.Service;
import com.framework.entity.base.JcZd;
import com.framework.entity.business.YwClxx;
import com.framework.redis.GetRedisPool;
import com.framework.redis.RedisPrefix;
import com.framework.redis.SerializeUtil;
@Service
public class GpsDistanceUtils {
// 常量定义如下: Crew
// WGS-84 长轴半径
private double EARTH_WGS84_A = 6378137.0000; // WGS-84Semi-major axis in
// meters
// WGS-84 短轴半径
private double EARTH_WGS84_B = 6356752.3142; // WGS-84 Semi-minor axis in
// meters
// WGS-84 偏心率的平方
private double EARTH_WGS84_E2 = 0.00669437999013; // WGS-84 Eccentricity
// squared
private double EARTH_WGS84_MPM = 1852.0; // meters per nmile
// WGS-84 地球扁率
private double EARTH_WGS84_FLATTENING = 298.257223563; // WGS-84 Flattening
// 圆周率
private double PI = 3.14159265359;
/**
* 度为单位 返回公里 - 纬度1,经度1,纬度2,经度2
* @param dLatitude
* @param dLongitude
* @param dLatitude1
* @param dLongitude1
* @return
*/
public double mileEarthDis(double dLatitude, double dLongitude, double dLatitude1, double dLongitude1) {
double D, dis;
double tmpVal;
double fi1, fi2;
double drda = dLongitude1 - dLongitude;
drda = drda * PI / 180.0;// in radians
fi1 = dLatitude;
fi2 = dLatitude1;
fi1 = fi1 * PI / 180.0;// in in radians
fi2 = fi2 * PI / 180.0;// in in radians
tmpVal = Math.sin(fi1) * Math.sin(fi2) + Math.cos(fi1) * Math.cos(fi2) * Math.cos(drda);
if (Math.abs(tmpVal) > 1.0)
return 0;
D = Math.acos(tmpVal);// in radians
if (D == 0)
return 0;
double tmp1, tmp2;
tmp1 = (Math.sin(fi1) + Math.sin(fi2));
tmp2 = (Math.sin(fi1) - Math.sin(fi2));
tmpVal = ((3 * Math.sin(D) - D) * tmp1 * tmp1) / (1 + Math.cos(D));
tmpVal = tmpVal - ((3 * Math.sin(D) + D) * tmp2 * tmp2) / (1 - Math.cos(D));
dis = EARTH_WGS84_A * D + (EARTH_WGS84_A / (4 * EARTH_WGS84_FLATTENING)) * tmpVal;
dis = dis / 1000;
// System.out.println(" Dis is: " + dis);
return dis;
}
/**
* 度为单位 返回米 - 纬度1,经度1,纬度2,经度2
* @param dLatitude
* @param dLongitude
* @param dLatitude1
* @param dLongitude1
* @return
*/
public double earthDis(double dLatitude, double dLongitude, double dLatitude1, double dLongitude1) {
double D, dis;
double tmpVal;
double fi1, fi2;
double drda = dLongitude1 - dLongitude;
drda = drda * PI / 180.0;// in radians
fi1 = dLatitude;
fi2 = dLatitude1;
fi1 = fi1 * PI / 180.0;// in in radians
fi2 = fi2 * PI / 180.0;// in in radians
tmpVal = Math.sin(fi1) * Math.sin(fi2) + Math.cos(fi1) * Math.cos(fi2) * Math.cos(drda);
if (Math.abs(tmpVal) > 1.0)
return 0;
D = Math.acos(tmpVal);// in radians
if (D == 0)
return 0;
double tmp1, tmp2;
tmp1 = (Math.sin(fi1) + Math.sin(fi2));
tmp2 = (Math.sin(fi1) - Math.sin(fi2));
tmpVal = ((3 * Math.sin(D) - D) * tmp1 * tmp1) / (1 + Math.cos(D));
tmpVal = tmpVal - ((3 * Math.sin(D) + D) * tmp2 * tmp2) / (1 - Math.cos(D));
dis = EARTH_WGS84_A * D + (EARTH_WGS84_A / (4 * EARTH_WGS84_FLATTENING)) * tmpVal;
// System.out.println(" Dis is: " + dis);
return dis;
}
/**
* 分为单位 返回公里 - 纬度1,经度1,纬度2,经度2
* @param dLatitude_FEN
* @param dLongitude_FEN
* @param dLatitude1_FEN
* @param dLongitude1_FEN
* @return
*/
public double mileEarthDisFEN(double dLatitude_FEN, double dLongitude_FEN, double dLatitude1_FEN, double dLongitude1_FEN) {
double dis;
double dLatitude_DU = dLatitude_FEN / 60;
double dLongitude_DU = dLongitude_FEN / 60;
double dLatitude1_DU = dLatitude1_FEN / 60;
double dLongitude1_DU = dLongitude1_FEN / 60;
dis = mileEarthDis(dLatitude_DU, dLongitude_DU, dLatitude1_DU, dLongitude1_DU);
return dis;
}
/**
* 分为单位 返回米 - 纬度1,经度1,纬度2,经度2
* @param dLatitude_FEN
* @param dLongitude_FEN
* @param dLatitude1_FEN
* @param dLongitude1_FEN
* @return
*/
public double earthDisFEN(double dLatitude_FEN, double dLongitude_FEN, double dLatitude1_FEN, double dLongitude1_FEN) {
double dis;
double dLatitude_DU = dLatitude_FEN / 60;
double dLongitude_DU = dLongitude_FEN / 60;
double dLatitude1_DU = dLatitude1_FEN / 60;
double dLongitude1_DU = dLongitude1_FEN / 60;
dis = earthDis(dLatitude_DU, dLongitude_DU, dLatitude1_DU, dLongitude1_DU);
return dis;
}
/**
* 分的1000倍为单位 返回公里 - 纬度1,经度1,纬度2,经度2
* @param dLatitude_ThousandFEN
* @param dLongitude_ThousandFEN
* @param dLatitude1_ThousandFEN
* @param dLongitude1_ThousandFEN
* @return
*/
public double mileEarthDisThousandFEN(int dLatitude_ThousandFEN, int dLongitude_ThousandFEN, int dLatitude1_ThousandFEN, int dLongitude1_ThousandFEN) {
double dis;
double dLatitude_DU = dLatitude_ThousandFEN * 1.00000000 / 60000;
double dLongitude_DU = dLongitude_ThousandFEN * 1.00000000 / 60000;
double dLatitude1_DU = dLatitude1_ThousandFEN * 1.00000000 / 60000;
double dLongitude1_DU = dLongitude1_ThousandFEN * 1.00000000 / 60000;
dis = mileEarthDis(dLatitude_DU, dLongitude_DU, dLatitude1_DU, dLongitude1_DU);
return dis;
}
/**
* 分的1000倍为单位 返回米 - 纬度1,经度1,纬度2,经度2
* @param dLatitude_ThousandFEN
* @param dLongitude_ThousandFEN
* @param dLatitude1_ThousandFEN
* @param dLongitude1_ThousandFEN
* @return
*/
public double earthDisThousandFEN(int dLatitude_ThousandFEN, int dLongitude_ThousandFEN, int dLatitude1_ThousandFEN, int dLongitude1_ThousandFEN) {
double dis;
double dLatitude_DU = dLatitude_ThousandFEN * 1.00000000 / 60000;
double dLongitude_DU = dLongitude_ThousandFEN * 1.00000000 / 60000;
double dLatitude1_DU = dLatitude1_ThousandFEN * 1.00000000 / 60000;
double dLongitude1_DU = dLongitude1_ThousandFEN * 1.00000000 / 60000;
dis = earthDis(dLatitude_DU, dLongitude_DU, dLatitude1_DU, dLongitude1_DU);
return dis;
}
/**
* 两个角度差 输入值 0~360 ; 返回值 0~360;
* @param StationAngle_R
* @param n_Course
* @return
*/
public int getCourseDes(int StationAngle_R, int n_Course) {
int Angle_R_des = 360;
if (StationAngle_R >= 270 && n_Course <= 90) {
Angle_R_des = n_Course + 360 - StationAngle_R;
} else if (n_Course >= 270 && StationAngle_R <= 90) {
Angle_R_des = StationAngle_R + 360 - n_Course;
} else {
Angle_R_des = (StationAngle_R > n_Course) ? (StationAngle_R - n_Course) : (n_Course - StationAngle_R);
}
return Angle_R_des;
}
/**
* z 出发点, 坐标参考点; 1 目标点;
* @param xz
* @param yz
* @param x1
* @param y1
* @return
*/
public int get2PtAngle(int xz, int yz, int x1, int y1) {
int ndx = x1 - xz;
int ndy = y1 - yz;
double dAng = 0;
int nAng = 0;
if (ndy == 0 && ndx == 0) // 全0 不计算
{
return -1;
} else if (ndy != 0 && ndx == 0) // x0 竖直
{
if (ndy > 0) {
nAng = 0;
} else {
nAng = 180;
}
} else if (ndy == 0 && ndx != 0) // y0 水平
{
if (ndx > 0) {
nAng = 90;
} else {
nAng = 270;
}
} else {
dAng = Math.atan2((double) ndx, (double) ndy);
nAng = (int) (dAng / PI * 180 + 0.5);
if (nAng < 0) {
nAng += 360;
}
}
return nAng;
}
/**
* 分的1000倍为单位 返回li米 - 纬度1,经度1,纬度2,经度2
* @param dLatitude_ThousandFEN
* @param dLongitude_ThousandFEN
* @param dLatitude1_ThousandFEN
* @param dLongitude1_ThousandFEN
* @return
*/
public double earthDisThousandFEN100(int dLatitude_ThousandFEN, int dLongitude_ThousandFEN, int dLatitude1_ThousandFEN, int dLongitude1_ThousandFEN) {
double dis;
double dLatitude_DU = dLatitude_ThousandFEN * 1.00000000 / 60000;
double dLongitude_DU = dLongitude_ThousandFEN * 1.00000000 / 60000;
double dLatitude1_DU = dLatitude1_ThousandFEN * 1.00000000 / 60000;
double dLongitude1_DU = dLongitude1_ThousandFEN * 1.00000000 / 60000;
dis = earthDis(dLatitude_DU, dLongitude_DU, dLatitude1_DU, dLongitude1_DU);
return dis * 100;
}
/**
* 根据车辆GPS点位计算出来距离线路站点(第一站)上下行方向的距离大小,返回结果。
* @param 线路id
* @return 上行:0 下行:1
*/
public Short getRunFlag(String clid) {
Short fxFlag = null;
// Redis获取车辆信息
Map<String, String> clInfoMap = GetRedisPool.getHashAll(RedisPrefix.REDIS_PREFIX_BUSRUNINFO + clid);
if (clInfoMap != null) {
// 车辆信息对象生成
YwClxx clInfo = BeanUtil.getMapBean(clInfoMap, YwClxx.class);
// 经度(最近一条记录)
int clJd = clInfo.getJd();
// 纬度(最近一条记录)
int clWd = clInfo.getWd();
if (0 == clJd || 0 == clWd) {
return fxFlag;
}
String xlid = clInfo.getYyxl();
// 查询上行站点信息
Set<byte[]> sxset = GetRedisPool
.getSortedSetByte(RedisPrefix.REDIS_PREFIX_STATION + xlid + RedisPrefix.REDIS_PREFIX_LIMIT + RedisPrefix.REDIS_PREFIX_UP, 1);
Set<byte[]> xxset = GetRedisPool
.getSortedSetByte(RedisPrefix.REDIS_PREFIX_STATION + xlid + RedisPrefix.REDIS_PREFIX_LIMIT + RedisPrefix.REDIS_PREFIX_DOWN, 1);
List<byte[]> sxlist = new ArrayList(sxset);
List<byte[]> xxlist = new ArrayList(xxset);
JcZd sxjcZd = (JcZd) SerializeUtil.unserizlize(sxlist.get(0));
JcZd xxjcZd = (JcZd) SerializeUtil.unserizlize(xxlist.get(0));
// 经度(上行)
long sxJd = sxjcZd.getZwjd().longValue();
// 纬度(上行)
long sxWd = sxjcZd.getZwwd().longValue();
// 经度(下行)
long xxJd = xxjcZd.getZwjd().longValue();
// 纬度(下行)
long xxWd = xxjcZd.getZwwd().longValue();
// 取得车辆位置和第一站点之间的距离
double sxRange = earthDisFEN(clWd / 10000.00, clJd / 10000.00, sxWd / 10000.00, sxJd / 10000.00);
double xxRange = earthDisFEN(clWd / 10000.00, clJd / 10000.00, xxWd / 10000.00, xxJd / 10000.00);
if (sxRange < xxRange) {
fxFlag = 0;
} else {
fxFlag = 1;
}
}
return fxFlag;
}
/**
* 根据车辆GPS点位计算出来距离线路站点(第一站)上下行方向的距离大小,返回结果。
* @param 线路id
* @return 上行:0 下行:1
*/
public double getGPSRunDis(String clid, String xlid, Byte yxfx, long clJd, long clWd) {
// 方向
String direction = yxfx == 1 ? RedisPrefix.REDIS_PREFIX_DOWN : RedisPrefix.REDIS_PREFIX_UP;
// 查询上行站点信息
Set<byte[]> zdset = GetRedisPool.getSortedSetByte(RedisPrefix.REDIS_PREFIX_STATION + xlid + RedisPrefix.REDIS_PREFIX_LIMIT + direction, 1);
List<byte[]> zdlist = new ArrayList(zdset);
JcZd jcZd = (JcZd) SerializeUtil.unserizlize(zdlist.get(0));
// 经度(上行)
long jd = jcZd.getZwjd().longValue();
// 纬度(上行)
long wd = jcZd.getZwwd().longValue();
// 取得车辆位置和第一站点之间的距离
return earthDisFEN(clWd / 10000.00, clJd / 10000.00, wd / 10000.00, jd / 10000.00);
}
}