使用 HTML + JavaScript 在高德地图上实现物流轨迹跟踪系统

news2025/7/22 3:07:47

在电商行业蓬勃发展的今天,物流信息查询已成为人们日常生活中的重要需求。本文将详细介绍如何基于高德地图 API 利用 HTML + JavaScript 实现物流轨迹跟踪系统的开发。

效果演示

image-20250529221124588

image-20250529221146585

image-20250529221226265

项目概述

本项目主要包含以下核心功能:

  • 地图初始化与展示
  • 运单号查询功能
  • 物流轨迹可视化显示

准备工作

  1. 注册高德开放平台账号,创建应用并获取API Key。

  2. 引入高德地图 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>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2398662.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

19-项目部署(Linux)

Linux是一套免费使用和自由传播的操作系统。说到操作系统&#xff0c;大家比较熟知的应该就是Windows和MacOS操作系统&#xff0c;我们今天所学习的Linux也是一款操作系统。 我们作为javaEE开发工程师&#xff0c;将来在企业中开发时会涉及到很多的数据库、中间件等技术&#…

html基础01:前端基础知识学习

html基础01&#xff1a;前端基础知识学习 1.个人建立打造 -- 之前知识的小总结1.1个人简历展示1.2简历信息填写页面 1.个人建立打造 – 之前知识的小总结 1.1个人简历展示 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8&qu…

【RoadRunner】自动驾驶模拟3D场景构建 | 软件简介与视角控制

&#x1f4af; 欢迎光临清流君的博客小天地&#xff0c;这里是我分享技术与心得的温馨角落 &#x1f4af; &#x1f525; 个人主页:【清流君】&#x1f525; &#x1f4da; 系列专栏: 运动控制 | 决策规划 | 机器人数值优化 &#x1f4da; &#x1f31f;始终保持好奇心&…

基于RK3576+FPGA芯片构建的CODESYS软PLC Linux实时系统方案,支持6T AI算力

基于RK3576芯片构建的CODESYS软PLC Linux实时系统方案&#xff0c;结合了异构计算架构与工业实时控制技术&#xff0c;主要特点如下&#xff1a; 一、硬件架构设计 ‌异构多核协同‌ ‌Cortex-A72四核‌&#xff08;2.3GHz&#xff09;&#xff1a;处理运动轨迹规划、AI视觉等…

适配器模式:让不兼容接口协同工作

文章目录 1. 适配器模式概述2. 适配器模式的分类2.1 类适配器2.2 对象适配器 3. 适配器模式的结构4. C#实现适配器模式4.1 对象适配器实现4.2 类适配器实现 5. 适配器模式的实际应用场景5.1 第三方库集成5.2 遗留系统集成5.3 系统重构与升级5.4 跨平台开发 6. 类适配器与对象适…

DDP与FSDP:分布式训练技术全解析

DDP与FSDP:分布式训练技术全解析 DDP(Distributed Data Parallel)和 FSDP(Fully Sharded Data Parallel)均为用于深度学习模型训练的分布式训练技术,二者借助多 GPU 或多节点来提升训练速度。 1. DDP(Distributed Data Parallel) 实现原理 数据并行:把相同的模型复…

【Spring AI 1.0.0】Spring AI 1.0.0框架快速入门(1)——Chat Client API

Spring AI框架快速入门 一、前言二、前期准备2.1 运行环境2.2 maven配置2.3 api-key申请 三、Chat Client API3.1 导入pom依赖3.2 配置application.properties文件3.3 创建 ChatClient3.3.1 使用自动配置的 ChatClient.Builder3.3.2 使用多个聊天模型 3.4 ChatClient请求3.5 Ch…

【笔记】在 MSYS2(MINGW64)中正确安装 Rust

#工作记录 1. 环境信息 Windows系统: MSYS2 MINGW64当前时间: 2025年6月1日Rust 版本: rustc 1.87.0 (17067e9ac 2025-05-09) (Rev2, Built by MSYS2 project) 2. 安装步骤 步骤 1: 更新系统包数据库并升级已安装的包 首先&#xff0c;确保我们的 MSYS2 系统是最新状态。打…

从汇编的角度揭秘C++引用,豁然开朗

C中的引用是指已有对象的别名&#xff0c;可以通过该别名访问并修改被引用的对象。那么其背后的原理是什么呢&#xff1f;引用是否会带来额外的开销呢&#xff1f;我们从一段代码入手&#xff0c;来分析一下引用的本质。 #include <stdio.h> int main() {int a 10;int …

聊聊Tomato Architecture

序 本文主要研究一下Tomato Architecture Clean/Onion/Hexagonal/Ports&Adapters Architectures Clean Architecture clean architecture定义了四层结构&#xff0c;最内层是entities(enterprise business rules)&#xff0c;再往外是use cases(application business ru…

小白的进阶之路系列之十二----人工智能从初步到精通pytorch综合运用的讲解第五部分

在本笔记本中,我们将针对Fashion-MNIST数据集训练LeNet-5的变体。Fashion-MNIST是一组描绘各种服装的图像瓦片,有十个类别标签表明所描绘的服装类型。 # PyTorch model and training necessities import torch import torch.nn as nn import torch.nn.functional as F impor…

2025年06月03日Github流行趋势

项目名称&#xff1a;onlook 项目地址url&#xff1a;https://github.com/onlook-dev/onlook项目语言&#xff1a;TypeScript历史star数&#xff1a;12871今日star数&#xff1a;624项目维护者&#xff1a;Kitenite, drfarrell, spartan-vutrannguyen, apps/devin-ai-integrati…

【数据分析】基于Cox模型的R语言实现生存分析与生物标志物风险评估

禁止商业或二改转载,仅供自学使用,侵权必究,如需截取部分内容请后台联系作者! 文章目录 介绍加载R包数据下载导入数据数据预处理生存分析画图输出图片其他标记物的分析总结系统信息介绍 分析生存数据与多种生物标志物之间的关系。它通过Cox比例风险模型来评估不同生物标志物…

使用nginx配置反向代理,负载均衡

首先啥叫反向代理 咋配置呢&#xff0c;那当然是在nginx目录下改conf文件了 具体咋改呢&#xff0c;那就新增一个新的server配置&#xff0c;然后在location里新增你想代理的服务器 实际上负载均衡也就是根据反向代理的思路来的&#xff0c;如下所示 配置的话实际上也与上…

从 iPhone 备份照片: 保存iPhone图片的5种方法

随着智能手机越来越融入我们的生活&#xff0c;我们的照片已成为我们设备上最有价值的数据形式之一。然而&#xff0c;iPhone内部存储空间仍然有限&#xff0c;因此我们需要将iPhone中的照片备份到另一个地方&#xff0c;以释放空间并确保珍贵的图像记忆的安全。阅读本指南&…

Spring Ai 从Demo到搭建套壳项目(一)初识与实现与deepseek对话模式

前言 为什么说Java长青&#xff0c;主要是因为其生态圈完善&#xff0c;Spring又做了一款脚手架&#xff0c;把对接各个LLM厂商的sdk做了一遍&#xff0c;形成一系列的spring-ai-starter-** 的依赖。 目前为止版本去到1.0.0.M6&#xff0c;golang跟不上了吧&#xff0c; Make …

快速上手pytest

1. pytest的基础 1.1 什么是pytest pytest 是 python 中的一个测试框架&#xff0c;用于编写简洁、可扩展的测试代码&#xff0c;帮助开发者验证结果是否与预期相符。 python 中有很多的测试框架&#xff0c;那我们为什么要学习 pytest 呢&#xff1f; pytest 的优势&…

设备驱动与文件系统:02 键盘

操作系统中键盘驱动的讲解 在这一讲中&#xff0c;我将为大家讲解键盘相关内容。从上一讲开始&#xff0c;我们进入了操作系统第四个部分的学习&#xff0c;也就是操作系统对设备的驱动与管理。 上一讲我们探讨的是显示器&#xff0c;并且提到&#xff0c;一个终端设备是由显示…

交通违法拍照数据集,可识别接打电话,不系安全带的行为,支持YOLO,COCO JSON,VOC XML格式的标注数据集 最高正确识别率可达88.6%

交通违法拍照数据集 数据集概述 数据来源&#xff1a;交通监控摄像头、执法记录仪、公开数据集数据类型&#xff1a;图像、视频、元数据&#xff08;时间、地点、车辆信息&#xff09;违法类型标注&#xff1a;接打电话、未系安全带 数据采集与标注方法 采集设备&#xff1…

Qt OpenGL 3D 编程入门

Qt 提供了强大的 OpenGL 集成功能&#xff0c;使得在 Qt 应用中实现 3D 图形变得更加简单。以下是使用 Qt 进行 OpenGL 3D 编程的基础知识。 1. 环境配置 创建 Qt 项目 新建 Qt Widgets Application 项目 在 .pro 文件中添加 OpenGL 模块&#xff1a; qmake QT co…