把GPS轨迹显示到百度地图

我用Android设备进行了GPS定位,然后下班回家就带着Android设备回家了,设备会把GPS定位保存到GPS.txt文件中,文件内容如下:

bash 复制代码
113.30288,23.130641666666666
113.30260166666667,23.130205
113.30277833333334,23.130634999999998
113.30324833333334,23.130803333333333
113.30366333333335,23.13113
113.304295,23.13118833333333

文件中的每一行都是一次GPS定位,Android定位默认是WGS84坐标系,我需要转换为百度地图的坐标系并显示到百度地图上,于是把需求告诉DeepSeek得到了代码并稍加修改,如下:

html 复制代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>GPS坐标实时转换与地图显示</title>
    <style>
        #map-container { width: 100%; height: 80vh; margin: 10px 0; border: 1px solid #ccc; }
        #file-input { margin: 10px 0; }
        #status { color: #666; font-size: 14px; }
    </style>
</head>
<body>
    <input type="file" id="file-input" accept=".txt" />
    <div id="status">等待上传GPS.txt文件...</div>
    <div id="map-container"></div>

    <!-- 百度地图API(替换YOUR_BAIDU_MAP_AK为您的实际AK) -->
    <script src="https://api.map.baidu.com/api?v=4.0&ak=YOUR_BAIDU_MAP_AK"></script>
    
    <script>
        // 1. 初始化地图
        let map = new BMap.Map("map-container");
        map.centerAndZoom(new BMap.Point(116.404, 39.915), 11); // 默认中心点
        map.enableScrollWheelZoom(true); // 启用滚轮缩放
        
        // 存储所有转换后的点
        let allPoints = [];
		
		// 2. 清除地图所有覆盖物和重置状态
        function clearMap() {
            map.clearOverlays(); // 清除所有标记
            allPoints = []; // 清空存储的点
            document.getElementById('status').textContent = "等待上传GPS.txt文件...";
            map.centerAndZoom(new BMap.Point(116.404, 39.915), 11); // 重置地图中心
        }

        // 2. 坐标转换函数:WGS84 → BD-09(基于开源算法)[10](@ref)
        function wgs84ToBd09(lng, lat) {
            const PI = 3.1415926535897932384626;
            const a = 6378245.0;
            const ee = 0.00669342162296594323;
            const xPI = PI * 3000.0 / 180.0;

            // WGS84转GCJ02(火星坐标)
            let dlat = transformLat(lng - 105.0, lat - 35.0);
            let dlng = transformLng(lng - 105.0, lat - 35.0);
            let radLat = lat / 180.0 * PI;
            let magic = Math.sin(radLat);
            magic = 1 - ee * magic * magic;
            let sqrtMagic = Math.sqrt(magic);
            dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * PI);
            dlng = (dlng * 180.0) / (a / sqrtMagic * Math.cos(radLat) * PI);
            let mgLat = lat + dlat;
            let mgLng = lng + dlng;

            // GCJ02转BD-09(百度坐标)
            let z = Math.sqrt(mgLng * mgLng + mgLat * mgLat) + 0.00002 * Math.sin(mgLat * xPI);
            let theta = Math.atan2(mgLat, mgLng) + 0.000003 * Math.cos(mgLng * xPI);
            return new BMap.Point(z * Math.cos(theta) + 0.0065, z * Math.sin(theta) + 0.006);
        }

        // 辅助转换函数
        function transformLat(x, y) {
            const PI = 3.1415926535897932384626;
            let ret = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y + 0.2 * Math.sqrt(Math.abs(x));
            ret += (20.0 * Math.sin(6.0 * x * PI) + 20.0 * Math.sin(2.0 * x * PI)) * 2.0 / 3.0;
            ret += (20.0 * Math.sin(y * PI) + 40.0 * Math.sin(y / 3.0 * PI)) * 2.0 / 3.0;
            ret += (160.0 * Math.sin(y / 12.0 * PI) + 320 * Math.sin(y * PI / 30.0)) * 2.0 / 3.0;
            return ret;
        }

        function transformLng(x, y) {
            const PI = 3.1415926535897932384626;
            let ret = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1 * Math.sqrt(Math.abs(x));
            ret += (20.0 * Math.sin(6.0 * x * PI) + 20.0 * Math.sin(2.0 * x * PI)) * 2.0 / 3.0;
            ret += (20.0 * Math.sin(x * PI) + 40.0 * Math.sin(x / 3.0 * PI)) * 2.0 / 3.0;
            ret += (150.0 * Math.sin(x / 12.0 * PI) + 300.0 * Math.sin(x / 30.0 * PI)) * 2.0 / 3.0;
            return ret;
        }

        // 计算所有点的中心点
        function calculateCenter(points) {
            if (points.length === 0) return new BMap.Point(116.404, 39.915);
            
            let sumLng = 0, sumLat = 0;
            points.forEach(point => {
                sumLng += point.lng;
                sumLat += point.lat;
            });
            
            return new BMap.Point(sumLng / points.length, sumLat / points.length);
        }

        // 3. 文件处理与实时显示逻辑
        document.getElementById('file-input').addEventListener('change', function(e) {
            const file = e.target.files[0];
            if (!file) {
                document.getElementById('status').textContent = "错误:请选择GPS.txt文件";
                return;
            }
			
			// 清除之前的结果
            clearMap();

            const reader = new FileReader();
            reader.onload = function(event) {
                const content = event.target.result;
                const lines = content.split('\n').filter(line => line.trim() !== '');
                document.getElementById('status').textContent = `已加载${lines.length}个坐标点,开始转换并显示...`;

                // 逐行处理(每500ms处理一个点以实现实时效果)
                let index = 0;
                function processNextPoint() {
                    if (index >= lines.length) {
                        document.getElementById('status').textContent = "转换完成!所有点已显示";
                        return;
                    }

                    // 解析坐标
                    const [lng, lat] = lines[index].split(',').map(Number);
                    if (isNaN(lng) || isNaN(lat)) {
                        index++;
                        processNextPoint();
                        return;
                    }

                    // 转换并添加标记
                    const baiduPoint = wgs84ToBd09(lng, lat);
                    const marker = new BMap.Marker(baiduPoint);
                    map.addOverlay(marker);
                    
                    // 将点添加到数组中
                    allPoints.push(baiduPoint);
                    
                    // 计算所有点的中心点并设置地图中心
                    const center = calculateCenter(allPoints);
                    map.setCenter(center);
                    
                    // 如果只有一个点,设置合适的缩放级别
                    if (allPoints.length === 1) {
                        map.setZoom(15);
                    }

                    document.getElementById('status').textContent = `已转换并显示第${index + 1}/${lines.length}个点 (原始: ${lng},${lat} → 百度: ${baiduPoint.lng.toFixed(6)},${baiduPoint.lat.toFixed(6)})`;
                    index++;
                    
                    // 延迟处理下一个点(模拟实时效果)
                    setTimeout(processNextPoint, 50);
                }
                processNextPoint();
            };
            reader.readAsText(file);
        });
    </script>
</body>
</html>

这个代码实现了加载文件中的定位坐标并显示到地图上,且每显示一个坐标的时候会把和之前的所有已显示的坐标当做一个整体居中显示。

代码中的https://api.map.baidu.com/api?v=4.0&ak=YOUR_BAIDU_MAP_AK中的YOUR_BAIDU_MAP_AK换成百度地图的ak,需要到百度地图开发者网站上申请浏览器端的地图ak,把如上代码保存为一个html文件,比如:gps_map.html,然后用浏览器打开效果如下:

点击 "选择文件" 按钮选择保存有GPS坐标的文件,效果如下: