在电商行业蓬勃发展的今天,物流信息查询已成为人们日常生活中的重要需求。本文将详细介绍如何基于高德地图 API 利用 HTML + JavaScript 实现物流轨迹跟踪系统的开发。
效果演示
项目概述
本项目主要包含以下核心功能:
- 地图初始化与展示
- 运单号查询功能
- 物流轨迹可视化显示
准备工作
-
注册高德开放平台账号,创建应用并获取API Key。
-
引入高德地图 API (将 API_Key 替换为自己的)和德地图 UI 组件库
<script src="https://webapi.amap.com/maps?v=2.0&key=API_Key"></script>
<script src="https://webapi.amap.com/ui/1.1/main.js"></script>
页面结构与样式设计
创建 HTML 结构
页面主要包含两个核心区域:
- container:用于承载地图展示的核心区域
- panel:右上角的操作面板,包含输入框、查询按钮和物流信息展示区
<div id="container"></div>
<div id="panel"><h3>物流轨迹查询</h3><div class="input-group"><input type="text" id="orderNumber" placeholder="请输入运单号"></div><button id="queryBtn">查询轨迹</button><div id="logistics-info"></div>
</div>
设计 CSS 样式
地图容器样式
#container {width: 100%;height: 100vh;position: relative;
}
操作面板样式
#panel {position: absolute;top: 10px;right: 10px;width: 300px;background: white;padding: 10px;box-shadow: 0 0 10px rgba(0,0,0,0.2);z-index: 999;border-radius: 5px;
}
.input-group {margin-bottom: 10px;
}
input, button {padding: 8px;width: 100%;box-sizing: border-box;
}
button {background: #1E90FF;color: white;border: none;cursor: pointer;
}
button:hover {background: #1874CD;
}
#logistics-info {margin-top: 10px;font-size: 14px;max-height: 300px;overflow-y: auto;
}
.info-item {margin-bottom: 5px;padding-bottom: 5px;border-bottom: 1px solid #eee;
}
.info-time {color: #888;font-size: 12px;
}
.info-content {color: #333;
}
核心功能实现
初始化地图
var map = new AMap.Map('container', {zoom: 10, // 缩放级别center: [116.397428, 39.90923], // 中心点坐标(北京)viewMode: '2D' // 使用2D视图
});
获取物流数据
这里只是示例,模拟了不同运单号返回不同数据,实际应用中可以通过请求后端 API 获取真实数据。
function getLogisticsData(orderNumber) {if (orderNumber === "123456") {return {status: "success",company: "顺丰速运",number: orderNumber,steps: [{time: "2023-05-01 08:00:00",location: [116.404, 39.915],content: "快件已到达【北京朝阳集散中心】"},// ...]};} else if (orderNumber === "654321") {return {status: "success",company: "中通快递",number: orderNumber,steps: [// ...]};} else {return {status: "error",message: "未找到该运单号的物流信息"};}
}
清除地图上的轨迹和标记
function clearMap() {if (polyline) {map.remove(polyline);polyline = null;}if (markers.length > 0) {map.remove(markers);markers = [];}
}
显示物流轨迹
function showLogisticsTrack(data) {// 清除之前的轨迹clearMap();// 更新物流信息显示var infoDiv = document.getElementById('logistics-info');infoDiv.innerHTML = '';if (data.status === "error") {infoDiv.innerHTML = '<div class="info-item">' + data.message + '</div>';return;}// 显示物流公司信息infoDiv.innerHTML += '<div class="info-item"><strong>' + data.company + '</strong> 运单号: ' + data.number + '</div>';// 提取轨迹点坐标var lineArr = [];// 按时间顺序排序(确保最早的步骤在最前面)data.steps.sort(function(a, b) {return new Date(a.time) - new Date(b.time);});// 添加标记和轨迹线data.steps.forEach(function(step, index) {// 添加到轨迹线lineArr.push(step.location);// 创建标记var marker = new AMap.Marker({position: step.location,map: map,content: '<div style="background: #1E90FF; color: white; border-radius: 50%; width: 20px; height: 20px; text-align: center; line-height: 20px;">' + (index + 1) + '</div>',offset: new AMap.Pixel(-10, -10)});// 信息窗口内容var infoContent = '<div style="padding: 5px;">' +'<div style="font-weight: bold;">步骤 ' + (index + 1) + '</div>' +'<div>' + step.content + '</div>' +'<div style="color: #888; font-size: 12px;">' + step.time + '</div>' +'</div>';// 点击标记显示信息窗口marker.on('click', function() {new AMap.InfoWindow({content: infoContent,offset: new AMap.Pixel(0, -30)}).open(map, step.location);});markers.push(marker);// 添加物流信息到面板infoDiv.innerHTML += '<div class="info-item">' +'<div class="info-time">' + step.time + '</div>' +'<div class="info-content">' + step.content + '</div>' +'</div>';});// 绘制轨迹线polyline = new AMap.Polyline({path: lineArr,isOutline: true,outlineColor: '#ffeeff',borderWeight: 1,strokeColor: "#3366FF",strokeOpacity: 1,strokeWeight: 5,strokeStyle: "solid",lineJoin: 'round',lineCap: 'round',zIndex: 50});map.add(polyline);// 调整视图以适应轨迹map.setFitView(polyline);
}
查询功能实现
输入运单号,点击【查询轨迹】按钮获取输入框中的运单号,根据运单号获取物流数据,显示物流轨迹。
document.getElementById('queryBtn').addEventListener('click', function() {var orderNumber = document.getElementById('orderNumber').value.trim();if (!orderNumber) return;var logisticsData = getLogisticsData(orderNumber);showLogisticsTrack(logisticsData);
});
完整代码
<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="utf-8"><title>物流轨迹跟踪系统</title><style>body, html {margin: 0;padding: 0;}#container {width: 100%;height: 100vh;position: relative;}#panel {position: absolute;top: 10px;right: 10px;width: 300px;background: white;padding: 10px;box-shadow: 0 0 10px rgba(0,0,0,0.2);z-index: 999;border-radius: 5px;}.input-group {margin-bottom: 10px;}input, button {padding: 8px;width: 100%;box-sizing: border-box;}button {background: #1E90FF;color: white;border: none;cursor: pointer;}button:hover {background: #1874CD;}#logistics-info {margin-top: 10px;font-size: 14px;max-height: 300px;overflow-y: auto;}.info-item {margin-bottom: 5px;padding-bottom: 5px;border-bottom: 1px solid #eee;}.info-time {color: #888;font-size: 12px;}.info-content {color: #333;}</style>
</head>
<body>
<div id="container"></div>
<div id="panel"><h3>物流轨迹查询</h3><div class="input-group"><input type="text" id="orderNumber" placeholder="请输入运单号"></div><button id="queryBtn">查询轨迹</button><div id="logistics-info"></div>
</div><!-- 引入高德地图API -->
<script src="https://webapi.amap.com/maps?v=2.0&key=API_Key"></script>
<!-- 引入高德地图UI组件库 -->
<script src="https://webapi.amap.com/ui/1.1/main.js"></script><script>// 初始化地图var map = new AMap.Map('container', {zoom: 10, // 缩放级别center: [116.397428, 39.90923], // 中心点坐标(北京)viewMode: '2D' // 使用2D视图});// 轨迹线var polyline = null;// 轨迹点标记var markers = [];// 模拟物流数据(实际应用中应从后端API获取)function getLogisticsData(orderNumber) {if (orderNumber === "123456") {return {status: "success",company: "顺丰速运",number: orderNumber,steps: [{time: "2023-05-01 08:00:00",location: [116.404, 39.915],content: "快件已到达【北京朝阳集散中心】"},{time: "2023-05-01 10:30:00",location: [116.408, 39.925],content: "快件已从【北京朝阳集散中心】发出,下一站【北京海淀集散中心】"},{time: "2023-05-01 14:15:00",location: [116.300, 39.960],content: "快件已到达【北京海淀集散中心】"},{time: "2023-05-02 09:00:00",location: [116.310, 39.980],content: "快件正在派送中,派件员:张三,电话:138****1234"},{time: "2023-05-02 11:30:00",location: [116.315, 39.985],content: "快件已签收,签收人:李四"}]};} else if (orderNumber === "654321") {return {status: "success",company: "中通快递",number: orderNumber,steps: [{time: "2023-05-10 13:20:00",location: [121.4737, 31.2304],content: "快件已从【上海虹口集散中心】发出"},{time: "2023-05-11 08:45:00",location: [120.1551, 30.2741],content: "快件已到达【杭州集散中心】"},{time: "2023-05-11 16:30:00",location: [120.2108, 30.2468],content: "快件已从【杭州集散中心】发出,下一站【杭州西湖分部】"}]};} else {return {status: "error",message: "未找到该运单号的物流信息"};}}// 清除地图上的轨迹和标记function clearMap() {if (polyline) {map.remove(polyline);polyline = null;}if (markers.length > 0) {map.remove(markers);markers = [];}}// 显示物流轨迹function showLogisticsTrack(data) {// 清除之前的轨迹clearMap();// 更新物流信息显示var infoDiv = document.getElementById('logistics-info');infoDiv.innerHTML = '';if (data.status === "error") {infoDiv.innerHTML = '<div class="info-item">' + data.message + '</div>';return;}// 显示物流公司信息infoDiv.innerHTML += '<div class="info-item"><strong>' + data.company + '</strong> 运单号: ' + data.number + '</div>';// 提取轨迹点坐标var lineArr = [];// 按时间顺序排序(确保最早的步骤在最前面)data.steps.sort(function(a, b) {return new Date(a.time) - new Date(b.time);});// 添加标记和轨迹线data.steps.forEach(function(step, index) {// 添加到轨迹线lineArr.push(step.location);// 创建标记var marker = new AMap.Marker({position: step.location,map: map,content: '<div style="background: #1E90FF; color: white; border-radius: 50%; width: 20px; height: 20px; text-align: center; line-height: 20px;">' + (index + 1) + '</div>',offset: new AMap.Pixel(-10, -10)});// 信息窗口内容var infoContent = '<div style="padding: 5px;">' +'<div style="font-weight: bold;">步骤 ' + (index + 1) + '</div>' +'<div>' + step.content + '</div>' +'<div style="color: #888; font-size: 12px;">' + step.time + '</div>' +'</div>';// 点击标记显示信息窗口marker.on('click', function() {new AMap.InfoWindow({content: infoContent,offset: new AMap.Pixel(0, -30)}).open(map, step.location);});markers.push(marker);// 添加物流信息到面板infoDiv.innerHTML += '<div class="info-item">' +'<div class="info-time">' + step.time + '</div>' +'<div class="info-content">' + step.content + '</div>' +'</div>';});// 绘制轨迹线polyline = new AMap.Polyline({path: lineArr,isOutline: true,outlineColor: '#ffeeff',borderWeight: 1,strokeColor: "#3366FF",strokeOpacity: 1,strokeWeight: 5,strokeStyle: "solid",lineJoin: 'round',lineCap: 'round',zIndex: 50});map.add(polyline);// 调整视图以适应轨迹map.setFitView(polyline);}// 查询按钮点击事件document.getElementById('queryBtn').addEventListener('click', function() {var orderNumber = document.getElementById('orderNumber').value.trim();if (!orderNumber) return;var logisticsData = getLogisticsData(orderNumber);showLogisticsTrack(logisticsData);});
</script>
</body>
</html>