| | |
| | | package com.xiaopeng.pushMessage.utils; |
| | | |
| | | import com.alibaba.fastjson2.JSON; |
| | | import com.alibaba.fastjson2.JSONArray; |
| | | import com.alibaba.fastjson2.JSONObject; |
| | | import com.xiaopeng.api.dto.operation.LonLatDto; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.gavaghan.geodesy.Ellipsoid; |
| | | import org.gavaghan.geodesy.GeodeticCalculator; |
| | | import org.gavaghan.geodesy.GeodeticCurve; |
| | | import org.gavaghan.geodesy.GlobalCoordinates; |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.Collections; |
| | | import java.util.List; |
| | | import java.util.*; |
| | | import java.util.concurrent.*; |
| | | |
| | | |
| | | @Slf4j |
| | | public class MapMatchingUtil { |
| | | |
| | | |
| | | |
| | | |
| | | /** |
| | | * 获取剩余导航数据 |
| | | * @param polyline |
| | | * @param longitude |
| | | * @param latitude |
| | | * @return |
| | | */ |
| | | public static Map<String, List<LonLatDto>> getRemainingNavigation(List<LonLatDto> polyline, Double longitude, Double latitude){ |
| | | //导航数据只有一个点的情况 |
| | | Map<String, List<LonLatDto>> map = new HashMap<>(); |
| | | if(polyline.size() == 1){ |
| | | LonLatDto lonLatDto = polyline.get(0); |
| | | GlobalCoordinates source1 = new GlobalCoordinates(lonLatDto.getLatitude(), lonLatDto.getLongitude()); |
| | | GlobalCoordinates target1 = new GlobalCoordinates(latitude, longitude); |
| | | GeodeticCurve geoCurve1 = new GeodeticCalculator().calculateGeodeticCurve(Ellipsoid.WGS84, source1, target1); |
| | | double distance =geoCurve1.getEllipsoidalDistance(); |
| | | //判断距离小于5米,则可以返回空数据 |
| | | if(5 >= distance){ |
| | | map.put("unserved", new ArrayList<>()); |
| | | map.put("served", new ArrayList<>()); |
| | | return map; |
| | | } |
| | | //大于5米的情况,将车子当前位置添加进结果中 |
| | | map.put("unserved", polyline); |
| | | map.put("served", new ArrayList<>()); |
| | | return map; |
| | | } |
| | | //多个点位的情况,需要找出当前点位处于那两个点位之间,然后截取掉超出的部分轨迹 |
| | | return getRecentlyPoint(polyline, longitude, latitude); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 判断点位在轨迹线路中的点位之间 |
| | | * 返回截取后的剩余轨迹 |
| | | * @param polyline |
| | | * @param longitude |
| | | * @param latitude |
| | | * @return |
| | | */ |
| | | public static Map<String, List<LonLatDto>> getRecentlyPoint(List<LonLatDto> polyline, Double longitude, Double latitude){ |
| | | Map<String, List<LonLatDto>> map = new HashMap<>(); |
| | | for (int i = 0; i < polyline.size(); i++) { |
| | | if(i == polyline.size() - 1){ |
| | | break; |
| | | } |
| | | LonLatDto lonLatDto1 = polyline.get(i); |
| | | |
| | | //车辆到第一个点位的距离 |
| | | GlobalCoordinates source1 = new GlobalCoordinates(lonLatDto1.getLatitude(), lonLatDto1.getLongitude()); |
| | | GlobalCoordinates target1 = new GlobalCoordinates(latitude, longitude); |
| | | GeodeticCurve geoCurve1 = new GeodeticCalculator().calculateGeodeticCurve(Ellipsoid.WGS84, source1, target1); |
| | | double distance1 =geoCurve1.getEllipsoidalDistance(); |
| | | |
| | | //车辆到第二个点位的距离 |
| | | LonLatDto lonLatDto2 = polyline.get(i + 1); |
| | | GlobalCoordinates source2 = new GlobalCoordinates(lonLatDto2.getLatitude(), lonLatDto2.getLongitude()); |
| | | GlobalCoordinates target2 = new GlobalCoordinates(latitude, longitude); |
| | | GeodeticCurve geoCurve2 = new GeodeticCalculator().calculateGeodeticCurve(Ellipsoid.WGS84, source2, target2); |
| | | double distance2 =geoCurve2.getEllipsoidalDistance(); |
| | | |
| | | //第一个点位到第二个点位的距离 |
| | | GlobalCoordinates source3 = new GlobalCoordinates(lonLatDto1.getLatitude(), lonLatDto1.getLongitude()); |
| | | GlobalCoordinates target3 = new GlobalCoordinates(lonLatDto2.getLatitude(), lonLatDto2.getLongitude()); |
| | | GeodeticCurve geoCurve3 = new GeodeticCalculator().calculateGeodeticCurve(Ellipsoid.WGS84, source3, target3); |
| | | double distance3 =geoCurve3.getEllipsoidalDistance(); |
| | | |
| | | //车辆位置在第二个点位的前面 |
| | | //这种情况需要从第二个点位开始截取,最终剩余的轨迹从第三个点位开始 |
| | | if(distance1 > distance2 && distance1 > distance3){ |
| | | //继续向前找,找车辆处于那一段点位中间 |
| | | continue; |
| | | } |
| | | //车辆位置在两点之间的情况 |
| | | //车辆位置到上一个点的距离+车辆位置到下一个点的距离 = 上一个点到下一个点的距离 |
| | | //车辆位置到上一个点的距离+车辆位置到下一个点的距离 <= 上一个点到下一个点的距离 + 5米的漂移量 |
| | | if ((distance1 + distance2) == distance3 || (distance1 + distance2) <= distance3 + 5) { |
| | | //剩余未服务的点位 |
| | | List<LonLatDto> unserved = new ArrayList<>(polyline.subList(i + 1, polyline.size())); |
| | | List<LonLatDto> served = new ArrayList<>(polyline.subList(0, i + 1)); |
| | | map.put("unserved", unserved); |
| | | map.put("served", served); |
| | | |
| | | System.err.println("车辆在两点之间,从第二个开始截取 : " + i); |
| | | return map; |
| | | } |
| | | } |
| | | //所有数据遍历完后任然没有合适的数据则返回原始数据 |
| | | map.put("unserved", polyline); |
| | | map.put("served", new ArrayList<>()); |
| | | return map; |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | /** |
| | | * 轨迹裁剪(线段版本) |
| | |
| | | } |
| | | |
| | | |
| | | public static void main(String[] args) { |
| | | String json = "[{\n" + |
| | | "\t\"latitude\": 23.155130575839845,\n" + |
| | | "\t\"longitude\": 113.3843844686235\n" + |
| | | "}, {\n" + |
| | | "\t\"latitude\": 23.155210151679693,\n" + |
| | | "\t\"longitude\": 113.38426593724698\n" + |
| | | "}, {\n" + |
| | | "\t\"latitude\": 23.155289727519538,\n" + |
| | | "\t\"longitude\": 113.38414740587048\n" + |
| | | "}, {\n" + |
| | | "\t\"latitude\": 23.15529,\n" + |
| | | "\t\"longitude\": 113.384147\n" + |
| | | "}, {\n" + |
| | | "\t\"latitude\": 23.155362958389055,\n" + |
| | | "\t\"longitude\": 113.38402358903004\n" + |
| | | "}, {\n" + |
| | | "\t\"latitude\": 23.155435916778114,\n" + |
| | | "\t\"longitude\": 113.38390017806007\n" + |
| | | "}, {\n" + |
| | | "\t\"latitude\": 23.15550887516717,\n" + |
| | | "\t\"longitude\": 113.3837767670901\n" + |
| | | "}, {\n" + |
| | | "\t\"latitude\": 23.155581833556226,\n" + |
| | | "\t\"longitude\": 113.38365335612013\n" + |
| | | "}, {\n" + |
| | | "\t\"latitude\": 23.155585,\n" + |
| | | "\t\"longitude\": 113.383648\n" + |
| | | "}, {\n" + |
| | | "\t\"latitude\": 23.155542,\n" + |
| | | "\t\"longitude\": 113.383621\n" + |
| | | "}, {\n" + |
| | | "\t\"latitude\": 23.155312,\n" + |
| | | "\t\"longitude\": 113.383648\n" + |
| | | "}, {\n" + |
| | | "\t\"latitude\": 23.155180919552134,\n" + |
| | | "\t\"longitude\": 113.3836848841087\n" + |
| | | "}, {\n" + |
| | | "\t\"latitude\": 23.155081,\n" + |
| | | "\t\"longitude\": 113.383713\n" + |
| | | "}, {\n" + |
| | | "\t\"latitude\": 23.15495796304221,\n" + |
| | | "\t\"longitude\": 113.38377424506344\n" + |
| | | "}, {\n" + |
| | | "\t\"latitude\": 23.154856,\n" + |
| | | "\t\"longitude\": 113.383825\n" + |
| | | "}, {\n" + |
| | | "\t\"latitude\": 23.154741004509642,\n" + |
| | | "\t\"longitude\": 113.38390239240225\n" + |
| | | "}, {\n" + |
| | | "\t\"latitude\": 23.154626009019285,\n" + |
| | | "\t\"longitude\": 113.38397978480451\n" + |
| | | "}, {\n" + |
| | | "\t\"latitude\": 23.154593,\n" + |
| | | "\t\"longitude\": 113.384002\n" + |
| | | "}, {\n" + |
| | | "\t\"latitude\": 23.154488868635756,\n" + |
| | | "\t\"longitude\": 113.3840956684042\n" + |
| | | "}, {\n" + |
| | | "\t\"latitude\": 23.15438473727151,\n" + |
| | | "\t\"longitude\": 113.3841893368084\n" + |
| | | "}, {\n" + |
| | | "\t\"latitude\": 23.153869,\n" + |
| | | "\t\"longitude\": 113.384732\n" + |
| | | "}, {\n" + |
| | | "\t\"latitude\": 23.153783434325412,\n" + |
| | | "\t\"longitude\": 113.38484554532484\n" + |
| | | "}, {\n" + |
| | | "\t\"latitude\": 23.153697868650823,\n" + |
| | | "\t\"longitude\": 113.38495909064967\n" + |
| | | "}, {\n" + |
| | | "\t\"latitude\": 23.153612302976235,\n" + |
| | | "\t\"longitude\": 113.3850726359745\n" + |
| | | "}, {\n" + |
| | | "\t\"latitude\": 23.153606,\n" + |
| | | "\t\"longitude\": 113.385081\n" + |
| | | "}, {\n" + |
| | | "\t\"latitude\": 23.15352802191651,\n" + |
| | | "\t\"longitude\": 113.38520076538181\n" + |
| | | "}, {\n" + |
| | | "\t\"latitude\": 23.153450043833022,\n" + |
| | | "\t\"longitude\": 113.38532053076364\n" + |
| | | "}, {\n" + |
| | | "\t\"latitude\": 23.153397,\n" + |
| | | "\t\"longitude\": 113.385402\n" + |
| | | "}, {\n" + |
| | | "\t\"latitude\": 23.15332878835048,\n" + |
| | | "\t\"longitude\": 113.38552854437049\n" + |
| | | "}, {\n" + |
| | | "\t\"latitude\": 23.15326057670096,\n" + |
| | | "\t\"longitude\": 113.38565508874098\n" + |
| | | "}, {\n" + |
| | | "\t\"latitude\": 23.153252,\n" + |
| | | "\t\"longitude\": 113.385671\n" + |
| | | "}, {\n" + |
| | | "\t\"latitude\": 23.153190501345524,\n" + |
| | | "\t\"longitude\": 113.3858015058656\n" + |
| | | "}, {\n" + |
| | | "\t\"latitude\": 23.15312900269105,\n" + |
| | | "\t\"longitude\": 113.38593201173121\n" + |
| | | "}, {\n" + |
| | | "\t\"latitude\": 23.15308,\n" + |
| | | "\t\"longitude\": 113.386036\n" + |
| | | "}, {\n" + |
| | | "\t\"latitude\": 23.15306,\n" + |
| | | "\t\"longitude\": 113.386128\n" + |
| | | "}]"; |
| | | List<LonLatDto> polyline = JSON.parseArray(json, LonLatDto.class); |
| | | String xcgj = "[{\"longitude\":113.38368194444445,\"latitude\":23.15508361111111}]"; |
| | | List<LonLatDto> lonLatDtos = JSON.parseArray(xcgj, LonLatDto.class); |
| | | for (LonLatDto lonLatDto : lonLatDtos) { |
| | | Map<String, List<LonLatDto>> remainingNavigation = getRemainingNavigation(polyline, lonLatDto.getLongitude(), lonLatDto.getLatitude()); |
| | | List<LonLatDto> unserved = remainingNavigation.get("unserved"); |
| | | List<LonLatDto> served = remainingNavigation.get("served"); |
| | | System.err.println(JSON.toJSONString(served)); |
| | | polyline = unserved; |
| | | |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | // JSONArray objects = JSON.parseArray("[{\"latitude\":23.154856,\"longitude\":113.383825},{\"latitude\":23.154741004509642,\"longitude\":113.38390239240225},{\"latitude\":23.154626009019285,\"longitude\":113.38397978480451},{\"latitude\":23.154593,\"longitude\":113.384002},{\"latitude\":23.154488868635756,\"longitude\":113.3840956684042},{\"latitude\":23.15438473727151,\"longitude\":113.3841893368084},{\"latitude\":23.153869,\"longitude\":113.384732},{\"latitude\":23.153783434325412,\"longitude\":113.38484554532484},{\"latitude\":23.153697868650823,\"longitude\":113.38495909064967},{\"latitude\":23.153612302976235,\"longitude\":113.3850726359745},{\"latitude\":23.153606,\"longitude\":113.385081},{\"latitude\":23.15352802191651,\"longitude\":113.38520076538181},{\"latitude\":23.153450043833022,\"longitude\":113.38532053076364},{\"latitude\":23.153397,\"longitude\":113.385402},{\"latitude\":23.15332878835048,\"longitude\":113.38552854437049},{\"latitude\":23.15326057670096,\"longitude\":113.38565508874098},{\"latitude\":23.153252,\"longitude\":113.385671},{\"latitude\":23.153190501345524,\"longitude\":113.3858015058656},{\"latitude\":23.15312900269105,\"longitude\":113.38593201173121},{\"latitude\":23.15308,\"longitude\":113.386036},{\"latitude\":23.15306,\"longitude\":113.386128}]"); |
| | | // String str = "["; |
| | | // for (int i = 0; i < objects.size(); i++) { |
| | | // JSONObject jsonObject = objects.getJSONObject(i); |
| | | // str += "[" + jsonObject.getDouble("longitude") + "," + jsonObject.getDouble("latitude") + "],"; |
| | | // } |
| | | // System.err.println(str + "]"); |
| | | } |
| | | |
| | | } |