SunnyFarm/tmp/ExpressMapTest.java
superlishunqin 364b7acbb7 END
2025-10-10 23:22:52 +08:00

478 lines
24 KiB
Java
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.io.File;
/**
* 阿里云物流轨迹地图API测试
* 快递单号434815453222560韵达快递
*/
public class ExpressMapTest {
public static void main(String[] args) {
String host = "https://alicloudmarket8002.kdniao.com";
String path = "/api/track/8002";
String appcode = "e7b5746ef8854cf2a6da24342ab53af6";
String body = "{\"CustomInfo\":\"0000\",\"LogisticCode\":\"434815453222560\"}";
System.out.println("========================================");
System.out.println("阿里云物流轨迹地图API测试");
System.out.println("========================================");
System.out.println("请求地址: " + host + path);
System.out.println("快递公司: 韵达快递");
System.out.println("快递单号: 434815453222560");
System.out.println("----------------------------------------");
try {
URL url = new URL(host + path);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
connection.setRequestProperty("Authorization", "APPCODE " + appcode);
connection.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
connection.setDoOutput(true);
try (OutputStream os = connection.getOutputStream()) {
byte[] input = body.getBytes(StandardCharsets.UTF_8);
os.write(input, 0, input.length);
}
int httpCode = connection.getResponseCode();
System.out.println("HTTP状态码: " + httpCode);
System.out.println("----------------------------------------");
BufferedReader br;
if (httpCode == 200) {
br = new BufferedReader(new InputStreamReader(connection.getInputStream(), StandardCharsets.UTF_8));
} else {
br = new BufferedReader(new InputStreamReader(connection.getErrorStream(), StandardCharsets.UTF_8));
}
StringBuilder response = new StringBuilder();
String line;
while ((line = br.readLine()) != null) {
response.append(line);
}
br.close();
if (httpCode == 200) {
System.out.println("✅ API调用成功");
System.out.println("返回结果:");
System.out.println(response.toString());
java.io.FileWriter fileWriter = new java.io.FileWriter("map_result.json");
fileWriter.write(response.toString());
fileWriter.close();
System.out.println("\n✅ 结果已保存到: map_result.json");
// 获取驾车路线数据
String routeData = getDrivingRoute();
createMapHtml(response.toString(), routeData);
} else {
System.out.println("❌ API调用失败");
System.out.println("错误信息: " + response.toString());
}
System.out.println("========================================");
} catch (Exception e) {
System.out.println("❌ 发生异常");
e.printStackTrace();
}
}
/**
* 调用高德Web服务API获取驾车路线
*/
private static String getDrivingRoute() {
try {
String key = "a0f9b8eecd097889d3aa21f4bd6665ff"; // Web服务API Key
String origin = "113.264385,23.129163"; // 广州
String destination = "114.057868,22.543099"; // 深圳
String urlStr = "https://restapi.amap.com/v3/direction/driving?origin=" + origin +
"&destination=" + destination +
"&key=" + key +
"&output=json";
System.out.println("\n🚗 调用高德驾车路线规划API...");
System.out.println("起点: 广州市");
System.out.println("终点: 深圳市");
URL url = new URL(urlStr);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
int httpCode = connection.getResponseCode();
if (httpCode == 200) {
BufferedReader br = new BufferedReader(
new InputStreamReader(connection.getInputStream(), StandardCharsets.UTF_8)
);
StringBuilder response = new StringBuilder();
String line;
while ((line = br.readLine()) != null) {
response.append(line);
}
br.close();
System.out.println("✅ 驾车路线获取成功");
return response.toString();
} else {
System.out.println("❌ 驾车路线获取失败,状态码: " + httpCode);
return null;
}
} catch (Exception e) {
System.out.println("❌ 获取驾车路线异常: " + e.getMessage());
return null;
}
}
/**
* 创建HTML地图页面使用Web服务API的路线数据
*/
private static void createMapHtml(String jsonData, String routeData) {
try {
String routeJson = routeData != null ? routeData : "null";
String html = "<!DOCTYPE html>\n" +
"<html lang=\"zh-CN\">\n" +
"<head>\n" +
" <meta charset=\"UTF-8\">\n" +
" <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n" +
" <title>物流轨迹地图 - 韵达快递</title>\n" +
" <script>\n" +
" window._AMapSecurityConfig = {\n" +
" securityJsCode: '1d765513173e511dd6e1c963f1b38c5e'\n" +
" };\n" +
" </script>\n" +
" <script src=\"https://webapi.amap.com/maps?v=2.0&key=47c7546d2ac2a12ff7de8caf5b62c753\"></script>\n" +
" <style>\n" +
" * { margin: 0; padding: 0; box-sizing: border-box; }\n" +
" body { font-family: 'Arial', 'Microsoft YaHei', sans-serif; background: #f5f5f5; }\n" +
" .container { max-width: 1600px; margin: 0 auto; padding: 20px; }\n" +
" .header {\n" +
" background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n" +
" color: white;\n" +
" padding: 30px;\n" +
" border-radius: 10px;\n" +
" margin-bottom: 20px;\n" +
" box-shadow: 0 4px 6px rgba(0,0,0,0.1);\n" +
" }\n" +
" .header h1 { font-size: 28px; margin-bottom: 10px; }\n" +
" .header p { opacity: 0.9; }\n" +
" .express-info {\n" +
" background: white;\n" +
" padding: 20px;\n" +
" border-radius: 10px;\n" +
" margin-bottom: 20px;\n" +
" box-shadow: 0 2px 4px rgba(0,0,0,0.1);\n" +
" }\n" +
" .info-item {\n" +
" display: inline-block;\n" +
" margin-right: 30px;\n" +
" padding: 10px 0;\n" +
" }\n" +
" .info-label {\n" +
" color: #666;\n" +
" font-size: 14px;\n" +
" margin-right: 10px;\n" +
" }\n" +
" .info-value {\n" +
" color: #333;\n" +
" font-weight: bold;\n" +
" font-size: 16px;\n" +
" }\n" +
" .main-content {\n" +
" display: grid;\n" +
" grid-template-columns: 1fr 400px;\n" +
" gap: 20px;\n" +
" }\n" +
" .map-container {\n" +
" background: white;\n" +
" border-radius: 10px;\n" +
" overflow: hidden;\n" +
" box-shadow: 0 2px 4px rgba(0,0,0,0.1);\n" +
" }\n" +
" #map {\n" +
" width: 100%;\n" +
" height: 600px;\n" +
" }\n" +
" .timeline-container {\n" +
" background: white;\n" +
" border-radius: 10px;\n" +
" padding: 20px;\n" +
" box-shadow: 0 2px 4px rgba(0,0,0,0.1);\n" +
" max-height: 600px;\n" +
" overflow-y: auto;\n" +
" }\n" +
" .timeline-title {\n" +
" font-size: 18px;\n" +
" font-weight: bold;\n" +
" color: #333;\n" +
" margin-bottom: 20px;\n" +
" padding-bottom: 10px;\n" +
" border-bottom: 2px solid #667eea;\n" +
" }\n" +
" .timeline-item {\n" +
" position: relative;\n" +
" padding-left: 30px;\n" +
" padding-bottom: 20px;\n" +
" border-left: 2px solid #e0e0e0;\n" +
" }\n" +
" .timeline-item:last-child {\n" +
" border-left: none;\n" +
" }\n" +
" .timeline-dot {\n" +
" position: absolute;\n" +
" left: -6px;\n" +
" top: 0;\n" +
" width: 12px;\n" +
" height: 12px;\n" +
" border-radius: 50%;\n" +
" background: #667eea;\n" +
" }\n" +
" .timeline-item:first-child .timeline-dot {\n" +
" background: #28a745;\n" +
" width: 16px;\n" +
" height: 16px;\n" +
" left: -8px;\n" +
" }\n" +
" .timeline-time {\n" +
" color: #999;\n" +
" font-size: 12px;\n" +
" margin-bottom: 5px;\n" +
" }\n" +
" .timeline-location {\n" +
" color: #667eea;\n" +
" font-weight: bold;\n" +
" font-size: 14px;\n" +
" margin-bottom: 5px;\n" +
" }\n" +
" .timeline-desc {\n" +
" color: #333;\n" +
" font-size: 14px;\n" +
" line-height: 1.6;\n" +
" }\n" +
" .status-badge {\n" +
" display: inline-block;\n" +
" padding: 5px 15px;\n" +
" background: #28a745;\n" +
" color: white;\n" +
" border-radius: 20px;\n" +
" font-size: 14px;\n" +
" margin-top: 10px;\n" +
" }\n" +
" .debug-info {\n" +
" background: #e7f3ff;\n" +
" border: 1px solid #b3d9ff;\n" +
" border-radius: 5px;\n" +
" padding: 10px;\n" +
" margin-top: 10px;\n" +
" font-size: 12px;\n" +
" color: #0066cc;\n" +
" }\n" +
" @media (max-width: 1200px) {\n" +
" .main-content {\n" +
" grid-template-columns: 1fr;\n" +
" }\n" +
" }\n" +
" </style>\n" +
"</head>\n" +
"<body>\n" +
" <div class=\"container\">\n" +
" <div class=\"header\">\n" +
" <h1>🗺️ 物流轨迹地图</h1>\n" +
" <p>实时追踪快递位置 - 真实驾车路线展示</p>\n" +
" <span class=\"status-badge\">✓ 在途中</span>\n" +
" </div>\n" +
" <div class=\"express-info\">\n" +
" <div class=\"info-item\">\n" +
" <span class=\"info-label\">快递公司:</span>\n" +
" <span class=\"info-value\">韵达快递</span>\n" +
" </div>\n" +
" <div class=\"info-item\">\n" +
" <span class=\"info-label\">快递单号:</span>\n" +
" <span class=\"info-value\">434815453222560</span>\n" +
" </div>\n" +
" <div class=\"info-item\">\n" +
" <span class=\"info-label\">当前位置:</span>\n" +
" <span class=\"info-value\" id=\"currentLocation\">加载中...</span>\n" +
" </div>\n" +
" <div class=\"debug-info\" id=\"debugInfo\">🚗 使用Web服务API获取真实路线...</div>\n" +
" </div>\n" +
" <div class=\"main-content\">\n" +
" <div class=\"map-container\">\n" +
" <div id=\"map\"></div>\n" +
" </div>\n" +
" <div class=\"timeline-container\">\n" +
" <div class=\"timeline-title\">📦 物流轨迹</div>\n" +
" <div id=\"timeline\"></div>\n" +
" </div>\n" +
" </div>\n" +
" </div>\n" +
" <script>\n" +
" const apiData = " + jsonData + ";\n" +
" const routeData = " + routeJson + ";\n" +
" \n" +
" console.log('🔍 物流数据:', apiData);\n" +
" console.log('🚗 路线数据:', routeData);\n" +
" \n" +
" // 预设主要城市坐标\n" +
" const cityCoords = {\n" +
" '广州市': [113.264385, 23.129163],\n" +
" '深圳市': [114.057868, 22.543099]\n" +
" };\n" +
" \n" +
" // 初始化地图\n" +
" const map = new AMap.Map('map', {\n" +
" zoom: 9,\n" +
" center: [113.664385, 23.129163],\n" +
" mapStyle: 'amap://styles/normal'\n" +
" });\n" +
" \n" +
" console.log('✅ 地图初始化完成');\n" +
" \n" +
" document.getElementById('currentLocation').textContent = apiData.Location || '未知';\n" +
" \n" +
" const traces = apiData.Traces || [];\n" +
" const timelineHTML = traces.map((trace, index) => `\n" +
" <div class=\"timeline-item\">\n" +
" <div class=\"timeline-dot\"></div>\n" +
" <div class=\"timeline-time\">${trace.AcceptTime || ''}</div>\n" +
" <div class=\"timeline-location\">${trace.Location || ''}</div>\n" +
" <div class=\"timeline-desc\">${trace.AcceptStation || ''}</div>\n" +
" </div>\n" +
" `).join('');\n" +
" document.getElementById('timeline').innerHTML = timelineHTML;\n" +
" \n" +
" const cities = [...new Set(traces.map(t => t.Location).filter(l => l))];\n" +
" console.log('🏙️ 城市列表:', cities);\n" +
" \n" +
" let debugMsg = `找到 ${cities.length} 个城市: ${cities.join(' → ')}`;\n" +
" \n" +
" // 添加城市标记\n" +
" cities.forEach((city, index) => {\n" +
" const coords = cityCoords[city];\n" +
" if (coords) {\n" +
" const marker = new AMap.CircleMarker({\n" +
" center: coords,\n" +
" radius: 15,\n" +
" strokeColor: '#667eea',\n" +
" strokeWeight: 3,\n" +
" fillColor: index === 0 ? '#28a745' : '#667eea',\n" +
" fillOpacity: 0.9,\n" +
" zIndex: 100\n" +
" });\n" +
" \n" +
" const text = new AMap.Text({\n" +
" text: `${index + 1}. ${city}`,\n" +
" position: coords,\n" +
" offset: new AMap.Pixel(0, -30),\n" +
" style: {\n" +
" 'background': 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',\n" +
" 'border': 'none',\n" +
" 'color': 'white',\n" +
" 'font-size': '14px',\n" +
" 'font-weight': 'bold',\n" +
" 'padding': '8px 12px',\n" +
" 'border-radius': '8px',\n" +
" 'box-shadow': '0 4px 8px rgba(102,126,234,0.4)'\n" +
" }\n" +
" });\n" +
" \n" +
" map.add([marker, text]);\n" +
" }\n" +
" });\n" +
" \n" +
" // 绘制路线\n" +
" if (routeData && routeData.status === '1' && routeData.route && routeData.route.paths) {\n" +
" console.log('✅ 使用Web服务API路线数据');\n" +
" \n" +
" const path = routeData.route.paths[0];\n" +
" const steps = path.steps;\n" +
" const polylinePath = [];\n" +
" \n" +
" // 提取所有路径点\n" +
" steps.forEach(step => {\n" +
" const points = step.polyline.split(';');\n" +
" points.forEach(point => {\n" +
" const coords = point.split(',');\n" +
" if (coords.length === 2) {\n" +
" polylinePath.push([parseFloat(coords[0]), parseFloat(coords[1])]);\n" +
" }\n" +
" });\n" +
" });\n" +
" \n" +
" // 绘制路径\n" +
" const polyline = new AMap.Polyline({\n" +
" path: polylinePath,\n" +
" strokeColor: '#667eea',\n" +
" strokeWeight: 8,\n" +
" strokeOpacity: 0.9,\n" +
" strokeStyle: 'solid',\n" +
" lineJoin: 'round',\n" +
" lineCap: 'round',\n" +
" zIndex: 50,\n" +
" showDir: true\n" +
" });\n" +
" map.add(polyline);\n" +
" \n" +
" const distance = (path.distance / 1000).toFixed(1);\n" +
" const duration = Math.round(path.duration / 60);\n" +
" \n" +
" debugMsg += `\\n✓ 已绘制真实驾车路线`;\n" +
" debugMsg += `\\n预计距离: ${distance} 公里`;\n" +
" debugMsg += `\\n预计时间: ${duration} 分钟`;\n" +
" \n" +
" map.setFitView();\n" +
" } else {\n" +
" console.warn('⚠️ 使用直线连接');\n" +
" \n" +
" const waypoints = cities.map(c => cityCoords[c]).filter(c => c);\n" +
" const polyline = new AMap.Polyline({\n" +
" path: waypoints,\n" +
" strokeColor: '#667eea',\n" +
" strokeWeight: 8,\n" +
" strokeOpacity: 0.8,\n" +
" strokeStyle: 'solid',\n" +
" lineJoin: 'round',\n" +
" showDir: true\n" +
" });\n" +
" map.add(polyline);\n" +
" \n" +
" debugMsg += '\\n⚠ 使用直线连接Web服务API未返回路线数据';\n" +
" map.setFitView();\n" +
" }\n" +
" \n" +
" document.getElementById('debugInfo').textContent = debugMsg;\n" +
" console.log('🎉 地图加载完成');\n" +
" </script>\n" +
"</body>\n" +
"</html>";
java.io.FileWriter fileWriter = new java.io.FileWriter("map_view.html");
fileWriter.write(html);
fileWriter.close();
String absPath = new File("map_view.html").getAbsolutePath();
System.out.println("\n✅ HTML地图页面已创建: map_view.html");
System.out.println("\n📌 请在浏览器中打开以下文件查看物流地图:");
System.out.println(" file://" + absPath);
System.out.println("\n🔑 改进内容:");
System.out.println(" ✓ 使用Web服务API获取真实驾车路线");
System.out.println(" ✓ 在Java端调用路径规划API");
System.out.println(" ✓ 避免JS API的安全密钥问题");
System.out.println(" ✓ 显示预计距离和时间");
} catch (Exception e) {
System.out.println("❌ 创建HTML失败: " + e.getMessage());
e.printStackTrace();
}
}
}