From 244228feba355b4df8e160fd4c7c353f674044f1 Mon Sep 17 00:00:00 2001
From: “mitao” <“2763622819@qq.com”>
Date: 星期六, 14 二月 2026 17:08:05 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/master'

---
 xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/utils/AmapWalkingRouteUtil.java |  606 +++++++++++++++++++++++++++++++-----------------------
 1 files changed, 349 insertions(+), 257 deletions(-)

diff --git a/xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/utils/AmapWalkingRouteUtil.java b/xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/utils/AmapWalkingRouteUtil.java
index 669d522..93afa94 100644
--- a/xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/utils/AmapWalkingRouteUtil.java
+++ b/xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/utils/AmapWalkingRouteUtil.java
@@ -1,18 +1,21 @@
 package com.xiaopeng.map.utils;
 
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
 import com.fasterxml.jackson.databind.JsonNode;
 import com.fasterxml.jackson.databind.ObjectMapper;
+import com.xiaopeng.api.dto.operation.LonLatDto;
+import com.xiaopeng.api.vo.map.PointByIpVo;
 import com.xiaopeng.common.core.exception.ServiceException;
+import com.xiaopeng.common.core.utils.HttpUtils;
 import com.xiaopeng.map.constant.I18nKeyConstant;
 import lombok.extern.slf4j.Slf4j;
 import okhttp3.OkHttpClient;
 import okhttp3.Request;
 import okhttp3.Response;
-import org.springframework.stereotype.Component;
+import org.springframework.beans.factory.annotation.Value;
 
 import java.io.IOException;
-import java.math.BigDecimal;
-import java.math.RoundingMode;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.concurrent.TimeUnit;
@@ -26,317 +29,406 @@
     // 高德地图Web服务API配置
     private static final String AMAP_API_BASE_URL = "https://restapi.amap.com/v3/direction/walking";
     private static final String AMAP_GEOCODING_URL = "https://restapi.amap.com/v3/geocode/geo";
+    // 高德API基础URL
+    private static final String IP_API_URL = "https://restapi.amap.com/v3/ip";
+    private static final String GEOCODE_API_URL = "https://restapi.amap.com/v3/geocode/geo";
 
-    // 你的高德地图API Key(请替换成你自己的)
-    private final String apiKey;
 
     // HTTP客户端
     private final OkHttpClient httpClient;
     private final ObjectMapper objectMapper;
 
+
+    //    @Value("${map.apikey}")
+    private static String apiKey="66ae577f63898dae3016d599fda57221";
+
     /**
-     * 构造函数
-     * @param apiKey 高德地图API Key
+     * IP定位
      */
+    public static PointByIpVo ipLocation(String ip) throws IOException {
+        PointByIpVo pointByIpVo = new PointByIpVo();
+        StringBuilder urlBuilder = new StringBuilder(IP_API_URL)
+                .append("?key=").append(apiKey)
+                .append("&output=json");
+
+        if (ip != null && !ip.trim().isEmpty()) {
+            urlBuilder.append("&ip=").append(ip);
+        }
+
+        String response = HttpUtils.sendGet(urlBuilder.toString());
+        JSONObject jsonObject = JSONObject.parseObject(response);
+
+        // 城市名称
+        String city = jsonObject.getString("city");
+        String province = jsonObject.getString("province");
+        if(("局域网").equals(province)){
+            pointByIpVo.setCity("成都市");
+            LonLatDto lonLatDto = new LonLatDto(104.07, 30.660);
+            pointByIpVo.setPoint(lonLatDto);
+            pointByIpVo.setAdcode("510100");
+            return pointByIpVo;
+        }
+        String adcode = jsonObject.getString("adcode");
+        if (city == null || city.trim().isEmpty() || "[]".equals(city)) {
+            // 直辖市:adcode前两位是11,12,31,50
+            if (adcode != null) {
+                String prefix = adcode.substring(0, 2);
+                if ("11".equals(prefix)) {
+                    city = "北京市";
+                }
+                if ("12".equals(prefix)) {
+                    city = "天津市";
+                }
+                if ("31".equals(prefix)) {
+                    city = "上海市";
+                }
+                if ("50".equals(prefix)) {
+                    city = "重庆市";
+                }
+                // 如果没有city但有province,使用省份
+                city = province;
+            }
+        }
+
+        LonLatDto lonLatDto = geocodeCity(city);
+        pointByIpVo.setCity(city);
+        pointByIpVo.setPoint(lonLatDto);
+        pointByIpVo.setAdcode(adcode);
+        return pointByIpVo;
+
+    }
+
+    private static LonLatDto geocodeCity(String cityName) throws IOException {
+        String url = GEOCODE_API_URL + "?key=" +apiKey + "&address=" + cityName + "&output=json&city=" + cityName;
+        String response = HttpUtils.sendGet(url);
+        System.out.println(response);
+        JSONObject jsonObject = JSONObject.parseObject(response);
+        // 获取geocodes数组
+        JSONArray geocodes = jsonObject.getJSONArray("geocodes");
+        if (geocodes == null || geocodes.isEmpty()) {
+            return null;
+        }
+
+        // 取第一个geocode
+        JSONObject firstGeocode = geocodes.getJSONObject(0);
+
+        // 获取location字段
+        String lonLat = firstGeocode.getString("location");
+        String[] lonLatArray = lonLat.split(",");
+        double longitude = Double.parseDouble(lonLatArray[0]);
+        double latitude = Double.parseDouble(lonLatArray[1]);
+        return new LonLatDto(longitude, latitude);
+
+    }
+        public static void main (String[]args) throws IOException {
+            geocodeCity("凉山彝族自治州");
+
+        }
+
+
+        /**
+         * 构造函数
+         * @param apiKey 高德地图API Key
+         */
     public AmapWalkingRouteUtil(String apiKey) {
-        this.apiKey = apiKey;
-        this.httpClient = new OkHttpClient.Builder()
-                .connectTimeout(10, TimeUnit.SECONDS)
-                .readTimeout(10, TimeUnit.SECONDS)
-                .writeTimeout(10, TimeUnit.SECONDS)
-                .build();
-        this.objectMapper = new ObjectMapper();
-    }
-
-    /**
-     * 位置坐标类
-     */
-    public static class Location {
-        private final double longitude; // 经度
-        private final double latitude;  // 纬度
-
-        public Location(double longitude, double latitude) {
-            this.longitude = longitude;
-            this.latitude = latitude;
-        }
-
-        public double getLongitude() {
-            return longitude;
-        }
-
-        public double getLatitude() {
-            return latitude;
-        }
-
-        @Override
-        public String toString() {
-            return String.format("%.6f,%.6f", longitude, latitude);
-        }
-    }
-
-    /**
-     * 步行路线结果类
-     */
-    public static class WalkingRouteResult {
-        private int duration;      // 步行时间(秒)
-        private int distance;      // 步行距离(米)
-        private String origin;     // 起点地址
-        private String destination; // 终点地址
-        private boolean success;   // 是否成功
-        private String message;    // 返回信息
-
-        // getters and setters
-        public int getDuration() {
-            return duration;
-        }
-
-        public void setDuration(int duration) {
-            this.duration = duration;
-        }
-
-        public int getDistance() {
-            return distance;
-        }
-
-        public void setDistance(int distance) {
-            this.distance = distance;
-        }
-
-        public String getOrigin() {
-            return origin;
-        }
-
-        public void setOrigin(String origin) {
-            this.origin = origin;
-        }
-
-        public String getDestination() {
-            return destination;
-        }
-
-        public void setDestination(String destination) {
-            this.destination = destination;
-        }
-
-        public boolean isSuccess() {
-            return success;
-        }
-
-        public void setSuccess(boolean success) {
-            this.success = success;
-        }
-
-        public String getMessage() {
-            return message;
-        }
-
-        public void setMessage(String message) {
-            this.message = message;
+            this.apiKey = apiKey;
+            this.httpClient = new OkHttpClient.Builder()
+                    .connectTimeout(10, TimeUnit.SECONDS)
+                    .readTimeout(10, TimeUnit.SECONDS)
+                    .writeTimeout(10, TimeUnit.SECONDS)
+                    .build();
+            this.objectMapper = new ObjectMapper();
         }
 
         /**
-         * 获取格式化的步行时间
-         * @return 格式化的时间字符串(如:15分钟30秒)
+         * 位置坐标类
          */
-        public String getFormattedDuration() {
+        public static class Location {
+            private final double longitude; // 经度
+            private final double latitude;  // 纬度
 
-            int seconds = duration;
-            int minutes = seconds / 60;
-            seconds = seconds % 60;
-            return String.format("%d分%d秒", minutes, seconds);
+            public Location(double longitude, double latitude) {
+                this.longitude = longitude;
+                this.latitude = latitude;
+            }
+
+            public double getLongitude() {
+                return longitude;
+            }
+
+            public double getLatitude() {
+                return latitude;
+            }
+
+            @Override
+            public String toString() {
+                return String.format("%.6f,%.6f", longitude, latitude);
+            }
         }
 
         /**
-         * 获取格式化的步行距离
-         * @return 格式化的距离字符串(如:1.2公里)
+         * 步行路线结果类
          */
-        public String getFormattedDistance() {
-            if (distance >= 1000) {
-                double km = distance / 1000.0;
-                return String.format("%.1f公里", km);
-            } else {
-                return String.format("%d米", distance);
-            }
-        }
-    }
+        public static class WalkingRouteResult {
+            private int duration;      // 步行时间(秒)
+            private int distance;      // 步行距离(米)
+            private String origin;     // 起点地址
+            private String destination; // 终点地址
+            private boolean success;   // 是否成功
+            private String message;    // 返回信息
 
-    /**
-     * 根据地址获取经纬度坐标
-     * @param address 地址信息
-     * @return 经纬度坐标
-     */
-    public Location getLocationByAddress(String address) throws IOException {
-        Map<String, String> params = new HashMap<>();
-        params.put("key", apiKey);
-        params.put("address", address);
-
-        String url = buildUrl(AMAP_GEOCODING_URL, params);
-        Request request = new Request.Builder().url(url).build();
-
-        try (Response response = httpClient.newCall(request).execute()) {
-            if (!response.isSuccessful()) {
-                throw new IOException("请求失败: " + response);
+            // getters and setters
+            public int getDuration() {
+                return duration;
             }
 
-            String responseBody = response.body().string();
-            JsonNode rootNode = objectMapper.readTree(responseBody);
+            public void setDuration(int duration) {
+                this.duration = duration;
+            }
 
-            if ("1".equals(rootNode.get("status").asText())) {
-                JsonNode geocodes = rootNode.get("geocodes");
-                if (geocodes != null && geocodes.size() > 0) {
-                    String locationStr = geocodes.get(0).get("location").asText();
-                    String[] locationArray = locationStr.split(",");
-                    double longitude = Double.parseDouble(locationArray[0]);
-                    double latitude = Double.parseDouble(locationArray[1]);
-                    return new Location(longitude, latitude);
+            public int getDistance() {
+                return distance;
+            }
+
+            public void setDistance(int distance) {
+                this.distance = distance;
+            }
+
+            public String getOrigin() {
+                return origin;
+            }
+
+            public void setOrigin(String origin) {
+                this.origin = origin;
+            }
+
+            public String getDestination() {
+                return destination;
+            }
+
+            public void setDestination(String destination) {
+                this.destination = destination;
+            }
+
+            public boolean isSuccess() {
+                return success;
+            }
+
+            public void setSuccess(boolean success) {
+                this.success = success;
+            }
+
+            public String getMessage() {
+                return message;
+            }
+
+            public void setMessage(String message) {
+                this.message = message;
+            }
+
+            /**
+             * 获取格式化的步行时间
+             * @return 格式化的时间字符串(如:15分钟30秒)
+             */
+            public String getFormattedDuration() {
+
+                int seconds = duration;
+                int minutes = seconds / 60;
+                seconds = seconds % 60;
+                return String.format("%d分%d秒", minutes, seconds);
+            }
+
+            /**
+             * 获取格式化的步行距离
+             * @return 格式化的距离字符串(如:1.2公里)
+             */
+            public String getFormattedDistance() {
+                if (distance >= 1000) {
+                    double km = distance / 1000.0;
+                    return String.format("%.1f公里", km);
+                } else {
+                    return String.format("%d米", distance);
                 }
             }
-
-            throw new IOException("地址解析失败: " + rootNode.get("info").asText());
         }
-    }
 
-    /**
-     * 获取步行路线和时间
-     * @param origin 起点坐标
-     * @param destination 终点坐标
-     * @return 步行路线结果
-     */
-    public WalkingRouteResult getWalkingRoute(Location origin, Location destination) {
-        WalkingRouteResult result = new WalkingRouteResult();
-
-        try {
+        /**
+         * 根据地址获取经纬度坐标
+         * @param address 地址信息
+         * @return 经纬度坐标
+         */
+        public Location getLocationByAddress (String address) throws IOException {
             Map<String, String> params = new HashMap<>();
             params.put("key", apiKey);
-            params.put("origin", origin.toString());
-            params.put("destination", destination.toString());
+            params.put("address", address);
 
-            String url = buildUrl(AMAP_API_BASE_URL, params);
+            String url = buildUrl(AMAP_GEOCODING_URL, params);
             Request request = new Request.Builder().url(url).build();
 
             try (Response response = httpClient.newCall(request).execute()) {
                 if (!response.isSuccessful()) {
-                    result.setSuccess(false);
-                    result.setMessage("HTTP请求失败: " + response.code());
-                    return result;
+                    throw new IOException("请求失败: " + response);
                 }
 
                 String responseBody = response.body().string();
                 JsonNode rootNode = objectMapper.readTree(responseBody);
 
-                String status = rootNode.get("status").asText();
-                String info = rootNode.get("info").asText();
-
-                if ("1".equals(status)) {
-                    JsonNode route = rootNode.get("route");
-                    JsonNode paths = route.get("paths");
-
-                    if (paths != null && paths.size() > 0) {
-                        JsonNode firstPath = paths.get(0);
-                        int duration = firstPath.get("duration").asInt();
-                        int distance = firstPath.get("distance").asInt();
-
-                        result.setDuration(duration);
-                        result.setDistance(distance);
-                        result.setSuccess(true);
-                        result.setMessage("成功获取步行路线");
-
-                        // 尝试获取地址信息
-                        result.setOrigin(getAddressByLocation(origin));
-                        result.setDestination(getAddressByLocation(destination));
-
-                    } else {
-                        result.setSuccess(false);
-                        result.setMessage("未找到步行路线");
-                        log.info("未找到步行路线");
-                        throw new ServiceException("未找到步行路线", I18nKeyConstant.NO_WALKING_ROUTE_FOUND);
+                if ("1".equals(rootNode.get("status").asText())) {
+                    JsonNode geocodes = rootNode.get("geocodes");
+                    if (geocodes != null && geocodes.size() > 0) {
+                        String locationStr = geocodes.get(0).get("location").asText();
+                        String[] locationArray = locationStr.split(",");
+                        double longitude = Double.parseDouble(locationArray[0]);
+                        double latitude = Double.parseDouble(locationArray[1]);
+                        return new Location(longitude, latitude);
                     }
-                } else {
-                    result.setSuccess(false);
-                    result.setMessage("API返回错误: " + info);
-                    log.info("API返回错误" + info);
-                    throw new ServiceException("未找到步行路线", I18nKeyConstant.NO_WALKING_ROUTE_FOUND);
                 }
+
+                throw new IOException("地址解析失败: " + rootNode.get("info").asText());
             }
-        } catch (Exception e) {
-            result.setSuccess(false);
-            result.setMessage("获取步行路线失败: " + e.getMessage());
-            log.info("获取步行路线失败" + e.getMessage());
-            throw new ServiceException("未找到步行路线", I18nKeyConstant.NO_WALKING_ROUTE_FOUND);
         }
 
-        return result;
-    }
+        /**
+         * 获取步行路线和时间
+         * @param origin 起点坐标
+         * @param destination 终点坐标
+         * @return 步行路线结果
+         */
+        public WalkingRouteResult getWalkingRoute (Location origin, Location destination){
+            WalkingRouteResult result = new WalkingRouteResult();
 
-    /**
-     * 根据经纬度获取地址(逆地理编码)
-     * @param location 经纬度坐标
-     * @return 地址信息
-     */
-    private String getAddressByLocation(Location location) {
-        try {
-            Map<String, String> params = new HashMap<>();
-            params.put("key", apiKey);
-            params.put("location", location.toString());
+            try {
+                Map<String, String> params = new HashMap<>();
+                params.put("key", apiKey);
+                params.put("origin", origin.toString());
+                params.put("destination", destination.toString());
 
-            String url = buildUrl("https://restapi.amap.com/v3/geocode/regeo", params);
-            Request request = new Request.Builder().url(url).build();
+                String url = buildUrl(AMAP_API_BASE_URL, params);
+                Request request = new Request.Builder().url(url).build();
 
-            try (Response response = httpClient.newCall(request).execute()) {
-                if (response.isSuccessful()) {
+                try (Response response = httpClient.newCall(request).execute()) {
+                    if (!response.isSuccessful()) {
+                        result.setSuccess(false);
+                        result.setMessage("HTTP请求失败: " + response.code());
+                        return result;
+                    }
+
                     String responseBody = response.body().string();
                     JsonNode rootNode = objectMapper.readTree(responseBody);
 
-                    if ("1".equals(rootNode.get("status").asText())) {
-                        JsonNode regeocode = rootNode.get("regeocode");
-                        if (regeocode != null) {
-                            return regeocode.get("formatted_address").asText();
+                    String status = rootNode.get("status").asText();
+                    String info = rootNode.get("info").asText();
+
+                    if ("1".equals(status)) {
+                        JsonNode route = rootNode.get("route");
+                        JsonNode paths = route.get("paths");
+
+                        if (paths != null && paths.size() > 0) {
+                            JsonNode firstPath = paths.get(0);
+                            int duration = firstPath.get("duration").asInt();
+                            int distance = firstPath.get("distance").asInt();
+
+                            result.setDuration(duration);
+                            result.setDistance(distance);
+                            result.setSuccess(true);
+                            result.setMessage("成功获取步行路线");
+
+                            // 尝试获取地址信息
+                            result.setOrigin(getAddressByLocation(origin));
+                            result.setDestination(getAddressByLocation(destination));
+
+                        } else {
+                            result.setSuccess(false);
+                            result.setMessage("未找到步行路线");
+                            log.info("未找到步行路线");
+                            throw new ServiceException("未找到步行路线", I18nKeyConstant.NO_WALKING_ROUTE_FOUND);
+                        }
+                    } else {
+                        result.setSuccess(false);
+                        result.setMessage("API返回错误: " + info);
+                        log.info("API返回错误" + info);
+                        throw new ServiceException("未找到步行路线", I18nKeyConstant.NO_WALKING_ROUTE_FOUND);
+                    }
+                }
+            } catch (Exception e) {
+                result.setSuccess(false);
+                result.setMessage("获取步行路线失败: " + e.getMessage());
+                log.info("获取步行路线失败" + e.getMessage());
+                throw new ServiceException("未找到步行路线", I18nKeyConstant.NO_WALKING_ROUTE_FOUND);
+            }
+
+            return result;
+        }
+
+        /**
+         * 根据经纬度获取地址(逆地理编码)
+         * @param location 经纬度坐标
+         * @return 地址信息
+         */
+        private String getAddressByLocation (Location location){
+            try {
+                Map<String, String> params = new HashMap<>();
+                params.put("key", apiKey);
+                params.put("location", location.toString());
+
+                String url = buildUrl("https://restapi.amap.com/v3/geocode/regeo", params);
+                Request request = new Request.Builder().url(url).build();
+
+                try (Response response = httpClient.newCall(request).execute()) {
+                    if (response.isSuccessful()) {
+                        String responseBody = response.body().string();
+                        JsonNode rootNode = objectMapper.readTree(responseBody);
+
+                        if ("1".equals(rootNode.get("status").asText())) {
+                            JsonNode regeocode = rootNode.get("regeocode");
+                            if (regeocode != null) {
+                                return regeocode.get("formatted_address").asText();
+                            }
                         }
                     }
                 }
+            } catch (Exception e) {
+                // 地址解析失败时返回坐标
             }
-        } catch (Exception e) {
-            // 地址解析失败时返回坐标
+            return location.toString();
         }
-        return location.toString();
-    }
 
-    /**
-     * 构建带参数的URL
-     * @param baseUrl 基础URL
-     * @param params 参数Map
-     * @return 完整的URL
-     */
-    private String buildUrl(String baseUrl, Map<String, String> params) {
-        StringBuilder urlBuilder = new StringBuilder(baseUrl).append("?");
-        params.forEach((key, value) -> {
-            urlBuilder.append(key).append("=").append(value).append("&");
-        });
-        // 删除最后一个&
-        urlBuilder.deleteCharAt(urlBuilder.length() - 1);
-        return urlBuilder.toString();
-    }
+        /**
+         * 构建带参数的URL
+         * @param baseUrl 基础URL
+         * @param params 参数Map
+         * @return 完整的URL
+         */
+        private String buildUrl (String baseUrl, Map < String, String > params){
+            StringBuilder urlBuilder = new StringBuilder(baseUrl).append("?");
+            params.forEach((key, value) -> {
+                urlBuilder.append(key).append("=").append(value).append("&");
+            });
+            // 删除最后一个&
+            urlBuilder.deleteCharAt(urlBuilder.length() - 1);
+            return urlBuilder.toString();
+        }
 
-    /**
-     * 计算两点间的直线距离(仅供参考,不是实际步行距离)
-     * @param loc1 坐标1
-     * @param loc2 坐标2
-     * @return 直线距离(米)
-     */
-    public static double calculateStraightDistance(Location loc1, Location loc2) {
-        double earthRadius = 6371000; // 地球半径(米)
-        double lat1 = Math.toRadians(loc1.getLatitude());
-        double lat2 = Math.toRadians(loc2.getLatitude());
-        double deltaLat = Math.toRadians(loc2.getLatitude() - loc1.getLatitude());
-        double deltaLon = Math.toRadians(loc2.getLongitude() - loc1.getLongitude());
+        /**
+         * 计算两点间的直线距离(仅供参考,不是实际步行距离)
+         * @param loc1 坐标1
+         * @param loc2 坐标2
+         * @return 直线距离(米)
+         */
+        public static double calculateStraightDistance (Location loc1, Location loc2){
+            double earthRadius = 6371000; // 地球半径(米)
+            double lat1 = Math.toRadians(loc1.getLatitude());
+            double lat2 = Math.toRadians(loc2.getLatitude());
+            double deltaLat = Math.toRadians(loc2.getLatitude() - loc1.getLatitude());
+            double deltaLon = Math.toRadians(loc2.getLongitude() - loc1.getLongitude());
 
-        double a = Math.sin(deltaLat / 2) * Math.sin(deltaLat / 2) +
-                Math.cos(lat1) * Math.cos(lat2) *
-                        Math.sin(deltaLon / 2) * Math.sin(deltaLon / 2);
-        double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
+            double a = Math.sin(deltaLat / 2) * Math.sin(deltaLat / 2) +
+                    Math.cos(lat1) * Math.cos(lat2) *
+                            Math.sin(deltaLon / 2) * Math.sin(deltaLon / 2);
+            double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
 
-        return earthRadius * c;
-    }
+            return earthRadius * c;
+        }
 
 
-}
\ No newline at end of file
+    }
\ No newline at end of file

--
Gitblit v1.7.1