经纬度经典用处
最近在公司做了一个地图的项目,核心的算法就是经纬度计算距离和根据距离扩展经纬度。
闲话少说,直接贴出代码看注释吧
经纬度计算距离
// 地球半径
private static double EARTH_RADIUS = 6378.137;
private static double rad(double d) {
return d * Math.PI / 180.0;
}
/**
* 通过经纬度获取距离(单位:米)
*
* @param lat1
* @param lng1
* @param lat2
* @param lng2
* @return 距离
*/
public static double getDistance(double lat1, double lng1, double lat2,
double lng2) {
double radLat1 = rad(lat1);
double radLat2 = rad(lat2);
double a = radLat1 - radLat2;
double b = rad(lng1) - rad(lng2);
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;
}
根据距离扩展经纬度
public static final double Ea = 6378137; // 赤道半径
public static final double Eb = 6356725; // 极半径
/***
* 这个根据一个经纬度坐标、距离然后求另外一个经纬度坐标的函数
* 例如,我要找一个坐标点(lat,lon)的5公里范围内的所有商户信息、景点信息等。这个MBR就是一个最大的范围,
* 这个矩形是包含5公里范围内所有这些有效信息的一个最小矩形。
* 求出四个方向0度、90度、180度、270度方向上的四个坐标点就可以得到这个矩形。
* @param lat
* @param lon
* @param distance 距离,单位:公里
* @param angle 正北极方向顺时针的角度
* @return
*/
public static LatLon getLatLon(double lat, double lon, double distance, double angle){
double dx = distance * 1000 * Math.sin(angle * Math.PI / 180.0);
double dy = distance * 1000 * Math.cos(angle * Math.PI / 180.0);
double ec = Eb + (Ea-Eb) * (90.0 - lat) / 90.0;
double ed = ec * Math.cos(lat * Math.PI / 180);
double newLon = (dx / ed + lon * Math.PI / 180.0) * 180.0 / Math.PI;
double newLat = (dy / ec + lat * Math.PI / 180.0) * 180.0 / Math.PI;
return new LatLon(newLat,newLon);
}
public static class LatLon{
double lat;
double lon;
public LatLon(double lat, double lon) {
this.lat = lat;
this.lon = lon;
}
public double getLat() {
return lat;
}
public void setLat(double lat) {
this.lat = lat;
}
public double getLon() {
return lon;
}
public void setLon(double lon) {
this.lon = lon;
}
public String toString(){
return "lat:"+lat+",lon:"+lon;
}
}
测试一把
public static void main(String[] args){
double lat = 32.402130126953125;
double lon = 119.42626953125;
System.out.println("left:"+getLatLon(lat,lon,4,0));
System.out.println("up:"+getLatLon(lat,lon,4,90));
System.out.println("right:"+getLatLon(lat,lon,4,180));
System.out.println("down:"+getLatLon(lat,lon,4,270));
}
运行结果:
left:lat:32.438106220211,lon:119.42626953125003
up:lat:32.402130126953125,lon:119.46887968427875
right:lat:32.36615403369525,lon:119.42626953125003
down:lat:32.402130126953125,lon:119.38365937822127
Process finished with exit code 0