依托Java和百度地图实现长沙市热门道路与景点实时路况检索的实践探索

目录

前言

一、实时路况服务简介

1、实时路况服务是什么

2、道路实时路况查询

3、周边实时路况查询

4、返回参数

二、Java响应对象封装

1、响应对象设计

2、响应对象实现

三、UniHttp集成及调用

1、检索接口声明

2、道路实时路况查询

3、周边实时路况查询

四、常见问题

1、道路名称错误

2、中心点坐标位置错误

3、坐标类型错误

4、命名的小插曲

五、总结


前言

在当今数字化时代,交通出行的便捷性与高效性已成为衡量城市智慧化水平的重要指标之一。随着城市化进程的加速,长沙市作为湖南省的省会城市,其交通流量日益复杂,再叠加现在的国庆旅游客流和中秋探亲客流,热门道路与景点的路况信息对于市民日常出行和游客旅游规划至关重要。因此,需要开发一套能够实时检索长沙市热门道路与景点路况的系统。

本实践探索旨在通过Java编程语言调用百度地图的API接口,实现对长沙市热门道路与景点的实时路况检索功能。通过对百度地图API的深入研究与应用,我们将构建一个用户友好的路况检索系统,使用户能够随时随地获取最新的路况信息,从而优化出行路线,减少交通拥堵,提高出行效率。在实践过程中,我们将详细探讨如何利用Java语言实现与百度地图API的无缝对接,包括API的注册与申请、数据的获取与解析等多个关键环节。长沙市作为本次实践探索的案例城市,其丰富的交通数据和多样的出行场景为我们的研究提供了良好的基础。通过对长沙市热门道路与景点的实时路况检索实践,我们希望能够为城市交通出行领域带来新的思路和方法,推动城市交通的智能化发展。

一、实时路况服务简介

本节将对实时路况服务进行重点介绍,主要包括百度地图的实时路况服务的内容,以道路实时路况实时查询和周边实时路况查询为例,重点介绍两个API的实际应用。通过本节的内容,让大家对实时路况服务有一个基本的了解,为后续的技术实现提供基础支撑。

1、实时路况服务是什么

实时路况查询服务(又名Traffic API)是一类Web API接口服务,开发者可利用该服务查询指定道路或区域的实时拥堵情况和拥堵趋势,可应用于智能音箱、智能车载设备、交通出行类应用中,实现诸如:"信息路堵不堵?"、"五道口堵不堵?"这类用户询问路况场景。

产品优势:

  1. 路况分钟级更新(更新频率1分钟),确保用户获得的是最新的实时路况

  2. 既支持对路况进行整体评价,也支持对具体拥堵路段的详细评价,使得用户在了解道路整体拥堵情况同时,也清晰了解具体拥堵路段的位置和拥堵程度

  3. 描述路段拥堵趋势(较10分钟前拥堵加重、持平或缓解),辅助用户判断接下来一段时间的拥堵情况

  4. 路网覆盖率高,支持全部百度地图道路路况

以上是百度地图实时路况的服务列表,下面将详细介绍道路实时路况服务和周边实时路况服务两个接口。

2、道路实时路况查询

请求参数

参数名称 参数含义 类型 必填 备注
ak 用户的AK,授权使用 string 开发者访问密钥
road_name 道路名称 string 如:"北五环"、"信息路"。 目前支持除多方向立交桥和多方向道路以外的各类道路名称(注:多方向是指道路方向多于2个方向,如:南向北、北向南、西向东、东向西,称为4方向)
city 城市名称 string 支持 1. 全国城市名称,如:"北京市"、"上海市"等 2. 百度地图行政区划adcode,仅支持城市级别(adcode映射表),如"110000"
sn 若用户所用AK的校验方式为SN校验时该参数必须。SN计算规则

3、周边实时路况查询

请求参数

参数名称 参数含义 类型 必填 备注
ak 用户的AK,授权使用 string 开发者访问密钥
center 中心点坐标 string 示例:center=39.912078,116.464303
radius 查询半径 int 单位:米,取值范围[1,1000] 示例: radius=200
road_grade 道路等级 int 用户可进行道路等级筛选,支持选择多个道路等级。道路等级之间使用英文","分隔。 默认值:road_grade=0 道路等级对应表如下: 0:全部驾车道路 1:高速路 2:环路及快速路 3:主干路 4:次干路 5:支干路 示例: 查询全部驾车道路路况:road_grade:0 查询高速道路路况:road_grade:1 查询高速路、环路及快速路、主干路的路况:road_grade=1,2,3
coord_type_input 请求参数 bounds的坐标类型 string 默认值:bd09ll 取值范围: bd09ll:百度经纬度坐标 gcj02:国测局加密坐标 wgs84:gps 坐标
coord_type_output 返回结果的坐标类型 string 默认值:bd09ll 该字段用于控制返回结果中坐标的类型。可选值为: bd09ll:百度经纬度坐标 gcj02:国测局加密坐标
sn 若用户所用AK的校验方式为SN校验时该参数必须。SN计算规则

4、返回参数

针对于实时路况查询服务,四个不同的查询服务,除了输入参数不同。其返回参数都是一样的,因此在实际接口请求时,可以使用统一的标准封装。官网的标准响应参数如下:

参数名称 参数含义 类型 备注
status 状态码 int 本次API访问状态,如果成功返回0,如果失败返回其他数字。
message 响应信息 string 对status的中文描述
description 路况语义化描述 string 组成规则:整体拥堵情况概述+拥堵路段。示例:'该区域整体拥堵。京包高速:北向南,从开拓路5到京新高速拥堵。京新上地桥:北向南,京新上地桥拥堵。京新高速:北向南,从京包高速到耳通百安拥堵。小营西路:西向东,上地三街附近拥堵。'
evaluation 路况整体评估
status 路况整体评价 int 支持以下值: 0:未知路况 1:畅通 2:缓行 3:拥堵 4:严重拥堵
status_desc 路况整体评价的语义化描述 string 道路的整体拥堵评价,较status更为细致,分为:畅通、较为畅通、缓行、轻微拥堵、拥堵、严重拥堵
road_traffic 路况详细信息 array
road_name 道路名称 string 如:'信息路'、'北五环'
congestion_sections 拥堵路段详情 array 若道路上有拥堵路段,则返回该字段。 若无拥堵路段,则不返回该字段 注意:拥堵路段是依据拥堵情况、车流量、拥堵距离等因素综合计算得到,并不完全参考拥堵情况
section_desc 路段拥堵语义化描述 string 如:南向北,北新桥地铁站附近严重拥堵
status 路段拥堵评价 int 支持以下值: 0:未知路况 1:畅通 2:缓行 3:拥堵 4:严重拥堵
speed 平均通行速度 double 当前路段的平均通行速度 单位:千米/小时
congestion_distance 拥堵距离 int 单位:米
congestion_trend 较10分钟前拥堵趋势 string 相较10分钟前拥堵变化情况,支持以下值: 持平:与10分钟前变化不大 缓解:较10分钟前拥堵有所缓解 加重:较10分钟前拥堵加重

这个返回参数非常重要,在后续的响应对象封装中也是针对这个返回参数进行实现的。

二、Java响应对象封装

Java作为一种广泛使用的编程语言,以其强大的跨平台性、稳定性和丰富的类库,为开发复杂的应用程序提供了坚实的基础。而百度地图作为地图服务提供商,拥有海量的地理信息数据和先进的定位技术,能够为用户提供精准的路况信息。将Java与百度地图相结合,不仅可以充分利用Java的开发优势,还能借助百度地图的地理信息服务,为长沙市的路况检索提供一种高效、准确的解决方案。本节将重点针对实时路况的返回参数进行对象设置,为后面的数据存储提供服务。

1、响应对象设计

这里按照统一建模的方式对百度地图路况实时情况响应参数进行统一封装,这里包含5个对象,其中根据响应参数,封装公共对象,包含状态码和消息属性。

2、响应对象实现

基于上述的对象设计思路,下面给出具体的对象代码。

首先是公共类BdCommonDTO.java,作为父类,可以作为百度地图的公有数据父类,

java 复制代码
package com.yelang.project.meteorology.domain;
import java.io.Serializable;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
/**
 * - 百度接口公共DTO对象,用于封装通用信息
 * @author 夜郎king
 */
@NoArgsConstructor
@AllArgsConstructor
@Setter
@Getter
@ToString
public class BdCommonDTO implements Serializable {
	private static final long serialVersionUID = 4985268844473756688L;
	private int status;//状态码 本次API访问状态,如果成功返回0,如果失败返回其他数字。
	private String message;//响应信息 对status的中文描述
}

然后是BdTrafficDTO.java,这个类用于接收服务端返回的对象,实现json的反序列化,源码如下:

java 复制代码
package com.yelang.project.meteorology.domain;
import java.io.Serializable;
import java.util.List;
import com.google.gson.annotations.SerializedName;
import lombok.AllArgsConstructor;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
@NoArgsConstructor
@AllArgsConstructor
@Setter
@Getter
@ToString(callSuper=true)//callSuper=true表示输出父类属性
@EqualsAndHashCode(callSuper=true)
public class BdTrafficDTO extends BdCommonDTO implements Serializable{
	private static final long serialVersionUID = -5247239994807521257L;
	private String description;//路况语义化描述,如:'东四北大街:双向行驶缓慢;南向北,北新桥地铁站附近严重拥堵。'
	private BdTrafficEvaluation evaluation;//路况整体评估对象
	@SerializedName("road_traffic")
	private List<BdRoadTrafficDetail> roadTraffic;//路况详细信息
}

路况的整体评价类BdTrafficEvaluation.java,整体评价是实时路况中的一个重要对象,源码如下:

java 复制代码
package com.yelang.project.meteorology.domain;
import java.io.Serializable;
import com.google.gson.annotations.SerializedName;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
@NoArgsConstructor
@AllArgsConstructor
@Setter
@Getter
@ToString
public class BdTrafficEvaluation implements Serializable{
	private static final long serialVersionUID = -5992227893340489097L;
	private int status;//路况整体评价,支持以下值:0:未知路况 1:畅通 2:缓行 3:拥堵 4:严重拥堵
	@SerializedName("status_desc")
	private String statusDesc;//路况整体评价的语义化描述,如:"双向拥堵"或"东向西拥堵,西向东畅通"等。
}

路况详情BdRoadTrafficDetail.java用于接收路况详细信息详情,源码如下:

java 复制代码
package com.yelang.project.meteorology.domain;
import java.io.Serializable;
import java.util.List;
import com.google.gson.annotations.SerializedName;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
@NoArgsConstructor
@AllArgsConstructor
@Setter
@Getter
@ToString
public class BdRoadTrafficDetail implements Serializable{
	private static final long serialVersionUID = 3662254110577542026L;
	@SerializedName("road_name")
	private String roadName;//道路名称
	@SerializedName("congestion_sections")
	private List<BdTrafficCongestionSection> congestionSections;//拥堵路段详情
}

最后是拥堵路段详情信息对象BdTrafficCongestionSection.java,源码如下:

java 复制代码
package com.yelang.project.meteorology.domain;
import java.io.Serializable;
import com.google.gson.annotations.SerializedName;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
/**
 * - 拥堵路段详情
 * @author 夜郎king
 */
@NoArgsConstructor
@AllArgsConstructor
@Setter
@Getter
@ToString
public class BdTrafficCongestionSection implements Serializable {
	private static final long serialVersionUID = 6723821728526157035L;
	@SerializedName("section_desc")
	private String sectionDesc;// 路段拥堵语义化描述,如:南向北,北新桥地铁站附近严重拥堵
	private int status;// 路段拥堵评价,支持以下值:0:未知路况 1:畅通 2:缓行 3:拥堵 4:严重拥堵
	private double speed;// 平均通行速度,当前路段的平均通行速度 单位:千米/小时
	@SerializedName("congestion_distance")
	private int congestionDistance;// 拥堵距离,单位:米
	@SerializedName("congestion_trend")
	private String congestionTrend;// 较10分钟前拥堵趋势,
}

三、UniHttp集成及调用

本节将详细说明如何使用UniHttp进行道路实时路况服务的集成及实际调用。关于UniHttp如何集成的方法,在之前的系列博客中做了详细的讲解,这里不再赘述,不太熟悉的朋友可以翻阅之前的博客。本节主要从以下三个方面进行讲解,第一是UniHttp的检索接口声明,第二是道路实时路况查询,第三是周边实时路况查询及调用。

1、检索接口声明

集成检索服务接口的代码如下:

java 复制代码
package com.yelang.project.thridinterface;
import com.burukeyou.uniapi.http.annotation.param.QueryPar;
import com.burukeyou.uniapi.http.annotation.request.GetHttpInterface;
import com.burukeyou.uniapi.http.core.response.HttpResponse;
import com.yelang.project.thridinterface.apiprocessor.BaiduHttpApi;

@BaiduHttpApi(snMode = false)
public interface BaiduTrafficService {
	/**
	 * -道路路况查询
	 * @param roadName 道路名称,如:"五一大道"、"中山路"。
	 * @param city     城市名称,全国城市名称,如:"北京市"、"上海市"等,也可以是百度的行政区划代号
	 * @param ak       用户的AK,授权使用
	 * @return
	 */
	@GetHttpInterface(path = "/traffic/v1/road")
	public HttpResponse<String> roadTraffic(@QueryPar("road_name") String roadName, @QueryPar("city") String city,
			@QueryPar("ak") String ak);

	/**
	 * - 周边路况查询
	 * 
	 * @param center         中心点坐标,如center=39.912078,116.464303
	 * @param radius         查询半径,单位:米,取值范围[1,1000] 示例: radius=200
	 * @param roadGrade      道路等级 - 用户可进行道路等级筛选,支持选择多个道路等级。道路等级之间使用英文","分隔。 
	 * -                      默认值:road_grade=0 道路等级对应表如下: 0:全部驾车道路 1:高速路 2:环路及快速路
	 * -                       3:主干路 4:次干路 5:支干路 - 示例: 查询全部驾车道路路况:road_grade:0
	 * -                       查询高速道路路况:road_grade:1
	 * -                     查询高速路、环路及快速路、主干路的路况:road_grade=1,2,3
	 * @param coordTypeInput 请求参数 bounds的坐标类型 默认值:bd09ll - 取值范围: bd09ll:百度经纬度坐标
	 *                       gcj02:国测局加密坐标 wgs84:gps 坐标
	 * @param                coordTypeOutput返回结果的坐标类型,默认值:bd09ll -
	 *-                       该字段用于控制返回结果中坐标的类型。可选值为: bd09ll:百度经纬度坐标 gcj02:国测局加密坐标
	 * @param ak
	 * @return 用户的AK,授权使用
	 */
	@GetHttpInterface(path = "/traffic/v1/around")
	public HttpResponse<String> aroundTraffic(@QueryPar("center") String center, @QueryPar("radius") int radius,
			@QueryPar("road_grade") int roadGrade, @QueryPar("coord_type_input") String coordTypeInput,
			@QueryPar("coord_type_output") String coordTypeOutput, @QueryPar("ak") String ak);
}

需要说明的是,这个接口我们没有使用SN签名模式,因此在创建接口时,需要指定snMode为false,代码如下:snMode = false

2、道路实时路况查询

我们先来看一下官方地图的道路拥堵情况,可以在百度地图首页进行道路拥堵情况查看,

这里我们将整理以下道路进行道路实况查询:

bash 复制代码
"三一大道","南湖路","五一大道","枫林三路","芙蓉中路"

来看一下通过道路实况服务的检索服务如何调用:

java 复制代码
package com.yelang.project.unihttp;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import com.burukeyou.uniapi.http.core.response.HttpResponse;
import com.google.gson.Gson;
import com.yelang.common.utils.StringUtils;
import com.yelang.project.meteorology.domain.BdTrafficDTO;
import com.yelang.project.thridinterface.BaiduTrafficService;
/**
 * - 百度地图实时路况服务测试类
 * @author 夜郎king
 */
@SpringBootTest
@RunWith(SpringRunner.class)
public class BaiduTrafficServiceCase {
	private static final String BAIDU_DEFAULT_AK = "yourak";
	@Autowired
	private BaiduTrafficService trafficService;
	private static final String DEFAULT_CITY = "长沙市";
	/**
	 * - 模拟根据道路名称查询拥堵情况
	 * @throws InterruptedException
	 */
	@Test
	public void testRoadTraffic() throws InterruptedException {
		//模拟获取三一大道、五一大道、枫林三路、芙蓉中路的交通实况
		String [] road_array = {"三一大道","南湖路","五一大道","枫林三路","芙蓉中路"};
		Gson gson = new Gson();
		for(String road : road_array) {
			HttpResponse<String> result = trafficService.roadTraffic(road, DEFAULT_CITY, BAIDU_DEFAULT_AK);
			if(StringUtils.isNotEmpty(result.getBodyResult())) {
				BdTrafficDTO trafficDTO = gson.fromJson(result.getBodyResult(), BdTrafficDTO.class);
				System.out.println(trafficDTO);
			}
			Thread.sleep(1500L);
		}
	}
}

运行以上代码后,在控制台可以看到以下内容输出:

可以看到路网的实时拥堵情况已经进行了实时输出。位置和拥堵情况基本是一致的。

3、周边实时路况查询

为了模拟周边实时路况查询,我们列出节日这几天的热门景点的位置,选取的景点如下:

bash 复制代码
橘子洲景区、芙蓉广场地铁站、岳麓山风景区、湖南省博物馆

我们通过坐标拾取器并将坐标转为wgs84后,进行周边道路实况模拟,核心代码如下:

java 复制代码
package com.yelang.project.unihttp;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import com.burukeyou.uniapi.http.core.response.HttpResponse;
import com.google.gson.Gson;
import com.yelang.common.utils.StringUtils;
import com.yelang.project.meteorology.domain.BdTrafficDTO;
import com.yelang.project.thridinterface.BaiduTrafficService;
/**
 * - 百度地图实时路况服务测试类
 * @author 夜郎king
 */
@SpringBootTest
@RunWith(SpringRunner.class)
public class BaiduTrafficServiceCase {
	private static final String BAIDU_DEFAULT_AK = "yourak";
	@Autowired
	private BaiduTrafficService trafficService;
	private static final String DEFAULT_CITY = "长沙市";
	/**
	 * - 模拟根据坐标查询附近周围交通情况
	 * @throws InterruptedException
	 */
	@Test
	public void testAroundTraffic() throws InterruptedException {
		// 以下位置分别表示  橘子洲景区、芙蓉广场地铁站、岳麓山风景区、湖南省博物馆
		String [] centers = {"28.198986,112.95722","28.198243,112.978962","28.196981,112.943391","28.215134,112.986896"};
		Gson gson = new Gson();
		int radius = 100;
		int roadGrade = 0;
		String coordTypeInput = "wgs84";// gps coord_type_input参数错误
		String coordTypeOutput = "bd09ll";//请注意,输出坐标,不能为wgs84
		for(String center : centers) {
			HttpResponse<String> result = trafficService.aroundTraffic(center, radius, roadGrade, coordTypeInput, coordTypeOutput, BAIDU_DEFAULT_AK);
			if(StringUtils.isNotEmpty(result.getBodyResult())) {
				BdTrafficDTO trafficDTO = gson.fromJson(result.getBodyResult(), BdTrafficDTO.class);
				System.out.println(trafficDTO);
			}
			Thread.sleep(1500L);
		}
	}
}

分别对以上位置求解100米范围的路网路况信息,运行程序后可以看到以下输出:

周边实时路况列表如下:

bash 复制代码
橘子洲景区:
该区域整体轻微拥堵。五一大道:东向西,橘子洲大桥附近严重拥堵。
橘子洲大桥:东向西,橘子洲大桥严重拥堵。

芙蓉广场地铁站附近:
区域整体畅通。

岳麓山风景区:
该区域整体畅通。

湖南省博物馆:
该区域整体轻微拥堵。东风路:南向北,德雅路附近行驶缓慢。

以上就是两个道路实时路况接口的集成及调用完整过程。

四、常见问题

本节将分享几个在集成的过程中容易碰到的问题以及解决办法。

1、道路名称错误

特别容易碰到的第一个问题就是道路名称,百度地图本身的路网数据中,如果没有要查找的道路(比如长沙市五一路,实际名称是五一大道),那么就会如下错误:

bash 复制代码
{"status":2,"message":"road_name错误"}

针对道路名称错误,一方面需要在官方平台进行道路名称查询,或者可以使用官网的地点输入提示接口进行道路的补充。

2、中心点坐标位置错误

中心点位坐标位置错误也是极易出现的问题,出现位置错误的后台错误信息如下:

bash 复制代码
{"message":"center参数错误","status":2}

这种情况可能有两种原因,第一种是坐标中有空格,比如:

java 复制代码
"28.198986,	 112.95722"

还有一种情况就是将经度放在了前面,标准格式是纬度,经度。

java 复制代码
"112.95722,28.198986"

因此针对这两种情况的解决办法都比较简单,首先一定要保证输入参数的顺序,必须是纬度,经度。并且坐标串之间不能有空格。

3、坐标类型错误

第三种是遇到坐标类型错误,错误信息如下:

bash 复制代码
{"message":"coord_type_input参数错误","status":2}

出现这种问题,通常是输入坐标的类型错误,一定要看清楚,如果是gps坐标,一定要选择wgs84,而不是gps。

特别需要注意的是,coordTypeOutput返回结果的坐标类型,默认值:bd09ll。这里可能有小伙伴会说,输出类型是不是也可以选wgs84。很遗憾,返回结果中,并没有wgs84。其实这里有个小小的疑问,在返回参数中,并没有坐标返回,因此这个参数的意义是什么呢?这需要咨询一下官方的技术同学了。

4、命名的小插曲

与上面输出坐标类型相似,在道路周边服务的请求参数中,道路等级的命名是road_grade。而在返回参数中有一个道路类型的标识,但此时的名称是road_type。虽然不影响使用,但是从统一性来说,还是一致会比较好。而且这个参数在官网的文档中没有说明。

五、总结

以上就是本文的主要内容,本实践探索旨在通过Java编程语言调用百度地图的API接口,实现对长沙市热门道路与景点的实时路况检索功能。通过对百度地图API的深入研究与应用,我们将构建一个用户友好的路况检索系统,使用户能够随时随地获取最新的路况信息,从而优化出行路线,减少交通拥堵,提高出行效率。在实践过程中,我们将详细探讨如何利用Java语言实现与百度地图API的无缝对接,包括API的注册与申请、数据的获取与解析等多个关键环节。通过文章详细的说明,相信大家对百度地图的实时路况API,Java响应对象封装和UniHttp的接口集成有了更深的了解,最后还分享了以下常见的问题,帮助大家更好的解决可能遇到的一些问题,在使用的过程中也能快速的发现问题,避免一些坑点和雷点。行文仓促,定有不足之处,欢迎各位朋友在评论区批评指正,不胜感激。