diff --git a/ghy-admin/src/main/resources/templates/goods/category/serviceTree.html b/ghy-admin/src/main/resources/templates/goods/category/serviceTree.html new file mode 100644 index 00000000..434924a0 --- /dev/null +++ b/ghy-admin/src/main/resources/templates/goods/category/serviceTree.html @@ -0,0 +1,69 @@ + + + + + + + +
+
+
+ +
+
+ + + +
+
+
+
+ +
+
+
+
+
+
+   + +
+
+
+
+ + + + + \ No newline at end of file diff --git a/ghy-common/src/main/java/com/ghy/common/utils/LocationUtils.java b/ghy-common/src/main/java/com/ghy/common/utils/LocationUtils.java new file mode 100644 index 00000000..dd16c1e9 --- /dev/null +++ b/ghy-common/src/main/java/com/ghy/common/utils/LocationUtils.java @@ -0,0 +1,166 @@ +package com.ghy.common.utils; + +/** + * 地理位置计算工具类 + * 提供经纬度之间的距离计算功能 + * + * @author clunt + */ +public class LocationUtils { + + /** 地球半径(千米) */ + private static final double EARTH_RADIUS_KM = 6371.0; + + /** 地球半径(米) */ + private static final double EARTH_RADIUS_M = 6371000.0; + + /** + * 使用Haversine公式计算两点间的距离(米) + * + * @param lat1 第一个点的纬度 + * @param lng1 第一个点的经度 + * @param lat2 第二个点的纬度 + * @param lng2 第二个点的经度 + * @return 距离(米) + */ + public static double getDistanceInMeters(double lat1, double lng1, double lat2, double lng2) { + return getDistanceInKilometers(lat1, lng1, lat2, lng2) * 1000; + } + + /** + * 使用Haversine公式计算两点间的距离(千米) + * + * @param lat1 第一个点的纬度 + * @param lng1 第一个点的经度 + * @param lat2 第二个点的纬度 + * @param lng2 第二个点的经度 + * @return 距离(千米) + */ + public static double getDistanceInKilometers(double lat1, double lng1, double lat2, double lng2) { + // 将角度转换为弧度 + double lat1Rad = Math.toRadians(lat1); + double lng1Rad = Math.toRadians(lng1); + double lat2Rad = Math.toRadians(lat2); + double lng2Rad = Math.toRadians(lng2); + + // 计算经纬度差值 + double deltaLat = lat2Rad - lat1Rad; + double deltaLng = lng2Rad - lng1Rad; + + // Haversine公式 + double a = Math.sin(deltaLat / 2) * Math.sin(deltaLat / 2) + + Math.cos(lat1Rad) * Math.cos(lat2Rad) * + Math.sin(deltaLng / 2) * Math.sin(deltaLng / 2); + + double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); + + return EARTH_RADIUS_KM * c; + } + + /** + * 判断某个点是否在指定范围内 + * + * @param centerLat 中心点纬度 + * @param centerLng 中心点经度 + * @param targetLat 目标点纬度 + * @param targetLng 目标点经度 + * @param radiusKm 半径(千米) + * @return 是否在范围内 + */ + public static boolean isWithinRadius(double centerLat, double centerLng, + double targetLat, double targetLng, + double radiusKm) { + double distance = getDistanceInKilometers(centerLat, centerLng, targetLat, targetLng); + return distance <= radiusKm; + } + + /** + * 格式化距离显示 + * + * @param distanceInMeters 距离(米) + * @return 格式化后的距离字符串 + */ + public static String formatDistance(double distanceInMeters) { + if (distanceInMeters < 1000) { + return String.format("%.0f米", distanceInMeters); + } else { + double km = distanceInMeters / 1000; + if (km < 10) { + return String.format("%.1f公里", km); + } else { + return String.format("%.0f公里", km); + } + } + } + + /** + * 计算两个坐标点的方位角(以正北为0度,顺时针) + * + * @param lat1 起点纬度 + * @param lng1 起点经度 + * @param lat2 终点纬度 + * @param lng2 终点经度 + * @return 方位角(度数,0-360) + */ + public static double getBearing(double lat1, double lng1, double lat2, double lng2) { + double lat1Rad = Math.toRadians(lat1); + double lat2Rad = Math.toRadians(lat2); + double deltaLngRad = Math.toRadians(lng2 - lng1); + + double y = Math.sin(deltaLngRad) * Math.cos(lat2Rad); + double x = Math.cos(lat1Rad) * Math.sin(lat2Rad) - + Math.sin(lat1Rad) * Math.cos(lat2Rad) * Math.cos(deltaLngRad); + + double bearingRad = Math.atan2(y, x); + double bearingDeg = Math.toDegrees(bearingRad); + + // 转换为0-360度 + return (bearingDeg + 360) % 360; + } + + /** + * 将方位角转换为方向描述 + * + * @param bearing 方位角(度数) + * @return 方向描述 + */ + public static String getDirectionDescription(double bearing) { + String[] directions = {"北", "东北", "东", "东南", "南", "西南", "西", "西北"}; + int index = (int) Math.round(bearing / 45) % 8; + return directions[index]; + } + + /** + * 验证经纬度的有效性 + * + * @param latitude 纬度 + * @param longitude 经度 + * @return 是否有效 + */ + public static boolean isValidCoordinate(Double latitude, Double longitude) { + if (latitude == null || longitude == null) { + return false; + } + return latitude >= -90 && latitude <= 90 && longitude >= -180 && longitude <= 180; + } + + /** + * 计算中心点坐标(多个点的几何中心) + * + * @param coordinates 坐标点数组,每个元素为[纬度, 经度] + * @return 中心点坐标 [纬度, 经度] + */ + public static double[] getCenterPoint(double[][] coordinates) { + if (coordinates == null || coordinates.length == 0) { + return null; + } + + double sumLat = 0, sumLng = 0; + for (double[] coord : coordinates) { + sumLat += coord[0]; + sumLng += coord[1]; + } + + return new double[]{sumLat / coordinates.length, sumLng / coordinates.length}; + } +} \ No newline at end of file