遇上了,记录一下...
大概就是,通过第三方sdk定位目标经纬度,然后计算两个位置的距离等,合并经纬度为一个单一数字等(方便存数据库)和一些转换操作,代码如下:
/** 地图工具类 */ public class WorldMapUtil { /** 经纬度转换常量 */ private static final double EARTH_RADIUS = 6378137.0; /** 保留经纬度小数点后的位数 */ private static int point_length = Context.point_length; /** * 计算AB两点距离(米) * @param lat_a A点纬度 * @param lng_a A点经度 * @param lat_b B点纬度 * @param lng_b B点经度 * @return AB两点距离多少米 */ public static Double getDistance(double lat_a, double lng_a, double lat_b, double lng_b) { double radLat1 = (lat_a * Math.PI / 180.0); double radLat2 = (lat_b * Math.PI / 180.0); double a = radLat1 - radLat2; double b = (lng_a - lng_b) * Math.PI / 180.0; 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; } /** * 计算角方位 * @param lat_a A点纬度 * @param lng_a A点经度 * @param lat_b B点纬度 * @param lng_b B点经度 * @return 返回角度 */ public static double gps2d(double lat_a, double lng_a, double lat_b, double lng_b) { double d = 0; lat_a=lat_a*Math.PI/180; lng_a=lng_a*Math.PI/180; lat_b=lat_b*Math.PI/180; lng_b=lng_b*Math.PI/180; d=Math.sin(lat_a)*Math.sin(lat_b)+Math.cos(lat_a)*Math.cos(lat_b)*Math.cos(lng_b-lng_a); d=Math.sqrt(1-d*d); d=Math.cos(lat_b)*Math.sin(lng_b-lng_a)/d; d=Math.asin(d)*180/Math.PI; // d = (d*10000); return d; } /** * 合并经纬度为一个单一数字 * @param lat 维度 * @param lng 经度 * @return 合并后的单一数据 */ public static Long mergerPoint(Double lat, Double lng) { if(isErrorLoction(lng, lat)) { throw new CommonException(Error.system_location_error); } String latStr = lat.toString(); String lngStr = lng.toString(); int lat_d = latStr.indexOf("."); int lng_d = lngStr.indexOf("."); latStr = latStr.replace(".", ""); lngStr = lngStr.replace(".", ""); // 处理掉过长经纬度 latStr = (latStr.length()-lat_d)>point_length ? latStr.substring(0, lat_d+point_length) : latStr; lngStr = (lngStr.length()-lng_d)>point_length ? lngStr.substring(0, lng_d+point_length) : lngStr; // 处理过短的经纬度 while(latStr.length()-lat_d < point_length) { latStr += "0"; } while(lngStr.length()-lng_d < point_length) { lngStr += "0"; } // 转换成数字数据并获取数据的二进制下的长度(准备做二进制对插) Long tempLat = Long.parseLong(latStr); Long tempLng = Long.parseLong(lngStr); int lengthLat = Long.toBinaryString(tempLat).length(); int lengthLng= Long.toBinaryString(tempLng).length(); // 获取经纬度中最长为位数 int maxLength = lengthLat>lengthLng?lengthLat:lengthLng; // 进行二进制对插处理 Long newPoint = 0L; for(int i=0; i<maxLength; i++) { newPoint += ((tempLat>>i)%2)*(new Double(Math.pow(2, i*2)).longValue()); newPoint += ((tempLng>>i)%2)*(new Double(Math.pow(2, i*2+1)).longValue()); } return newPoint; } /** * 将合并后的数值重新转换为经纬度 * @param num 合并后的数值 * @return 借用 Point.Double 来表示经纬度(x:纬度lat,y:经度lng) */ public static Point.Double getPointForMerger(Long num) { int binaryLength = Long.toBinaryString(num).length(); Long latNg = 0L; Long lngNg = 0L; for(int i=0; i<binaryLength; i++) { if(i%2 == 0) { latNg += ((num>>i)%2) * (new Double(Math.pow(2, i/2)).longValue()); } else { lngNg += ((num>>i)%2) * (new Double(Math.pow(2, i/2)).longValue()); } } Double pow = Math.pow(10, point_length); Double lat = latNg / pow; Double lng = lngNg / pow; return new Point2D.Double(lat, lng); } /** * 校验经纬度是否是异常值 * (处理经纬度有获取不到的情况) * @param lng 经度 * @param lat 纬度 * @return 是否正常(true:非正常) */ public static boolean isErrorLoction(Double lng, Double lat) { if(lng==null || lat==null) { return true; } if(lng.equals(Double.MAX_VALUE) || lat.equals(Double.MAX_VALUE)) { return true; } if(lng.equals(0.0d) || lat.equals(0.0d)) { return true; } // 特殊值(未获取到经纬度时的值) if(lng.equals(4.9E-324) || lat.equals(4.9E-324)) { return true; } return false; } /** * 计算合并后数值间的距离 * @param num1 数值1 * @param num2 数值2 * @return 距离(米) */ public static double getDistance(Long num1, Long num2) { Point.Double pd1 = getPointForMerger(num1); Point.Double pd2 = getPointForMerger(num2); return getDistance(pd1.x, pd1.y, pd2.x, pd2.y); } /** * 计算合并后数值间的角方位 * @param num1 数值1 * @param num2 数值2 * @return 角度 */ public static double gps2d(Long num1, Long num2) { Point.Double pd1 = getPointForMerger(num1); Point.Double pd2 = getPointForMerger(num2); return gps2d(pd1.x, pd1.y, pd2.x, pd2.y); } }