478 lines
24 KiB
Java
478 lines
24 KiB
Java
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();
|
||
}
|
||
}
|
||
}
|