java+postgis实现根据两点生成模拟轨迹gps数据
java+postgis实现根据两点生成模拟轨迹gps数据
文章目录
前言
在我们开发系统过程中少不了需要制造一些测试数据用来检验功能的正确性,同时在功能演示给客户坐汇报也需要用到一些测试模拟真实的数据来展示效果,但是我们如果手动去制作这些测试数据就会很耗时耗力,通过代码的方式去自动生成测试数据就显得比较重要了。
常见的测试数据文本描述类型的制造起来相对容易,但是我们如果需要制造出模拟一辆或者多辆车的行驶轨迹GPS点位数据就比较麻烦,首先得保证数据是在道路上面且道路具有连贯性,其次需要保证移动的位置和方向以及每次行驶的距离具有真实性,这样难度就比较大了,下文就来实现如何快速生成这种比较难以手动制造的车辆行驶轨迹的模拟GPS点位数据。
一、实现流程
1.请求参数
points:点位信息,可以设置途径点,多个点位用分号隔开,格式:起点;途径点;终点
timeInterval:间隔时间 用来控制模拟数据的计算点位 单位秒
speed:平均速度 用来控制模拟数据的计算点位 单位KM/H
randomBase:用来控制数据点位的随机起伏基数,动态调整模拟出来的点位效果
2.功能流程
发送请求 —》根据点位信息查询路径规划数据 —》根据路径规划线(基于graphHopper实现可以参照之前的文章实现)路数据进行插值计算遍历获取到轨迹点位 —》生成结果geojson轨迹点位数据
3.postgis重要使用函数介绍
ST_LineInterpolatePoint:返回沿直线在分数位置处插补的点。
函数结构:第一个参数为线的空间几何数据,第二个参数是一个介于0和1之间的浮点数,表示点所在的线长度的分数。返回一个点几何对象。
geometry ST_LineInterpolatePoint(geometry a_linestring, float8 a_fraction);
4.生成的GPS模拟轨迹点位效果图
二、具体代码
1.核心代码
代码如下(示例):
public JSONObject generateTrackData(String points, Double timeInterval, Double speed,Double randomBase) {
JSONObject result = new JSONObject();
result.put("type","FeatureCollection");
JSONArray features = new JSONArray();
List<GHPoint> GHpoints = new ArrayList<>();
String[] pointsz = points.split(";", -1);
// 遍历同时检查点位 如果超出中国范围的点位直接处理掉
for (int i = 0; i < pointsz.length; i++) {
GHpoints.add(GHPoint.fromStringLonLat(pointsz[i]));
}
// 请求对象的简单配置
GHRequest req = new GHRequest(GHpoints).setProfile("car").setLocale(Locale.CHINA);
// 获取返回结果
GHResponse rsp = graphHopper.route(req);
// handle errors
if (rsp.hasErrors())
throw new RuntimeException(rsp.getErrors().toString());
// 获取返回的路线数据 然后根据路线生成对应轨迹点
ResponsePath path = rsp.getBest();
// 全路径的点、距离(米)和时间(毫秒)
PointList routePointList = path.getPoints();
//获取到总路线长度距离 单位米
double routeDistance = path.getDistance();
String routeWkt = routePointList.toLineString(true).toString();
// 根据参数计算传入间隔时间每次行驶距离 单位米
double distanceOneS = timeInterval * speed / 3600 * 1000;
//获取到模拟生成的点位个数
int pointCount = (int) Math.ceil(routeDistance / distanceOneS);
double percent = 0.0;
for(int i = 0;i <pointCount;i++){
double dl = 1.0 / pointCount;
Map<String, Object> feature = new HashMap<>();
double bl = Math.random() * randomBase;
if(Math.random()<0.5 && dl+(bl*-1) > 0 ){
bl += bl*-1;
}
percent += dl + bl;
if(percent <= 1){
// 赋值 空间字段
Map<String, Object> geometry = new HashMap<>();
String sql = "SELECT ST_x(ST_LineInterpolatePoint(geom, " + percent + ")) as x,ST_y(ST_LineInterpolatePoint(geom, " + percent + ")) as y FROM (SELECT ST_GeomFromText('" + routeWkt + "',4326) as geom) As insert_point ;";
Map<String, Object> xy = jdbcTemplate.queryForMap(sql);
double lng = (double) xy.get("x");
double lat = (double) xy.get("y");
double[] location = new double[2];
location[0] = lng;
location[1] = lat;
geometry.put("type", "Point");
geometry.put("coordinates", location);
feature.put("geometry",geometry );
feature.put("type","Feature" );
features.add(feature);
}
}
result.put("features",features);
return result;
}
总结
以上就是实现生成模拟轨迹GPS数据的整体流程,可以根据具体使用场景去完善,目前随机生成点位这块还有优化空间。