JAVA经纬度互转、计算工具类

JAVA经纬度互转、计算工具类1 经纬度转换工具类 import com wh whcloud core base util StringUtil import lombok extern slf4j Slf4j 经纬度工具类 Slf4j public class LonlatUtils public static void

大家好,我是讯享网,很高兴认识大家。

1、经纬度转换工具类

 import com.wh.whcloud.core.base.util.StringUtil; import lombok.extern.slf4j.Slf4j; / * 经纬度工具类 */ @Slf4j public class LonlatUtils { /* public static void main(String[] args) { System.out.println(DmTurnD("120°39.516'")); System.out.println(DmTurnD("30°46.237'")); }*/ / * 表示角度的度、分、秒分别使用°、′、″符号进行表示。 * 1°=60′,1′=60″ ,1°=3600″。 * 由上述可知度分秒转换度的计算公式为:(dd°mm′ss″) dd+mm/60+ss/3600 * 经纬度转换 ,度分秒转度 * @param jwd * @return */ public static String DmsTurnD(String jwd){ try{ if(StringUtil.isNotEmpty(jwd)&&(jwd.contains("°"))){//如果不为空并且存在度单位 //计算前进行数据处理 jwd = jwd.replace("E", "").replace("N", "").replace(":", "").replace(":", ""); double d=0,m=0,s=0; d = Double.parseDouble(jwd.split("°")[0]); //不同单位的分,可扩展 if(jwd.contains("′")){//正常的′ m = Double.parseDouble(jwd.split("°")[1].split("′")[0]); }else if(jwd.contains("'")){//特殊的' m = Double.parseDouble(jwd.split("°")[1].split("'")[0]); } //不同单位的秒,可扩展 if(jwd.contains("″")){//正常的″ //有时候没有分 如:112°10.25″ s = jwd.contains("′")?Double.parseDouble(jwd.split("′")[1].split("″")[0]):Double.parseDouble(jwd.split("°")[1].split("″")[0]); }else if(jwd.contains("''")){//特殊的'' //有时候没有分 如:112°10.25'' s = jwd.contains("'")?Double.parseDouble(jwd.split("'")[1].split("''")[0]):Double.parseDouble(jwd.split("°")[1].split("''")[0]); } jwd = String.valueOf(d+m/60+s/60/60);//计算并转换为string //使用BigDecimal进行加减乘除 /*BigDecimal bd = new BigDecimal("60"); BigDecimal d = new BigDecimal(jwd.contains("°")?jwd.split("°")[0]:"0"); BigDecimal m = new BigDecimal(jwd.contains("′")?jwd.split("°")[1].split("′")[0]:"0"); BigDecimal s = new BigDecimal(jwd.contains("″")?jwd.split("′")[1].split("″")[0]:"0"); //divide相除可能会报错(无限循环小数),要设置保留小数点 jwd = String.valueOf(d.add(m.divide(bd,6,BigDecimal.ROUND_HALF_UP) .add(s.divide(bd.multiply(bd),6,BigDecimal.ROUND_HALF_UP))));*/ } }catch (Exception e){ log.info("度分秒转换错误"); return jwd; } return jwd; } / * 度分 转度 * 十进制经纬度转换 ddd°mm.mmmm' 转 ddd.ddddd° * 如:112°30.4128' = 112.50688 * @param jwd * @return */ public static String DmTurnD(String jwd){ try { if(StringUtil.isNotEmpty(jwd)&&(jwd.contains("°")&&jwd.contains("'"))){//如果不为空并且存在度、分单位 double d=0,m=0; d = Double.parseDouble(jwd.split("°")[0]); m = Double.parseDouble(jwd.split("°")[1].split("'")[0])/60; jwd = String.valueOf(d+m); }else if(StringUtil.isNotEmpty(jwd)&&(jwd.contains("°"))){//如果不为空并且存在度单位 double d=0,m=0; d = Double.parseDouble(jwd.split("°")[0]); m = Double.parseDouble(jwd.split("°")[1])/60; jwd = String.valueOf(d+m); } }catch (Exception e){ log.info("度分转换错误"); return jwd; } return jwd; } } 

讯享网

 2、DistanceUtil工具类

讯享网public class DistanceUtil { public static final double earthRadius = 6371.393D; public static final double nmi = 5.4E-4D; public DistanceUtil() { } public static double meterToNmi(double len) { return len * 5.4E-4D; } public static double meterToDegree(double len) { return km2Degree(len / 1000.0D); } private static double rad(double d) { return d * 3.9793D / 180.0D; } 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.0D * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2.0D), 2.0D) + Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(b / 2.0D), 2.0D))); s *= 6371.393D; s = (double)Math.round(s * 10000.0D) / 10000.0D; s *= 1000.0D; return s; } public static Double km2Degree(Double l) { Double degree = 0.0005603D * l; return degree; } public static Double degree2Km(Double degree) { Double l = 111.908D * degree; return l; } } 

3、经纬度角度计算工具类


讯享网

import com.util.DistanceUtil; public class AngleUtil { / * 根据俯仰角计算水平距离 俯仰角小于45度时适用 * * @param h 单位米 * @param angle 单位度 * @return */ public static double HorizontalAngleCal(double h, double angle) { return h * Math.tan(angle); } / * 获取云台和目标的直线距离(斜边长) * @param lon1 * @param lat1 * @param lon2 * @param lat2 * @param h * @return */ public static double getDistance(double lon1,double lat1,double lon2,double lat2,double h){ double l = DistanceUtil.getDistance(lat1,lon1,lat2,lon2); return Math.sqrt(Math.pow(h,2)+ Math.pow(l,2)); } / * 获取俯仰角度 * @param lon1 * @param lat1 * @param lon2 * @param lat2 * @param h * @return */ public static double getTilAngle(double lon1,double lat1,double lon2,double lat2,double h){ double l = DistanceUtil.getDistance(lat1,lon1,lat2,lon2); return Math.toDegrees(Math.atan (l/h)); } / * 求两点连线与正北方向的角度(水平角度) * @param A * @param B * @return */ public static double getPanAngle(LatLon A, LatLon B) { double dx = (B.m_RadLo - A.m_RadLo) * A.Ed; double dy = (B.m_RadLa - A.m_RadLa) * A.Ec; double angle = 0.0; angle = Math.atan(Math.abs(dx / dy)) * 180 / Math.PI; double dLo = B.m_Longitude - A.m_Longitude; double dLa = B.m_Latitude - A.m_Latitude; if (dLo > 0 && dLa <= 0) { angle = (90 - angle) + 90; } else if (dLo <= 0 && dLa < 0) { angle = angle + 180; } else if (dLo < 0 && dLa >= 0) { angle = (90 - angle) + 270; } return angle; } / * 获取方位角 * @param lat_a 纬度1 * @param lng_a 经度1 * @param lat_b 纬度2 * @param lng_b 经度2 * @return */ public static double getBearingAngle(double lat_a, double lng_a, double lat_b, double lng_b) { try { double y = Math.sin(lng_b-lng_a) * Math.cos(lat_b); double x = Math.cos(lat_a)*Math.sin(lat_b) - Math.sin(lat_a)*Math.cos(lat_b)*Math.cos(lng_b-lng_a); double brng = Math.atan2(y, x); brng = Math.toDegrees(brng); if(brng < 0){ brng = brng +360; } return brng; }catch (Exception e){ e.printStackTrace(); return 0d; } } } 

 4、判断经纬度坐标点是否在区域内工具类

讯享网import java.math.BigDecimal; import java.util.ArrayList; import java.util.Collections; import java.util.List; public class PolygonUtil { / * 求一个坐标点距离区域最近距离 * * @param lon * @param lat * @param plotPointModelList * @return */ /*public static double getDistanceFromPointToPolygon(BigDecimal lon, BigDecimal lat, List<PlotPointModel> plotPointModelList) { if (plotPointModelList.size() > 2) { //求出距离最短的两个点 PlotPointModel minPoint1 = plotPointModelList.get(0); PlotPointModel minPoint2 = plotPointModelList.get(1); double d1 = DistanceUtil.getDistance(lat.doubleValue(), lon.doubleValue(), minPoint1.getLat().doubleValue(), minPoint1.getLon().doubleValue()); double d2 = DistanceUtil.getDistance(lat.doubleValue(), lon.doubleValue(), minPoint2.getLat().doubleValue(), minPoint2.getLon().doubleValue()); if (d1 > d2) { PlotPointModel temp = minPoint1; minPoint1 = minPoint2; minPoint2 = temp; } for (int i = 2; i < plotPointModelList.size(); i++) { PlotPointModel plotPoint = plotPointModelList.get(i); double d = DistanceUtil.getDistance(lat.doubleValue(), lon.doubleValue(), plotPoint.getLat().doubleValue(), plotPoint.getLon().doubleValue()); if (d < d1) { d2 = d1; d1 = d; minPoint2 = minPoint1; minPoint1 = plotPoint; } else if (d < d2) { d2 = d; minPoint2 = plotPoint; } } //根据最短两点,求最短距离 double c = DistanceUtil .getDistance(minPoint1.getLat().doubleValue(), minPoint1.getLon().doubleValue(), minPoint2.getLat().doubleValue(), minPoint2.getLon().doubleValue()); if (Math.pow(d2, 2) >= Math.pow(d1, 2) + Math.pow(c, 2)) { //钝角三角形 return d1; } //锐角三角形,计算垂足,海伦公式 //计算周长 double p = (d1 + d2 + c) / 2; //计算面积 double a = p * (p - d1) * (p - d2) * (p - c); double s = Math.sqrt(a); //返回高 return s / c; } return -1; }*/ / * <p> * 计算点到折线的最短距离 * 计算点到每条线段的最短距离,排序之后,拿最短的一条 * </p> * * @param lon * @param lat * @param plotPointModelList * @return {@link double} * @author hahalouti * @date 2021/10/26 */ public static double getDistanceFromPointToPolygon(BigDecimal lon, BigDecimal lat, List<PlotPointModel> plotPointModelList) { List<Double> distance = new ArrayList<>(); for (int i = 0; i < plotPointModelList.size() - 1; i++) { PlotPointModel plotPoint = plotPointModelList.get(i); PlotPointModel plotPoint2 = plotPointModelList.get(i + 1); double d1 = DistanceUtil.getDistance(lat.doubleValue(), lon.doubleValue(), plotPoint.getLat().doubleValue(), plotPoint.getLon().doubleValue()); double d2 = DistanceUtil.getDistance(lat.doubleValue(), lon.doubleValue(), plotPoint2.getLat().doubleValue(), plotPoint2.getLon().doubleValue()); double c = DistanceUtil .getDistance(plotPoint.getLat().doubleValue(), plotPoint.getLon().doubleValue(), plotPoint2.getLat().doubleValue(), plotPoint2.getLon().doubleValue()); // 判断是否是钝角三角形 if (Math.pow(d1, 2) >= Math.pow(d2, 2) + Math.pow(c, 2)) { //钝角三角形 distance.add(d2); } else if (Math.pow(d2, 2) >= Math.pow(d1, 2) + Math.pow(c, 2)) { //钝角三角形 distance.add(d1); } else { double p = (d1 + d2 + c) / 2; //计算面积 double a = p * (p - d1) * (p - d2) * (p - c); double s = Math.sqrt(a); //返回高 distance.add(s / c); } } Collections.sort(distance); return distance.get(0); } / * 判断坐标点是否在一个区域内 * * @param lon * @param lat * @param plotPointModelList * @return */ public static boolean checkInPolygon(BigDecimal lon, BigDecimal lat, List<PlotPointModel> plotPointModelList) { double pointLon = lon.doubleValue(); double pointLat = lat.doubleValue(); int size = plotPointModelList.size(); if (size < 3) { return false; } else { PlotPointModel first = plotPointModelList.get(0); PlotPointModel end = plotPointModelList.get(size - 1); if (first.getLon().doubleValue() == end.getLon().doubleValue() && first.getLat().doubleValue() == end.getLat().doubleValue()) { plotPointModelList.remove(size - 1); } int pointCount = plotPointModelList.size(); int intersectPointCount = 0; float intersectPointWeights = 0.0F; double precision = 2.0E-10D; for (int i = 1; i <= pointCount; ++i) { PlotPointModel next = plotPointModelList.get(i % pointCount); double firstLon = first.getLon().doubleValue(); double firstLat = first.getLat().doubleValue(); double nextLon = next.getLon().doubleValue(); double nextLat = next.getLat().doubleValue(); if (pointLat >= Math.min(firstLat, nextLat) && pointLat <= Math.max(firstLat, nextLat)) { if (pointLat > Math.min(firstLat, nextLat) && pointLat < Math.max(firstLat, nextLat)) { if (firstLon == nextLon) { if (pointLon == firstLon) { return true; } if (pointLon < firstLon) { ++intersectPointCount; } } else if (pointLon <= Math.min(firstLon, nextLon)) { ++intersectPointCount; } else if (pointLon > Math.min(firstLon, nextLon) && pointLon < Math .max(firstLon, nextLon)) { double slopeDiff = 0.0D; if (firstLat > nextLat) { slopeDiff = (pointLat - nextLat) / (pointLon - nextLon) - (firstLat - nextLat) / ( firstLon - nextLon); } else { slopeDiff = (pointLat - firstLat) / (pointLon - firstLon) - (nextLat - firstLat) / ( nextLon - firstLon); } if (slopeDiff > 0.0D) { if (slopeDiff < precision) { return true; } ++intersectPointCount; } } } else { if (firstLat == nextLat && pointLon <= Math.max(firstLon, nextLon) && pointLon >= Math .min(firstLon, nextLon)) { return true; } if (pointLat == firstLat && pointLon < firstLon || pointLat == nextLat && pointLon < nextLon) { if (nextLat < firstLat) { intersectPointWeights = (float) ((double) intersectPointWeights + -0.5D); } else if (nextLat > firstLat) { intersectPointWeights = (float) ((double) intersectPointWeights + 0.5D); } } } first = next; } else { first = next; } } if (((float) intersectPointCount + Math.abs(intersectPointWeights)) % 2.0F == 0.0F) { return false; } else { return true; } } } // // // public static void main(String[] args) { // BigDecimal lon = new BigDecimal(122.63987); // BigDecimal lat = new BigDecimal(39.25399); // List<PlotPointModel> plotPointModelList = new ArrayList<>(); // PlotPointModel plotPointModel = new PlotPointModel(); // plotPointModel.setLon(new BigDecimal(122.)); // plotPointModel.setLat(new BigDecimal(39.)); // plotPointModelList.add(plotPointModel); // // PlotPointModel plotPointModel2 = new PlotPointModel(); // plotPointModel2.setLon(new BigDecimal(122.)); // plotPointModel2.setLat(new BigDecimal(39.)); // plotPointModelList.add(plotPointModel2); // // PlotPointModel plotPointModel3 = new PlotPointModel(); // plotPointModel3.setLon(new BigDecimal(122.)); // plotPointModel3.setLat(new BigDecimal(39.)); // plotPointModelList.add(plotPointModel3); // // PlotPointModel plotPointModel4 = new PlotPointModel(); // plotPointModel4.setLon(new BigDecimal(122.)); // plotPointModel4.setLat(new BigDecimal(39.)); // plotPointModelList.add(plotPointModel4); // // System.out.println(checkInPolygon(lon,lat,plotPointModelList)); // } }

小讯
上一篇 2025-02-20 15:57
下一篇 2025-02-14 19:47

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/122232.html