利用java、js或mysql计算高德地图中两坐标之间的距离
程序员文章站
2024-04-01 21:05:34
前言
因为工作的原因,最近在做与地图相关的应用,使用了高德地图,研究了下高德地图计算两坐标距离的方法,官网上提供的开发包中有相关的方法,但是我的产品中比较特殊,无法直接使...
前言
因为工作的原因,最近在做与地图相关的应用,使用了高德地图,研究了下高德地图计算两坐标距离的方法,官网上提供的开发包中有相关的方法,但是我的产品中比较特殊,无法直接使用提供的方法,所以就自己封装了相关计算方法,供大家参考,下面话不多说了,来一起看看详细的介绍吧。
java实现
首先定义一个用于存储经纬度的类,这里起个名字叫:lnglat
package amap; import java.text.decimalformat; import java.text.decimalformatsymbols; import java.util.locale; /** * 存储经纬度坐标值的类,单位角度 * * @author jianggujin * */ public final class lnglat implements cloneable { /** * 纬度 (垂直方向) */ public final double latitude; /** * 经度 (水平方向) */ public final double longitude; /** * 格式化 */ private static decimalformat format = new decimalformat("0.000000", new decimalformatsymbols(locale.us)); /** * 使用传入的经纬度构造latlng 对象,一对经纬度值代表地球上一个地点。 * * @param longitude * 地点的经度,在-180 与180 之间的double 型数值。 * @param latitude * 地点的纬度,在-90 与90 之间的double 型数值。 */ public lnglat(double longitude, double latitude) { this(longitude, latitude, true); } /** * 使用传入的经纬度构造latlng 对象,一对经纬度值代表地球上一个地点 * * @param longitude * 地点的经度,在-180 与180 之间的double 型数值。 * * @param latitude * 地点的纬度,在-90 与90 之间的double 型数值。 * @param ischeck * 是否需要检查经纬度的合理性,建议填写true */ public lnglat(double longitude, double latitude, boolean ischeck) { if (ischeck) { if ((-180.0d <= longitude) && (longitude < 180.0d)) this.longitude = parse(longitude); else { throw new illegalargumentexception("the longitude range [-180, 180]."); // this.longitude = parse(((longitude - 180.0d) % 360.0d + 360.0d) % // 360.0d - 180.0d); } if ((latitude < -90.0d) || (latitude > 90.0d)) { throw new illegalargumentexception("the latitude range [-90, 90]."); } this.latitude = latitude; // this.latitude = parse(math.max(-90.0d, math.min(90.0d, latitude))); } else { this.latitude = latitude; this.longitude = longitude; } } /** * 解析 * * @param d * @return */ private static double parse(double d) { return double.parsedouble(format.format(d)); } public lnglat clone() { return new lnglat(this.latitude, this.longitude); } @override public int hashcode() { final int prime = 31; int result = 1; long temp; temp = double.doubletolongbits(latitude); result = prime * result + (int) (temp ^ (temp >>> 32)); temp = double.doubletolongbits(longitude); result = prime * result + (int) (temp ^ (temp >>> 32)); return result; } @override public boolean equals(object obj) { if (this == obj) return true; if (obj == null) return false; if (getclass() != obj.getclass()) return false; lnglat other = (lnglat) obj; if (double.doubletolongbits(latitude) != double.doubletolongbits(other.latitude)) return false; if (double.doubletolongbits(longitude) != double.doubletolongbits(other.longitude)) return false; return true; } public string tostring() { return "lat/lng: (" + this.latitude + "," + this.longitude + ")"; } }
计算工具类如下:
package amap; /** * 高德地图工具 * * @author jianggujin * */ public class amaputils { /** * 根据用户的起点和终点经纬度计算两点间距离,此距离为相对较短的距离,单位米。 * * @param start * 起点的坐标 * @param end * 终点的坐标 * @return */ public static double calculatelinedistance(lnglat start, lnglat end) { if ((start == null) || (end == null)) { throw new illegalargumentexception("非法坐标值,不能为null"); } double d1 = 0.01745329251994329d; double d2 = start.longitude; double d3 = start.latitude; double d4 = end.longitude; double d5 = end.latitude; d2 *= d1; d3 *= d1; d4 *= d1; d5 *= d1; double d6 = math.sin(d2); double d7 = math.sin(d3); double d8 = math.cos(d2); double d9 = math.cos(d3); double d10 = math.sin(d4); double d11 = math.sin(d5); double d12 = math.cos(d4); double d13 = math.cos(d5); double[] arrayofdouble1 = new double[3]; double[] arrayofdouble2 = new double[3]; arrayofdouble1[0] = (d9 * d8); arrayofdouble1[1] = (d9 * d6); arrayofdouble1[2] = d7; arrayofdouble2[0] = (d13 * d12); arrayofdouble2[1] = (d13 * d10); arrayofdouble2[2] = d11; double d14 = math.sqrt((arrayofdouble1[0] - arrayofdouble2[0]) * (arrayofdouble1[0] - arrayofdouble2[0]) + (arrayofdouble1[1] - arrayofdouble2[1]) * (arrayofdouble1[1] - arrayofdouble2[1]) + (arrayofdouble1[2] - arrayofdouble2[2]) * (arrayofdouble1[2] - arrayofdouble2[2])); return (math.asin(d14 / 2.0d) * 12742001.579854401d); } }
最后边写一段测试代码测试一下:
package test; import org.junit.test; import amap.amaputils; import amap.lnglat; public class amaptest { @test public void test() { lnglat start = new lnglat(116.368904, 39.923423); lnglat end = new lnglat(116.387271, 39.922501); system.err.println(amaputils.calculatelinedistance(start, end)); } }
运行结果为:1569.6213922679392,官网的javascript api示例结果如图:
结果虽然有一点误差,但是这hi在可接受范围内的。
javascript实现
同样的算法,将其转换成js的写法,完整的代码如下:
<!doctype html> <html> <head> <meta charset="utf-8" /> <title></title> <script type="text/javascript" src="js/ajax.js"></script> <script> /** * 存储经纬度 * @param {object} longitude * @param {object} latitude */ function lnglat(longitude, latitude) { this.longitude = longitude; this.latitude = latitude; } function calculatelinedistance(start, end) { var d1 = 0.01745329251994329; var d2 = start.longitude; var d3 = start.latitude; var d4 = end.longitude; var d5 = end.latitude; d2 *= d1; d3 *= d1; d4 *= d1; d5 *= d1; var d6 = math.sin(d2); var d7 = math.sin(d3); var d8 = math.cos(d2); var d9 = math.cos(d3); var d10 = math.sin(d4); var d11 = math.sin(d5); var d12 = math.cos(d4); var d13 = math.cos(d5); var arrayofdouble1 = []; var arrayofdouble2 = []; arrayofdouble1.push(d9 * d8); arrayofdouble1.push(d9 * d6); arrayofdouble1.push(d7); arrayofdouble2.push(d13 * d12); arrayofdouble2.push(d13 * d10); arrayofdouble2.push(d11); var d14 = math.sqrt((arrayofdouble1[0] - arrayofdouble2[0]) * (arrayofdouble1[0] - arrayofdouble2[0]) + (arrayofdouble1[1] - arrayofdouble2[1]) * (arrayofdouble1[1] - arrayofdouble2[1]) + (arrayofdouble1[2] - arrayofdouble2[2]) * (arrayofdouble1[2] - arrayofdouble2[2])); return(math.asin(d14 / 2.0) * 12742001.579854401); } var start = new lnglat(116.368904, 39.923423); var end = new lnglat(116.387271, 39.922501); </script> </head> <body> <script> document.write(calculatelinedistance(start, end)); </script> </body> </html>
mysql实现
delimiter $$ create function `calculatelinedistance`(startlng double, startlat double, endlng double, endlat double) returns double begin declare d2 double; declare d3 double; declare d4 double; declare d5 double; declare d6 double; declare d7 double; declare d8 double; declare d9 double; declare d10 double; declare d11 double; declare d12 double; declare d13 double; declare d14 double; declare arrayofdouble10 double; declare arrayofdouble11 double; declare arrayofdouble12 double; declare arrayofdouble20 double; declare arrayofdouble21 double; declare arrayofdouble22 double; set d2 = startlng * 0.01745329251994329; set d3 = startlat * 0.01745329251994329; set d4 = endlng * 0.01745329251994329; set d5 = endlat * 0.01745329251994329; set d6 = sin(d2); set d7 = sin(d3); set d8 = cos(d2); set d9 = cos(d3); set d10 = sin(d4); set d11 = sin(d5); set d12 = cos(d4); set d13 = cos(d5); set arrayofdouble10 = (d9 * d8); set arrayofdouble11 = (d9 * d6); set arrayofdouble12 = d7; set arrayofdouble20 = (d13 * d12); set arrayofdouble21 = (d13 * d10); set arrayofdouble22 = d11; set d14 = sqrt((arrayofdouble10 - arrayofdouble20) * (arrayofdouble10 - arrayofdouble20) + (arrayofdouble11 - arrayofdouble21) * (arrayofdouble11 - arrayofdouble21) + (arrayofdouble12 - arrayofdouble22) * (arrayofdouble12 - arrayofdouble22)); return (asin(d14 / 2.0) * 12742001.579854401); end $$ delimiter ;
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对的支持。