计算经纬度距离,点到直线的距离,点到点的距离
作者:互联网
计算经纬度距离,点到直线的距离,点到点的距离
一、计算经纬度距离根据坐标点经纬度计算两点间距离。(单位:km)
1.1 Java
public static void main(String[] args) {
System.out.println(getDistance(40.00694,116.394476,40.007538,116.375561));
}
//根据经纬度计算两点距离
public static double getDistance(double lat1, double lng1, double lat2, double lng2) {
double radLat1 = lat1 * Math.PI / 180.0;
double radLat2 = lat2 * Math.PI / 180.0;
double lng_1 = lng1 * Math.PI / 180.0;
double lng_2 = lng2 * Math.PI / 180.0;
double a = radLat1 - radLat2;// 两点纬度差
double b = lng_1 - lng_2;// 两点的经度差
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 * 6378.137;
return s;
}
1.2 scala
def main(args: Array[String]): Unit = {
val aa :Double = getDistatce(40.00694,116.394476,40.007538,116.375561)
}
//根据经纬度计算两点距离
def getDistatce(lat1: Double, lon1: Double, lat2: Double, lon2: Double) = {
if (lat1 != 0 && lon1 != 0 && lat2 != 0 && lon2 != 0) {
val R = 6378.137
val radLat1 = lat1 * Math.PI / 180
val radLat2 = lat2 * Math.PI / 180
val a = radLat1 - radLat2
val b = lon1 * Math.PI / 180 - lon2 * Math.PI / 180
val s = 2 * Math.sin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) + Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(b / 2), 2)))
BigDecimal.decimal(s * R).setScale(2, BigDecimal.RoundingMode.HALF_UP).doubleValue()
} else {
BigDecimal.decimal(0).setScale(2, BigDecimal.RoundingMode.HALF_UP).doubleValue()
}
}
1.3 scala计算两个Gps点之间的距离
通常进行轨迹数据的挖掘,都会用到经纬度转换距离。
object getDistance{
def main(args: Array[String]) {
val lon1 = 108.956769;val lat1 = 34.229644
val lon2 = 108.958830;val lat2 =34.229701
def getDistance(lon1: Double, lat1: Double, lon2: Double, lat2: Double): Double ={
//pi为π,r为地球半径
val pi = 3.1415926
val r: Double = 6370.99681
//a1、a2、b1、b2分别为上面数据的经纬度转换为弧度
val a1 = lat1 * pi /180.0
val a2 = lon1 * pi /180.0
val b1 = lat2 * pi /180.0
val b2 = lon2 * pi /180.0
var t1: Double = Math.cos(a1) * Math.cos(a2) * Math.cos(b1)* Math.cos(b2)
var t2: Double = Math.cos(a1) * Math.sin(a2) * Math.cos(b1)* Math.sin(b2)
var t3: Double = Math.sin(a1) * Math.sin(b1)
val distance = Math.acos(t1 + t2 + t3) * r
distance
}
println(getDistance(lon1,lat1,lon2,lat2))
}
}
二、经纬度和距离之间的计算
import org.junit.Test;
import org.springframework.util.Assert;
public class GeoUtils {
public final static float EARTH_RADIUS = 6378137; // 地球半径
@Test
public void test2() {
// GeoUtils.getBoxByCoordinate(120.0, 40.0, 2000.0);
Double distance = GeoUtils.getDistance(new Point(119.9765412051408, 39.98202952055585),
new Point(120.0234587948592, 40.01797047944415));
System.out.println(distance);
}
/**
* 根据中心点获取box
* @return
*/
public static Double[] getBoxByCoordinate(Double longitude, Double latitude, Double raidusMile) {
Assert.notNull(longitude);
Assert.notNull(latitude);
Double degree = (24901 * 1609) / 360.0; // 获取每度弧长
Double mpdLng = Double.parseDouble((degree * Math.cos(latitude * (Math.PI / 180)) + "").replace("-", ""));
Double dpmLng = 1 / mpdLng;
Double radiusLng = dpmLng * raidusMile;
// 获取最小经度
Double minLat = longitude - radiusLng;
// 获取最大经度
Double maxLat = longitude + radiusLng;
Double dpmLat = 1 / degree;
Double radiusLat = dpmLat * raidusMile;
// 获取最小纬度
Double minLng = latitude - radiusLat;
// 获取最大纬度
Double maxLng = latitude + radiusLat;
System.out.println(minLat + ": " + maxLat + ": " + minLng + ": " + maxLng);
return null;
}
/**
* 获取距离
* @param from
* 开始点
* @param to
* 结束点
* @return
*/
public static Double getDistance(Point from, Point to) {
if (from == null || to == null || from.getLat() == null || from.getLng() == null || to.getLat() == null
|| to.getLng() == null) {
return Double.NaN;
} else {
double lat1 = from.getLat() * Math.PI / 180.0;
double lat2 = to.getLat() * Math.PI / 180.0;
double a = lat1 - lat2;
double b = (from.getLng() - to.getLng()) * Math.PI / 180.0;
double sa2, sb2;
sa2 = Math.sin(a / 2.0);
sb2 = Math.sin(b / 2.0);
return 2 * EARTH_RADIUS * Math.asin(Math.sqrt(sa2 * sa2 + Math.cos(lat1) * Math.cos(lat2) * sb2 * sb2));
}
}
/**
* 点
*/
public static class Point {
public Double lat; // 纬度
public Double lng; // 经度
public Point() { super(); }
/**
* @param lat
* @param lng
*/
public Point(Double lat, Double lng) {
super();
this.lat = lat;
this.lng = lng;
}
/**
* @return the lat
*/
public Double getLat() {
return lat;
}
/**
* @param lat
* the lat to set
*/
public void setLat(Double lat) {
this.lat = lat;
}
/**
* @return the lng
*/
public Double getLng() {
return lng;
}
/**
* @param lng
* the lng to set
*/
public void setLng(Double lng) {
this.lng = lng;
}
}
}
2.1 角度计算
package com.iwhere.easy.travel.tool;
import org.junit.Test;
public class GeoTools {
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 / 180 * pi;
double j1 = x1 / 180 * pi;
double w2 = y2 / 180 * pi;
double j2 = x2 / 180 * pi;
double ret;
if (j1 == j2) {
if (w1 > w2)
return 270; // 北半球的情况,南半球忽略
else if (w1 < w2)
return 90;
else
return -1;// 位置完全相同
}
ret = 4 * Math.pow(Math.sin((w1 - w2) / 2), 2)
- Math.pow(Math.sin((j1 - j2) / 2) * (Math.cos(w1) - Math.cos(w2)), 2);
ret = Math.sqrt(ret);
double temp = (Math.sin(Math.abs(j1 - j2) / 2) * (Math.cos(w1) + Math.cos(w2)));
ret = ret / temp;
ret = Math.atan(ret) / pi * 180;
if (j1 > j2) { // 1为参考点坐标
if (w1 > w2)
ret += 180;
else
ret = 180 - ret;
} else if (w1 > w2)
ret = 360 - 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 <= 10) || (jiaodu > 350))
return "正东方";
if ((jiaodu > 10) && (jiaodu <= 80))
return "东北方";
if ((jiaodu > 80) && (jiaodu <= 100))
return "正北方";
if ((jiaodu > 100) && (jiaodu <= 170))
return "西北方";
if ((jiaodu > 170) && (jiaodu <= 190))
return "正西方";
if ((jiaodu > 190) && (jiaodu <= 260))
return "西南方";
if ((jiaodu > 260) && (jiaodu <= 280))
return "正南方";
if ((jiaodu > 280) && (jiaodu <= 350))
return "东南方";
return "";
}
/**
* 获取方位角描述
* 前一个点
* 参照点
* 目标点
* @return
*/
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 <=10 && jiaodu > 0) || jiaodu > 350) || ((jiaodu >= -10 && jiaodu < 0) || jiaodu < -350)) {
return "正前方";
}else if ((jiaodu <= 80 && jiaodu > 10) || (jiaodu >= -350 && jiaodu < -280)) {
return "左前方";
}else if ((jiaodu <= 100 && jiaodu > 80) || (jiaodu >= -280 && jiaodu < -260)) {
return "左侧";
}else if ((jiaodu <= 170 && jiaodu > 100) || (jiaodu >= -260 && jiaodu < -190)) {
return "左后方";
}else if ((jiaodu <= 190 && jiaodu > 170) || (jiaodu >= -190 && jiaodu < -170)) {
return "后方";
}else if ((jiaodu <=260 && jiaodu > 190) || (jiaodu >= -170 && jiaodu < -100)) {
return "右后方";
}else if ((jiaodu <=280 && jiaodu > 260) || (jiaodu >= -100 && jiaodu < -80)) {
return "右侧";
}else if ((jiaodu <= 350 && jiaodu > 280) || (jiaodu >= -80 && jiaodu < -10)) {
return "右前方";
}
return "";
}
@Test
public void test() {
String azimuth = GeoTools.getAzimuth(0d, 0d, -40d, 20d, 30d, 30d);
System.out.println(azimuth);
}
public static void main(String[] args) {
String str = getDirection(0, 0, -40, -34);
System.out.println(str);
}
}
三、通过经纬度坐标计算两个点之间的距离
单位:米
public static double getDistance(double lat1, double longt1, double lat2,
double longt2) {
double PI = 3.14159265358979323; // 圆周率
double R = 6371229; // 地球的半径
double x, y, distance;
x = (longt2 - longt1) * PI * R
* Math.cos(((lat1 + lat2) / 2) * PI / 180) / 180;
y = (lat2 - lat1) * PI * R / 180;
distance = Math.hypot(x, y);
return distance;
}
四、根据gps计算两点之间的距离
/** 参数说明:
* 基于googleMap中的算法得到两经纬度之间的距离,
* 计算精度与谷歌地图的距离精度差不多,相差范围在0.2米以下
* @param lon1 第一点的经度
* @param lat1 第一点的纬度
* @param lon2 第二点的经度
* @param lat3 第二点的纬度
* @return 返回的距离,单位m
* */
public class GPSHelper {
// 圆周率
public static final double PI = 3.14159265358979324;
// 赤道半径(单位m)
private static final double EARTH_RADIUS = 6378137;
/**
* 转化为弧度(rad)
* */
private static double rad(double d) {
return d * Math.PI / 180.0;
}
public static double GetDistance(double lon1,double lat1,double lon2, double lat2) {
double radLat1 = rad(lat1);
double radLat2 = rad(lat2);
double a = radLat1 - radLat2;
double b = rad(lon1) - rad(lon2);
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 * 10000) / 10000;
return s;
}
}
测试:
public double getDistance(double lat1, double lon1, double lat2, double lon2) {
float[] results=new float[1];
Location.distanceBetween(lat1, lon1, lat2, lon2, results);
return results[0];
}
标签:return,经纬度,double,点到点,距离,jiaodu,Double,public,Math 来源: https://blog.51cto.com/u_15078339/2869823