最近使用百度地图生成路径规划的路径。
在行驶的路径中有部分是直线,两个点的距离比较长(最长的大约在500左右)。
我这里处理是对超两个点距离超过300米的进行密度细化处理。
大致逻辑:
1.判断两个点的距离是否大于300米。
2.如果超过300米,对点进行细化。
因为处理的是中国地区的点,这里逻辑有不同的地方。
我们身处北半球,也就是北纬,东经地带。
大概分析,路线走向的4种情况。
经过实测,细化的点跟百度地图生成的点可以完全融合。
代码如下:
1 /** 2 * 地图工具 3 * 4 * @date 2019-09-04 13:51 5 */ 6 public class MapUtil { 7 8 /** 9 * 地球半径 平均值,千米 10 */ 11 public static final double EARTH_RADIUS = 6371.0; 12 13 private MapUtil() { 14 } 15 16 /** 17 * 给定的经度1,纬度1;经度2,纬度2. 计算2个经纬度之间的距离。 18 * 19 * @param lat1 经度1 20 * @param lon1 纬度1 21 * @param lat2 经度2 22 * @param lon2 纬度2 23 * @return 距离(公里、千米) 24 */ 25 public static double distance(double lat1, double lon1, double lat2, double lon2) { 26 // 用haversine公式计算球面两点间的距离。 27 // 经纬度转换成弧度 28 lat1 = convertDegreesToRadians(lat1); 29 lon1 = convertDegreesToRadians(lon1); 30 lat2 = convertDegreesToRadians(lat2); 31 lon2 = convertDegreesToRadians(lon2); 32 // 差值 33 double vLon = Math.abs(lon1 - lon2); 34 double vLat = Math.abs(lat1 - lat2); 35 // h is the great circle distance in radians, great circle就是一个球体上的切面,它的圆心即是球心的一个周长最大的圆。 36 double h = haverSin(vLat) + Math.cos(lat1) * Math.cos(lat2) * haverSin(vLon); 37 return 2 * EARTH_RADIUS * Math.asin(Math.sqrt(h)); 38 } 39 40 public static double haverSin(double theta) { 41 double v = Math.sin(theta / 2); 42 return v * v; 43 } 44 45 /** 46 * 将角度换算为弧度。 47 * 48 * @param degrees 角度 49 * @return 弧度 50 */ 51 public static double convertDegreesToRadians(double degrees) { 52 return degrees * Math.PI / 180; 53 } 54 55 /** 56 * 弧度换算为角度 57 * 58 * @param radian 弧度 59 * @return 角度 60 */ 61 public static double convertRadiansToDegrees(double radian) { 62 return radian * 180.0 / Math.PI; 63 } 64 65 /** 66 * 对两个点做直线密度细化 67 * 条件:北半球,北纬,东经 68 * 69 * @param lat1 经度1 70 * @param lon1 纬度1 71 * @param lat2 经度2 72 * @param lon2 纬度2 73 * @return 细化点 74 */ 75 public static double[] averagePoint(double lat1, double lon1, double lat2, double lon2) { 76 // 对经度进行偏差计算 77 // 判断斜率 78 // 经度斜率,纬度斜率 79 boolean slopeLat = lat1 > lat2; 80 boolean slopeLon = lon1 > lon2; 81 // 斜率差 82 double avLat; 83 double avLon; 84 // 第三个点的位置 85 double lat3; 86 double lon3; 87 // -+ 88 if (slopeLat && slopeLon) { 89 avLat = averageValue(lat1, lat2); 90 avLon = averageValue(lon2, lon1); 91 lat3 = format6(lat1 - avLat); 92 lon3 = format6(lon1 + avLon); 93 } 94 // -- 95 else if (slopeLat && !slopeLon) { 96 avLat = averageValue(lat1, lat2); 97 avLon = averageValue(lon1, lon2); 98 lat3 = format6(lat1 - avLat); 99 lon3 = format6(lon1 - avLon); 100 } 101 // +- 102 else if (!slopeLat && slopeLon) { 103 avLat = averageValue(lat2, lat1); 104 avLon = averageValue(lon1, lon2); 105 lat3 = format6(lat1 + avLat); 106 lon3 = format6(lon1 - avLon); 107 } 108 // ++ 109 else { 110 avLat = averageValue(lat2, lat1); 111 avLon = averageValue(lon2, lon1); 112 lat3 = format6(lat1 + avLat); 113 lon3 = format6(lon1 + avLon); 114 } 115 return new double[]{lat3, lon3}; 116 } 117 118 /** 119 * 计算两点平均差值 120 * 121 * @param d1 点1 122 * @param d2 点2 123 * @return 点差值 124 */ 125 public static double averageValue(double d1, double d2) { 126 double d3 = d1 - d2; 127 // 除2,做平均差值 128 return format6(d3 / 2); 129 } 130 131 /** 132 * 留六位小数 133 * 134 * @param value 小数 135 * @return 小数 136 */ 137 public static double format6(double value) { 138 return (double) Math.round(value * 1000000) / 1000000; 139 } 140 }
作者:Se7end
声明:本博客文章为原创,只代表本人在工作学习中某一时间内总结的观点或结论。转载时请在文章页面明显位置给出原文链接。