基于 Leaflet Trackplayer 的 WebGIS 高速公路轨迹可视化
利用 WebGIS 技术与 Leaflet-Trackplayer 插件,对湖南首条免费高速(长永高速)的运行轨迹进行可视化的实现方案。通过天地图地理编码获取起止点坐标,结合百度地图 AOI/POI 数据及驾车规划接口生成路径,最终在 Leaflet 地图上实现车辆轨迹的动态回放、速度控制及车牌信息跟随展示。该方案为交通管理、规划及公众出行提供了直观的数据展示参考。

利用 WebGIS 技术与 Leaflet-Trackplayer 插件,对湖南首条免费高速(长永高速)的运行轨迹进行可视化的实现方案。通过天地图地理编码获取起止点坐标,结合百度地图 AOI/POI 数据及驾车规划接口生成路径,最终在 Leaflet 地图上实现车辆轨迹的动态回放、速度控制及车牌信息跟随展示。该方案为交通管理、规划及公众出行提供了直观的数据展示参考。

一、相关背景
将湖南首条免费高速的轨迹数据通过 Leaflet-Trackplayer 嵌入到 WebGIS 系统中,可以实现多方面的优势。首先,从交通管理的角度来看,交通管理部门能够实时监控高速公路的车辆运行轨迹,通过分析轨迹数据,可以更精准地掌握交通流量、车速分布、拥堵点等信息,从而为交通疏导、事故预防、道路维护等工作提供科学依据,提高交通管理的效率和决策的准确性。
1994 年 12 月 28 日,长永高速公路建成通车。这条高速公路于 1993 年开工修建,全长 27 公里,连接黄花机场和长沙市区。这是湖南的第一条高速公路。长永高速,即长沙—永安高速公路,是连接长沙县与浏阳市的高速公路,西起长沙收费站,东止于浏阳市永安镇永安收费站。这条高速的通车建成,彻底终结了湖南'无高速公路'的历史。
长永高速公路收费期将于 2025 年 11 月 1 日到期。根据有关规定,借鉴外省做法,长永高速公路收费期到期后,保留现有收费设施,实行'零费率'方式终止收费,并由湖南省高速公路集团有限公司负责运营。自 2025 年 11 月 2 日 0 时起,对通行长永高速公路主线、匝道及连接线的车辆,按'0 元'计算车辆通行费。
除了长永高速外,以下这些高速的运营期也即将到 30 年:
| 序号 | 高速名称 | 起止地点 | 通车年限 |
| 1 | 长潭高速 | 长沙市长沙县和湘潭市岳塘区 | 29 年 |
| 2 | 长沙 - 益阳高速公路 | 长沙与益阳 | 27 年 |
| 3 | 益常高速 | 阳市资阳区与常德市武陵区 | 26 年 |
| 4 | 潭耒高速 | 湘潭市岳塘区和衡阳市耒阳市 | 25 年 |
Leaflet-Trackplayer 是一个基于 Leaflet 的轨迹回放插件,具有以下核心功能:
为了实现长永高速的通行道路展示,我们需要整理高速起始点、途径重要 AOI 和 POI 点和区间道路路线等空间信息。下面将使用天地图来进行综合构建。
为了模拟从长沙收费站到永安收费站,这里我们使用的道路起始点分别使用'长沙市马栏山财富广场'到'长沙永安收费站',这里我们使用天地图的地理编码接口,使用天地图的好处是得到的坐标不需要进行转换,可以直接叠加到天地图的底图上。根据起止点获取对应的坐标点的实现方法如下:
@Test public void benzeneToLocation() {
String target = "长沙市马栏山财富广场";
String keyWord = "%7B'keyWord':'" + target + "'%7D" ;
HttpResponse<String> resp = tdtOptService.getGeocoder(keyWord, TDT_SERVER_KEY);
System.out.println(resp.getBodyResult());
}
通过查询地理编码接口,得到我们模拟的起始点位置如下:
{"msg":"ok","location":{ "score":71, "level":"区县及以上级行政区划", "lon":"113.03667", "lat":"28.23593", "keyWord":"长沙市马栏山财富广场"}, "searchVersion":"7.4.3V", "status":"0"}
{"msg":"ok","location":{ "score":100, "level":"兴趣点", "lon":"113.285187", "lat":"28.209144",
为了展示该高速公路经过的重要 AOI 和 POI 数据,我们使用百度地图获取其对应的 AOI 数据,一共 7 个兴趣面,具体如下:
var jdsq = [
{"name":"月湖公园","children":[{lat:28.237564,lon:113.033027}],"aoi":""},
{"name":"长沙世界之窗","children":[{lat:28.23595,lon:113.046658}],"aoi":""},
{"name":"金科公园","children":[{lat:28.231451,lon:113.064211}],"aoi":""},
{"name":"香槟小镇","children":[{lat:28.235061,lon:113.078557}],"aoi":""},
{"name":"星沙服务区","children":[{lat:28.240166,lon:113.117113}],"aoi":""},
{"name":"鸽子湖公园","children":[{lat:28.243757,lon:113.162166}],"aoi":""},
{"name":"长沙黄花国际机场",:[{:,:}],:},
];
除了 AOI 之外,还可以增加一些辅助的 POI 信息,让整体的效果看起来更丰富一些。POI 准备了以下信息:
//途径 POI 信息
var dataJson = [
{lat:28.23457,lon:113.035247,p_name:"马栏山"},
{lat:28.237538,lon:113.043587,p_name:"湖南广播电视局"},
{lat:28.233681,lon:113.048907,p_name:"湖南省高速公路局"},
{lat:28.234513,lon:113.059526,p_name:"长永佳苑"},
{lat:28.233927,lon:113.073449,p_name:"长沙华夏医院"},
{lat:28.234986,lon:113.087125,p_name:"东二路"},
{lat:28.238332,lon:113.096006,p_name:"东家屋场"},
{lat:28.237954,lon:113.10586,p_name:"东六路"},
{lat:28.238218,lon:113.126946,p_name:"老屋冲"},
{lat:28.239806,:,:},
{:,:,:},
{:,:,:},
{:,:,:},
{:,:,:},
{:,:,:},
{:,:,:},
{:,:,:}
];
常用高速区间路径规划,这里调用天地图的驾车接口来进行查询,调用天地图的驾车规划服务的核心方法如下:
@Test public void xml2JavaBean() {
String origInfo = "113.03667,28.23593";//长沙市马栏山财富广场
String destInfo = "113.285187,28.209144";//长沙永安收费站
// style 默认 0(0:最快路线,1:最短路线,2:避开高速,3:步行)
// 这里选择最短路线
String postStr = "%7B'orig':'" + origInfo + "','dest':'" + destInfo + "','style':'1'%7D" ;
HttpResponse<String> resp = tdtOptService.drivePlan(postStr,"search",TDT_SERVER_KEY);
try {
System.out.println(resp.getBodyResult());
JAXBContext context = JAXBContext.newInstance(TdtResult.class);
Unmarshaller unmarshaller = context.createUnmarshaller();
TdtResult result = (TdtResult) unmarshaller.unmarshal(new StringReader(resp.getBodyResult()));
System.out.println("距离:" + result.getDistance());
System.out.println("时长:" + result.getDuration());
System.out.println("起始点:" + result.getParameters().getOrig());
Gson gson = new Gson();
System.out.println("json 格式化如下:");
System.out.println(gson.toJson(result));
System.out.println(result);
} (JAXBException e) {
e.printStackTrace();
}
}
图中红框中的即为道路路线信息的坐标。有了以上三类信息之后,下面就可以使用 leaflet-trackplayer 组件来进行轨迹模拟。
Leaflet 是一个轻量级的开源 JavaScript 地图库,它专注于移动设备和性能优化,能够快速地在网页上生成交互式地图。它易于使用,拥有丰富的插件生态系统,可以方便地扩展其功能。Trackplayer 则是一个基于 Leaflet 的扩展插件,专门用于在地图上播放和展示轨迹数据。
在 leaflet-trackplayer 组件中,为了实现道路的自动轨迹播放,需要我们来设置行驶的轨迹道路。在经过上一节的内容讲解中,我们知道了如何生成道路区间信息,这里我们将分两个部分展开,即道路生成和设置。首先来看下如何将通过天地图获取的规划路线转为线坐标。核心方法如下:
var routelatlonArray = new Array();
var routelatlonTarget = routelatlon.split(";");
for(var i=0;i < routelatlonTarget.length;i++){
var routelatlonVal = routelatlonTarget[i];
if("" != routelatlonVal){
var _tempVal = routelatlonVal.split(",");
routelatlonArray.push({lat:_tempVal[1],lng:_tempVal[0]});
}
}
const path = routelatlonArray;
map.fitBounds(path);
在得到了以上的道路坐标后,我们将道路路线坐标与 leaflet-trackplayer 组件进行绑定,核心方法如下:
let track = new L.TrackPlayer(path, {
markerIcon: L.icon({
iconSize: [27, 54],
iconUrl: "./lib/assets/bus_online.png",
iconAnchor: [13.5, 27],
}),
speed: 800,
});
track.addTo(map);
这里注意一下行驶车辆的速度,为了能快速展示整条道路,这里设置车速为 800 公里/小时,此处为演示,实际情况车速不能这么快。
单独标注行驶途径重要的 AOI 的方法如下:
for(var i=0;i<jdsq.length;i++){
for(var j = 0;j<jdsq[i].children.length;j++){
var tempInfo = jdsq[i].children;
var marker = L.marker([tempInfo[j].lat, tempInfo[j].lon], {
icon: L.divIcon({
iconSize: null,
className: '',
popupAnchor:[5,5],
shadowAnchor:[5,5],
html: buildHtml(jdsq[i].name)
})
}).addTo(collisionLayer);
}
L.polygon([ convertStr2DataArrayTrans(jdsq[i].aoi) ],style).addTo(map);
}
POI 的标注方法类似,采用 marker 直接标注的方式。在此不再进行赘述。
与传统的只有模型独自在运动不同的是,这里我们不仅让模型车辆按照预定路线运动,同时我们也想让车辆展示车牌信息,同时车牌信息也跟着车辆一起运动,这样就比较好玩。下面来看一下如何实现这个需求。首先我们需要单独定义一个 marker,用于标注车牌信息,然后空间坐标可以使用起始点位置,方法如下:
var carNo = "湘 A32MH6/张三";
var sourceMarker = L.marker([28.235638, 113.036629], {
icon: L.divIcon({
iconSize: null,
className: '',
popupAnchor:[5,5],
shadowAnchor:[5,5],
html: "<div animation-spaceInDown><div>"+carNo +"</div>" +"</div>"
})
}).addTo(map);
要想实现在车辆在运动的时候,车牌也能跟随车辆运动,需要在 trackplayer 组件中监听变化数据,并将实时的经纬度坐标设置到 mark 上即可,实现代码如下:
track.on("progress", (progress, { lng, lat },index) => {
control.carLatLng = `${lng},${lat}`;
console.log(sourceMarker);
// 更新标记位置
sourceMarker.setLatLng([lat, lng]);
control.progress = progress * 100;
control.status = "行驶中";
console.log(`progress:${progress} - position:${lng},${lat} - trackIndex:${index}`)
});
最后是成果展示时间,我们来看一下具体的效果:

车辆从马栏山出发

车辆经过星沙服务区

途径长沙黄花机场

到达永安收费站
以上就是本文的主要内容,文章详细的介绍了湖南首条免费高速轨迹的 WebGIS 可视化呈现,也是对交通数据价值挖掘的一次积极探索和实践。文章不仅详细的介绍了湖南省的首条免费高速公路,同时再次详细介绍了 leaflet-trackplayer 组件,围绕长永高速轨迹可视化,我们进行基础数据准备处理,最后基于 leaflet-trackplayer 进行了代码功能研发,并成功实现免费高速的道路可视化。

微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online
JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online
使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online
Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online