1500字范文,内容丰富有趣,写作好帮手!
1500字范文 > 由GPS定位的经纬度转换成百度地图经纬度坐标

由GPS定位的经纬度转换成百度地图经纬度坐标

时间:2020-03-30 22:52:16

相关推荐

由GPS定位的经纬度转换成百度地图经纬度坐标

/**

* @Description: 各地图API坐标系统比较与转换; WGS84坐标系:即地球坐标系,国际上通用的坐标系。设备一般包含GPS芯片或者北斗芯片获取的经纬度为WGS84地理坐标系,

* 谷歌地图采用的是WGS84地理坐标系(中国范围除外);

* GCJ02坐标系:即火星坐标系,是由中国国家测绘局制订的地理信息系统的坐标系统。由WGS84坐标系经加密后的坐标系。

* 谷歌中国地图和搜搜中国地图采用的是GCJ02地理坐标系; BD09坐标系:即百度坐标系,GCJ02坐标系经加密后的坐标系;

* 搜狗坐标系、图吧坐标系等,估计也是在GCJ02基础上加密而成的。

*/

public class GpsUtil {

public static final String BAIDU_LBS_TYPE = "bd09ll";

public final static double PI = 3.1415926535897932384626;

public final static double X_PI = PI * 3000.0 / 180.0;

/**

* 地球赤道半径

*/

public final static double GLOBAL_R = 6371393.0;

public final static double EE = 0.00669342162296594323;

/**

* 国际坐标 to 火星坐标系 (GCJ-02) World Geodetic System ==> Mars Geodetic System

*

* @param wgsLat 纬度

* @param wgsLgt 经度

* @return GpsTranslateDTO

*/

public static GpsTranslateDTO wgs84ToGcj02(double wgsLat, double wgsLgt) {

if (outOfChina(wgsLat, wgsLgt)) {

return null;

}

double dLat = transformLat(wgsLgt - 105.0, wgsLat - 35.0);

double dLon = transformLon(wgsLgt - 105.0, wgsLat - 35.0);

double radLat = wgsLat / 180.0 * PI;

double magic = Math.sin(radLat);

magic = 1 - EE * magic * magic;

double sqrtMagic = Math.sqrt(magic);

dLat = (dLat * 180.0) / ((GLOBAL_R * (1 - EE)) / (magic * sqrtMagic) * PI);

dLon = (dLon * 180.0) / (GLOBAL_R / sqrtMagic * Math.cos(radLat) * PI);

double mgLat = wgsLat + dLat;

double mgLon = wgsLgt + dLon;

return new GpsTranslateDTO(mgLat, mgLon);

}

/**

* dddmmmmmm格式国际坐标 to 火星坐标系 (GCJ-02)

*

* @param wgsLat 纬度

* @param wgsLgt 经度

* @return GpsTranslateDTO

*/

public static GpsTranslateDTO wgs84ToGcj02(int wgsLat, int wgsLgt) {

return wgs84ToGcj02(changeRad(wgsLat), changeRad(wgsLgt));

}

/**

* * 火星坐标系 (GCJ-02) to 国际坐标

*

* @param ggLat 纬度

* @param ggLgt 经度

* @return GpsTranslateDTO

*/

public static GpsTranslateDTO gcj02ToWgs84(double ggLat, double ggLgt) {

GpsTranslateDTO gps = transform(ggLat, ggLgt);

double wgsLgt = ggLgt * 2 - gps.getLgt();

double wgsLat = ggLat * 2 - gps.getLat();

return new GpsTranslateDTO(wgsLat, wgsLgt);

}

/**

* 火星坐标系 (GCJ-02) to 百度坐标系 (BD-09) 的转换算法 将 GCJ-02 坐标转换成 BD-09 坐标

*

* @param ggLat 纬度

* @param ggLgt 经度

* @return GpsTranslateDTO

*/

public static GpsTranslateDTO gcj02ToBd09(double ggLat, double ggLgt) {

double z = Math.sqrt(ggLgt * ggLgt + ggLat * ggLat) + 0.00002 * Math.sin(ggLat * X_PI);

double theta = Math.atan2(ggLat, ggLgt) + 0.000003 * Math.cos(ggLgt * X_PI);

double bdLgt = z * Math.cos(theta) + 0.0065;

double bdLat = z * Math.sin(theta) + 0.006;

return new GpsTranslateDTO(bdLat, bdLgt);

}

/**

* * 百度坐标系 (BD-09) to 火星坐标系 (GCJ-02) 的转换算法 * * 将 BD-09 坐标转换成GCJ-02 坐标

*

* @param bdLat 纬度

* @param bdLgt 经度

* @return GpsTranslateDTO

*/

public static GpsTranslateDTO bd09ToGcj02(double bdLat, double bdLgt) {

double x = bdLgt - 0.0065, y = bdLat - 0.006;

double z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * X_PI);

double theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * X_PI);

double ggLgt = z * Math.cos(theta);

double ggLat = z * Math.sin(theta);

return new GpsTranslateDTO(ggLat, ggLgt);

}

/**

* 百度坐标系 (BD-09) to 国际坐标

*

* @param bdLat 纬度

* @param bdLgt 经度

* @return GpsTranslateDTO

*/

public static GpsTranslateDTO bd09ToWgs84(double bdLat, double bdLgt) {

GpsTranslateDTO gcj02 = bd09ToGcj02(bdLat, bdLgt);

return gcj02ToWgs84(gcj02.getLat(), gcj02.getLgt());

}

/**

* 国际坐标 to 百度坐标系 (BD-09)

*

* @param wgsLat 纬度

* @param wgsLgt 经度

* @return GpsTranslateDTO

*/

public static GpsTranslateDTO wgs84ToBd09(double wgsLat, double wgsLgt) {

GpsTranslateDTO gcj02 = wgs84ToGcj02(wgsLat, wgsLgt);

if (null == gcj02) {

return new GpsTranslateDTO(0.0, 0.0);

}

return gcj02ToBd09(gcj02.getLat(), gcj02.getLgt());

}

/**

* dddmmmmmm格式国际坐标 to 百度坐标系 (BD-09)

*

* @param wgsLat 纬度

* @param wgsLgt 经度

* @return

*/

public static GpsTranslateDTO wgs84ToBd09(int wgsLat, int wgsLgt) {

return wgs84ToBd09(changeRad(wgsLat), changeRad(wgsLgt));

}

private static boolean outOfChina(double lat, double lon) {

return lon < 72.004 || lon > 137.8347 || lat < 0.8293 || lat > 55.8271;

}

private static GpsTranslateDTO transform(double lat, double lon) {

if (outOfChina(lat, lon)) {

return new GpsTranslateDTO(lat, lon);

}

double dLat = transformLat(lon - 105.0, lat - 35.0);

double dLon = transformLon(lon - 105.0, lat - 35.0);

double radLat = lat / 180.0 * PI;

double magic = Math.sin(radLat);

magic = 1 - EE * magic * magic;

double sqrtMagic = Math.sqrt(magic);

dLat = (dLat * 180.0) / ((GLOBAL_R * (1 - EE)) / (magic * sqrtMagic) * PI);

dLon = (dLon * 180.0) / (GLOBAL_R / sqrtMagic * Math.cos(radLat) * PI);

double mgLat = lat + dLat;

double mgLon = lon + dLon;

return new GpsTranslateDTO(mgLat, mgLon);

}

private static double transformLat(double x, double y) {

double ret =

-100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y + 0.2 * Math.sqrt(Math.abs(x));

ret += (20.0 * Math.sin(6.0 * x * PI) + 20.0 * Math.sin(2.0 * x * PI)) * 2.0 / 3.0;

ret += (20.0 * Math.sin(y * PI) + 40.0 * Math.sin(y / 3.0 * PI)) * 2.0 / 3.0;

ret += (160.0 * Math.sin(y / 12.0 * PI) + 320 * Math.sin(y * PI / 30.0)) * 2.0 / 3.0;

return ret;

}

private static double transformLon(double x, double y) {

double ret = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1 * Math.sqrt(Math.abs(x));

ret += (20.0 * Math.sin(6.0 * x * PI) + 20.0 * Math.sin(2.0 * x * PI)) * 2.0 / 3.0;

ret += (20.0 * Math.sin(x * PI) + 40.0 * Math.sin(x / 3.0 * PI)) * 2.0 / 3.0;

ret += (150.0 * Math.sin(x / 12.0 * PI) + 300.0 * Math.sin(x / 30.0 * PI)) * 2.0 / 3.0;

return ret;

}

/**

* 将dddmmmmmm或者ddmmmmmm转换为十进制的度

*

* @param val dddmmmmmm表示的经纬度

* @return 转化后的十进制经纬度

*/

private static double changeRad(int val) {

if (val >= 0) {

return Math.round((val / 1000000 + (val - (val / 1000000) * 1000000) / 600000.0) * 100000.0)

/ 100000.0;

} else {

val = -val;

return -Math.round((val / 1000000 + (val - (val / 1000000) * 1000000) / 600000.0) * 100000.0)

/ 100000.0;

}

}

public static double calculateAutoSpeed(GpsDataDTO gps1, GpsDataDTO gps2) {

double distance = calculateDistance(gps1.getLng(), gps1.getLat(), gps2.getLng(), gps2.getLat(),

EcallConst.MILE);

return (distance / Math.abs(TimeTransform.dateStrToUnixTimeStamp(gps1.getDate())

- TimeTransform.dateStrToUnixTimeStamp(gps2.getDate()))) * 3.6;

}

public static double calculateAutoSpeed(SourceGps gps1, SourceGps gps2) {

double distance =

calculateDistance(gps1.getX(), gps1.getY(), gps2.getX(), gps2.getY(), EcallConst.MILE);

return (distance / Math.abs(gps1.getT() - gps2.getT())) * 3.6;

}

/**

* TODO 计算地球上两点之间的距离

*

* @param lat1

* @param lng1

* @param lat2

* @param lng2

* @return Create at 8月10日 下午1:08:39

*/

public static double calculateDistance(double lng1, double lat1, double lng2, double lat2,

String mileUnit) {

double radLat1 = rad(lat1);

double radLat2 = rad(lat2);

// 纬度差

double radLatSpan = radLat1 - radLat2;

// 经度差

double radLngSpan = rad(lng1) - rad(lng2);

double dis = Math.pow(Math.sin(radLatSpan / 2), 2)

+ Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(radLngSpan / 2), 2);

dis = 2 * Math.asin(Math.min(1, Math.sqrt(dis))) * EcallConst.EARTH_RADIUS_CENTER;

switch (mileUnit) {

// 千米

case EcallConst.KMILE:

return MathUtil.round(dis, 3);

// 米

case EcallConst.MILE:

return MathUtil.round(dis * 1000, 3);

// 厘米

case EcallConst.CMILE:

return MathUtil.round(dis * 100000, 3);

default:

// 默认返回千米

return MathUtil.round(dis, 3);

}

}

private static double rad(double d) {

return d * Math.PI / 180.0;

}

public static JSONObject gpsJsonFromPojo(double[] xy, double hight, long time) {

JSONObject ob = new JSONObject();

ob.put(PojoFieldConst.GPS_LONGITUDE, MathUtil.round(xy[0], 6));

ob.put(PojoFieldConst.GPS_LATITUDE, MathUtil.round(xy[1], 6));

ob.put(PojoFieldConst.GPS_ALTITUDE, hight);

ob.put(PojoFieldConst.GPS_DATE, TimeTransform.unixTimeStampToDateStr(time));

return ob;

}

public static JSONObject gpsJsonFromPojo(double[] xy, double hight, String date) {

JSONObject ob = new JSONObject();

ob.put(PojoFieldConst.GPS_LONGITUDE, MathUtil.round(xy[0], 6));

ob.put(PojoFieldConst.GPS_LATITUDE, MathUtil.round(xy[1], 6));

ob.put(PojoFieldConst.GPS_ALTITUDE, hight);

ob.put(PojoFieldConst.GPS_DATE, date);

return ob;

}

public static double su(double num) {

BigDecimal bg = new BigDecimal(num);

return bg.setScale(6, BigDecimal.ROUND_HALF_UP).doubleValue();

}

public static void main(String[] args) {

GpsTranslateDTO wgs84ToBd09 = wgs84ToBd09(经度, 维度);

System.out.println(su(wgs84ToBd09.getLat()));

System.out.println(su(wgs84ToBd09.getLgt()));

}

}

@Setter

@Getter

@NoArgsConstructor

@AllArgsConstructor

@ToString

public class GpsTranslateDTO implements Serializable {

private static final long serialVersionUID = 5717495677928773775L;

private Double lat;

private Double lgt;

}

/**

*/

public class MathUtil {

// 默认除法运算精度

private static final int DEF_DIV_SCALE = 10;

/**

* 提供精确的加法运算。

*

* @param v1

*被加数

* @param v2

*加数

* @return 两个参数的和

*/

public static double add(double v1, double v2) {

BigDecimal b1 = new BigDecimal(v1);

BigDecimal b2 = new BigDecimal(v2);

return b1.add(b2).doubleValue();

}

/**

* 提供精确的减法运算。

*

* @param v1

*被减数

* @param v2

*减数

* @return 两个参数的差

*/

public static double sub(double v1, double v2) {

BigDecimal b1 = new BigDecimal(v1);

BigDecimal b2 = new BigDecimal(v2);

return b1.subtract(b2).doubleValue();

}

/**

* 提供精确的乘法运算。

*

* @param v1

*被乘数

* @param v2

*乘数

* @return 两个参数的积

*/

public static double mul(double v1, double v2) {

BigDecimal b1 = new BigDecimal(v1);

BigDecimal b2 = new BigDecimal(v2);

return b1.multiply(b2).doubleValue();

}

/**

* 提供(相对)精确的除法运算,当发生除不尽的情况时,精确到 小数点以后10位,以后的数字四舍五入。

*

* @param v1

*被除数

* @param v2

*除数

* @return 两个参数的商

*/

public static double div(double v1, double v2) {

return div(v1, v2, DEF_DIV_SCALE);

}

/**

* 提供(相对)精确的除法运算。当发生除不尽的情况时,由scale参数指 定精度,以后的数字四舍五入。

*

* @param v1

*被除数

* @param v2

*除数

* @param scale

*表示表示需要精确到小数点以后几位。

* @return 两个参数的商

*/

public static double div(double v1, double v2, int scale) {

if (scale < 0) {

throw new IllegalArgumentException(

"The scale must be a positive integer or zero");

}

BigDecimal b1 = new BigDecimal(v1);

BigDecimal b2 = new BigDecimal(v2);

return b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP).doubleValue();

}

/**

* 提供精确的小数位四舍五入处理。

*

* @param val

*需要四舍五入的数字

* @param scale

*小数点后保留几位

* @return 四舍五入后的结果

*/

public static double round(double val, int scale) {

if (scale < 0) {

throw new IllegalArgumentException(

"The scale must be a positive integer or zero");

}

BigDecimal b = new BigDecimal(val);

BigDecimal one = new BigDecimal(1.0);

return b.divide(one, scale, BigDecimal.ROUND_HALF_UP).doubleValue();

}

}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。